/// <summary>
        /// Checks and removes any GAB folders that are not registered to accounts. This
        /// happens if an account is removed while Outlook is closed.
        /// </summary>
        private void CheckGABUnused()
        {
            if (!CheckUnused)
            {
                return;
            }

            if (_store != null)
            {
                _store.Dispose();
                _store = null;
            }
            _store = ZPushLocalStore.GetInstance(ThisAddIn.Instance);
            if (_store == null)
            {
                return;
            }

            bool deletedSomething = false;

            using (IFolder root = _store.GetRootFolder())
            {
                foreach (IFolder subfolder in root.GetSubFolders <IFolder>())
                {
                    using (subfolder)
                    {
                        // Remove any contacts folder that is not registered for GAB
                        GABInfo info = GetGABContactsFolderInfo(subfolder);
                        if (info != null && !_domains.Contains(info.Domain))
                        {
                            Logger.Instance.Info(this, "Unused GAB folder: {0} - {1}", subfolder.EntryID, subfolder.Name);
                            try
                            {
                                deletedSomething = true;
                                subfolder.Delete();
                            }
                            catch (System.Exception e)
                            {
                                Logger.Instance.Error(this, "Error removing GAB folder: {0}", e);
                            }
                        }
                    }
                }
            }

            if (deletedSomething)
            {
                DoEmptyDeletedItems();
            }
        }
        private IAddressBook CreateGABContacts(string domainName)
        {
            if (_store != null)
            {
                _store.Dispose();
                _store = null;
            }
            _store = ZPushLocalStore.GetInstance(ThisAddIn.Instance);
            if (_store == null)
            {
                return(null);
            }

            // Try to find the existing GAB
            using (IFolder root = _store.GetRootFolder())
            {
                IAddressBook gab = FindGABForDomain(root, domainName);
                if (gab == null)
                {
                    Logger.Instance.Debug(this, "Creating new GAB folder for {0}", domainName);
                    string name = string.Format(Properties.Resources.GAB_FolderFormat, domainName);
                    gab = root.CreateFolder <IAddressBook>(name);
                }
                else
                {
                    Logger.Instance.Debug(this, "Found existing GAB folder for {0}", domainName);
                }

                // The local folders are hidden, unhide tha GAB folder
                gab.AttrHidden = false;

                // Update admin
                _gabFolders.Add(gab.EntryID);
                GABInfo gabInfo = GABInfo.Get(gab, domainName);
                gabInfo.Store(gab);

                if (SuppressModifications)
                {
                    // Hook BeforeMove event to prevent modifications
                    // TODO: use ZPushWatcher for this?
                    gab.BeforeItemMove += SuppressMoveEventHandler;
                }

                return(gab);
            }
        }
        /// <summary>
        /// Performs a full resync.
        /// </summary>
        /// <param name="completion">The completion tracker, or null.</param>
        /// <param name="accounts">The accounts to resync, or null to resync all</param>
        internal void FullResync(CompletionTracker completion, ZPushAccount[] accounts)
        {
            try
            {
                // TODO: implement per-account resyncing
                Logger.Instance.Trace(this, "FullResync begin: {0}", _processing);
                BeginProcessing();

                // Delete any contacts folders in the local store
                if (DeleteExistingFolder)
                {
                    using (IStore store = ZPushLocalStore.GetInstance(ThisAddIn.Instance))
                    {
                        if (store != null)
                        {
                            using (IFolder root = store.GetRootFolder())
                            {
                                foreach (IFolder folder in root.GetSubFolders <IFolder>().DisposeEnum())
                                {
                                    try
                                    {
                                        if (IsGABContactsFolder(folder, accounts))
                                        {
                                            Logger.Instance.Debug(this, "FullResync: Deleting contacts folder: {0}", folder.Name);
                                            folder.Delete();
                                        }
                                    }
                                    catch (System.Exception e)
                                    {
                                        Logger.Instance.Error(this, "FullResync: Exception deleting contacts folder: {0}", e);
                                    }
                                }
                            }
                        }
                    }
                }

                // Do the resync
                using (completion.Begin())
                {
                    foreach (GABHandler gab in _gabsByDomainName.Values)
                    {
                        // Check if the gab is appropriate for the accounts
                        if (accounts == null || accounts.Contains(gab.ActiveAccount))
                        {
                            completion.Begin();
                            CompletionTracker partCompletion = new CompletionTracker(() =>
                            {
                                OnGabSyncFinished(gab);
                                completion.End();
                            });

                            Logger.Instance.Debug(this, "FullResync: Starting resync: {0}", gab.DisplayName);
                            Tasks.Task(partCompletion, this, "FullResync", () =>
                            {
                                gab.FullResync(partCompletion);
                            });
                        }
                    }
                }
            }
            finally
            {
                EndProcessing();
                Logger.Instance.Trace(this, "FullResync done: {0}", _processing);
            }
        }