示例#1
0
        /// <summary>
        /// Merges the recurrence.
        /// </summary>
        /// <param name="outlookCalendarItem">The outlook calendar item.</param>
        /// <param name="recurrence">The recurrence.</param>
        /// <returns>True if Change.</returns>
        public static bool MergeRecurrence(this AppointmentItem outlookCalendarItem, Recurrence recurrence)
        {
            if (recurrence != null && !string.IsNullOrWhiteSpace(recurrence.Value))
            {
                var result = false;
                var outlookRecurrencePattern = outlookCalendarItem.GetRecurrencePattern();
                var googleRecurrencePattern  = RecurrenceSerializer.Deserialize(recurrence.Value);

                try { result |= outlookCalendarItem.ApplyProperty(r => r.AllDayEvent, googleRecurrencePattern.AllDayEvent); } catch (TargetInvocationException) { }
                result |= outlookRecurrencePattern.ApplyProperty(r => r.RecurrenceType, googleRecurrencePattern.RecurrenceType);
                result |= outlookRecurrencePattern.ApplyProperty(r => r.PatternStartDate, googleRecurrencePattern.StartPattern.HasValue ? googleRecurrencePattern.StartPattern.Value.Date : DateTime.Today);
                if (googleRecurrencePattern.EndPattern.HasValue)
                {
                    result |= outlookRecurrencePattern.ApplyProperty(r => r.PatternEndDate, googleRecurrencePattern.EndPattern.Value.Date);
                }
                else
                {
                    result |= outlookRecurrencePattern.ApplyProperty(r => r.NoEndDate, true);
                }

                result |= outlookRecurrencePattern.ApplyProperty(r => r.DayOfMonth, googleRecurrencePattern.DayOfMonth);
                result |= outlookRecurrencePattern.ApplyProperty(r => r.DayOfWeekMask, googleRecurrencePattern.DayOfWeek);
                result |= outlookRecurrencePattern.ApplyProperty(r => r.MonthOfYear, googleRecurrencePattern.MonthOfYear);

                if (outlookRecurrencePattern.StartTime.TimeOfDay.Ticks != googleRecurrencePattern.StartTime.TimeOfDay.Ticks)
                {
                    result |= outlookRecurrencePattern.ApplyProperty(r => r.StartTime, googleRecurrencePattern.StartTime);
                }

                if (outlookRecurrencePattern.EndTime.TimeOfDay.Ticks != googleRecurrencePattern.EndTime.TimeOfDay.Ticks)
                {
                    result |= outlookRecurrencePattern.ApplyProperty(r => r.EndTime, googleRecurrencePattern.EndTime);
                }

                if (googleRecurrencePattern.Count.HasValue)
                {
                    result |= outlookRecurrencePattern.ApplyProperty(r => r.Occurrences, googleRecurrencePattern.Count.Value);
                }

                if (googleRecurrencePattern.Interval.HasValue)
                {
                    result |= outlookRecurrencePattern.ApplyProperty(r => r.Interval, googleRecurrencePattern.Interval.Value);
                }

                return(result);
            }

            if (outlookCalendarItem.RecurrenceState == OlRecurrenceState.olApptNotRecurring)
            {
                outlookCalendarItem.ClearRecurrencePattern();
                return(true);
            }

            return(false);
        }
示例#2
0
        public AppointmentItem UpdateCalendarEntry(AppointmentItem ai, Event ev, ref int itemModified, Boolean forceCompare = false)
        {
            if (ai.RecurrenceState == OlRecurrenceState.olApptMaster)   //The exception child objects might have changed
            {
                log.Debug("Processing recurring master appointment.");
            }
            else
            {
                if (!forceCompare)   //Needed if the exception has just been created, but now needs updating
                {
                    if (Settings.Instance.SyncDirection != SyncDirection.Bidirectional)
                    {
                        if (DateTime.Parse(GoogleCalendar.GoogleTimeFrom(ai.LastModificationTime)) > DateTime.Parse(ev.Updated))
                        {
                            return(null);
                        }
                    }
                    else
                    {
                        if (GoogleCalendar.OGCSlastModified(ev).AddSeconds(5) >= DateTime.Parse(ev.Updated))
                        {
                            //Google last modified by OGCS
                            return(null);
                        }
                        if (DateTime.Parse(GoogleCalendar.GoogleTimeFrom(ai.LastModificationTime)) > DateTime.Parse(ev.Updated))
                        {
                            return(null);
                        }
                    }
                }
            }

            String evSummary = GoogleCalendar.GetEventSummary(ev);

            log.Debug("Processing >> " + evSummary);

            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            sb.AppendLine(evSummary);

            RecurrencePattern oPattern = (ai.RecurrenceState == OlRecurrenceState.olApptNotRecurring) ? null : ai.GetRecurrencePattern();

            if (ev.Start.Date != null)
            {
                if (ai.RecurrenceState != OlRecurrenceState.olApptMaster)
                {
                    ai.AllDayEvent = true;
                }
                if (MainForm.CompareAttribute("Start time", SyncDirection.GoogleToOutlook, ev.Start.Date, ai.Start.ToString("yyyy-MM-dd"), sb, ref itemModified))
                {
                    if (ai.RecurrenceState == OlRecurrenceState.olApptMaster)
                    {
                        oPattern.PatternStartDate = DateTime.Parse(ev.Start.Date);
                    }
                    else
                    {
                        ai.Start = DateTime.Parse(ev.Start.Date);
                    }
                }
                if (MainForm.CompareAttribute("End time", SyncDirection.GoogleToOutlook, ev.End.Date, ai.End.ToString("yyyy-MM-dd"), sb, ref itemModified))
                {
                    if (ai.RecurrenceState == OlRecurrenceState.olApptMaster)
                    {
                        oPattern.PatternEndDate = DateTime.Parse(ev.End.Date);
                    }
                    else
                    {
                        ai.End = DateTime.Parse(ev.End.Date);
                    }
                }
            }
            else
            {
                if (ai.RecurrenceState != OlRecurrenceState.olApptMaster)
                {
                    ai.AllDayEvent = false;
                }
                if (MainForm.CompareAttribute("Start time",
                                              SyncDirection.GoogleToOutlook,
                                              GoogleCalendar.GoogleTimeFrom(DateTime.Parse(ev.Start.DateTime)),
                                              GoogleCalendar.GoogleTimeFrom(ai.Start), sb, ref itemModified))
                {
                    if (ai.RecurrenceState == OlRecurrenceState.olApptMaster)
                    {
                        oPattern.PatternStartDate = DateTime.Parse(ev.Start.DateTime);
                    }
                    else
                    {
                        ai.Start = DateTime.Parse(ev.Start.DateTime);
                    }
                }
                if (MainForm.CompareAttribute("End time",
                                              SyncDirection.GoogleToOutlook,
                                              GoogleCalendar.GoogleTimeFrom(DateTime.Parse(ev.End.DateTime)),
                                              GoogleCalendar.GoogleTimeFrom(ai.End), sb, ref itemModified))
                {
                    if (ai.RecurrenceState == OlRecurrenceState.olApptMaster)
                    {
                        oPattern.PatternEndDate = DateTime.Parse(ev.End.DateTime);
                    }
                    else
                    {
                        ai.End = DateTime.Parse(ev.End.DateTime);
                    }
                }
            }
            oPattern = (RecurrencePattern)ReleaseObject(oPattern);

            if (ai.RecurrenceState == OlRecurrenceState.olApptMaster)
            {
                if (ev.Recurrence == null || ev.RecurringEventId != null)
                {
                    log.Debug("Converting to non-recurring events.");
                    ai.ClearRecurrencePattern();
                    itemModified++;
                }
                else
                {
                    Recurrence.Instance.CompareOutlookPattern(ev, ai, sb, ref itemModified);
                    Recurrence.Instance.UpdateOutlookExceptions(ai, ev);
                }
            }
            else if (ai.RecurrenceState == OlRecurrenceState.olApptNotRecurring)
            {
                if (!ai.IsRecurring && ev.Recurrence != null && ev.RecurringEventId == null)
                {
                    log.Debug("Converting to recurring appointment.");
                    Recurrence.Instance.CreateOutlookExceptions(ai, ev);
                    itemModified++;
                }
            }

            String summaryObfuscated = Obfuscate.ApplyRegex(ev.Summary, SyncDirection.GoogleToOutlook);

            if (MainForm.CompareAttribute("Subject", SyncDirection.GoogleToOutlook, summaryObfuscated, ai.Subject, sb, ref itemModified))
            {
                ai.Subject = summaryObfuscated;
            }
            if (!Settings.Instance.AddDescription)
            {
                ev.Description = "";
            }
            if (Settings.Instance.SyncDirection == SyncDirection.GoogleToOutlook || !Settings.Instance.AddDescription_OnlyToGoogle)
            {
                if (MainForm.CompareAttribute("Description", SyncDirection.GoogleToOutlook, ev.Description, ai.Body, sb, ref itemModified))
                {
                    ai.Body = ev.Description;
                }
            }

            if (MainForm.CompareAttribute("Location", SyncDirection.GoogleToOutlook, ev.Location, ai.Location, sb, ref itemModified))
            {
                ai.Location = ev.Location;
            }

            String oPrivacy = (ai.Sensitivity == OlSensitivity.olNormal) ? "default" : "private";
            String gPrivacy = (ev.Visibility == null ? "default" : ev.Visibility);

            if (MainForm.CompareAttribute("Private", SyncDirection.GoogleToOutlook, gPrivacy, oPrivacy, sb, ref itemModified))
            {
                ai.Sensitivity = (ev.Visibility != null && ev.Visibility == "private") ? OlSensitivity.olPrivate : OlSensitivity.olNormal;
            }
            String oFreeBusy = (ai.BusyStatus == OlBusyStatus.olFree) ? "transparent" : "opaque";
            String gFreeBusy = (ev.Transparency == null ? "opaque" : ev.Transparency);

            if (MainForm.CompareAttribute("Free/Busy", SyncDirection.GoogleToOutlook, gFreeBusy, oFreeBusy, sb, ref itemModified))
            {
                ai.BusyStatus = (ev.Transparency != null && ev.Transparency == "transparent") ? OlBusyStatus.olFree : OlBusyStatus.olBusy;
            }

            if (Settings.Instance.AddAttendees)
            {
                if (ev.Description != null && ev.Description.Contains("===--- Attendees ---==="))
                {
                    //Protect against <v1.2.4 where attendees were stored as text
                    log.Info("This event still has attendee information in the description - cannot sync them.");
                }
                else if (Settings.Instance.SyncDirection == SyncDirection.Bidirectional &&
                         ev.Attendees != null && ev.Attendees.Count == 0 && ai.Recipients.Count > 150)
                {
                    log.Info("Attendees not being synced - there are too many (" + ai.Recipients.Count + ") for Google.");
                }
                else
                {
                    //Build a list of Outlook attendees. Any remaining at the end of the diff must be deleted.
                    List <Recipient> removeRecipient = new List <Recipient>();
                    if (ai.Recipients != null)
                    {
                        foreach (Recipient recipient in ai.Recipients)
                        {
                            if (recipient.Name != ai.Organizer)
                            {
                                removeRecipient.Add(recipient);
                            }
                        }
                    }
                    if (ev.Attendees != null)
                    {
                        for (int g = ev.Attendees.Count - 1; g >= 0; g--)
                        {
                            bool          foundRecipient = false;
                            EventAttendee attendee       = ev.Attendees[g];

                            foreach (Recipient recipient in ai.Recipients)
                            {
                                if (!recipient.Resolved)
                                {
                                    recipient.Resolve();
                                }
                                String recipientSMTP = IOutlook.GetRecipientEmail(recipient);
                                if (recipientSMTP.ToLower() == attendee.Email.ToLower())
                                {
                                    foundRecipient = true;
                                    removeRecipient.Remove(recipient);

                                    //Optional attendee
                                    bool oOptional = (ai.OptionalAttendees != null && ai.OptionalAttendees.Contains(attendee.DisplayName ?? attendee.Email));
                                    bool gOptional = (attendee.Optional == null) ? false : (bool)attendee.Optional;
                                    if (MainForm.CompareAttribute("Recipient " + recipient.Name + " - Optional Check",
                                                                  SyncDirection.GoogleToOutlook, gOptional, oOptional, sb, ref itemModified))
                                    {
                                        if (gOptional)
                                        {
                                            recipient.Type = (int)OlMeetingRecipientType.olOptional;
                                        }
                                        else
                                        {
                                            recipient.Type = (int)OlMeetingRecipientType.olRequired;
                                        }
                                    }
                                    //Response is readonly in Outlook :(
                                    break;
                                }
                            }
                            if (!foundRecipient &&
                                (attendee.DisplayName != ai.Organizer)) //Attendee in Google is owner in Outlook, so can't also be added as a recipient)
                            {
                                sb.AppendLine("Recipient added: " + (attendee.DisplayName ?? attendee.Email));
                                createRecipient(attendee, ai);
                                itemModified++;
                            }
                        }
                    }

                    foreach (Recipient recipient in removeRecipient)
                    {
                        sb.AppendLine("Recipient removed: " + recipient.Name);
                        recipient.Delete();
                        itemModified++;
                    }
                }
            }
            //Reminders
            if (Settings.Instance.AddReminders)
            {
                if (ev.Reminders.Overrides != null)
                {
                    //Find the popup reminder in Google
                    for (int r = ev.Reminders.Overrides.Count - 1; r >= 0; r--)
                    {
                        EventReminder reminder = ev.Reminders.Overrides[r];
                        if (reminder.Method == "popup")
                        {
                            if (ai.ReminderSet)
                            {
                                if (MainForm.CompareAttribute("Reminder", SyncDirection.GoogleToOutlook, reminder.Minutes.ToString(), ai.ReminderMinutesBeforeStart.ToString(), sb, ref itemModified))
                                {
                                    ai.ReminderMinutesBeforeStart = (int)reminder.Minutes;
                                }
                            }
                            else
                            {
                                sb.AppendLine("Reminder: nothing => " + reminder.Minutes);
                                ai.ReminderSet = true;
                                ai.ReminderMinutesBeforeStart = (int)reminder.Minutes;
                                itemModified++;
                            } //if Outlook reminders set
                        }     //if google reminder found
                    }         //foreach reminder
                }
                else     //no google reminders set
                {
                    if (ai.ReminderSet)
                    {
                        sb.AppendLine("Reminder: " + ai.ReminderMinutesBeforeStart + " => removed");
                        ai.ReminderSet = false;
                        itemModified++;
                    }
                }
            }
            if (itemModified > 0)
            {
                MainForm.Instance.Logboxout(sb.ToString(), false, verbose: true);
                MainForm.Instance.Logboxout(itemModified + " attributes updated.", verbose: true);
                System.Windows.Forms.Application.DoEvents();
            }
            return(ai);
        }
        public AppointmentItem UpdateCalendarEntry(AppointmentItem ai, Event ev, ref int itemModified, Boolean forceCompare = false)
        {
            if (ai.RecurrenceState == OlRecurrenceState.olApptMaster) { //The exception child objects might have changed
                log.Debug("Processing recurring master appointment.");
            } else {
                if (!(MainForm.Instance.ManualForceCompare || forceCompare)) { //Needed if the exception has just been created, but now needs updating
                    if (Settings.Instance.SyncDirection != SyncDirection.Bidirectional) {
                        if (DateTime.Parse(GoogleCalendar.GoogleTimeFrom(ai.LastModificationTime)) > DateTime.Parse(ev.Updated))
                            return null;
                    } else {
                        if (GoogleCalendar.GetOGCSlastModified(ev).AddSeconds(5) >= DateTime.Parse(ev.Updated))
                            //Google last modified by OGCS
                            return null;
                        if (DateTime.Parse(GoogleCalendar.GoogleTimeFrom(ai.LastModificationTime)) > DateTime.Parse(ev.Updated))
                            return null;
                    }
                }
            }

            String evSummary = GoogleCalendar.GetEventSummary(ev);
            log.Debug("Processing >> " + evSummary);

            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            sb.AppendLine(evSummary);

            if (ai.RecurrenceState != OlRecurrenceState.olApptMaster) {
                if (ai.AllDayEvent != (ev.Start.DateTime == null)) {
                    sb.AppendLine("All-Day: " + ai.AllDayEvent + " => " + (ev.Start.DateTime == null));
                    ai.AllDayEvent = (ev.Start.DateTime == null);
                    itemModified++;
                }
            }

            RecurrencePattern oPattern = (ai.RecurrenceState == OlRecurrenceState.olApptMaster) ? ai.GetRecurrencePattern() : null;
            Recurrence.Instance.CompareOutlookPattern(ev, ai, SyncDirection.GoogleToOutlook, sb, ref itemModified);

            DateTime evParsedDate = DateTime.Parse(ev.Start.Date ?? ev.Start.DateTime);
            if (MainForm.CompareAttribute("Start time", SyncDirection.GoogleToOutlook,
                GoogleCalendar.GoogleTimeFrom(evParsedDate),
                GoogleCalendar.GoogleTimeFrom(ai.Start), sb, ref itemModified))
            {
                if (ai.RecurrenceState == OlRecurrenceState.olApptMaster) {
                    oPattern.PatternStartDate = evParsedDate;
                    oPattern.StartTime = evParsedDate;
                } else {
                    ai.Start = evParsedDate;
                }
            }

            evParsedDate = DateTime.Parse(ev.End.Date ?? ev.End.DateTime);
            if (MainForm.CompareAttribute("End time", SyncDirection.GoogleToOutlook,
                GoogleCalendar.GoogleTimeFrom(evParsedDate),
                GoogleCalendar.GoogleTimeFrom(ai.End), sb, ref itemModified))
            {
                if (ai.RecurrenceState == OlRecurrenceState.olApptMaster) {
                    oPattern.EndTime = evParsedDate;
                } else {
                    ai.End = evParsedDate;
                }
            }

            if (oPattern != null) {
                oPattern.Duration = Convert.ToInt32((evParsedDate - DateTime.Parse(ev.Start.Date ?? ev.Start.DateTime)).TotalMinutes);
                oPattern = (RecurrencePattern)ReleaseObject(oPattern);
            }

            if (ai.RecurrenceState == OlRecurrenceState.olApptMaster) {
                if (ev.Recurrence == null || ev.RecurringEventId != null) {
                    log.Debug("Converting to non-recurring events.");
                    ai.ClearRecurrencePattern();
                    itemModified++;
                } else {
                    Recurrence.Instance.UpdateOutlookExceptions(ai, ev);
                }
            } else if (ai.RecurrenceState == OlRecurrenceState.olApptNotRecurring) {
                if (!ai.IsRecurring && ev.Recurrence != null && ev.RecurringEventId == null) {
                    log.Debug("Converting to recurring appointment.");
                    Recurrence.Instance.CreateOutlookExceptions(ai, ev);
                    itemModified++;
                }
            }

            String summaryObfuscated = Obfuscate.ApplyRegex(ev.Summary, SyncDirection.GoogleToOutlook);
            if (MainForm.CompareAttribute("Subject", SyncDirection.GoogleToOutlook, summaryObfuscated, ai.Subject, sb, ref itemModified)) {
                ai.Subject = summaryObfuscated;
            }
            if (!Settings.Instance.AddDescription) ev.Description = "";
            if (Settings.Instance.SyncDirection == SyncDirection.GoogleToOutlook || !Settings.Instance.AddDescription_OnlyToGoogle) {
                if (MainForm.CompareAttribute("Description", SyncDirection.GoogleToOutlook, ev.Description, ai.Body, sb, ref itemModified))
                    ai.Body = ev.Description;
            }

            if (MainForm.CompareAttribute("Location", SyncDirection.GoogleToOutlook, ev.Location, ai.Location, sb, ref itemModified))
                ai.Location = ev.Location;

            String oPrivacy = (ai.Sensitivity == OlSensitivity.olNormal) ? "default" : "private";
            String gPrivacy = ev.Visibility ?? "default";
            if (MainForm.CompareAttribute("Private", SyncDirection.GoogleToOutlook, gPrivacy, oPrivacy, sb, ref itemModified)) {
                ai.Sensitivity = (ev.Visibility != null && ev.Visibility == "private") ? OlSensitivity.olPrivate : OlSensitivity.olNormal;
            }
            String oFreeBusy = (ai.BusyStatus == OlBusyStatus.olFree) ? "transparent" : "opaque";
            String gFreeBusy = ev.Transparency ?? "opaque";
            if (MainForm.CompareAttribute("Free/Busy", SyncDirection.GoogleToOutlook, gFreeBusy, oFreeBusy, sb, ref itemModified)) {
                ai.BusyStatus = (ev.Transparency != null && ev.Transparency == "transparent") ? OlBusyStatus.olFree : OlBusyStatus.olBusy;
            }

            if (Settings.Instance.AddAttendees) {
                if (ev.Description != null && ev.Description.Contains("===--- Attendees ---===")) {
                    //Protect against <v1.2.4 where attendees were stored as text
                    log.Info("This event still has attendee information in the description - cannot sync them.");
                } else if (Settings.Instance.SyncDirection == SyncDirection.Bidirectional &&
                    ev.Attendees != null && ev.Attendees.Count == 0 && ai.Recipients.Count > 150) {
                        log.Info("Attendees not being synced - there are too many ("+ ai.Recipients.Count +") for Google.");
                } else {
                    //Build a list of Outlook attendees. Any remaining at the end of the diff must be deleted.
                    List<Recipient> removeRecipient = new List<Recipient>();
                    if (ai.Recipients != null) {
                        foreach (Recipient recipient in ai.Recipients) {
                            if (recipient.Name != ai.Organizer)
                                removeRecipient.Add(recipient);
                        }
                    }
                    if (ev.Attendees != null) {
                        for (int g = ev.Attendees.Count - 1; g >= 0; g--) {
                            bool foundRecipient = false;
                            EventAttendee attendee = ev.Attendees[g];

                            foreach (Recipient recipient in ai.Recipients) {
                                if (!recipient.Resolved) recipient.Resolve();
                                String recipientSMTP = IOutlook.GetRecipientEmail(recipient);
                                if (recipientSMTP.ToLower() == attendee.Email.ToLower()) {
                                    foundRecipient = true;
                                    removeRecipient.Remove(recipient);

                                    //Optional attendee
                                    bool oOptional = (ai.OptionalAttendees != null && ai.OptionalAttendees.Contains(attendee.DisplayName ?? attendee.Email));
                                    bool gOptional = (attendee.Optional == null) ? false : (bool)attendee.Optional;
                                    if (MainForm.CompareAttribute("Recipient " + recipient.Name + " - Optional Check",
                                        SyncDirection.GoogleToOutlook, gOptional, oOptional, sb, ref itemModified)) {
                                        if (gOptional) {
                                            recipient.Type = (int)OlMeetingRecipientType.olOptional;
                                        } else {
                                            recipient.Type = (int)OlMeetingRecipientType.olRequired;
                                        }
                                    }
                                    //Response is readonly in Outlook :(
                                    break;
                                }
                            }
                            if (!foundRecipient &&
                                (attendee.DisplayName != ai.Organizer)) //Attendee in Google is owner in Outlook, so can't also be added as a recipient)
                                {
                                sb.AppendLine("Recipient added: " + (attendee.DisplayName ?? attendee.Email));
                                createRecipient(attendee, ai);
                                itemModified++;
                            }
                        }
                    }

                    foreach (Recipient recipient in removeRecipient) {
                        sb.AppendLine("Recipient removed: " + recipient.Name);
                        recipient.Delete();
                        itemModified++;
                    }
                }
            }
            //Reminders
            if (Settings.Instance.AddReminders) {
                if (ev.Reminders.Overrides != null) {
                    //Find the popup reminder in Google
                    for (int r = ev.Reminders.Overrides.Count - 1; r >= 0; r--) {
                        EventReminder reminder = ev.Reminders.Overrides[r];
                        if (reminder.Method == "popup") {
                            if (ai.ReminderSet) {
                                if (MainForm.CompareAttribute("Reminder", SyncDirection.GoogleToOutlook, reminder.Minutes.ToString(), ai.ReminderMinutesBeforeStart.ToString(), sb, ref itemModified)) {
                                    ai.ReminderMinutesBeforeStart = (int)reminder.Minutes;
                                }
                            } else {
                                sb.AppendLine("Reminder: nothing => " + reminder.Minutes);
                                ai.ReminderSet = true;
                                ai.ReminderMinutesBeforeStart = (int)reminder.Minutes;
                                itemModified++;
                            } //if Outlook reminders set
                        } //if google reminder found
                    } //foreach reminder

                } else { //no google reminders set
                    if (ai.ReminderSet && IsOKtoSyncReminder(ai)) {
                        sb.AppendLine("Reminder: " + ai.ReminderMinutesBeforeStart + " => removed");
                        ai.ReminderSet = false;
                        itemModified++;
                    }
                }
            }
            if (itemModified > 0) {
                MainForm.Instance.Logboxout(sb.ToString(), false, verbose: true);
                MainForm.Instance.Logboxout(itemModified + " attributes updated.", verbose: true);
                System.Windows.Forms.Application.DoEvents();
            }
            return ai;
        }
        private static void UpdateOutlookAppointment(AppointmentItem appointment, string mtg_id, MeetingRequest request, bool reload_pattern = false)
        {
            int mrbs_id = -1;

            int.TryParse(mtg_id.Substring(0, mtg_id.IndexOf(";")), out mrbs_id);

            // appointment.Subject = request.Description;

            if ((appointment.RecurrenceState != OlRecurrenceState.olApptMaster) || (appointment.EntryID == ""))
            {
                appointment.Start = request.Start;
                appointment.End   = request.End;
            }

            appointment.Location = String.Format("{0} - {1}", Database.GetAreaNameByRoomId(request.RoomId), Database.GetRoomNameById(request.RoomId));

            if (request.RepeatTypeId > 0)
            {
                RecurrencePattern pattern;

                if (reload_pattern)
                {
                    appointment.ClearRecurrencePattern();
                }

                pattern = appointment.GetRecurrencePattern();

                switch (request.RepeatTypeId)
                {
                case 1:
                    pattern.RecurrenceType = OlRecurrenceType.olRecursDaily;
                    pattern.Interval       = 1;
                    break;

                case 2:
                    char[] rev = request.RepeatWeeklyCode.ToCharArray();

                    pattern.RecurrenceType = OlRecurrenceType.olRecursWeekly;
                    pattern.Interval       = request.RepeatNumberOfWeeks;
                    pattern.DayOfWeekMask  = (OlDaysOfWeek)Convert.ToInt32(new string(request.RepeatWeeklyCode.ToCharArray().Reverse().ToArray()), 2);
                    break;

                case 3:
                    if (request.RepeatMonthlyByWeekday)
                    {
                        pattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                        pattern.Interval       = 1;
                        pattern.DayOfWeekMask  = (OlDaysOfWeek)((int)Math.Pow(2, request.RepeatWeekdayOfMonth));
                        pattern.Instance       = request.RepeatWeekdaysOfMonth;
                    }
                    else
                    {
                        pattern.RecurrenceType = OlRecurrenceType.olRecursMonthly;
                        pattern.Interval       = 1;
                        pattern.DayOfMonth     = request.RepeatDayOfMonth;
                    }
                    break;

                case 4:
                    pattern.RecurrenceType = OlRecurrenceType.olRecursYearly;
                    break;
                }

                pattern.Duration         = (request.End - request.Start).Minutes;
                pattern.EndTime          = request.RepeatEnd.Date + request.End.TimeOfDay;
                pattern.NoEndDate        = false;
                pattern.PatternStartDate = request.Start;
                pattern.PatternEndDate   = request.RepeatEnd + request.End.TimeOfDay;
                pattern.StartTime        = request.Start;
            }

            try
            {
                appointment.UserProperties.Add("MJ-MRBS-ID", OlUserPropertyType.olText, true, OlFormatText.olFormatTextText);
            }
            catch (UnauthorizedAccessException)
            {
                //appointment.UserProperties.Add("MJ-MRBS-ID", OlUserPropertyType.olText, true, OlFormatText.olFormatTextText);
            }

            appointment.UserProperties["MJ-MRBS-ID"].Value = mtg_id;
            if (!appointment.Body.Contains("has been linked to a reservation in MRBS."))
            {
                appointment.Body += String.Format("\n\n\n***** This {0} has been linked to a reservation in MRBS. To change the {0} location, you must use the Modify Reservation button in the ribbon. *****", appointment.MeetingStatus == OlMeetingStatus.olNonMeeting ? "appointment" : "meeting");
            }

            appointment.Save();
            if (request.RepeatTypeId > 0)
            {
                RecurrencePattern pattern   = appointment.GetRecurrencePattern();
                List <Entry>      entries   = Database.GetAllEntries(mrbs_id);
                List <Entry>      conflicts = Database.FindConflicts(request, mrbs_id);

                foreach (Entry conflict in conflicts)
                {
                    DateTime start_time = Database.UnixTimeStampToDateTime(conflict.start_time);

                    AppointmentItem item = pattern.GetOccurrence(start_time);
                    item.Delete();
                }

                foreach (Entry entry in entries)
                {
                    try
                    {
                        DateTime        start_time = Database.UnixTimeStampToDateTime(entry.start_time);
                        AppointmentItem item       = pattern.GetOccurrence(start_time);
                        item.UserProperties.Add("MJ-MRBS-ID", OlUserPropertyType.olText, true, OlFormatText.olFormatTextText);
                        item.UserProperties["MJ-MRBS-ID"].Value = String.Format("{0};{1}", entry.id, entry.ical_uid);
                        item.Save();
                    }
                    catch { }
                }

                appointment.Save();
            }
        }