Contain the information to be changed for calendar related item.
        public void MSOXWSMTGS_S06_TC01_CalendarPermissionLevelOwner()
        {
            this.MTGSAdapter = new MS_OXWSMTGSAdapter();
            this.MTGSAdapter.Initialize(this.Site);
            this.SRCHAdapter = new MS_OXWSSRCHAdapter();
            this.SRCHAdapter.Initialize(this.Site);
            this.FOLDAdapter = new MS_OXWSFOLDAdapter();
            this.FOLDAdapter.Initialize(this.Site);

            #region Organizer creates a calendar folder in the inbox folder and grant Owner permission to attendee.

            // Switch to user organizer.
            this.FOLDAdapter.SwitchUser(this.Organizer, this.OrganizerPassword, this.Domain);

            CalendarPermissionSetType calendarPermissionSet = new CalendarPermissionSetType();
            calendarPermissionSet.CalendarPermissions = new CalendarPermissionType[1];
            calendarPermissionSet.CalendarPermissions[0] = new CalendarPermissionType();
            calendarPermissionSet.CalendarPermissions[0].CalendarPermissionLevel = CalendarPermissionLevelType.Owner;
            calendarPermissionSet.CalendarPermissions[0].UserId = new UserIdType();
            calendarPermissionSet.CalendarPermissions[0].UserId.PrimarySmtpAddress = Common.GetConfigurationPropertyValue("AttendeeName", this.Site) + "@" + Common.GetConfigurationPropertyValue("Domain", this.Site);

            CreateFolderType createFolderRequest = this.GetCreateFolderRequest(DistinguishedFolderIdNameType.inbox.ToString(), new string[] { "CustomFolderByOrganizer" }, new string[] { "IPF.Appointment" }, null);
            ((CalendarFolderType)createFolderRequest.Folders[0]).PermissionSet = calendarPermissionSet;

            // Create a new folder.
            CreateFolderResponseType createFolderResponse = this.FOLDAdapter.CreateFolder(createFolderRequest);

            // Check the response.
            Common.CheckOperationSuccess(createFolderResponse, 1, this.Site);

            // Save the new created folder's folder id.
            FolderIdType newFolderIdByOrganizer = ((FolderInfoResponseMessageType)createFolderResponse.ResponseMessages.Items[0]).Folders[0].FolderId;
            this.FolderToDelete = newFolderIdByOrganizer;
            #endregion

            #region Organizer gets the new created folder.

            // GetFolder request.
            GetFolderType getNewFolderRequest = this.GetGetFolderRequest(DefaultShapeNamesType.AllProperties, newFolderIdByOrganizer);

            // Get the new created folder.
            GetFolderResponseType getInboxFolderResponse = this.FOLDAdapter.GetFolder(getNewFolderRequest);

            // Check the response.
            Common.CheckOperationSuccess(getInboxFolderResponse, 1, this.Site);

            // Verify the folder is created successfully.
            FolderInfoResponseMessageType foldersResponseInfo = (FolderInfoResponseMessageType)getInboxFolderResponse.ResponseMessages.Items[0];
            Site.Assert.AreEqual<string>(newFolderIdByOrganizer.Id, foldersResponseInfo.Folders[0].FolderId.Id, "The calendar folder should be created successfully in inbox.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R507");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R507
            // The element with type CalendarFolderType is returned and pass the schema validation, this requirement can be captured.
            this.Site.CaptureRequirementIfIsInstanceOfType(
                foldersResponseInfo.Folders[0],
                typeof(CalendarFolderType),
                507,
                @"[In t:CalendarFolderType Complex Type] This complex type extends the BaseFolderType complex type, as specified in [MS-OXWSFOLD] section 2.2.4.6.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R143");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R143
            // The element with type CalendarFolderType is returned and pass the schema validation, this requirement can be captured.
            this.Site.CaptureRequirementIfIsInstanceOfType(
                foldersResponseInfo.Folders[0],
                typeof(CalendarFolderType),
                143,
                @"[In t:CalendarFolderType Complex Type] [its schema is] <xs:complexType name=""CalendarFolderType"">
                  <xs:complexContent>
                    <xs:extension
                      base=""t:BaseFolderType""
                      >
                    <xs:sequence>
                      <xs:element name=""SharingEffectiveRights""
                      type=""t:CalendarPermissionReadAccessType""
                      minOccurs=""0""
                    />
                    <xs:element name=""PermissionSet""
                      type=""t:CalendarPermissionSetType""
                      minOccurs=""0""
                    />
                  </xs:sequence>
                </xs:extension>
              </xs:complexContent>
            </xs:complexType>");

            CalendarFolderType folderInfo = (CalendarFolderType)foldersResponseInfo.Folders[0];

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R237");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R237
            this.Site.CaptureRequirementIfIsNotNull(
                folderInfo.PermissionSet,
                237,
                @"[In t:CalendarPermissionSetType Complex Type] [its schema is] <xs:complexType name=""CalendarPermissionSetType"">
                  <xs:sequence>
                    <xs:element name=""CalendarPermissions""
                      type=""t:ArrayOfCalendarPermissionsType""
                     />
                    <xs:element name=""UnknownEntries""
                      type=""t:ArrayOfUnknownEntriesType""
                      minOccurs=""0""
                     />
                  </xs:sequence>
                </xs:complexType>");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R146");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R146
            this.Site.CaptureRequirementIfIsNotNull(
                folderInfo.PermissionSet,
                146,
                @"[In t:CalendarFolderType Complex Type] The type of PermissionSet is t:CalendarPermissionSetType (section 2.2.4.5).");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R147");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R147
            this.Site.CaptureRequirementIfAreEqual<CalendarPermissionLevelType>(
                CalendarPermissionLevelType.Owner,
                folderInfo.PermissionSet.CalendarPermissions[2].CalendarPermissionLevel,
                147,
                @"[In t:CalendarFolderType Complex Type]PermissionSet: Specifies all permissions that are configured for a Calendar folder.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R534");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R534
            this.Site.CaptureRequirementIfIsNotNull(
                folderInfo.PermissionSet.CalendarPermissions,
                534,
                @"[In t:CalendarPermissionType Complex Type] This complex type extends the BasePermissionType complex type, as specified in [MS-OXWSFOLD] section 2.2.4.3.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R238");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R238
            this.Site.CaptureRequirementIfIsNotNull(
                folderInfo.PermissionSet.CalendarPermissions,
                238,
                @"[In t:CalendarPermissionSetType Complex Type] The type of CalendarPermissions is t:ArrayofCalendarPermissionsType ([MS-OXWSCDATA] section 2.2.4.4).");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R243");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R243
            this.Site.CaptureRequirementIfIsNotNull(
                folderInfo.PermissionSet.CalendarPermissions,
                243,
                @"[In t:CalendarPermissionType Complex Type] [its schema is] <xs:complexType name=""CalendarPermissionType"">
                  <xs:complexContent>
                    <xs:extension
                      base=""t:BasePermissionType""
                    >
                      <xs:sequence>
                        <xs:element name=""ReadItems""
                          type=""t:CalendarPermissionReadAccessType""
                          minOccurs=""0""
                          maxOccurs=""1""
                         />
                        <xs:element name=""CalendarPermissionLevel""
                          type=""t:CalendarPermissionLevelType""
                          minOccurs=""1""
                          maxOccurs=""1""
                         />
                      </xs:sequence>
                    </xs:extension>
                  </xs:complexContent>
                </xs:complexType>");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R244");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R244
            this.Site.CaptureRequirementIfIsTrue(
                folderInfo.PermissionSet.CalendarPermissions[2].ReadItemsSpecified,
                244,
                @"[In t:CalendarPermissionType Complex Type] The type of ReadItems is t:CalendarPermissionReadAccessType (section 2.2.5.5).");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R245");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R245
            // As organizer grants Owner to attendee, so ReadItems should be FullDetails.
            this.Site.CaptureRequirementIfAreEqual<CalendarPermissionReadAccessType>(
                CalendarPermissionReadAccessType.FullDetails,
                folderInfo.PermissionSet.CalendarPermissions[2].ReadItems,
                245,
                @"[In t:CalendarPermissionType Complex Type] ReadItems: Specifies the permissions a user has to view items in a Calendar folder.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R246");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R246
            this.Site.CaptureRequirementIfAreEqual<CalendarPermissionLevelType>(
                CalendarPermissionLevelType.Owner,
                folderInfo.PermissionSet.CalendarPermissions[2].CalendarPermissionLevel,
                246,
                @"[In t:CalendarPermissionType Complex Type] The type of CalendarPermissionLevel is t:CalendarPermissionLevelType (section 2.2.5.4).");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R247");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R247
            this.Site.CaptureRequirementIfAreEqual<CalendarPermissionLevelType>(
                CalendarPermissionLevelType.Owner,
                folderInfo.PermissionSet.CalendarPermissions[2].CalendarPermissionLevel,
                247,
                @"[In t:CalendarPermissionType Complex Type]CalendarPermissionLevel: Specifies the permission level that a user has on a Calendar folder.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R248");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R248
            this.Site.CaptureRequirementIfAreEqual<CalendarPermissionLevelType>(
                CalendarPermissionLevelType.Owner,
                folderInfo.PermissionSet.CalendarPermissions[2].CalendarPermissionLevel,
                248,
                @"[In t:CalendarPermissionType Complex Type] CalendarPermissionLevel: This element MUST exist if calendar permissions are set on a Calendar folder.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R97");

            // Verify MS-OXWSFOLD requirement: MS-OXWSMTGS_R97
            this.Site.CaptureRequirementIfIsTrue(
                folderInfo.PermissionSet.CalendarPermissions[2].IsFolderContactSpecified && folderInfo.PermissionSet.CalendarPermissions[2].IsFolderContact,
                97,
                @"[In t:CalendarPermissionLevelType Simple Type] Owner: The user is both folder owner and folder contact.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R239");

            // Verify MS-OXWSFOLD requirement: MS-OXWSMTGS_R239
            // This requirement can be captured directly after the verifications in above.
            this.Site.CaptureRequirement(
                239,
                @"[In t:CalendarPermissionSetType Complex Type] CalendarPermissions: Contains an array of calendar permissions for a folder.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R86");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R86
            // Element in type CalendarPermissionLevelType is returned, this requirement can be captured directly.
            this.Site.CaptureRequirement(
                86,
                @"[In t:CalendarPermissionLevelType Simple Type] [its schema is] <xs:simpleType name=""CalendarPermissionLevelType"">
                  <xs:restriction
                    base=""xs:string""
                  >
                    <xs:enumeration
                      value=""Author""
                     />
                    <xs:enumeration
                      value=""Contributor""
                     />
                    <xs:enumeration
                      value=""Custom""
                     />
                    <xs:enumeration
                      value=""Editor""
                     />
                    <xs:enumeration
                      value=""FreeBusyTimeAndSubjectAndLocation""
                     />
                    <xs:enumeration
                      value=""FreeBusyTimeOnly""
                     />
                    <xs:enumeration
                      value=""None""
                     />
                    <xs:enumeration
                      value=""NoneditingAuthor""
                     />
                    <xs:enumeration
                      value=""Owner""
                     />
                    <xs:enumeration
                      value=""PublishingAuthor""
                     />
                    <xs:enumeration
                      value=""PublishingEditor""
                     />
                    <xs:enumeration
                      value=""Reviewer""
                     />
                  </xs:restriction>
                </xs:simpleType>");
            #endregion

            #region Organizer creates a calendar item in the created folder.
            CalendarItemType calendarItembyOrganizer = new CalendarItemType();
            calendarItembyOrganizer.UID = Guid.NewGuid().ToString();
            calendarItembyOrganizer.Subject = Common.GenerateResourceName(this.Site, "CalendarItemCreatedByOrganizer");
            calendarItembyOrganizer.LegacyFreeBusyStatus = LegacyFreeBusyType.Busy;
            calendarItembyOrganizer.LegacyFreeBusyStatusSpecified = true;
            calendarItembyOrganizer.Location = this.Location;
            calendarItembyOrganizer.Body = new BodyType();
            calendarItembyOrganizer.Body.BodyType1 = BodyTypeType.Text;
            calendarItembyOrganizer.Body.Value = Common.GenerateResourceName(this.Site, "CalendarBody");
            NonEmptyArrayOfAllItemsType allItemArray = new NonEmptyArrayOfAllItemsType();
            allItemArray.Items = new ItemType[] { calendarItembyOrganizer };
            CreateItemType createItemRequest = new CreateItemType();
            createItemRequest.Items = allItemArray;
            createItemRequest.SendMeetingInvitationsSpecified = true;
            createItemRequest.SendMeetingInvitations = CalendarItemCreateOrDeleteOperationType.SendToNone;
            createItemRequest.SavedItemFolderId = new TargetFolderIdType();
            createItemRequest.SavedItemFolderId.Item = newFolderIdByOrganizer;
            CreateItemResponseType response = this.MTGSAdapter.CreateItem(createItemRequest);
            Site.Assert.AreEqual<ResponseClassType>(ResponseClassType.Success, response.ResponseMessages.Items[0].ResponseClass, "The calendar item should be created successfully.");
            ItemInfoResponseMessageType itemInfoResponse = response.ResponseMessages.Items[0] as ItemInfoResponseMessageType;
            Site.Assert.IsNotNull(itemInfoResponse, "The calendar item should be created successfully.");
            ItemIdType itemIdByOrganizer = itemInfoResponse.Items.Items[0].ItemId;
            #endregion

            #region Attendee creates a folder in the created folder.

            // Switch to user attendee.
            this.FOLDAdapter.SwitchUser(this.Attendee, this.AttendeePassword, this.Domain);

            createFolderRequest = this.GetCreateFolderRequest(newFolderIdByOrganizer.Id, new string[] { "CustomFolderByAttendee" }, new string[] { "IPF.Appointment" }, null);
            createFolderResponse = this.FOLDAdapter.CreateFolder(createFolderRequest);
            bool canCreateSubFolder = ResponseClassType.Success == createFolderResponse.ResponseMessages.Items[0].ResponseClass;

            #endregion

            #region Attendee creates a calendar item in the created folder.
            this.SwitchMTGSUser(Role.Attendee);
            CalendarItemType calendarItembyAttendee = new CalendarItemType();
            calendarItembyAttendee.UID = Guid.NewGuid().ToString();
            calendarItembyAttendee.Subject = Common.GenerateResourceName(this.Site, "CalendarItemCreatedByAttendee");
            createItemRequest.Items.Items[0] = calendarItembyAttendee;
            response = this.MTGSAdapter.CreateItem(createItemRequest);
            Site.Assert.AreEqual<ResponseClassType>(ResponseClassType.Success, response.ResponseMessages.Items[0].ResponseClass, "The calendar item should be created successfully.");
            itemInfoResponse = response.ResponseMessages.Items[0] as ItemInfoResponseMessageType;
            bool canCreateOwnItem = null != itemInfoResponse;
            Site.Assert.IsTrue(canCreateOwnItem, "The calendar item should be created successfully.");
            ItemIdType itemIdByAttendee = itemInfoResponse.Items.Items[0].ItemId;
            #endregion

            #region Attendee gets the calendar item created by hisself.
            itemInfoResponse = this.GetSingleCalendarItem(Role.Attendee, itemIdByAttendee);
            bool canReadOwnItem = null != itemInfoResponse;
            #endregion

            #region Attendee updates the calendar item created by hisself.
            CalendarItemType calendarUpdate = new CalendarItemType();
            calendarUpdate.Location = this.LocationUpdate;

            AdapterHelper itemChangeInfo = new AdapterHelper();
            itemChangeInfo.FieldURI = UnindexedFieldURIType.calendarLocation;
            itemChangeInfo.Item = calendarUpdate;
            itemChangeInfo.ItemId = itemIdByAttendee;

            // Update the created calendar item.
            UpdateItemResponseMessageType updatedItem = this.UpdateSingleCalendarItem(Role.Attendee, itemChangeInfo, CalendarItemUpdateOperationType.SendToNone);
            bool canUpdateOwnItem = null != updatedItem;
            #endregion

            #region Attendee deletes the calendar item created by hisself.
            ResponseMessageType responseMessage = this.DeleteSingleCalendarItem(Role.Attendee, itemIdByAttendee, CalendarItemCreateOrDeleteOperationType.SendToNone);
            bool canDeleteOwnItem = null != responseMessage && responseMessage.ResponseClass == ResponseClassType.Success;
            #endregion

            #region Attendee gets the calendar item created by organizer.
            itemInfoResponse = this.GetSingleCalendarItem(Role.Attendee, itemIdByOrganizer);
            bool canReadNotOwnItem = null != itemInfoResponse;

            if (canReadNotOwnItem)
            {
                CalendarItemType temp = itemInfoResponse.Items.Items[0] as CalendarItemType;
                Site.Assert.AreEqual<string>(calendarItembyOrganizer.Subject, temp.Subject, "User should have permission to view subject of appointment.");
                Site.Assert.AreEqual<string>(calendarItembyOrganizer.Location, temp.Location, "User should have permission to view location of appointment.");
                Site.Assert.AreEqual<bool>(calendarItembyOrganizer.LegacyFreeBusyStatusSpecified, temp.LegacyFreeBusyStatusSpecified, "User should have permission to view free/busy time of appointment.");
                Site.Assert.AreEqual<LegacyFreeBusyType>(calendarItembyOrganizer.LegacyFreeBusyStatus, temp.LegacyFreeBusyStatus, "User should have permission to view free/busy time of appointment.");
                Site.Assert.IsNotNull(temp.Body, "User should have permission to view body of appointment.");
                Site.Assert.AreEqual<BodyTypeType>(calendarItembyOrganizer.Body.BodyType1, temp.Body.BodyType1, "User should have permission to view body of appointment.");
                Site.Assert.AreEqual<string>(calendarItembyOrganizer.Body.Value, temp.Body.Value, "User should have permission to view body of appointment.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R107, the value of ReadItems is {0}", folderInfo.PermissionSet.CalendarPermissions[2].ReadItems);

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R107
                this.Site.CaptureRequirementIfIsTrue(
                    folderInfo.PermissionSet.CalendarPermissions[2].ReadItemsSpecified && folderInfo.PermissionSet.CalendarPermissions[2].ReadItems == CalendarPermissionReadAccessType.FullDetails,
                    107,
                    @"[In t:CalendarPermissionReadAccessType Simple Type] FullDetails: The user has permission to view all items in the calendar, including free/busy time and subject, location, and details of appointments.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R102");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R102
                this.Site.CaptureRequirement(
                    102,
                    @"[In t:CalendarPermissionReadAccessType Simple Type] [its schema is] <xs:simpleType name=""CalendarPermissionReadAccessType"">
                      <xs:restriction
                        base=""xs:string""                    
                      >
                        <xs:enumeration
                          value=""None""
                         />
                        <xs:enumeration
                          value=""TimeOnly""
                         />
                        <xs:enumeration
                          value=""TimeAndSubjectAndLocation""
                         />
                        <xs:enumeration
                          value=""FullDetails""
                         />
                      </xs:restriction>
                    </xs:simpleType>");
            }
            #endregion

            #region Attendee updates the calendar item created by organizer.
            calendarUpdate = new CalendarItemType();
            calendarUpdate.Location = this.LocationUpdate;

            itemChangeInfo = new AdapterHelper();
            itemChangeInfo.FieldURI = UnindexedFieldURIType.calendarLocation;
            itemChangeInfo.Item = calendarUpdate;
            itemChangeInfo.ItemId = itemIdByOrganizer;

            // Update the created calendar item.
            updatedItem = this.UpdateSingleCalendarItem(Role.Attendee, itemChangeInfo, CalendarItemUpdateOperationType.SendToNone);
            bool canUpdateNotOwnItem = null != updatedItem;
            #endregion

            #region Attendee deletes the calendar item created by organizer.
            responseMessage = this.DeleteSingleCalendarItem(Role.Attendee, itemIdByOrganizer, CalendarItemCreateOrDeleteOperationType.SendToNone);
            bool canDeleteNotOwnItem = null != responseMessage && responseMessage.ResponseClass == ResponseClassType.Success;
            #endregion

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R96");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R96
            bool isVerifiedR96 = canCreateOwnItem && canReadOwnItem && canUpdateOwnItem && canDeleteOwnItem && canReadNotOwnItem
                && canUpdateNotOwnItem && canDeleteNotOwnItem && canCreateSubFolder;

            Site.Assert.IsTrue(
                isVerifiedR96,
                "Can create own item is {0};\n" +
                "Can read own item is {1};\n" +
                "Can edit own item is {2};\n " +
                "Can delete own item is {3};\n" +
                "Can read not own item is {4};\n" +
                "Can edit not own item is {5};\n" +
                "Can delete not own item is {6};\n" +
                "Can create subfolders is {7};\n",
                canCreateOwnItem,
                canReadOwnItem,
                canUpdateOwnItem,
                canDeleteOwnItem,
                canReadNotOwnItem,
                canUpdateNotOwnItem,
                canDeleteNotOwnItem,
                canCreateSubFolder);

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR96,
                96,
                @"[In t:CalendarPermissionLevelType Simple Type] Owner: The user can create, read, edit, and delete all items in the folder, and create subfolders.");
        }
        public void MSOXWSMTGS_S06_TC04_CalendarPermissionLevelEditor()
        {
            this.MTGSAdapter = new MS_OXWSMTGSAdapter();
            this.MTGSAdapter.Initialize(this.Site);
            this.SRCHAdapter = new MS_OXWSSRCHAdapter();
            this.SRCHAdapter.Initialize(this.Site);
            this.FOLDAdapter = new MS_OXWSFOLDAdapter();
            this.FOLDAdapter.Initialize(this.Site);

            #region Organizer creates a calendar folder in the inbox folder and grant Editor permission to attendee.

            // Switch to user organizer.
            this.FOLDAdapter.SwitchUser(this.Organizer, this.OrganizerPassword, this.Domain);

            CalendarPermissionSetType calendarPermissionSet = new CalendarPermissionSetType();
            calendarPermissionSet.CalendarPermissions = new CalendarPermissionType[1];
            calendarPermissionSet.CalendarPermissions[0] = new CalendarPermissionType();
            calendarPermissionSet.CalendarPermissions[0].CalendarPermissionLevel = CalendarPermissionLevelType.Editor;
            calendarPermissionSet.CalendarPermissions[0].UserId = new UserIdType();
            calendarPermissionSet.CalendarPermissions[0].UserId.PrimarySmtpAddress = Common.GetConfigurationPropertyValue("AttendeeName", this.Site) + "@" + Common.GetConfigurationPropertyValue("Domain", this.Site);

            CreateFolderType createFolderRequest = this.GetCreateFolderRequest(DistinguishedFolderIdNameType.inbox.ToString(), new string[] { "CustomFolderByOrganizer" }, new string[] { "IPF.Appointment" }, null);
            ((CalendarFolderType)createFolderRequest.Folders[0]).PermissionSet = calendarPermissionSet;

            // Create a new folder.
            CreateFolderResponseType createFolderResponse = this.FOLDAdapter.CreateFolder(createFolderRequest);

            // Check the response.
            Common.CheckOperationSuccess(createFolderResponse, 1, this.Site);

            // Save the new created folder's folder id.
            FolderIdType newFolderIdByOrganizer = ((FolderInfoResponseMessageType)createFolderResponse.ResponseMessages.Items[0]).Folders[0].FolderId;
            this.FolderToDelete = newFolderIdByOrganizer;
            #endregion

            #region Organizer gets the new created folder.

            // GetFolder request.
            GetFolderType getNewFolderRequest = this.GetGetFolderRequest(DefaultShapeNamesType.AllProperties, newFolderIdByOrganizer);

            // Get the new created folder.
            GetFolderResponseType getInboxFolderResponse = this.FOLDAdapter.GetFolder(getNewFolderRequest);

            // Check the response.
            Common.CheckOperationSuccess(getInboxFolderResponse, 1, this.Site);

            // Verify the folder is created successfully.
            FolderInfoResponseMessageType foldersResponseInfo = (FolderInfoResponseMessageType)getInboxFolderResponse.ResponseMessages.Items[0];
            Site.Assert.AreEqual<string>(newFolderIdByOrganizer.Id, foldersResponseInfo.Folders[0].FolderId.Id, "The calendar folder should be created successfully in inbox.");
            #endregion

            #region Organizer creates a calendar item in the created folder.
            CalendarItemType calendarItembyOrganizer = new CalendarItemType();
            calendarItembyOrganizer.UID = Guid.NewGuid().ToString();
            calendarItembyOrganizer.Subject = Common.GenerateResourceName(this.Site, "CalendarItemCreatedByOrganizer");
            NonEmptyArrayOfAllItemsType allItemArray = new NonEmptyArrayOfAllItemsType();
            allItemArray.Items = new ItemType[] { calendarItembyOrganizer };
            CreateItemType createItemRequest = new CreateItemType();
            createItemRequest.Items = allItemArray;
            createItemRequest.SendMeetingInvitationsSpecified = true;
            createItemRequest.SendMeetingInvitations = CalendarItemCreateOrDeleteOperationType.SendToNone;
            createItemRequest.SavedItemFolderId = new TargetFolderIdType();
            createItemRequest.SavedItemFolderId.Item = newFolderIdByOrganizer;
            CreateItemResponseType response = this.MTGSAdapter.CreateItem(createItemRequest);
            Site.Assert.AreEqual<ResponseClassType>(ResponseClassType.Success, response.ResponseMessages.Items[0].ResponseClass, "The calendar item should be created successfully.");
            ItemInfoResponseMessageType itemInfoResponse = response.ResponseMessages.Items[0] as ItemInfoResponseMessageType;
            Site.Assert.IsNotNull(itemInfoResponse, "The calendar item should be created successfully.");
            ItemIdType itemIdByOrganizer = itemInfoResponse.Items.Items[0].ItemId;
            #endregion

            #region Attendee creates a folder in the created folder.

            // Switch to user attendee.
            this.FOLDAdapter.SwitchUser(this.Attendee, this.AttendeePassword, this.Domain);

            createFolderRequest = this.GetCreateFolderRequest(newFolderIdByOrganizer.Id, new string[] { "CustomFolderByAttendee" }, new string[] { "IPF.Appointment" }, null);
            createFolderResponse = this.FOLDAdapter.CreateFolder(createFolderRequest);
            bool canCreateSubFolder = ResponseClassType.Success == createFolderResponse.ResponseMessages.Items[0].ResponseClass;

            #endregion

            #region Attendee creates a calendar item in the created folder.
            this.SwitchMTGSUser(Role.Attendee);
            CalendarItemType calendarItembyAttendee = new CalendarItemType();
            calendarItembyAttendee.UID = Guid.NewGuid().ToString();
            calendarItembyAttendee.Subject = Common.GenerateResourceName(this.Site, "CalendarItemCreatedByAttendee");
            createItemRequest.Items.Items[0] = calendarItembyAttendee;
            response = this.MTGSAdapter.CreateItem(createItemRequest);
            Site.Assert.AreEqual<ResponseClassType>(ResponseClassType.Success, response.ResponseMessages.Items[0].ResponseClass, "The calendar item should be created successfully.");
            itemInfoResponse = response.ResponseMessages.Items[0] as ItemInfoResponseMessageType;
            bool canCreateOwnItem = null != itemInfoResponse;
            Site.Assert.IsTrue(canCreateOwnItem, "The calendar item should be created successfully.");
            ItemIdType itemIdByAttendee = itemInfoResponse.Items.Items[0].ItemId;
            #endregion

            #region Attendee gets the calendar item created by hisself.
            itemInfoResponse = this.GetSingleCalendarItem(Role.Attendee, itemIdByAttendee);
            bool canReadOwnItem = null != itemInfoResponse;
            #endregion

            #region Attendee updates the calendar item created by hisself.
            CalendarItemType calendarUpdate = new CalendarItemType();
            calendarUpdate.Location = this.LocationUpdate;

            AdapterHelper itemChangeInfo = new AdapterHelper();
            itemChangeInfo.FieldURI = UnindexedFieldURIType.calendarLocation;
            itemChangeInfo.Item = calendarUpdate;
            itemChangeInfo.ItemId = itemIdByAttendee;

            // Update the created calendar item.
            UpdateItemResponseMessageType updatedItem = this.UpdateSingleCalendarItem(Role.Attendee, itemChangeInfo, CalendarItemUpdateOperationType.SendToNone);
            bool canUpdateOwnItem = null != updatedItem;
            #endregion

            #region Attendee deletes the calendar item created by hisself.
            ResponseMessageType responseMessage = this.DeleteSingleCalendarItem(Role.Attendee, itemIdByAttendee, CalendarItemCreateOrDeleteOperationType.SendToNone);
            bool canDeleteOwnItem = null != responseMessage && responseMessage.ResponseClass == ResponseClassType.Success;
            #endregion

            #region Attendee gets the calendar item created by organizer.
            itemInfoResponse = this.GetSingleCalendarItem(Role.Attendee, itemIdByOrganizer);
            bool canReadNotOwnItem = null != itemInfoResponse;
            #endregion

            #region Attendee updates the calendar item created by organizer.
            calendarUpdate = new CalendarItemType();
            calendarUpdate.Location = this.LocationUpdate;

            itemChangeInfo = new AdapterHelper();
            itemChangeInfo.FieldURI = UnindexedFieldURIType.calendarLocation;
            itemChangeInfo.Item = calendarUpdate;
            itemChangeInfo.ItemId = itemIdByOrganizer;

            // Update the created calendar item.
            updatedItem = this.UpdateSingleCalendarItem(Role.Attendee, itemChangeInfo, CalendarItemUpdateOperationType.SendToNone);
            bool canUpdateNotOwnItem = null != updatedItem;
            #endregion

            #region Attendee deletes the calendar item created by organizer.
            responseMessage = this.DeleteSingleCalendarItem(Role.Attendee, itemIdByOrganizer, CalendarItemCreateOrDeleteOperationType.SendToNone);
            bool canDeleteNotOwnItem = null != responseMessage && responseMessage.ResponseClass == ResponseClassType.Success;
            #endregion

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R91");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R91
            bool isVerifiedR91 = canCreateOwnItem && canReadOwnItem && canUpdateOwnItem && canDeleteOwnItem && canReadNotOwnItem
                && canUpdateNotOwnItem && canDeleteNotOwnItem && !canCreateSubFolder;

            Site.Assert.IsTrue(
                isVerifiedR91,
                "Can create own item is {0};\n" +
                "Can read own item is {1};\n" +
                "Can edit own item is {2};\n " +
                "Can delete own item is {3};\n" +
                "Can read not own item is {4};\n" +
                "Can edit not own item is {5};\n" +
                "Can delete not own item is {6};\n" +
                "Can create subfolders is {7};\n",
                canCreateOwnItem,
                canReadOwnItem,
                canUpdateOwnItem,
                canDeleteOwnItem,
                canReadNotOwnItem,
                canUpdateNotOwnItem,
                canDeleteNotOwnItem,
                canCreateSubFolder);

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR91,
                91,
                @"[In t:CalendarPermissionLevelType Simple Type] Editor: The user can create, read, edit and delete all items in the folder.");
        }
        public void MSOXWSMTGS_S05_TC02_UpdateMultipleCalendarItems()
        {
            #region Define two calendar items
            CalendarItemType calendarItem1 = new CalendarItemType();
            calendarItem1.UID = Guid.NewGuid().ToString();
            calendarItem1.Subject = Common.GenerateResourceName(this.Site, Common.GetConfigurationPropertyValue("MeetingSubject", this.Site));
            calendarItem1.Location = this.Location;

            CalendarItemType calendarItem2 = new CalendarItemType();
            calendarItem2.UID = Guid.NewGuid().ToString();
            calendarItem2.Subject = Common.GenerateResourceName(this.Site, Common.GetConfigurationPropertyValue("MeetingSubject", this.Site));
            calendarItem2.Location = this.Location;
            #endregion

            #region Create the two calendar items
            ItemInfoResponseMessageType[] calendars = this.CreateMultipleCalendarItems(Role.Organizer, new ItemType[] { calendarItem1, calendarItem2 }, CalendarItemCreateOrDeleteOperationType.SendToNone);
            Site.Assert.IsNotNull(calendars, "The calendars should be created successfully.");
            Site.Assert.IsTrue(calendars.Length == 2, "There should be only two calendars created.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R1198");

            // Verify MS-OXWSMSG requirement: MS-OXWSMTGS_R1198
            // The calendars are gotten successfully, it means the calendars are created successfully.
            Site.CaptureRequirement(
                1198,
                @"[In Messages] A successful CreateItem operation returns a CreateItemResponse element, as specified in [MS-OXWSCORE] section 3.1.4.2.2.2, with the ResponseClass attribute of the CreateItemResponseMessage element, as specified in [MS-OXWSCDATA] section 2.2.4.12, set to ""Success"".");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R1199");

            // Verify MS-OXWSMSG requirement: MS-OXWSMTGS_R1199
            // The calendars are gotten successfully, it means the calendars are created successfully.
            Site.CaptureRequirement(
                1199,
                @"[In Messages] The ResponseCode element, as specified in [MS-OXWSCDATA] section 2.2.4.43, of the CreateItemResponseMessage element is set to ""NoError"".");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R1217");

            // Verify MS-OXWSMSG requirement: MS-OXWSMTGS_R1217
            // The calendars are gotten successfully, this requirement can be captured.
            Site.CaptureRequirement(
                1217,
                @"[In Messages] A successful GetItem operation returns a GetItemResponse element, as specified in [MS-OXWSCORE] section 3.1.4.4.2.2, with the ResponseClass attribute of the GetItemResponseMessage element, as specified in [MS-OXWSCDATA] section 2.2.4.12, set to ""Success"". ");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R1218");

            // Verify MS-OXWSMSG requirement: MS-OXWSMTGS_R1218
            // The calendars are gotten successfully, this requirement can be captured.
            Site.CaptureRequirement(
                1218,
                @"[In Messages] The ResponseCode element, as specified in [MS-OXWSCDATA] section 2.2.4.43, of the GetItemResponseMessage element is set to ""NoError"".");

            ItemIdType[] calendarIds = new ItemIdType[] { calendars[0].Items.Items[0].ItemId, calendars[1].Items.Items[0].ItemId };
            #endregion

            #region Update the Location element of the two created calendar items
            List<AdapterHelper> itemsChangeInfo = new List<AdapterHelper>();
            foreach (ItemIdType calendarId in calendarIds)
            {
                CalendarItemType calendarUpdate = new CalendarItemType();
                calendarUpdate.Location = this.LocationUpdate;

                AdapterHelper itemChangeInfo = new AdapterHelper();
                itemChangeInfo.FieldURI = UnindexedFieldURIType.calendarLocation;
                itemChangeInfo.Item = calendarUpdate;
                itemChangeInfo.ItemId = calendarId;
                itemsChangeInfo.Add(itemChangeInfo);
            }

            Site.Assert.IsNotNull(
                this.UpdateMultipleCalendarItems(Role.Organizer, itemsChangeInfo.ToArray(), CalendarItemUpdateOperationType.SendToNone),
                "Server should return success for updating multiple calendar items.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R1235");

            // Verify MS-OXWSMSG requirement: MS-OXWSMTGS_R1235
            // The updated calendars are gotten successfully, this requirement can be captured.
            Site.CaptureRequirement(
                1235,
                @"[In Messages] A successful UpdateItem operation returns an UpdateItemResponse element, as specified in [MS-OXWSCORE] section 3.1.4.9.2.2, with the ResponseClass attribute of the UpdateItemResponseMessage element, as specified in [MS-OXWSCDATA] section 2.2.4.12, set to ""Success"".");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R1236");

            // Verify MS-OXWSMSG requirement: MS-OXWSMTGS_R1236
            // The updated calendars are gotten successfully, this requirement can be captured.
            Site.CaptureRequirement(
                1236,
                @"[In Messages] The ResponseCode element, as specified in [MS-OXWSCDATA] section 2.2.4.43, of the UpdateItemResponseMessage element is set to ""NoError"".");
            #endregion

            #region Verify the Location elements of the two calendar items are updated
            ItemInfoResponseMessageType getItem1 = this.GetSingleCalendarItem(Role.Organizer, calendarIds[0]);
            Site.Assert.IsNotNull(getItem1, "The first updated item should exist.");

            CalendarItemType calendar1 = getItem1.Items.Items[0] as CalendarItemType;
            Site.Assert.AreEqual<string>(
                this.LocationUpdate,
                calendar1.Location,
                string.Format("The Location of the first updated calendar should be {0}. The actual value is {1}.", this.LocationUpdate, calendar1.Location));

            ItemInfoResponseMessageType getItem2 = this.GetSingleCalendarItem(Role.Organizer, calendarIds[1]);
            Site.Assert.IsNotNull(getItem2, "The second updated item should exist.");

            CalendarItemType calendar2 = getItem2.Items.Items[0] as CalendarItemType;
            Site.Assert.AreEqual<string>(
                this.LocationUpdate,
                calendar2.Location,
                string.Format("The Location of the second updated calendar should be {0}. The actual value is {1}.", this.LocationUpdate, calendar2.Location));
            #endregion

            #region Clean up organizer's calendar folder.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.calendar });
            #endregion
        }
        /// <summary>
        /// Update an occurrence of a recurring meeting.
        /// </summary>
        /// <param name="occurrence">The occurrence to be updated.</param>
        /// <returns>If update operation succeeds, return true; otherwise, false.</returns>
        private bool UpdateOccurrenceItem(ItemType occurrence)
        {
            ItemIdType occurrenceId = occurrence.ItemId;

            if (occurrenceId != null)
            {
                CalendarItemType calendarUpdate = new CalendarItemType();
                calendarUpdate.Location = this.LocationUpdate;

                // Location change info
                AdapterHelper locationChangeInfo = new AdapterHelper();
                locationChangeInfo.FieldURI = UnindexedFieldURIType.calendarLocation;
                locationChangeInfo.Item = new CalendarItemType() { Location = this.LocationUpdate };
                locationChangeInfo.ItemId = occurrenceId;
                UpdateItemResponseMessageType itemOfLocationUpdate = this.UpdateSingleCalendarItem(Role.Organizer, locationChangeInfo, CalendarItemUpdateOperationType.SendOnlyToAll);
                Site.Assert.IsNotNull(itemOfLocationUpdate, "The location of the occurrence should be updated successfully.");
                CalendarItemType occurrenceOfLocationUpdate = itemOfLocationUpdate.Items.Items[0] as CalendarItemType;

                CalendarItemType calendar = occurrence as CalendarItemType;
                Site.Assert.IsNotNull(calendar, "The type conversion from ItemType to CalendarItemType should succeed.");

                // Start time change info
                DateTime start = calendar.Start;
                AdapterHelper startChangeInfo = new AdapterHelper();
                startChangeInfo.FieldURI = UnindexedFieldURIType.calendarStart;
                startChangeInfo.Item = new CalendarItemType() { Start = start.AddHours(-26.0), StartSpecified = true };
                startChangeInfo.ItemId = occurrenceOfLocationUpdate.ItemId;
                UpdateItemResponseMessageType itemOfStartUpdate = this.UpdateSingleCalendarItem(Role.Organizer, startChangeInfo, CalendarItemUpdateOperationType.SendOnlyToAll);
                Site.Assert.IsNotNull(itemOfStartUpdate, "The start time of the occurrence should be updated successfully.");
                CalendarItemType occurrenceOfStartUpdate = itemOfStartUpdate.Items.Items[0] as CalendarItemType;

                // End time change info
                DateTime end = calendar.End;
                AdapterHelper endChangeInfo = new AdapterHelper();
                endChangeInfo.FieldURI = UnindexedFieldURIType.calendarEnd;
                endChangeInfo.Item = new CalendarItemType() { End = end.AddHours(-26.0), EndSpecified = true };
                endChangeInfo.ItemId = occurrenceOfStartUpdate.ItemId;
                UpdateItemResponseMessageType itemOfEndUpdate = this.UpdateSingleCalendarItem(Role.Organizer, endChangeInfo, CalendarItemUpdateOperationType.SendOnlyToAll);
                Site.Assert.IsNotNull(itemOfEndUpdate, "The end time of the occurrence should be updated successfully.");

                return true;
            }

            return false;
        }
        public void MSOXWSMTGS_S02_TC10_MeetingRequestTypeInformationalUpdate()
        {
            #region Organizer creates the meeting and sends it to attendee.
            CalendarItemType meeting = new CalendarItemType();
            meeting.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meeting.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            meeting.Resources = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) };
            meeting.Subject = this.Subject;
            meeting.UID = Guid.NewGuid().ToString();
            meeting.Location = this.Location;
            meeting.IsResponseRequested = true;
            meeting.IsResponseRequestedSpecified = true;
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meeting, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "The meeting should be created successfully.");
            #endregion

            #region Attendee accepts the meeting request.
            MeetingRequestMessageType request = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Request", meeting.UID) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(request, "The meeting request message should be found in attendee's Inbox folder after organizer calls CreateItem with CalendarItemCreateOrDeleteOperationType set to SendOnlyToAll.");

            AcceptItemType acceptItem = new AcceptItemType();
            acceptItem.ReferenceItemId = new ItemIdType();
            acceptItem.ReferenceItemId.Id = request.ItemId.Id;
            item = this.CreateSingleCalendarItem(Role.Attendee, acceptItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "Accept the meeting request should be successful.");
            #endregion

            #region Organizer updates the meeting.
            CalendarItemType calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meeting.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The calendar should be created successfully.");

            CalendarItemType calendarUpdate = new CalendarItemType();
            calendarUpdate.Location = this.LocationUpdate;
            AdapterHelper locationChangeInfo = new AdapterHelper();
            locationChangeInfo.FieldURI = UnindexedFieldURIType.calendarLocation;
            locationChangeInfo.Item = new CalendarItemType() { Location = this.LocationUpdate };
            locationChangeInfo.ItemId = calendar.ItemId;
            UpdateItemResponseMessageType itemOfLocationUpdate = this.UpdateSingleCalendarItem(Role.Organizer, locationChangeInfo, CalendarItemUpdateOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(itemOfLocationUpdate, "Update the meeting item should be successful.");
            #endregion

            #region Attendee gets the meeting request.
            MeetingRequestMessageType meetingRequest = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Request", meeting.UID) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(meetingRequest, "The meeting request should exist.");
            Site.Assert.AreEqual<string>(this.LocationUpdate, meetingRequest.Location, "Location in meeting request message should be updated.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R71");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R71
            this.Site.CaptureRequirementIfAreEqual<MeetingRequestTypeType>(
                MeetingRequestTypeType.InformationalUpdate,
                meetingRequest.MeetingRequestType,
                71,
                @"[In t:MeetingRequestTypeType Simple Type] InformationUpdate: Identifies the meeting request as an updated meeting request.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R587");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R587
            // Attendee has accepted the meeting and InformationalUpdate is returned, this requirement can be captured.
            this.Site.CaptureRequirementIfAreEqual<MeetingRequestTypeType>(
                MeetingRequestTypeType.InformationalUpdate,
                meetingRequest.MeetingRequestType,
                587,
                @"[In t:MeetingRequestTypeType Simple Type] This value [InformationUpdate] indicates that the attendee had previously accepted or tentatively accepted the original meeting request.");
            #endregion

            #region Clean up organizer's inbox and calendar folders, and attendee's deleted items and calendar folders.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.calendar });
            this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.deleteditems, DistinguishedFolderIdNameType.calendar });
            #endregion
        }
        /// <summary>
        /// Verify the value of CalendarItemUpdateOperationType.
        /// </summary>
        /// <param name="calendarItemUpdateOperationType">Specify a value of CalendarItemUpdateOperationType.</param>
        protected void VerifyCalendarItemUpdateOperationType(CalendarItemUpdateOperationType calendarItemUpdateOperationType)
        {
            #region Step1: Organizer set the properties of the meeting to create
            CalendarItemType meeting = new CalendarItemType();
            meeting.UID = Guid.NewGuid().ToString();
            meeting.Subject = Common.GenerateResourceName(this.Site, Common.GetConfigurationPropertyValue("MeetingSubject", this.Site));
            meeting.Location = this.Location;

            meeting.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meeting.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            #endregion

            #region Step2: Organizer create the meeting and sends to none
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meeting, CalendarItemCreateOrDeleteOperationType.SendToNone);
            Site.Assert.IsNotNull(item, "Create a meeting item should be successful.");
            ItemIdType meetingId = item.Items.Items[0].ItemId;
            #endregion

            #region Step3: Organizer updates a meeting with CalendarItemUpdateOperationType
            CalendarItemType calendarUpdate = new CalendarItemType();
            calendarUpdate.Location = this.LocationUpdate;

            AdapterHelper itemChangeInfo = new AdapterHelper();
            itemChangeInfo.FieldURI = UnindexedFieldURIType.calendarLocation;
            itemChangeInfo.Item = calendarUpdate;
            itemChangeInfo.ItemId = meetingId;

            // Update the calendar item created.
            UpdateItemResponseMessageType updatedItem = this.UpdateSingleCalendarItem(Role.Organizer, itemChangeInfo, calendarItemUpdateOperationType);
            Site.Assert.IsNotNull(updatedItem, "Update the Location of the calendar item should be successful.");

            // Get the UpdateItem and verify if the update operation is successful
            ItemInfoResponseMessageType getItem = this.GetSingleCalendarItem(Role.Organizer, updatedItem.Items.Items[0].ItemId);
            Site.Assert.IsNotNull(getItem, "The updated calendar item should exist.");

            bool isLocationUpdatedSuccess = ((CalendarItemType)getItem.Items.Items[0]).Location == this.LocationUpdate;
            switch (calendarItemUpdateOperationType)
            {
                case CalendarItemUpdateOperationType.SendToNone:
                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R60");

                    // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R60
                    this.Site.CaptureRequirementIfIsTrue(
                        isLocationUpdatedSuccess,
                        60,
                        @"[In t:CalendarItemUpdateOperationType Simple Type] SendToNone: The calendar item is updated.");
                    break;
                case CalendarItemUpdateOperationType.SendOnlyToAll:
                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R61");

                    // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R61
                    this.Site.CaptureRequirementIfIsTrue(
                        isLocationUpdatedSuccess,
                        61,
                        @"[In t:CalendarItemUpdateOperationType Simple Type] SendOnlyToAll: The calendar item is updated.");
                    break;
                case CalendarItemUpdateOperationType.SendToAllAndSaveCopy:
                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R64");

                    // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R64
                    this.Site.CaptureRequirementIfIsTrue(
                        isLocationUpdatedSuccess,
                        64,
                        @"[In t:CalendarItemUpdateOperationType Simple Type] SendToAllAndSaveCopy: The calendar item is updated.");
                    break;
            }
            #endregion

            #region Step4: Verify CalendarItemUpdateOperationType used in UpdateItem operation
            #region Find the update meeting request in Organizer SentItems
            bool updatedIsFoundInOrganizerSentItems = false;
            MeetingRequestMessageType meetingRequestMessageInOrganizer = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.sentitems, "IPM.Schedule.Meeting.Request", meeting.UID) as MeetingRequestMessageType;
            if (null != meetingRequestMessageInOrganizer)
            {
                if (null != meetingRequestMessageInOrganizer.Location && meetingRequestMessageInOrganizer.Location == this.LocationUpdate)
                {
                    updatedIsFoundInOrganizerSentItems = true;
                }
            }
            #endregion

            #region Find the update meeting request in Attendees Inbox
            bool updatedIsFoundInAttendeeInbox = false;
            MeetingRequestMessageType meetingRequestMessageInAttendee = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Request", meeting.UID) as MeetingRequestMessageType;
            if (null != meetingRequestMessageInAttendee)
            {
                if (null != meetingRequestMessageInAttendee.Location && meetingRequestMessageInAttendee.Location == this.LocationUpdate)
                {
                    updatedIsFoundInAttendeeInbox = true;
                }
            }
            #endregion

            switch (calendarItemUpdateOperationType)
            {
                case CalendarItemUpdateOperationType.SendToNone:
                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R6000");

                    // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R6000
                    this.Site.CaptureRequirementIfIsFalse(
                        updatedIsFoundInAttendeeInbox,
                        6000,
                        @"[In t:CalendarItemUpdateOperationType Simple Type] SendToNone: [The calendar item is updated] but updates are not sent to attendees.");
                    break;
                case CalendarItemUpdateOperationType.SendOnlyToAll:
                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R6100");

                    // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R6100
                    this.Site.CaptureRequirementIfIsTrue(
                        updatedIsFoundInAttendeeInbox,
                        6100,
                        @"[In t:CalendarItemUpdateOperationType Simple Type] SendOnlyToAll: the meeting update is sent to all attendees.");

                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R6101");

                    // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R6101
                    this.Site.CaptureRequirementIfIsFalse(
                        updatedIsFoundInOrganizerSentItems,
                        6101,
                        @"[In t:CalendarItemUpdateOperationType Simple Type] SendOnlyToAll: [The calendar item is updated and the meeting update is sent to all attendees] but is not saved in the folder that is specified in the request.");
                    break;
                case CalendarItemUpdateOperationType.SendToAllAndSaveCopy:
                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R6400");

                    // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R6400
                    this.Site.CaptureRequirementIfIsTrue(
                        updatedIsFoundInAttendeeInbox,
                        6400,
                        @"[In t:CalendarItemUpdateOperationType Simple Type] SendToAllAndSaveCopy: [The calendar item is updated,] the meeting update is sent to all attendees.");

                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R6401");

                    // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R6401
                    this.Site.CaptureRequirementIfIsTrue(
                        updatedIsFoundInOrganizerSentItems,
                        6401,
                        @"[In t:CalendarItemUpdateOperationType Simple Type] SendToAllAndSaveCopy: [The calendar item is updated, the meeting update is sent to all attendees,] and a copy of the updated meeting request is saved in the Sent Items folder.");
                    break;
            }
            #endregion
        }
        public void MSOXWSMTGS_S02_TC09_MeetingRequestTypeFullUpdate()
        {
            this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.deleteditems });

            #region Organizer creates the meeting and sends it to attendee.
            CalendarItemType meeting = new CalendarItemType();
            meeting.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meeting.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            meeting.Resources = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) };
            meeting.Subject = this.Subject;
            meeting.UID = Guid.NewGuid().ToString();
            meeting.Location = this.Location;
            meeting.IsResponseRequested = true;
            meeting.IsResponseRequestedSpecified = true;
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meeting, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "The meeting should be created successfully.");
            #endregion

            #region Organizer updates the meeting.
            CalendarItemType calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meeting.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The calendar should be created successfully.");

            CalendarItemType calendarUpdate = new CalendarItemType();
            calendarUpdate.Location = this.LocationUpdate;
            AdapterHelper locationChangeInfo = new AdapterHelper();
            locationChangeInfo.FieldURI = UnindexedFieldURIType.calendarLocation;
            locationChangeInfo.Item = new CalendarItemType() { Location = this.LocationUpdate };
            locationChangeInfo.ItemId = calendar.ItemId;
            UpdateItemResponseMessageType itemOfLocationUpdate = this.UpdateSingleCalendarItem(Role.Organizer, locationChangeInfo, CalendarItemUpdateOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(itemOfLocationUpdate, "Update the meeting item should be successful.");
            #endregion

            #region Attendee gets the meeting request.
            MeetingRequestMessageType meetingRequest = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, this.LocationUpdate, meeting.UID, UnindexedFieldURIType.calendarLocation) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(meetingRequest, "The meeting request should exist.");
            Site.Assert.AreEqual<string>(this.LocationUpdate, meetingRequest.Location, "Location in meeting request message should be updated.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R484");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R484
            this.Site.CaptureRequirementIfAreEqual<MeetingRequestTypeType>(
                MeetingRequestTypeType.FullUpdate,
                meetingRequest.MeetingRequestType,
                484,
                @"[In t:MeetingRequestTypeType Simple Type] FullUpdate: Identifies the meeting request as an updated meeting request.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R485");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R485
            // Attendee does not response the meeting request and FullUpdate is returned, this requirement can be captured.
            this.Site.CaptureRequirementIfAreEqual<MeetingRequestTypeType>(
                MeetingRequestTypeType.FullUpdate,
                meetingRequest.MeetingRequestType,
                485,
                @"[In t:MeetingRequestTypeType Simple Type] This value [FullUpdate] indicates that the attendee has not yet responded to the original meeting request.");
            #endregion

            #region Clean up organizer's calendar folder, and attendee's inbox, calendar and deleted items folders.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.calendar });
            this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.deleteditems });
            #endregion
        }
        public void MSOXWSMTGS_S02_TC01_UpdateSingleCalendarItem()
        {
            #region Organizer creates a single calendar
            #region Define a calendar item to update
            CalendarItemType calendarItem = new CalendarItemType();
            calendarItem.UID = Guid.NewGuid().ToString();
            calendarItem.Subject = this.Subject;
            calendarItem.Location = this.Location;
            if (Common.IsRequirementEnabled(16505, this.Site))
            {
                calendarItem.LegacyFreeBusyStatus = LegacyFreeBusyType.WorkingElsewhere;
                calendarItem.LegacyFreeBusyStatusSpecified = true;
            }

            calendarItem.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            calendarItem.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            calendarItem.Resources = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) };
            #endregion

            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, calendarItem, CalendarItemCreateOrDeleteOperationType.SendToNone);
            Site.Assert.IsNotNull(item, "Create a single calendar item should be successful.");
            ItemIdType calendarId = item.Items.Items[0].ItemId;

            CalendarItemType calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", calendarItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The calendar should exist.");

            if (Common.IsRequirementEnabled(16505, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R16505");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R16505
                this.Site.CaptureRequirementIfAreEqual<LegacyFreeBusyType>(
                    LegacyFreeBusyType.WorkingElsewhere,
                    calendar.LegacyFreeBusyStatus,
                    16505,
                    @"[In Appendix C: Product Behavior] Implementation does support the LegacyFreeBusyStatus in t:CalendarItemType Complex Type which value set to ""WorkingElsewhere"" specifies the status as working outside the office. (Exchange 2013 and above follow this behavior.)");
            }

            if (Common.IsRequirementEnabled(713, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R713");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R713
                // The type of StartTimeZone has been verified in the schema validation.
                this.Site.CaptureRequirementIfIsNotNull(
                    calendar.StartTimeZone,
                    713,
                    @"[In Appendix C: Product Behavior] Implementation does support ""StartTimeZone"" with type ""t:TimeZoneDefinitionType ([MS-OXWSGTZ] section 2.2.4.12)"" which specifies the calendar item start time zone information. (Exchange 2010 and above follow this behavior.)");
            }

            if (Common.IsRequirementEnabled(714, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R714");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R714
                // The type of EndTimeZone has been verified in the schema validation.
                this.Site.CaptureRequirementIfIsNotNull(
                    calendar.EndTimeZone,
                    714,
                    @"[In Appendix C: Product Behavior] Implementation does support complex type ""EndTimeZone"" with type ""t:TimeZoneDefinitionType"" which specifies the calendar item end time zone information. (Exchange 2010 and above follow this behavior.)");
            }
            #endregion

            #region Organizer updates the Location property of the created calendar item
            CalendarItemType calendarUpdate = new CalendarItemType();
            calendarUpdate.Location = this.LocationUpdate;

            AdapterHelper itemChangeInfo = new AdapterHelper();
            itemChangeInfo.FieldURI = UnindexedFieldURIType.calendarLocation;
            itemChangeInfo.Item = calendarUpdate;
            itemChangeInfo.ItemId = calendarId;

            // Update the created calendar item.
            UpdateItemResponseMessageType updatedItem = this.UpdateSingleCalendarItem(Role.Organizer, itemChangeInfo, CalendarItemUpdateOperationType.SendOnlyToAll);

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R650");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R650
            this.Site.CaptureRequirementIfIsNotNull(
                updatedItem,
                650,
                @"[In Messages] UpdateItemSoapIn: For each item being updated that is not a recurring calendar item, the ItemChange element MUST contain an ItemId child element ([MS-OXWSCORE] section 3.1.4.9.3.7).");

            #region Verify the Location of the calendar has been updated
            ItemInfoResponseMessageType getItem = this.GetSingleCalendarItem(Role.Organizer, calendarId);
            Site.Assert.IsNotNull(getItem, "The updated calendar should exist.");

            CalendarItemType updatedCalendar = getItem.Items.Items[0] as CalendarItemType;
            Site.Assert.AreEqual<string>(
                this.LocationUpdate,
                updatedCalendar.Location,
                string.Format("The Location of the updated calendar should be {0}. The actual value is {1}.", this.LocationUpdate, updatedCalendar.Location));
            #endregion
            #endregion

            #region Attendee gets the meeting request message
            MeetingRequestMessageType meetingRequest = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Request", calendarItem.UID) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(meetingRequest, "The update meeting request message should exist in attendee's inbox folder.");

            if (Common.IsRequirementEnabled(28505, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R28505");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R28505
                this.Site.CaptureRequirementIfAreEqual<LegacyFreeBusyType>(
                    LegacyFreeBusyType.WorkingElsewhere,
                    meetingRequest.IntendedFreeBusyStatus,
                    28505,
                    @"[In Appendix C: Product Behavior] Implementation does support the IntendedFreeBusyStatus which value set to ""WorkingElsewhere"" specifies the status as working outside the office. (Exchange 2013 and above follow this behavior.)");
            }

            if (Common.IsRequirementEnabled(80049, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R80049");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R80049
                this.Site.CaptureRequirementIfIsFalse(
                    meetingRequest.IsOrganizer,
                    80049,
                    "[In Appendix C: Product Behavior] Implementation does support the IsOrganizer, which specifies whether the current user is the organizer of the meeting. (Exchange 2013 and above follow this behavior.)");
            }

            if (Common.IsRequirementEnabled(718, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R718");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R718
                // The type of StartTimeZone has been verified in the schema validation.
                this.Site.CaptureRequirementIfIsNotNull(
                    meetingRequest.StartTimeZone,
                    718,
                    @"[In Appendix C: Product Behavior] Implementation does support the complex type ""StartTimeZone"" with type ""t:TimeZoneDefinitionType ([MS-OXWSGTZ] section 2.2.4.12)"" which specifies the time zone for the start of the meeting item. (Exchange 2010 and above follow this behavior.)");
            }

            if (Common.IsRequirementEnabled(719, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R719");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R719
                // The type of EndTimeZone has been verified in the schema validation.
                this.Site.CaptureRequirementIfIsNotNull(
                    meetingRequest.EndTimeZone,
                    719,
                    @"[In Appendix C: Product Behavior] Implementation does support the complex type ""EndTimeZone"" with type ""t:TimeZoneDefinitionType"" which specifies the time zone for the end of the meeting item. (Exchange 2010 and above follow this behavior.)");
            }

            if (Common.IsRequirementEnabled(710, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R710");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R710
                // The type of StartTimeZoneId has been verified in the schema validation.
                this.Site.CaptureRequirementIfIsNotNull(
                    meetingRequest.StartTimeZoneId,
                    710,
                    @"[In Appendix C: Product Behavior] Implementation does support the complex type ""StartTimeZoneId"" with type ""xs:string"" which specifies the start time zone identifier. (Exchange 2013 and above follow this behavior.)");
            }

            if (Common.IsRequirementEnabled(711, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R711");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R711
                // The type of EndTimeZoneId has been verified in the schema validation.
                this.Site.CaptureRequirementIfIsNotNull(
                    meetingRequest.EndTimeZoneId,
                    711,
                    @"[In Appendix C: Product Behavior] Implementation does support the complex type ""EndTimeZoneId"" with type ""xs:string"" which specifies the end time zone identifier. (Exchange 2013 and above follow this behavior.)");
            }
            #endregion

            #region Organizer cancels the meeting
            CancelCalendarItemType cancelMeetingItem = new CancelCalendarItemType();
            cancelMeetingItem.ReferenceItemId = updatedItem.Items.Items[0].ItemId;
            item = this.CreateSingleCalendarItem(Role.Organizer, cancelMeetingItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "The meeting should be canceled successfully.");
            #endregion

            #region Organizer gets the deleted calendar item in Deleted Items folder.
            calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.deleteditems, "IPM.Appointment", calendarItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The canceled calendar item should exist in organizer's Deleted Items folder.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R740");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R740
            this.Site.CaptureRequirementIfAreEqual<int>(
                5,
                calendar.AppointmentState,
                740,
                "[In t:CalendarItemType Complex Type] [AppointmentState: Valid values include:] 5: the meeting corresponding to the organizer's calendar item has been cancelled");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R1052");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R1052
            this.Site.CaptureRequirementIfAreEqual<int>(
                5,
                calendar.AppointmentState,
                1052,
                "[In t:CalendarItemType Complex Type] [AppointmentState: Valid values include:] This value [5] is found in the Deleted Items folder of the organizer.");

            #endregion

            #region Attendee verifies canceled meeting
            CalendarItemType canceledCalendar = null;
            int counter = 0;
            while (counter < this.UpperBound)
            {
                System.Threading.Thread.Sleep(this.WaitTime);
                canceledCalendar = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", calendar.UID) as CalendarItemType;

                if (canceledCalendar.AppointmentStateSpecified && canceledCalendar.AppointmentState == 7)
                {
                    break;
                }

                counter++;
            }

            if (counter == this.UpperBound && canceledCalendar.AppointmentState != 7)
            {
                Site.Assert.Fail("Attendee should get the calendar cancelled by the organizer.");
            }

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R741");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R741
            this.Site.CaptureRequirementIfAreEqual<int>(
                7,
                canceledCalendar.AppointmentState,
                741,
                "[In t:CalendarItemType Complex Type] [AppointmentState: Valid values include:] 7: the meeting corresponding to the attendee's calendar item has been cancelled");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R730");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R730
            this.Site.CaptureRequirementIfIsTrue(
                canceledCalendar.IsCancelled,
                730,
                "[In t:CalendarItemType Complex Type] [IsCancelled is] True if a meeting has been canceled.");
            #endregion

            #region Clean up organizer's sentitems and deleteditems folder, and attendee's inbox, calendar and deleteditems folders.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.deleteditems });
            this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.deleteditems });
            #endregion
        }
        public void MSOXWSMTGS_S02_TC03_UpdateRecurringCalendar()
        {
            #region Define a recurring calendar item
            DateTime startTime = DateTime.Now;

            DailyRecurrencePatternType pattern = new DailyRecurrencePatternType();
            pattern.Interval = this.PatternInterval;

            NumberedRecurrenceRangeType range = new NumberedRecurrenceRangeType();
            range.NumberOfOccurrences = this.NumberOfOccurrences;
            range.StartDate = startTime;

            CalendarItemType meetingItem = new CalendarItemType();
            meetingItem.UID = Guid.NewGuid().ToString();
            meetingItem.Subject = this.Subject;
            meetingItem.Start = startTime;
            meetingItem.StartSpecified = true;
            meetingItem.End = startTime.AddHours(this.TimeInterval);
            meetingItem.EndSpecified = true;
            meetingItem.Location = this.Location;
            meetingItem.Recurrence = new RecurrenceType();
            meetingItem.Recurrence.Item = pattern;
            meetingItem.Recurrence.Item1 = range;
            meetingItem.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meetingItem.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            meetingItem.Resources = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) };
            #endregion

            #region Organizer creates a recurring calendar item with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meetingItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R494");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R494
            Site.CaptureRequirementIfIsNotNull(
                 item,
                 494,
                 @"[In CreateItem Operation] This operation [CreateItem] can be used to create meetings.");
            #endregion

            #region Organizer updates the Location element of the first occurrence of the recurring calendar item
            CalendarItemType calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meetingItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The meeting should be found in the organizer's Calendar folder after organizer calls CreateItem with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll.");

            OccurrenceItemIdType occurrenceId = new OccurrenceItemIdType();
            occurrenceId.RecurringMasterId = calendar.ItemId.Id;
            occurrenceId.InstanceIndex = 1;

            ItemInfoResponseMessageType getItem = this.GetSingleCalendarItem(Role.Organizer, occurrenceId);
            Site.Assert.IsNotNull(getItem, "The updated occurrence should exist.");

            // Update the first occurrence of the recurring meeting
            CalendarItemType calendarUpdate = new CalendarItemType();
            calendarUpdate.Location = this.LocationUpdate;

            AdapterHelper itemChangeInfo = new AdapterHelper();
            itemChangeInfo.FieldURI = UnindexedFieldURIType.calendarLocation;
            itemChangeInfo.Item = calendarUpdate;
            itemChangeInfo.ItemId = getItem.Items.Items[0].ItemId;

            UpdateItemResponseMessageType updatedItem = this.UpdateSingleCalendarItem(Role.Organizer, itemChangeInfo, CalendarItemUpdateOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(updatedItem, "The UpdateItem operation should be successful.");
            #endregion

            #region Attendee verifies whether the location of the first occurrence of the recurring calendar item has been updated
            CalendarItemType updatedOccurrence = null;
            bool locationUpdateSuccess = false;
            int counter = 0;
            while (counter < this.UpperBound)
            {
                System.Threading.Thread.Sleep(this.WaitTime);
                calendar = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meetingItem.UID) as CalendarItemType;
                Site.Assert.IsNotNull(calendar, "The meeting should be found in attendee's Calendar folder after organizer updates the meeting.");

                occurrenceId = new OccurrenceItemIdType();
                occurrenceId.RecurringMasterId = calendar.ItemId.Id;
                occurrenceId.InstanceIndex = 1;

                getItem = this.GetSingleCalendarItem(Role.Attendee, occurrenceId);
                Site.Assert.IsNotNull(getItem, "The updated occurrence should exist.");

                updatedOccurrence = getItem.Items.Items[0] as CalendarItemType;

                locationUpdateSuccess = string.Compare(this.LocationUpdate, updatedOccurrence.Location, true) == 0;
                if (locationUpdateSuccess)
                {
                    break;
                }

                counter++;
            }

            if (counter == this.UpperBound && !locationUpdateSuccess)
            {
                Site.Assert.Fail("Attendee should get the update information of calendar by the organizer.");
            }

            MeetingRequestMessageType updateRequest = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Request", meetingItem.UID) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(updateRequest, "The meeting update request should be found in attendee's inbox folder after organizer updates the meeting.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R277");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R277
            this.Site.CaptureRequirementIfIsNotNull(
                updateRequest.RecurrenceId,
                277,
                "[In t:MeetingMessageType Complex Type] RecurrenceId: Identifies a specific instance of a recurring calendar item.");
            #endregion

            #region Attendee declines the meeting request with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            DeclineItemType declineItem = new DeclineItemType();
            declineItem.ReferenceItemId = new ItemIdType();
            declineItem.ReferenceItemId = updatedOccurrence.ItemId;

            item = this.CreateSingleCalendarItem(Role.Attendee, declineItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "The response messages returned by the CreateItem operation should succeed.");
            #endregion

            #region Organizer calls FindItem to re-obtain the ItemId of the updated recurring calendar item because the changekey of ItemId is updated
            MeetingResponseMessageType response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Resp", meetingItem.UID) as MeetingResponseMessageType;
            Site.Assert.IsNotNull(response, "The declined meeting response returned by Attendee should be in organizer's Inbox folder.");

            if (Common.IsRequirementEnabled(80049, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R80049");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R80049
                this.Site.CaptureRequirementIfIsTrue(
                    response.IsOrganizer,
                    80049,
                    "[In Appendix C: Product Behavior] Implementation does support the IsOrganizer, which specifies whether the current user is the organizer of the meeting. (Exchange 2013 and above follow this behavior.)");
            }

            if (Common.IsRequirementEnabled(909, this.Site))
            {
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R909");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R909
                Site.CaptureRequirementIfIsNotNull(
                     response.Recurrence,
                     909,
                     @"[In Appendix C: Product Behavior] Implementation does support Recurrence which is a RecurrenceType element that represents the recurrence for the calendar item. (Exchange 2013 and above follow this behavior.)");
            }
            #endregion

            #region Clean up organizer's inbox, calendar and deleteditems folders, and attendee's inbox, calendar and sentitems folders.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.deleteditems });
            this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.calendar });
            #endregion
        }
        public void MSOXWSMTGS_S02_TC02_UpdateSingleMeeting()
        {
            #region Define a meeting
            CalendarItemType meetingItem = new CalendarItemType();
            int timeInterval = this.TimeInterval;
            meetingItem.UID = Guid.NewGuid().ToString();
            meetingItem.Subject = this.Subject;
            meetingItem.Start = DateTime.Now.AddHours(timeInterval);
            meetingItem.StartSpecified = true;
            timeInterval++;
            meetingItem.End = DateTime.Now.AddHours(timeInterval);
            meetingItem.EndSpecified = true;
            meetingItem.Location = this.Location;
            meetingItem.LegacyFreeBusyStatus = LegacyFreeBusyType.NoData;
            meetingItem.LegacyFreeBusyStatusSpecified = true;

            meetingItem.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meetingItem.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            meetingItem.Resources = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) };
            #endregion

            #region Organizer creates a meeting with CalendarItemCreateOrDeleteOperationType value set to SendToNone
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meetingItem, CalendarItemCreateOrDeleteOperationType.SendToNone);
            Site.Assert.IsNotNull(item, "Create a meeting item should be successful.");
            ItemIdType meetingId = item.Items.Items[0].ItemId;

            CalendarItemType calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meetingItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The calendar should be created successfully.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R16502");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R16502
            this.Site.CaptureRequirementIfAreEqual<LegacyFreeBusyType>(
                LegacyFreeBusyType.NoData,
                calendar.LegacyFreeBusyStatus,
                16502,
                @"[In t:CalendarItemType Complex Type] The LegacyFreeBusyStatus which value is ""NoData"" specifies that there is no data for that recipient.");

            #endregion

            #region Organizer updates the Location element in the created meeting item with CalendarItemUpdateOperationType value set to SendOnlyToAll
            CalendarItemType calendarUpdate = new CalendarItemType();
            calendarUpdate.Location = this.LocationUpdate;

            AdapterHelper itemChangeInfo = new AdapterHelper();
            itemChangeInfo.FieldURI = UnindexedFieldURIType.calendarLocation;
            itemChangeInfo.Item = calendarUpdate;
            itemChangeInfo.ItemId = meetingId;

            // Update the created calendar item.
            UpdateItemResponseMessageType updatedItem = this.UpdateSingleCalendarItem(Role.Organizer, itemChangeInfo, CalendarItemUpdateOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(updatedItem, "Update the meeting item should be successful.");
            #endregion

            #region Attendee gets the meeting request message to check whether the Location element of meeting request message is updated
            MeetingRequestMessageType meetingRequest = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Request", meetingItem.UID) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(meetingRequest, "The meeting request should exist.");
            Site.Assert.AreEqual<string>(this.LocationUpdate, meetingRequest.Location, "Location in meeting request message should be updated.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R28502");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R28502
            this.Site.CaptureRequirementIfAreEqual<LegacyFreeBusyType>(
                LegacyFreeBusyType.NoData,
                meetingRequest.IntendedFreeBusyStatus,
                28502,
                @"[In t:MeetingRequestMessageType Complex Type] The IntendedFreeBusyStatus which value is ""NoData"" specifies that there is no data for that recipient.");
            #endregion

            #region Clean up organizer's calendar and deleteditems folders, and attendee's inbox and calendar folders.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.deleteditems });
            this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.calendar });
            #endregion
        }
        /// <summary>
        /// Verify the "SendOnlyToChanged" and "SendToChangedAndSaveCopy" value of CalendarItemUpdateOperationType.
        /// </summary>
        /// <param name="calendarItemUpdateOperationType">Specify a value of CalendarItemUpdateOperationType.</param>
        protected void VerifyChangeAttendeesWithCalendarItemUpdateOperationType(CalendarItemUpdateOperationType calendarItemUpdateOperationType)
        {
            #region Step1: Organizer set the properties of the meeting to create
            CalendarItemType meeting = new CalendarItemType();
            meeting.UID = Guid.NewGuid().ToString();
            meeting.Subject = Common.GenerateResourceName(this.Site, Common.GetConfigurationPropertyValue("MeetingSubject", this.Site));
            meeting.Location = this.Location;

            meeting.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            #endregion

            #region Step2: Organizer create the meeting and sends to none
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meeting, CalendarItemCreateOrDeleteOperationType.SendToNone);
            Site.Assert.IsNotNull(item, "Create a meeting item should be successful.");
            ItemIdType meetingId = item.Items.Items[0].ItemId;
            #endregion

            #region Step3: Organizer updates RequiredAttendees of the a meeting with CalendarItemUpdateOperationType
            CalendarItemType calendarUpdate = new CalendarItemType();
            calendarUpdate.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };

            AdapterHelper itemChangeInfo = new AdapterHelper();
            itemChangeInfo.FieldURI = UnindexedFieldURIType.calendarRequiredAttendees;
            itemChangeInfo.Item = calendarUpdate;
            itemChangeInfo.ItemId = meetingId;

            // Update the calendar item created.
            UpdateItemResponseMessageType updatedItem = this.UpdateSingleCalendarItem(Role.Organizer, itemChangeInfo, calendarItemUpdateOperationType);
            Site.Assert.IsNotNull(updatedItem, @"Update the RequiredAttendees of the calendar item should be successful.");

            ItemInfoResponseMessageType getItem = this.GetSingleCalendarItem(Role.Organizer, updatedItem.Items.Items[0].ItemId);
            Site.Assert.IsNotNull(getItem, "The updated item should exist.");
            bool isRequiredAttendeesUpdatedSuccess = string.Equals(((CalendarItemType)getItem.Items.Items[0]).RequiredAttendees[0].Mailbox.EmailAddress, this.AttendeeEmailAddress, StringComparison.OrdinalIgnoreCase);

            switch (calendarItemUpdateOperationType)
            {
                case CalendarItemUpdateOperationType.SendOnlyToChanged:
                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R62");

                    // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R62
                    this.Site.CaptureRequirementIfIsTrue(
                        isRequiredAttendeesUpdatedSuccess,
                        62,
                        @"[In t:CalendarItemUpdateOperationType Simple Type] SendOnlyToChanged: The calendar item is updated.");
                    break;
                case CalendarItemUpdateOperationType.SendToChangedAndSaveCopy:
                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R65");

                    // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R65
                    this.Site.CaptureRequirementIfIsTrue(
                        isRequiredAttendeesUpdatedSuccess,
                        65,
                        @"[In t:CalendarItemUpdateOperationType Simple Type] SendToChangedAndSaveCopy: The calendar item is updated.");
                    break;
            }
            #endregion

            #region Step4: Verify CalendarItemUpdateOperationType used in UpdateItem operation
            #region Find the update meeting request in Organizer SentItems
            bool updatedIsFoundInOrganizerSentItems = false;
            MeetingRequestMessageType meetingRequestMessageInOrgnizer = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.sentitems, "IPM.Schedule.Meeting.Request", meeting.UID) as MeetingRequestMessageType;
            if (null != meetingRequestMessageInOrgnizer)
            {
                if (null != meetingRequestMessageInOrgnizer.RequiredAttendees && meetingRequestMessageInOrgnizer.RequiredAttendees.Length > 0)
                {
                    for (int i = 0; i < meetingRequestMessageInOrgnizer.RequiredAttendees.Length; i++)
                    {
                        if (string.Equals(meetingRequestMessageInOrgnizer.RequiredAttendees[i].Mailbox.EmailAddress, this.AttendeeEmailAddress, StringComparison.OrdinalIgnoreCase))
                        {
                            updatedIsFoundInOrganizerSentItems = true;
                        }
                    }
                }
            }

            #endregion

            #region Find the update meeting request in Attendees Inbox
            bool updatedIsFoundInAttendeeInbox = false;
            MeetingRequestMessageType meetingRequestMessageInAttendee = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Request", meeting.UID) as MeetingRequestMessageType;
            if (null != meetingRequestMessageInAttendee)
            {
                if (null != meetingRequestMessageInAttendee.RequiredAttendees && meetingRequestMessageInAttendee.RequiredAttendees.Length > 0)
                {
                    for (int i = 0; i < meetingRequestMessageInAttendee.RequiredAttendees.Length; i++)
                    {
                        if (string.Equals(meetingRequestMessageInAttendee.RequiredAttendees[i].Mailbox.EmailAddress, this.AttendeeEmailAddress, StringComparison.OrdinalIgnoreCase))
                        {
                            updatedIsFoundInAttendeeInbox = true;
                        }
                    }
                }
            }
            #endregion

            switch (calendarItemUpdateOperationType)
            {
                case CalendarItemUpdateOperationType.SendOnlyToChanged:
                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R6200");

                    // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R6200
                    // Server always treat the Organizer as RequiredAttendees, therefore, after updated the RequiredAttendees to Attendee, only Attendee will receive the updated meeting message.
                    this.Site.CaptureRequirementIfIsTrue(
                        updatedIsFoundInAttendeeInbox,
                        6200,
                        @"[In t:CalendarItemUpdateOperationType Simple Type] SendOnlyToChanged: [The calendar item is updated] and the meeting update is sent only to attendees that were added and/or deleted because of the update.");
                    break;
                case CalendarItemUpdateOperationType.SendToChangedAndSaveCopy:
                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R6500");

                    // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R6500
                    // Server always treat the Organizer as RequiredAttendees, therefore, after updated the RequiredAttendees to Attendee, only Attendee will receive the updated meeting message.            
                    this.Site.CaptureRequirementIfIsTrue(
                        updatedIsFoundInAttendeeInbox,
                        6500,
                        @"[In t:CalendarItemUpdateOperationType Simple Type] SendToChangedAndSaveCopy: [The calendar item is updated,] the meeting update is sent to all attendees that were added and/or deleted as a result of the update.");

                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R6501");

                    // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R6501
                    this.Site.CaptureRequirementIfIsTrue(
                        updatedIsFoundInOrganizerSentItems,
                        6501,
                        @"[In t:CalendarItemUpdateOperationType Simple Type] SendToChangedAndSaveCopy: [The calendar item is updated, the meeting update is sent to all attendees that were added and/or deleted as a result of the update,] and a copy of the updated meeting request is saved in the Sent Items folder.");
                    break;
            }
            #endregion
        }