private void ProcessRecurringCalendarItem(Appointment targetAppointment, CalendarItemType calendarItem, RadScheduler owner, ICollection<Appointment> instances)
		{
			targetAppointment.RecurrenceState = RecurrenceState.Master;

			RecurrencePattern pattern = calendarItem.Recurrence.Item.ConvertToRecurrencePattern();

			RecurrenceRange range = calendarItem.Recurrence.Item1.ConvertToRecurrenceRange();
			range.EventDuration = targetAppointment.Duration;
			range.Start = targetAppointment.Start;

			RecurrenceRule rrule = RecurrenceRule.FromPatternAndRange(pattern, range);

			if (calendarItem.ModifiedOccurrences != null)
			{
				foreach (CalendarItemType modifiedOccurrence in GetModifiedOccurrences(calendarItem))
				{
					foreach (Appointment aptException in CreateAppointmentsFromCalendarItem(owner, modifiedOccurrence))
					{
						aptException.RecurrenceState = RecurrenceState.Exception;
						aptException.RecurrenceParentID = calendarItem.ItemId.Id;

						instances.Add(aptException);
					}

					rrule.Exceptions.Add(modifiedOccurrence.OriginalStart);
				}
			}

			if (calendarItem.DeletedOccurrences != null)
			{
				foreach (DeletedOccurrenceInfoType occurenceInfo in calendarItem.DeletedOccurrences)
				{
					rrule.Exceptions.Add(occurenceInfo.Start);
				}
			}

			targetAppointment.RecurrenceRule = rrule.ToString();
		}
		private IList<CalendarItemType> GetModifiedOccurrences(CalendarItemType calendarItem)
		{
			List<ItemIdType> exceptionIds = new List<ItemIdType>();
			foreach (OccurrenceInfoType occurenceInfo in calendarItem.ModifiedOccurrences)
			{
				exceptionIds.Add(occurenceInfo.ItemId);
			}

			return GetCalendarItems(exceptionIds.ToArray());
		}
		private static SetItemFieldType GetEndUpdate(Appointment apt)
		{
			SetItemFieldType endUpdate = new SetItemFieldType();

			PathToUnindexedFieldType endPath = new PathToUnindexedFieldType();
			endPath.FieldURI = UnindexedFieldURIType.calendarEnd;

			CalendarItemType endData = new CalendarItemType();
			endData.End = apt.End;
			endData.EndSpecified = true;

			endUpdate.Item = endPath;
			endUpdate.Item1 = endData;
			return endUpdate;
		}
		private static SetItemFieldType GetRecurrenceUpdate(Appointment apt)
		{
			SetItemFieldType recurrenceUpdate = new SetItemFieldType();

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

			CalendarItemType recurrenceData = new CalendarItemType();
			RecurrenceRule rrule;
			RecurrenceRule.TryParse(apt.RecurrenceRule, out rrule);
			if (rrule != null && rrule.Pattern.Frequency != RecurrenceFrequency.Hourly)
			{
				recurrenceData.Recurrence = CreateRecurrence(rrule, apt.Owner);
			}

			recurrenceUpdate.Item = recurrencePath;
			recurrenceUpdate.Item1 = recurrenceData;
			return recurrenceUpdate;
		}
		private static SetItemFieldType GetStartUpdate(Appointment apt)
		{
			SetItemFieldType startUpdate = new SetItemFieldType();

			PathToUnindexedFieldType startPath = new PathToUnindexedFieldType();
			startPath.FieldURI = UnindexedFieldURIType.calendarStart;

			CalendarItemType startData = new CalendarItemType();
			startData.Start = apt.Start;
			startData.StartSpecified = true;

			startUpdate.Item = startPath;
			startUpdate.Item1 = startData;
			return startUpdate;
		}
		private static SetItemFieldType GetSubjectUpdate(Appointment apt)
		{
			SetItemFieldType subjectUpdate = new SetItemFieldType();

			PathToUnindexedFieldType subjectPath = new PathToUnindexedFieldType();
			subjectPath.FieldURI = UnindexedFieldURIType.itemSubject;

			CalendarItemType subjectData = new CalendarItemType();
			subjectData.Subject = apt.Subject;

			subjectUpdate.Item = subjectPath;
			subjectUpdate.Item1 = subjectData;
			return subjectUpdate;
		}
		protected virtual IEnumerable<Appointment> CreateAppointmentsFromCalendarItem(RadScheduler owner, string sharedCalendarName, CalendarItemType calendarItem)
		{
			Appointment calendarAppointment = new Appointment();
			calendarAppointment.ID = calendarItem.ItemId.Id;
			calendarAppointment.Subject = calendarItem.Subject;
			calendarAppointment.Start = calendarItem.Start;
			calendarAppointment.End = calendarItem.End;
			calendarAppointment.Owner = owner;

			calendarAppointment.Attributes[ExchangeIdAttribute] = calendarItem.ItemId.Id;
			calendarAppointment.Attributes[ExchangeChangeKeyAttribute] = calendarItem.ItemId.ChangeKey;


            //Get any additional data to display.
            calendarAppointment.Attributes["Location"] = calendarItem.Location;
            calendarAppointment.Attributes["Organizer"] = calendarItem.Organizer.Item.Name;

            //Create a ToolTip similar to the one in Outlook.
		    const string hourFormat = "%h:mmtt";


            string tooltip;
            if (!String.IsNullOrEmpty(calendarItem.Location))
            {
                tooltip = String.Format("{0}-{1} {2}\n({3})",
                calendarItem.Start.ToString(hourFormat).ToLower(),
                calendarItem.End.ToString(hourFormat).ToLower(),
                calendarItem.Subject,
                calendarItem.Location);
            }
            else
            {
                tooltip = String.Format("{0}-{1} {2}",
                calendarItem.Start.ToString(hourFormat).ToLower(),
                calendarItem.End.ToString(hourFormat).ToLower(),
                calendarItem.Subject);
            }
           

		    calendarAppointment.ToolTip = tooltip;

            if (sharedCalendarName != null)
            {
                calendarAppointment.Resources.Add(owner.Resources.GetResource("SharedCalendar", sharedCalendarName));
            }


		    List<Appointment> instances = new List<Appointment>();
			instances.Add(calendarAppointment);

			if (calendarItem.Recurrence != null)
			{
				ProcessRecurringCalendarItem(calendarAppointment, calendarItem, owner, instances);
			}

			return instances;
		}
 protected virtual IEnumerable<Appointment> CreateAppointmentsFromCalendarItem(RadScheduler owner, CalendarItemType calendarItem)
 {
     return CreateAppointmentsFromCalendarItem(owner, null, calendarItem);
 }
        protected virtual CalendarItemType CreateCalendarItem(RadScheduler owner, Appointment apt)
        {
            CalendarItemType calendarItem = new CalendarItemType();
            calendarItem.Subject = apt.Subject;
            calendarItem.Start = apt.Start;
            calendarItem.StartSpecified = true;
            calendarItem.End = apt.End;
            calendarItem.EndSpecified = true;
         
            calendarItem.MeetingTimeZone = GetTimeZone(owner.TimeZoneOffset);

            RecurrenceRule rrule;
            RecurrenceRule.TryParse(apt.RecurrenceRule, out rrule);
            if (rrule != null && rrule.Pattern.Frequency != RecurrenceFrequency.Hourly)
            {
                calendarItem.Recurrence = CreateRecurrence(rrule, owner);
            }

            return calendarItem;
        }