/// <summary>
        /// Get the existing sync state for this item, if it exists and is of the appropriate
        /// type, else null.
        /// </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="task">The item.</param>
        /// <returns>The appropriate sync state, or null if none.</returns>
        /// <exception cref="UnexpectedSyncStateClassException">if the sync state found is not of the expected class (shouldn't happen).</exception>
        public TaskSyncState GetSyncState(Outlook.TaskItem task)
        {
            SyncState result;

            try
            {
                result = this.byOutlookId.ContainsKey(task.EntryID) ? this.byOutlookId[task.EntryID] : null;
                CrmId crmId = result == null?task.GetCrmId() : CheckForDuplicateSyncState(result, task.GetCrmId());

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

                if (result != null && !(result is TaskSyncState))
                {
                    throw new UnexpectedSyncStateClassException("TaskSyncState", result);
                }
            }
            catch (COMException)
            {
                // dead item passed.
                result = null;
            }

            return(result as TaskSyncState);
        }
        /// <summary>
        /// Create an appropriate sync state for an task 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="task">The item.</param>
        /// <returns>An appropriate sync state, or null if the task was invalid.</returns>
        private TaskSyncState CreateSyncState(Outlook.TaskItem task)
        {
            TaskSyncState result;

            CrmId crmId = task.GetCrmId();

            if (CrmId.IsValid(crmId) && this.byCrmId.ContainsKey(crmId) && this.byCrmId[crmId] != null)
            {
                result = CheckUnexpectedFoundState <Outlook.TaskItem, TaskSyncState>(task, crmId);
            }
            else
            {
                result = this.SetByOutlookId <TaskSyncState>(task.EntryID,
                                                             new TaskSyncState(task, crmId,
                                                                               ParseDateTimeFromUserProperty(task.UserProperties[ModifiedDatePropertyName])));
            }

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

            return(result);
        }