/// <summary>
        /// Merges the with.
        /// </summary>
        /// <param name="outlookCalendarItem">The outlook calendar item.</param>
        /// <param name="googleCalendarItem">The google calendar item.</param>
        /// <returns>True if Changed.</returns>
        public static bool MergeWith(this AppointmentItem outlookCalendarItem, EventEntry googleCalendarItem)
        {
            var result = false;

            result |= outlookCalendarItem.ApplyProperty(c => c.Subject, googleCalendarItem.Title.Text);
            result |= outlookCalendarItem.ApplyProperty(c => c.Body, googleCalendarItem.Content.Content);
            result |= outlookCalendarItem.ApplyProperty(c => c.Location, googleCalendarItem.Locations.FirstOrInstance(l => l.Rel == Where.RelType.EVENT).ValueString);
            result |= outlookCalendarItem.ApplyProperty(c => c.BusyStatus, googleCalendarItem.EventTransparency.GetStatus());
            result |= outlookCalendarItem.ApplyProperty(c => c.Sensitivity, googleCalendarItem.EventVisibility.GetStatus());
            result |= outlookCalendarItem.MergeRecipients(googleCalendarItem.Participants);

            if (googleCalendarItem.Times.Any())
            {
                var time = googleCalendarItem.Times.First();
                result |= outlookCalendarItem.ApplyProperty(c => c.AllDayEvent, time.AllDay);
                result |= outlookCalendarItem.ApplyProperty(c => c.Start, time.StartTime);
                result |= outlookCalendarItem.ApplyProperty(c => c.End, time.EndTime);

                if (time.Reminders.Any(r => r.Method == Google.GData.Extensions.Reminder.ReminderMethod.alert))
                {
                    var reminder = time.Reminders.First(r => r.Method == Google.GData.Extensions.Reminder.ReminderMethod.alert);
                    result |= outlookCalendarItem.ApplyProperty(c => c.ReminderSet, true);
                    result |= outlookCalendarItem.ApplyProperty(c => c.ReminderOverrideDefault, true);
                    result |= outlookCalendarItem.ApplyProperty(c => c.ReminderMinutesBeforeStart, reminder.GetMinutes());
                }
                else
                {
                    result |= outlookCalendarItem.ApplyProperty(c => c.ReminderSet, false);
                    result |= outlookCalendarItem.ApplyProperty(c => c.ReminderOverrideDefault, false);
                }
            }

            result |= outlookCalendarItem.MergeRecurrence(googleCalendarItem.Recurrence);

            return result;
        }
        /// <summary>
        /// Merges the with.
        /// </summary>
        /// <param name="outlookContact">The outlook contact.</param>
        /// <param name="googleContact">The google contact.</param>
        /// <param name="outlookGroups">The outlook groups.</param>
        /// <returns>
        /// True if Changed.
        /// </returns>
        public static bool MergeWith(this ContactItem outlookContact, Contact googleContact, IEnumerable<Group> outlookGroups)
        {
            var result = false;

            result |= outlookContact.ApplyProperty(c => c.FullName, googleContact.Name.FullName);
            result |= outlookContact.ApplyProperty(c => c.FirstName, googleContact.Name.GivenName);
            result |= outlookContact.ApplyProperty(c => c.LastName, googleContact.Name.FamilyName);

            result |= outlookContact.ApplyProperty(c => c.Email1Address, googleContact.Emails.FirstOrInstance(e => e.Primary).Address);
            result |= outlookContact.ApplyProperty(c => c.Email2Address, googleContact.Emails.FirstOrInstance(e => !e.Primary).Address);
            result |= outlookContact.ApplyProperty(c => c.Email3Address, googleContact.Emails.FirstOrInstance(e => !e.Primary && e.Address != outlookContact.Email2Address).Address);

            result |= outlookContact.ApplyProperty(c => c.PrimaryTelephoneNumber, (googleContact.Phonenumbers.FirstOrDefault(p => p.Primary) ?? googleContact.Phonenumbers.FirstOrInstance()).Value.FormatPhone());
            result |= outlookContact.ApplyProperty(c => c.HomeTelephoneNumber, googleContact.Phonenumbers.FirstOrInstance(p => p.Rel == ContactsRelationships.IsHome).Value.FormatPhone());
            result |= outlookContact.ApplyProperty(c => c.HomeFaxNumber, googleContact.Phonenumbers.FirstOrInstance(p => p.Rel == ContactsRelationships.IsHomeFax).Value.FormatPhone());
            result |= outlookContact.ApplyProperty(c => c.BusinessTelephoneNumber, googleContact.Phonenumbers.FirstOrInstance(p => p.Rel == ContactsRelationships.IsWork).Value.FormatPhone());
            result |= outlookContact.ApplyProperty(c => c.BusinessFaxNumber, googleContact.Phonenumbers.FirstOrInstance(p => p.Rel == ContactsRelationships.IsWorkFax).Value.FormatPhone());
            result |= outlookContact.ApplyProperty(c => c.OtherFaxNumber, googleContact.Phonenumbers.FirstOrInstance(p => p.Rel == ContactsRelationships.IsOther).Value.FormatPhone());
            result |= outlookContact.ApplyProperty(c => c.OtherTelephoneNumber, googleContact.Phonenumbers.FirstOrInstance(p => p.Rel == ContactsRelationships.IsFax).Value.FormatPhone());
            result |= outlookContact.ApplyProperty(c => c.MobileTelephoneNumber, googleContact.Phonenumbers.FirstOrInstance(p => p.Rel == ContactsRelationships.IsMobile).Value.FormatPhone());

            var primaryMailAddress = googleContact.PostalAddresses.FirstOrDefault(p => p.Primary) ?? googleContact.PostalAddresses.FirstOrInstance();
            result |= outlookContact.ApplyProperty(c => c.MailingAddressStreet, string.Format("{0} {1}", primaryMailAddress.Street, primaryMailAddress.Housename));
            result |= outlookContact.ApplyProperty(c => c.MailingAddressCity, primaryMailAddress.City);
            result |= outlookContact.ApplyProperty(c => c.MailingAddressCountry, primaryMailAddress.Country);
            result |= outlookContact.ApplyProperty(c => c.MailingAddressPostalCode, primaryMailAddress.Postcode);
            result |= outlookContact.ApplyProperty(c => c.MailingAddressPostOfficeBox, primaryMailAddress.Pobox);
            result |= outlookContact.ApplyProperty(c => c.MailingAddressState, primaryMailAddress.Region);

            DateTime birth;
            if (!string.IsNullOrEmpty(googleContact.ContactEntry.Birthday) && DateTime.TryParseExact(googleContact.ContactEntry.Birthday, DateFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, out birth) && birth.Year > 1000 && birth.Year < 2500)
            {
                result |= outlookContact.ApplyProperty(c => c.Birthday, birth);
            }

            result |= outlookContact.ApplyProperty(c => c.BillingInformation, googleContact.ContactEntry.BillingInformation);
            result |= outlookContact.ApplyProperty(c => c.IMAddress, (googleContact.IMs.FirstOrDefault(i => i.Primary) ?? googleContact.IMs.FirstOrInstance()).Address);
            result |= outlookContact.ApplyProperty(c => c.Initials, googleContact.ContactEntry.Initials);
            result |= outlookContact.ApplyProperty(c => c.Language, googleContact.ContactEntry.Language);
            result |= outlookContact.ApplyProperty(c => c.Mileage, googleContact.ContactEntry.Mileage);
            result |= outlookContact.ApplyProperty(c => c.NickName, googleContact.ContactEntry.Nickname);
            result |= outlookContact.ApplyProperty(c => c.WebPage, (googleContact.ContactEntry.Websites.FirstOrDefault(w => w.Primary) ?? googleContact.ContactEntry.Websites.FirstOrInstance()).Href);
            result |= outlookContact.ApplyProperty(c => c.PersonalHomePage, googleContact.ContactEntry.Websites.FirstOrInstance(w => w.Rel == "home-page").Href);
            result |= outlookContact.ApplyProperty(c => c.BusinessHomePage, googleContact.ContactEntry.Websites.FirstOrInstance(w => w.Rel == "work").Href);

            var organization = googleContact.ContactEntry.Organizations.FirstOrDefault(o => o.Primary) ?? googleContact.ContactEntry.Organizations.FirstOrInstance();
            result |= outlookContact.ApplyProperty(c => c.CompanyName, organization.Name);
            result |= outlookContact.ApplyProperty(c => c.Department, organization.Department);
            result |= outlookContact.ApplyProperty(c => c.Profession, organization.Title);

            // Syncing Groups/Categories
            var contactGroups = googleContact.GroupMembership.Select(g => outlookGroups.FirstOrInstance(m => m.Id == g.HRef));
            result |= outlookContact.ApplyProperty(c => c.Categories, string.Join("; ", contactGroups.Select(g => (string.IsNullOrEmpty(g.SystemGroup) ? g.Title : g.SystemGroup))));

            return result;
        }
        /// <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;
        }