private IEnumerable<Appointment> GetAppointments(RadScheduler owner, string sharedCalendarName, ItemIdType[] itemIdsArray)
		{
			IList<CalendarItemType> calendarItems = GetCalendarItems(itemIdsArray);
			List<Appointment> appointments = new List<Appointment>(calendarItems.Count);
			foreach (CalendarItemType item in calendarItems)
			{
                appointments.AddRange(CreateAppointmentsFromCalendarItem(owner, sharedCalendarName, item));
			}

			return appointments;
		}
		private CalendarItemType GetOccurrenceItem(Appointment master, int index)
		{
			ItemIdType masterItemId = new ItemIdType();
			masterItemId.Id = master.Attributes[ExchangeIdAttribute];
			masterItemId.ChangeKey = master.Attributes[ExchangeChangeKeyAttribute];

			OccurrenceItemIdType occurrenceItemId = new OccurrenceItemIdType();
			occurrenceItemId.RecurringMasterId = masterItemId.Id;
			occurrenceItemId.InstanceIndex = index;

			PathToUnindexedFieldType calendarItemTypePath = new PathToUnindexedFieldType();
			calendarItemTypePath.FieldURI = UnindexedFieldURIType.calendarCalendarItemType;

			GetItemType getItemRequest = new GetItemType();
			getItemRequest.ItemShape = new ItemResponseShapeType();
			getItemRequest.ItemShape.BaseShape = DefaultShapeNamesType.IdOnly;
			getItemRequest.ItemShape.AdditionalProperties = new BasePathToElementType[] { calendarItemTypePath };
			getItemRequest.ItemIds = new BaseItemIdType[] { masterItemId, occurrenceItemId };

			GetItemResponseType getItemResponse = Service.GetItem(getItemRequest);

			CalendarItemType occurrenceItem = null;
			foreach (ItemInfoResponseMessageType getItemResponseMessage in getItemResponse.ResponseMessages.Items)
			{
				if (getItemResponseMessage.ResponseClass == ResponseClassType.Success &&
				    getItemResponseMessage.Items.Items != null &&
				    getItemResponseMessage.Items.Items.Length > 0)
				{
					occurrenceItem = (CalendarItemType) getItemResponseMessage.Items.Items[0];
				}
			}

			if (occurrenceItem == null)
			{
				throw new Exception("Unable to find occurrence");
			}

			return occurrenceItem;
		}
		private void SynchronizeDeletedOccurrences(Appointment apt)
		{
			RecurrenceRule rrule;
			if (!RecurrenceRule.TryParse(apt.RecurrenceRule, out rrule))
			{
				return;
			}

			ItemIdType itemId = new ItemIdType();
			itemId.Id = apt.Attributes[ExchangeIdAttribute];
			itemId.ChangeKey = apt.Attributes[ExchangeChangeKeyAttribute];
			CalendarItemType calendarItem = GetCalendarItems(new ItemIdType[] { itemId })[0];

			List<DateTime> existingExceptions = new List<DateTime>();
			if (calendarItem.ModifiedOccurrences != null)
			{
				foreach (CalendarItemType modifiedOccurrence in GetModifiedOccurrences(calendarItem))
				{
					existingExceptions.Add(modifiedOccurrence.OriginalStart);
				}
			}

			if (calendarItem.DeletedOccurrences != null)
			{
				foreach (DeletedOccurrenceInfoType deletedOccurrence in calendarItem.DeletedOccurrences)
				{
					existingExceptions.Add(deletedOccurrence.Start);
				}
			}

			foreach (DateTime recurrenceException in rrule.Exceptions)
			{
				// Search in ModifiedOccurrences and DeletedOccurrences for this exception.	
				if (existingExceptions.Contains(recurrenceException))
				{
					continue;
				}

				// If it is not found in either, delete the occurrence.
				int occurrenceIndex = GetOccurrenceIndex(recurrenceException, apt);
				CalendarItemType occurrenceItem = GetOccurrenceItem(apt, occurrenceIndex);
				DeleteItem(occurrenceItem.ItemId);
			}
		}
		private void RemoveRecurrenceExceptions(Appointment appointmentToUpdate)
		{
			ItemChangeType itemUpdates = new ItemChangeType();

			ItemIdType itemId = new ItemIdType();
			itemId.Id = appointmentToUpdate.Attributes[ExchangeIdAttribute];
			itemId.ChangeKey = appointmentToUpdate.Attributes[ExchangeChangeKeyAttribute];

			itemUpdates.Item = itemId;

			PathToUnindexedFieldType deletedOccurrencesPath = new PathToUnindexedFieldType();
			deletedOccurrencesPath.FieldURI = UnindexedFieldURIType.calendarRecurrence;

			DeleteItemFieldType deletedOccurrencesUpdate = new DeleteItemFieldType();
			deletedOccurrencesUpdate.Item = deletedOccurrencesPath;

			// To reset the deleted and modified occurrences we must
			// remove the recurrence rule and then immediately restore it
			itemUpdates.Updates = new ItemChangeDescriptionType[] { deletedOccurrencesUpdate, GetRecurrenceUpdate(appointmentToUpdate) };
			UpdateCalendarItem(new ItemChangeType[] { itemUpdates });
		}
		protected internal IList<CalendarItemType> GetCalendarItems(ItemIdType[] itemIds)
		{
			if (itemIds.Length == 0)
			{
				return new CalendarItemType[0];
			}

			List<CalendarItemType> calendarItems = new List<CalendarItemType>(itemIds.Length);

			// Form the GetItem request.
			GetItemType getItemRequest = new GetItemType();
			getItemRequest.ItemShape = new ItemResponseShapeType();
			getItemRequest.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;
			getItemRequest.ItemIds = itemIds;

			GetItemResponseType getItemResponse = Service.GetItem(getItemRequest);

			foreach (ItemInfoResponseMessageType responseMessage in getItemResponse.ResponseMessages.Items)
			{
				if (responseMessage.ResponseClass == ResponseClassType.Success &&
				    responseMessage.Items.Items != null &&
				    responseMessage.Items.Items.Length > 0)
				{
					calendarItems.Add((CalendarItemType) responseMessage.Items.Items[0]);
				}
			}

			return calendarItems.ToArray();
		}
		protected virtual ItemChangeType GetAppointmentChanges(Appointment apt)
		{
			ItemChangeType itemUpdates = new ItemChangeType();

			ItemIdType itemId = new ItemIdType();
			itemId.Id = apt.Attributes[ExchangeIdAttribute];
			itemId.ChangeKey = apt.Attributes[ExchangeChangeKeyAttribute];

			itemUpdates.Item = itemId;
			List<ItemChangeDescriptionType> updates = new List<ItemChangeDescriptionType>();
			updates.Add(GetSubjectUpdate(apt));
			updates.Add(GetStartUpdate(apt));
			updates.Add(GetEndUpdate(apt));

			if (apt.RecurrenceRule != string.Empty)
			{
				updates.Add(GetRecurrenceUpdate(apt));
			}

			itemUpdates.Updates = updates.ToArray();

			return itemUpdates;
		}
		/// <summary>
		/// Deletes the specified appointment.
		/// </summary>
		/// <param name="owner">The owner RadScheduler instance.</param>
		/// <param name="appointmentToDelete">The appointment to delete.</param>
		public override void Delete(RadScheduler owner, Appointment appointmentToDelete)
		{
			if (owner.ProviderContext is RemoveRecurrenceExceptionsContext)
			{
				return;
			}

			ItemIdType itemId = new ItemIdType();
			itemId.Id = appointmentToDelete.Attributes[ExchangeIdAttribute];
			itemId.ChangeKey = appointmentToDelete.Attributes[ExchangeChangeKeyAttribute];

			DeleteItem(itemId);
		}