/// <summary>
        /// Create an appropriate sync state for an appointment item.
        /// </summary>
        /// <remarks>Outlook items are not true objects and don't have a common superclass,
        /// so we have to use this rather clumsy overloading.</remarks>
        /// <param name="appointment">The item.</param>
        /// <returns>An appropriate sync state, or null if the appointment was invalid.</returns>
        private AppointmentSyncState CreateSyncState(Outlook.AppointmentItem appointment)
        {
            AppointmentSyncState result;

            CrmId crmId = appointment.GetCrmId();

            if (CrmId.IsValid(crmId) && this.byCrmId.ContainsKey(crmId) && this.byCrmId[crmId] != null)
            {
                result = CheckUnexpectedFoundState <Outlook.AppointmentItem, AppointmentSyncState>(appointment, crmId);
            }
            else
            {
                var modifiedDate = ParseDateTimeFromUserProperty(appointment.UserProperties[ModifiedDatePropertyName]);
                if (appointment.IsCall())
                {
                    result = this.SetByOutlookId <AppointmentSyncState>(appointment.EntryID,
                                                                        new CallSyncState(appointment, crmId, modifiedDate));
                }
                else
                {
                    result = this.SetByOutlookId <AppointmentSyncState>(appointment.EntryID,
                                                                        new MeetingSyncState(appointment, crmId, modifiedDate));
                }
                this.byGlobalId[appointment.GlobalAppointmentID] = result;
            }

            if (result != null && CrmId.IsValid(crmId))
            {
                this.byCrmId[crmId] = result;
            }

            return(result);
        }