Exemple #1
0
        public static void SyncNotes(Syncronizer sync)
        {
            for (int i = 0; i < sync.Notes.Count; i++)
            {
                NoteMatch match = sync.Notes[i];
                if (NotificationReceived != null)
                {
                    string name = string.Empty;
                    if (match.OutlookNote != null)
                    {
                        name = match.OutlookNote.Subject;
                    }
                    else if (match.GoogleNote != null)
                    {
                        name = match.GoogleNote.Title;
                    }
                    NotificationReceived(String.Format("Syncing note {0} of {1}: {2} ...", i + 1, sync.Notes.Count, name));
                }

                SyncNote(match, sync);
            }
        }
        private void UpdateNoteMatchId(NoteMatch match)
        {
            NotePropertiesUtils.SetOutlookGoogleNoteId(this, match.OutlookNote, match.GoogleNote);
            match.OutlookNote.Save();

            //As GoogleDocuments don't have UserProperties, we have to use the file to check, if Note was already synced or not
            File.Delete(NotePropertiesUtils.GetFileName(match.GoogleNote.Id, SyncProfile));
            File.Move(NotePropertiesUtils.GetFileName(match.OutlookNote.EntryID, SyncProfile), NotePropertiesUtils.GetFileName(match.GoogleNote.Id, SyncProfile));
        }
        private void MoveGoogleNote(DocumentEntry entry, NoteMatch match, bool create, Exception ex, bool cancelled)
        {
            if (ex != null)
            {
                ErrorHandler.Handle(new Exception("Google Note couldn't be " + (create ? "created" : "updated") + " :" + entry == null ? null : entry.Summary.ToString(), ex));
                return;
            }

            if (cancelled || entry == null)
            {
                ErrorHandler.Handle(new Exception("Google Note " + (create ? "creation" : "update") + " was cancelled: " + entry == null ? null : entry.Summary.ToString()));
                return;
            }

            //Get updated Google Note
            Document newNote = LoadGoogleNotes(null, entry.Id);
            match.GoogleNote = newNote;

            //Doesn't work because My Drive is not listed as parent folder: Remove all parent folders except for the Notes subfolder
            //if (create)
            //{
            //    foreach (string parentFolder in newNote.ParentFolders)
            //        if (parentFolder != googleNotesFolder.Self)
            //            DocumentsRequest.Delete(new Uri(googleNotesFolder.DocumentEntry.Content.AbsoluteUri + "/" + newNote.ResourceId),newNote.ETag);
            //}

            //first delete the note from all categories, the still valid categories are assigned again later
            foreach (string parentFolder in newNote.ParentFolders)
                if (parentFolder != googleNotesFolder.Self) //Except for Notes root folder
                {
                    Document deletedNote = LoadGoogleNotes(parentFolder + "/contents", newNote.DocumentEntry.Id);
                    //DocumentsRequest.Delete(new Uri(parentFolder + "/contents/" + newNote.ResourceId), newNote.ETag);
                    DocumentsRequest.Delete(deletedNote); //Just delete it from this category
                }

            //Move now to Notes subfolder (if not already there)
            if (!IsInFolder(googleNotesFolder, newNote))
                newNote = DocumentsRequest.MoveDocumentTo(googleNotesFolder, newNote);

            //Move now to all categories subfolder (if not already there)
            foreach (string category in Utilities.GetOutlookGroups(match.OutlookNote.Categories))
            {
                Document categoryFolder = GetOrCreateGoogleFolder(googleNotesFolder, category);

                if (!IsInFolder(categoryFolder, newNote))
                    newNote = DocumentsRequest.MoveDocumentTo(categoryFolder, newNote);
            }

            //Then update the match IDs
            UpdateNoteMatchId(match);

            Logger.Log((create ? "Created" : "Updated") + " Google note from Outlook: \"" + match.OutlookNote.Subject + "\".", EventType.Information);
            //Then release this match as completed (to not log the summary already before each single note result has been synced
            match.AsyncUpdateCompleted = true;
        }
        public void SaveNote(NoteMatch match)
        {
            if (match.GoogleNote != null && match.OutlookNote != null)
            {
                //bool googleChanged, outlookChanged;
                //SaveNoteGroups(match, out googleChanged, out outlookChanged);
                if (match.GoogleNote.DocumentEntry.Dirty || match.GoogleNote.DocumentEntry.IsDirty())
                {
                    //google note was modified. save.
                    SyncedCount++;
                    SaveGoogleNote(match);
                    //Don't log here, because the DocumentsRequest uses async upload, log when async upload was successful
                    //Logger.Log("Updated Google note from Outlook: \"" + match.OutlookNote.Subject + "\".", EventType.Information);
                }
                else if (!match.OutlookNote.Saved)// || outlookChanged) //If google note is saved above, Saving the OutlookNote not necessary anymore, because this will be done when updating NoteMatchId during saving the Google Note above
                {
                    //outlook note was modified. save.
                    SyncedCount++;
                    NotePropertiesUtils.SetOutlookGoogleNoteId(this, match.OutlookNote, match.GoogleNote);
                    match.OutlookNote.Save();
                    Logger.Log("Updated Outlook note from Google: \"" + match.OutlookNote.Subject + "\".", EventType.Information);
                }

                // save photos
                //SaveNotePhotos(match);
            }
            else if (match.GoogleNote == null && match.OutlookNote != null)
            {
                if (match.OutlookNote.ItemProperties[this.OutlookPropertyNameId] != null)
                {
                    string name = match.OutlookNote.Subject;
                    if (_syncOption == SyncOption.OutlookToGoogleOnly)
                    {
                        SkippedCount++;
                        Logger.Log("Skipped Deletion of Outlook note because of SyncOption " + _syncOption + ":" + name + ".", EventType.Information);
                    }
                    else if (!SyncDelete)
                    {
                        SkippedCount++;
                        Logger.Log("Skipped Deletion of Outlook note because SyncDeletion is switched off: " + name + ".", EventType.Information);
                    }
                    else
                    {
                        // peer google note was deleted, delete outlook note
                        Outlook.NoteItem item = match.OutlookNote;
                        //try
                        //{
                        string outlookNoteId = NotePropertiesUtils.GetOutlookGoogleNoteId(this, match.OutlookNote);
                        try
                        {
                            //First reset OutlookGoogleContactId to restore it later from trash
                            NotePropertiesUtils.ResetOutlookGoogleNoteId(this, item);
                            item.Save();
                        }
                        catch (Exception)
                        {
                            Logger.Log("Error resetting match for Outlook note: \"" + name + "\".", EventType.Warning);
                        }

                        item.Delete();
                        try
                        { //Delete also the according temporary NoteFile
                            File.Delete(NotePropertiesUtils.GetFileName(outlookNoteId, SyncProfile));
                        }
                        catch (Exception)
                        { }
                        DeletedCount++;
                        Logger.Log("Deleted Outlook note: \"" + name + "\".", EventType.Information);
                        //}
                        //finally
                        //{
                        //    Marshal.ReleaseComObject(item);
                        //    item = null;
                        //}
                    }
                }
            }
            else if (match.GoogleNote != null && match.OutlookNote == null)
            {
                if (NotePropertiesUtils.NoteFileExists(match.GoogleNote.Id, SyncProfile))
                {
                    string name = match.GoogleNote.Title;

                    if (_syncOption == SyncOption.GoogleToOutlookOnly)
                    {
                        SkippedCount++;
                        Logger.Log("Skipped Deletion of Google note because of SyncOption " + _syncOption + ":" + name + ".", EventType.Information);
                    }
                    else if (!SyncDelete)
                    {
                        SkippedCount++;
                        Logger.Log("Skipped Deletion of Google note because SyncDeletion is switched off :" + name + ".", EventType.Information);
                    }
                    else
                    {
                        // peer outlook note was deleted, delete google note
                        DocumentsRequest.Delete(new Uri(Google.GData.Documents.DocumentsListQuery.documentsBaseUri + "/" + match.GoogleNote.ResourceId), match.GoogleNote.ETag);
                        //DocumentsRequest.Service.Delete(match.GoogleNote.DocumentEntry); //ToDo: Currently, the Delete only removes the Notes label from the document but keeps the document in the root folder, therefore I use the URI Delete above for now: "https://docs.google.com/feeds/default/private/full"
                        //DocumentsRequest.Delete(match.GoogleNote);

                        ////ToDo: Currently, the Delete only removes the Notes label from the document but keeps the document in the root folder, therefore the following workaround
                        //Document deletedNote = LoadGoogleNotes(match.GoogleNote.DocumentEntry.Id);
                        //if (deletedNote != null)
                        //    DocumentsRequest.Delete(deletedNote);

                        try
                        {//Delete also the according temporary NoteFile
                            File.Delete(NotePropertiesUtils.GetFileName(match.GoogleNote.Id, SyncProfile));
                        }
                        catch (Exception)
                        { }

                        DeletedCount++;
                        Logger.Log("Deleted Google note: \"" + name + "\".", EventType.Information);
                    }
                }
            }
            else
            {
                //TODO: ignore for now:
                throw new ArgumentNullException("To save notes, at least a GoogleContacat or OutlookNote must be present.");
                //Logger.Log("Both Google and Outlook note: \"" + match.OutlookNote.FileAs + "\" have been changed! Not implemented yet.", EventType.Warning);
            }
        }
        public void SaveGoogleNote(NoteMatch match)
        {
            Outlook.NoteItem outlookNoteItem = match.OutlookNote;
            //try
            //{

            //ToDo: Somewhow, the content is not uploaded to Google, only an empty document
            //match.GoogleNote = SaveGoogleNote(match.GoogleNote);

            //New approach how to update an existing document: https://developers.google.com/google-apps/documents-list/#updatingchanging_documents_and_files
            // Instantiate the ResumableUploader component.
            ResumableUploader uploader = new ResumableUploader();
            // Set the handlers for the completion and progress events
            //uploader.AsyncOperationProgress += new AsyncOperationProgressEventHandler(OnProgress);

            //ToDo: Therefoe I use DocumentService.UploadDocument instead and move it to the NotesFolder
            string oldOutlookGoogleNoteId = NotePropertiesUtils.GetOutlookGoogleNoteId(this, outlookNoteItem);
            if (match.GoogleNote.DocumentEntry.Id.Uri != null)
            {
                //DocumentsRequest.Delete(new Uri(Google.GData.Documents.DocumentsListQuery.documentsBaseUri + "/" + match.GoogleNote.ResourceId), match.GoogleNote.ETag);
                ////DocumentsRequest.Delete(match.GoogleNote); //ToDo: Currently, the Delete only removes the Notes label from the document but keeps the document in the root folder
                //NotePropertiesUtils.ResetOutlookGoogleNoteId(this, outlookNoteItem);

                ////ToDo: Currently, the Delete only removes the Notes label from the document but keeps the document in the root folder
                //Document deletedNote = LoadGoogleNotes(match.GoogleNote.DocumentEntry.Id);
                //if (deletedNote != null)
                //    DocumentsRequest.Delete(deletedNote);

                // Start the update process.
                uploader.AsyncOperationCompleted += new AsyncOperationCompletedEventHandler(OnGoogleNoteUpdated);
                uploader.UpdateAsync(authenticator, match.GoogleNote.DocumentEntry, match);

                //uploader.Update(_authenticator, match.GoogleNote.DocumentEntry);

            }
            else
            {
                uploader.AsyncOperationCompleted += new AsyncOperationCompletedEventHandler(OnGoogleNoteCreated);
                CreateGoogleNote(match.GoogleNote, match, DocumentsRequest, uploader, authenticator);
            }

            match.AsyncUpdateCompleted = false;

            //Google.GData.Documents.DocumentEntry entry = DocumentsRequest.Service.UploadDocument(NotePropertiesUtils.GetFileName(outlookNoteItem.EntryID, SyncProfile), match.GoogleNote.Title.Replace(":", String.Empty));
            //Document newNote = LoadGoogleNotes(entry.Id);
            //match.GoogleNote = DocumentsRequest.MoveDocumentTo(GoogleNotesFolder, newNote);

            //First delete old temporary file, because it was saved with old GoogleNoteID, because every sync to Google becomes a new ID, because updateMedia doesn't work
            //File.Delete(NotePropertiesUtils.GetFileName(oldOutlookGoogleNoteId, SyncProfile));
            //UpdateNoteMatchId(match);
            //}
            //finally
            //{
            //    Marshal.ReleaseComObject(outlookNoteItem);
            //    outlookNoteItem = null;
            //}
        }
Exemple #6
0
        public static void SyncNote(NoteMatch match, Syncronizer sync)
        {
            Outlook.NoteItem outlookNoteItem = match.OutlookNote;

            //try
            //{
            if (match.GoogleNote == null && match.OutlookNote != null)
            {
                //no google note
                string googleNotetId = NotePropertiesUtils.GetOutlookGoogleNoteId(sync, outlookNoteItem);
                if (!string.IsNullOrEmpty(googleNotetId))
                {
                    //Redundant check if exist, but in case an error occurred in MatchNotes
                    Document matchingGoogleNote = sync.GetGoogleNoteById(googleNotetId);
                    if (matchingGoogleNote == null)
                    {
                        if (!sync.PromptDelete)
                        {
                            sync.DeleteOutlookResolution = DeleteResolution.DeleteOutlookAlways;
                        }
                        else if (sync.DeleteOutlookResolution != DeleteResolution.DeleteOutlookAlways &&
                                 sync.DeleteOutlookResolution != DeleteResolution.KeepOutlookAlways)
                        {
                            var r = new ConflictResolver();
                            sync.DeleteOutlookResolution = r.ResolveDelete(match.OutlookNote);
                        }
                    }
                    switch (sync.DeleteOutlookResolution)
                    {
                    case DeleteResolution.KeepOutlook:
                    case DeleteResolution.KeepOutlookAlways:
                        NotePropertiesUtils.ResetOutlookGoogleNoteId(sync, match.OutlookNote);
                        break;

                    case DeleteResolution.DeleteOutlook:
                    case DeleteResolution.DeleteOutlookAlways:
                        //Avoid recreating a GoogleNote already existing
                        //==> Delete this outlookNote instead if previous match existed but no match exists anymore
                        return;

                    default:
                        throw new ApplicationException("Cancelled");
                    }
                }

                if (sync.SyncOption == SyncOption.GoogleToOutlookOnly)
                {
                    sync.SkippedCount++;
                    Logger.Log(string.Format("Outlook Note not added to Google, because of SyncOption " + sync.SyncOption.ToString() + ": {0}", match.OutlookNote.Subject), EventType.Information);
                    return;
                }

                //create a Google note from Outlook note
                match.GoogleNote      = new Document();
                match.GoogleNote.Type = Document.DocumentType.Document;
                //match.GoogleNote.Categories.Add(new AtomCategory("http://schemas.google.com/docs/2007#document"));
                //match.GoogleNote.Categories.Add(new AtomCategory("document"));

                sync.UpdateNote(outlookNoteItem, match.GoogleNote);
            }
            else if (match.OutlookNote == null && match.GoogleNote != null)
            {
                // no outlook note
                if (NotePropertiesUtils.NoteFileExists(match.GoogleNote.Id, sync.SyncProfile))
                {
                    if (!sync.PromptDelete)
                    {
                        sync.DeleteGoogleResolution = DeleteResolution.DeleteGoogleAlways;
                    }
                    else if (sync.DeleteGoogleResolution != DeleteResolution.DeleteGoogleAlways &&
                             sync.DeleteGoogleResolution != DeleteResolution.KeepGoogleAlways)
                    {
                        var r = new ConflictResolver();
                        sync.DeleteGoogleResolution = r.ResolveDelete(match.GoogleNote, sync);
                    }
                    switch (sync.DeleteGoogleResolution)
                    {
                    case DeleteResolution.KeepGoogle:
                    case DeleteResolution.KeepGoogleAlways:
                        System.IO.File.Delete(NotePropertiesUtils.GetFileName(match.GoogleNote.Id, sync.SyncProfile));
                        break;

                    case DeleteResolution.DeleteGoogle:
                    case DeleteResolution.DeleteGoogleAlways:
                        //Avoid recreating a OutlookNote already existing
                        //==> Delete this googleNote instead if previous match existed but no match exists anymore
                        return;

                    default:
                        throw new ApplicationException("Cancelled");
                    }
                }


                if (sync.SyncOption == SyncOption.OutlookToGoogleOnly)
                {
                    sync.SkippedCount++;
                    Logger.Log(string.Format("Google Note not added to Outlook, because of SyncOption " + sync.SyncOption.ToString() + ": {0}", match.GoogleNote.Title), EventType.Information);
                    return;
                }

                //create a Outlook note from Google note
                outlookNoteItem = Syncronizer.CreateOutlookNoteItem(Syncronizer.SyncNotesFolder);

                sync.UpdateNote(match.GoogleNote, outlookNoteItem);
                match.OutlookNote = outlookNoteItem;
            }
            else if (match.OutlookNote != null && match.GoogleNote != null)
            {
                //merge note details

                //determine if this note pair were syncronized
                //DateTime? lastUpdated = GetOutlookPropertyValueDateTime(match.OutlookNote, sync.OutlookPropertyNameUpdated);
                DateTime?lastSynced = NotePropertiesUtils.GetOutlookLastSync(sync, outlookNoteItem);
                if (lastSynced.HasValue)
                {
                    //note pair was syncronysed before.

                    //determine if google note was updated since last sync

                    //lastSynced is stored without seconds. take that into account.
                    DateTime lastUpdatedOutlook = match.OutlookNote.LastModificationTime.AddSeconds(-match.OutlookNote.LastModificationTime.Second);
                    DateTime lastUpdatedGoogle  = match.GoogleNote.Updated.AddSeconds(-match.GoogleNote.Updated.Second);

                    //check if both outlok and google notes where updated sync last sync
                    if (lastUpdatedOutlook.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance &&
                        lastUpdatedGoogle.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance)
                    {
                        //both notes were updated.
                        //options: 1) ignore 2) loose one based on SyncOption
                        //throw new Exception("Both notes were updated!");

                        switch (sync.SyncOption)
                        {
                        case SyncOption.MergeOutlookWins:
                        case SyncOption.OutlookToGoogleOnly:
                            //overwrite google note
                            Logger.Log("Outlook and Google note have been updated, Outlook note is overwriting Google because of SyncOption " + sync.SyncOption + ": " + match.OutlookNote.Subject + ".", EventType.Information);
                            sync.UpdateNote(outlookNoteItem, match.GoogleNote);
                            break;

                        case SyncOption.MergeGoogleWins:
                        case SyncOption.GoogleToOutlookOnly:
                            //overwrite outlook note
                            Logger.Log("Outlook and Google note have been updated, Google note is overwriting Outlook because of SyncOption " + sync.SyncOption + ": " + match.OutlookNote.Subject + ".", EventType.Information);
                            sync.UpdateNote(match.GoogleNote, outlookNoteItem);
                            break;

                        case SyncOption.MergePrompt:
                            //promp for sync option
                            if (sync.ConflictResolution != ConflictResolution.GoogleWinsAlways &&
                                sync.ConflictResolution != ConflictResolution.OutlookWinsAlways &&
                                sync.ConflictResolution != ConflictResolution.SkipAlways)
                            {
                                var r = new ConflictResolver();
                                sync.ConflictResolution = r.Resolve(outlookNoteItem, match.GoogleNote, sync, false);
                            }
                            switch (sync.ConflictResolution)
                            {
                            case ConflictResolution.Skip:
                            case ConflictResolution.SkipAlways:
                                Logger.Log(string.Format("User skipped note ({0}).", match.ToString()), EventType.Information);
                                sync.SkippedCount++;
                                break;

                            case ConflictResolution.OutlookWins:
                            case ConflictResolution.OutlookWinsAlways:
                                sync.UpdateNote(outlookNoteItem, match.GoogleNote);
                                break;

                            case ConflictResolution.GoogleWins:
                            case ConflictResolution.GoogleWinsAlways:
                                sync.UpdateNote(match.GoogleNote, outlookNoteItem);
                                break;

                            default:
                                throw new ApplicationException("Canceled");
                            }
                            break;
                        }
                        return;
                    }


                    //check if outlook note was updated (with X second tolerance)
                    if (sync.SyncOption != SyncOption.GoogleToOutlookOnly &&
                        (lastUpdatedOutlook.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance ||
                         lastUpdatedGoogle.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance &&
                         sync.SyncOption == SyncOption.OutlookToGoogleOnly
                        )
                        )
                    {
                        //outlook note was changed or changed Google note will be overwritten

                        if (lastUpdatedGoogle.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance &&
                            sync.SyncOption == SyncOption.OutlookToGoogleOnly)
                        {
                            Logger.Log("Google note has been updated since last sync, but Outlook note is overwriting Google because of SyncOption " + sync.SyncOption + ": " + match.OutlookNote.Subject + ".", EventType.Information);
                        }

                        sync.UpdateNote(outlookNoteItem, match.GoogleNote);

                        //at the moment use outlook as "master" source of notes - in the event of a conflict google note will be overwritten.
                        //TODO: control conflict resolution by SyncOption
                        return;
                    }

                    //check if google note was updated (with X second tolerance)
                    if (sync.SyncOption != SyncOption.OutlookToGoogleOnly &&
                        (lastUpdatedGoogle.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance ||
                         lastUpdatedOutlook.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance &&
                         sync.SyncOption == SyncOption.GoogleToOutlookOnly
                        )
                        )
                    {
                        //google note was changed or changed Outlook note will be overwritten

                        if (lastUpdatedOutlook.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance &&
                            sync.SyncOption == SyncOption.GoogleToOutlookOnly)
                        {
                            Logger.Log("Outlook note has been updated since last sync, but Google note is overwriting Outlook because of SyncOption " + sync.SyncOption + ": " + match.OutlookNote.Subject + ".", EventType.Information);
                        }

                        sync.UpdateNote(match.GoogleNote, outlookNoteItem);
                    }
                }
                else
                {
                    //notes were never synced.
                    //merge notes.
                    switch (sync.SyncOption)
                    {
                    case SyncOption.MergeOutlookWins:
                    case SyncOption.OutlookToGoogleOnly:
                        //overwrite google note
                        sync.UpdateNote(outlookNoteItem, match.GoogleNote);
                        break;

                    case SyncOption.MergeGoogleWins:
                    case SyncOption.GoogleToOutlookOnly:
                        //overwrite outlook note
                        sync.UpdateNote(match.GoogleNote, outlookNoteItem);
                        break;

                    case SyncOption.MergePrompt:
                        //promp for sync option
                        if (sync.ConflictResolution != ConflictResolution.GoogleWinsAlways &&
                            sync.ConflictResolution != ConflictResolution.OutlookWinsAlways &&
                            sync.ConflictResolution != ConflictResolution.SkipAlways)
                        {
                            var r = new ConflictResolver();
                            sync.ConflictResolution = r.Resolve(outlookNoteItem, match.GoogleNote, sync, true);
                        }
                        switch (sync.ConflictResolution)
                        {
                        case ConflictResolution.Skip:
                        case ConflictResolution.SkipAlways:             //Keep both, Google AND Outlook
                            sync.Notes.Add(new NoteMatch(match.OutlookNote, null));
                            sync.Notes.Add(new NoteMatch(null, match.GoogleNote));
                            break;

                        case ConflictResolution.OutlookWins:
                        case ConflictResolution.OutlookWinsAlways:
                            sync.UpdateNote(outlookNoteItem, match.GoogleNote);
                            break;

                        case ConflictResolution.GoogleWins:
                        case ConflictResolution.GoogleWinsAlways:
                            sync.UpdateNote(match.GoogleNote, outlookNoteItem);
                            break;

                        default:
                            throw new ApplicationException("Canceled");
                        }
                        break;
                    }
                }
            }
            else
            {
                throw new ArgumentNullException("NotetMatch has all peers null.");
            }
            //}
            //finally
            //{
            //if (outlookNoteItem != null &&
            //    match.OutlookNote != null)
            //{
            //    match.OutlookNote.Update(outlookNoteItem, sync);
            //    Marshal.ReleaseComObject(outlookNoteItem);
            //    outlookNoteItem = null;
            //}
            //}
        }
Exemple #7
0
        /// <summary>
        /// Matches outlook and google note by a) google id b) properties.
        /// </summary>
        /// <param name="sync">Syncronizer instance</param>
        /// <returns>Returns a list of match pairs (outlook note + google note) for all note. Those that weren't matche will have it's peer set to null</returns>
        public static List <NoteMatch> MatchNotes(Syncronizer sync)
        {
            Logger.Log("Matching Outlook and Google notes...", EventType.Information);
            var result = new List <NoteMatch>();

            //string duplicateGoogleMatches = "";
            //string duplicateOutlookNotes = "";
            //sync.GoogleNoteDuplicates = new Collection<NoteMatch>();
            //sync.OutlookNoteDuplicates = new Collection<NoteMatch>();

            //for each outlook note try to get google note id from user properties
            //if no match - try to match by properties
            //if no match - create a new match pair without google note.
            //foreach (Outlook._NoteItem olc in outlookNotes)
            var outlookNotesWithoutOutlookGoogleId = new Collection <Outlook.NoteItem>();

            #region Match first all outlookNotes by sync id
            for (int i = 1; i <= sync.OutlookNotes.Count; i++)
            {
                Outlook.NoteItem oln;
                try
                {
                    oln = sync.OutlookNotes[i] as Outlook.NoteItem;
                    if (oln == null || string.IsNullOrEmpty(oln.Subject))
                    {
                        Logger.Log("Empty Outlook note found. Skipping", EventType.Warning);
                        sync.SkippedCount++;
                        sync.SkippedCountNotMatches++;
                        continue;
                    }
                }
                catch (Exception ex)
                {
                    //this is needed because some notes throw exceptions
                    Logger.Log("Accessing Outlook note threw and exception. Skipping: " + ex.Message, EventType.Warning);
                    sync.SkippedCount++;
                    sync.SkippedCountNotMatches++;
                    continue;
                }

                //try
                //{

                if (NotificationReceived != null)
                {
                    NotificationReceived(String.Format("Matching note {0} of {1} by id: {2} ...", i, sync.OutlookNotes.Count, oln.Subject));
                }

                // Create our own info object to go into collections/lists, so we can free the Outlook objects and not run out of resources / exceed policy limits.
                //OutlookNoteInfo olci = new OutlookNoteInfo(oln, sync);

                //try to match this note to one of google notes
                Outlook.ItemProperties userProperties = oln.ItemProperties;
                Outlook.ItemProperty   idProp         = userProperties[sync.OutlookPropertyNameId];
                try
                {
                    if (idProp != null)
                    {
                        string   googleNoteId = string.Copy((string)idProp.Value);
                        Document foundNote    = sync.GetGoogleNoteById(googleNoteId);
                        var      match        = new NoteMatch(oln, null);

                        //Check first, that this is not a duplicate
                        //e.g. by copying an existing Outlook note
                        //or by Outlook checked this as duplicate, but the user selected "Add new"
                        //    Collection<OutlookNoteInfo> duplicates = sync.OutlookNoteByProperty(sync.OutlookPropertyNameId, googleNoteId);
                        //    if (duplicates.Count > 1)
                        //    {
                        //        foreach (OutlookNoteInfo duplicate in duplicates)
                        //        {
                        //            if (!string.IsNullOrEmpty(googleNoteId))
                        //            {
                        //                Logger.Log("Duplicate Outlook note found, resetting match and try to match again: " + duplicate.FileAs, EventType.Warning);
                        //                idProp.Value = "";
                        //            }
                        //        }

                        //        if (foundNote != null && !foundNote.Deleted)
                        //        {
                        //            NotePropertiesUtils.ResetGoogleOutlookNoteId(sync.SyncProfile, foundNote);
                        //        }

                        //        outlookNotesWithoutOutlookGoogleId.Add(olci);
                        //    }
                        //    else
                        //    {

                        if (foundNote != null)
                        {
                            //we found a match by google id, that is not deleted yet
                            match.AddGoogleNote(foundNote);
                            result.Add(match);
                            //Remove the note from the list to not sync it twice
                            sync.GoogleNotes.Remove(foundNote);
                        }
                        else
                        {
                            ////If no match found, is the note either deleted on Google side or was a copy on Outlook side
                            ////If it is a copy on Outlook side, the idProp.Value must be emptied to assure, the note is created on Google side and not deleted on Outlook side
                            ////bool matchIsDuplicate = false;
                            //foreach (NoteMatch existingMatch in result)
                            //{
                            //    if (existingMatch.OutlookNote.UserProperties[sync.OutlookPropertyNameId].Value.Equals(idProp.Value))
                            //    {
                            //        //matchIsDuplicate = true;
                            //        idProp.Value = "";
                            //        break;
                            //    }

                            //}
                            outlookNotesWithoutOutlookGoogleId.Add(oln);

                            //if (!matchIsDuplicate)
                            //    result.Add(match);
                        }
                        //    }
                    }
                    else
                    {
                        outlookNotesWithoutOutlookGoogleId.Add(oln);
                    }
                }
                finally
                {
                    if (idProp != null)
                    {
                        Marshal.ReleaseComObject(idProp);
                    }
                    Marshal.ReleaseComObject(userProperties);
                }
                //}

                //finally
                //{
                //    Marshal.ReleaseComObject(oln);
                //    oln = null;
                //}
            }
            #endregion
            #region Match the remaining notes by properties

            for (int i = 0; i < outlookNotesWithoutOutlookGoogleId.Count; i++)
            {
                Outlook.NoteItem oln = outlookNotesWithoutOutlookGoogleId[i];

                if (NotificationReceived != null)
                {
                    NotificationReceived(String.Format("Matching note {0} of {1} by unique properties: {2} ...", i + 1, outlookNotesWithoutOutlookGoogleId.Count, oln.Subject));
                }

                //no match found by id => match by subject/title
                //create a default match pair with just outlook note.
                var match = new NoteMatch(oln, null);

                //foreach google contact try to match and create a match pair if found some match(es)
                for (int j = sync.GoogleNotes.Count - 1; j >= 0; j--)
                {
                    Document entry = sync.GoogleNotes[j];

                    string body = NotePropertiesUtils.GetBody(sync, entry);
                    if (!string.IsNullOrEmpty(body))
                    {
                        body = body.Replace("\r\n", string.Empty).Replace(" ", string.Empty).Replace("�", string.Empty);
                    }

                    string outlookBody = null;
                    if (!string.IsNullOrEmpty(oln.Body))
                    {
                        outlookBody = oln.Body.Replace("\t", "        ").Replace("\r\n", string.Empty).Replace(" ", string.Empty).Replace("�", string.Empty);
                    }

                    // only match if there is a note body, else
                    // a matching google note will be created at each sync
                    if (!string.IsNullOrEmpty(outlookBody) && !string.IsNullOrEmpty(body) && outlookBody.Equals(body, StringComparison.InvariantCultureIgnoreCase)
                        )
                    {
                        match.AddGoogleNote(entry);
                        sync.GoogleNotes.Remove(entry);
                    }
                }

                #region find duplicates not needed now
                //if (match.GoogleNote == null && match.OutlookNote != null)
                //{//If GoogleNote, we have to expect a conflict because of Google insert of duplicates
                //    foreach (Note entry in sync.GoogleNotes)
                //    {
                //        if (!string.IsNullOrEmpty(olc.FullName) && olc.FullName.Equals(entry.Title, StringComparison.InvariantCultureIgnoreCase) ||
                //         !string.IsNullOrEmpty(olc.FileAs) && olc.FileAs.Equals(entry.Title, StringComparison.InvariantCultureIgnoreCase) ||
                //         !string.IsNullOrEmpty(olc.Email1Address) && FindEmail(olc.Email1Address, entry.Emails) != null ||
                //         !string.IsNullOrEmpty(olc.Email2Address) && FindEmail(olc.Email1Address, entry.Emails) != null ||
                //         !string.IsNullOrEmpty(olc.Email3Address) && FindEmail(olc.Email1Address, entry.Emails) != null ||
                //         olc.MobileTelephoneNumber != null && FindPhone(olc.MobileTelephoneNumber, entry.Phonenumbers) != null
                //         )
                //    }
                //// check for each email 1,2 and 3 if a duplicate exists with same email, because Google doesn't like inserting new notes with same email
                //Collection<Outlook.NoteItem> duplicates1 = new Collection<Outlook.NoteItem>();
                //Collection<Outlook.NoteItem> duplicates2 = new Collection<Outlook.NoteItem>();
                //Collection<Outlook.NoteItem> duplicates3 = new Collection<Outlook.NoteItem>();
                //if (!string.IsNullOrEmpty(olc.Email1Address))
                //    duplicates1 = sync.OutlookNoteByEmail(olc.Email1Address);

                //if (!string.IsNullOrEmpty(olc.Email2Address))
                //    duplicates2 = sync.OutlookNoteByEmail(olc.Email2Address);

                //if (!string.IsNullOrEmpty(olc.Email3Address))
                //    duplicates3 = sync.OutlookNoteByEmail(olc.Email3Address);


                //if (duplicates1.Count > 1 || duplicates2.Count > 1 || duplicates3.Count > 1)
                //{
                //    if (string.IsNullOrEmpty(duplicatesEmailList))
                //        duplicatesEmailList = "Outlook notes with the same email have been found and cannot be synchronized. Please delete duplicates of:";

                //    if (duplicates1.Count > 1)
                //        foreach (Outlook.NoteItem duplicate in duplicates1)
                //        {
                //            string str = olc.FileAs + " (" + olc.Email1Address + ")";
                //            if (!duplicatesEmailList.Contains(str))
                //                duplicatesEmailList += Environment.NewLine + str;
                //        }
                //    if (duplicates2.Count > 1)
                //        foreach (Outlook.NoteItem duplicate in duplicates2)
                //        {
                //            string str = olc.FileAs + " (" + olc.Email2Address + ")";
                //            if (!duplicatesEmailList.Contains(str))
                //                duplicatesEmailList += Environment.NewLine + str;
                //        }
                //    if (duplicates3.Count > 1)
                //        foreach (Outlook.NoteItem duplicate in duplicates3)
                //        {
                //            string str = olc.FileAs + " (" + olc.Email3Address + ")";
                //            if (!duplicatesEmailList.Contains(str))
                //                duplicatesEmailList += Environment.NewLine + str;
                //        }
                //    continue;
                //}
                //else if (!string.IsNullOrEmpty(olc.Email1Address))
                //{
                //    NoteMatch dup = result.Find(delegate(NoteMatch match)
                //    {
                //        return match.OutlookNote != null && match.OutlookNote.Email1Address == olc.Email1Address;
                //    });
                //    if (dup != null)
                //    {
                //        Logger.Log(string.Format("Duplicate note found by Email1Address ({0}). Skipping", olc.FileAs), EventType.Information);
                //        continue;
                //    }
                //}

                //// check for unique mobile phone, because this sync tool uses the also the mobile phone to identify matches between Google and Outlook
                //Collection<Outlook.NoteItem> duplicatesMobile = new Collection<Outlook.NoteItem>();
                //if (!string.IsNullOrEmpty(olc.MobileTelephoneNumber))
                //    duplicatesMobile = sync.OutlookNoteByProperty("MobileTelephoneNumber", olc.MobileTelephoneNumber);

                //if (duplicatesMobile.Count > 1)
                //{
                //    if (string.IsNullOrEmpty(duplicatesMobileList))
                //        duplicatesMobileList = "Outlook notes with the same mobile phone have been found and cannot be synchronized. Please delete duplicates of:";

                //    foreach (Outlook.NoteItem duplicate in duplicatesMobile)
                //    {
                //        sync.OutlookNoteDuplicates.Add(olc);
                //        string str = olc.FileAs + " (" + olc.MobileTelephoneNumber + ")";
                //        if (!duplicatesMobileList.Contains(str))
                //            duplicatesMobileList += Environment.NewLine + str;
                //    }
                //    continue;
                //}
                //else if (!string.IsNullOrEmpty(olc.MobileTelephoneNumber))
                //{
                //    NoteMatch dup = result.Find(delegate(NoteMatch match)
                //    {
                //        return match.OutlookNote != null && match.OutlookNote.MobileTelephoneNumber == olc.MobileTelephoneNumber;
                //    });
                //    if (dup != null)
                //    {
                //        Logger.Log(string.Format("Duplicate note found by MobileTelephoneNumber ({0}). Skipping", olc.FileAs), EventType.Information);
                //        continue;
                //    }
                //}

                #endregion

                //    if (match.AllGoogleNoteMatches == null || match.AllGoogleNoteMatches.Count == 0)
                //    {
                //        //Check, if this Outlook note has a match in the google duplicates
                //        bool duplicateFound = false;
                //        foreach (NoteMatch duplicate in sync.GoogleNoteDuplicates)
                //        {
                //            if (duplicate.AllGoogleNoteMatches.Count > 0 &&
                //                (!string.IsNullOrEmpty(olci.FileAs) && !string.IsNullOrEmpty(duplicate.AllGoogleNoteMatches[0].Title) && olci.FileAs.Equals(duplicate.AllGoogleNoteMatches[0].Title.Replace("\r\n", "\n").Replace("\n", "\r\n"), StringComparison.InvariantCultureIgnoreCase) ||  //Replace twice to not replace a \r\n by \r\r\n. This is necessary because \r\n are saved as \n only to google
                //                 !string.IsNullOrEmpty(olci.FileAs) && !string.IsNullOrEmpty(duplicate.AllGoogleNoteMatches[0].Name.FullName) && olci.FileAs.Equals(duplicate.AllGoogleNoteMatches[0].Name.FullName.Replace("\r\n", "\n").Replace("\n", "\r\n"), StringComparison.InvariantCultureIgnoreCase) ||
                //                 !string.IsNullOrEmpty(olci.FullName) && !string.IsNullOrEmpty(duplicate.AllGoogleNoteMatches[0].Name.FullName) && olci.FullName.Equals(duplicate.AllGoogleNoteMatches[0].Name.FullName.Replace("\r\n", "\n").Replace("\n", "\r\n"), StringComparison.InvariantCultureIgnoreCase) ||
                //                 !string.IsNullOrEmpty(olci.Email1Address) && duplicate.AllGoogleNoteMatches[0].Emails.Count > 0 && olci.Email1Address.Equals(duplicate.AllGoogleNoteMatches[0].Emails[0].Address, StringComparison.InvariantCultureIgnoreCase) ||
                //                //!string.IsNullOrEmpty(olci.Email2Address) && FindEmail(olci.Email2Address, duplicate.AllGoogleNoteMatches[0].Emails) != null ||
                //                //!string.IsNullOrEmpty(olci.Email3Address) && FindEmail(olci.Email3Address, duplicate.AllGoogleNoteMatches[0].Emails) != null ||
                //                 olci.MobileTelephoneNumber != null && FindPhone(olci.MobileTelephoneNumber, duplicate.AllGoogleNoteMatches[0].Phonenumbers) != null ||
                //                 !string.IsNullOrEmpty(olci.FileAs) && string.IsNullOrEmpty(duplicate.AllGoogleNoteMatches[0].Title) && duplicate.AllGoogleNoteMatches[0].Organizations.Count > 0 && olci.FileAs.Equals(duplicate.AllGoogleNoteMatches[0].Organizations[0].Name, StringComparison.InvariantCultureIgnoreCase)
                //                ) ||
                //                !string.IsNullOrEmpty(olci.FileAs) && olci.FileAs.Equals(duplicate.OutlookNote.Subject, StringComparison.InvariantCultureIgnoreCase) ||
                //                !string.IsNullOrEmpty(olci.FullName) && olci.FullName.Equals(duplicate.OutlookNote.FullName, StringComparison.InvariantCultureIgnoreCase) ||
                //                !string.IsNullOrEmpty(olci.Email1Address) && olci.Email1Address.Equals(duplicate.OutlookNote.Email1Address, StringComparison.InvariantCultureIgnoreCase) ||
                //                //                                              olci.Email1Address.Equals(duplicate.OutlookNote.Email2Address, StringComparison.InvariantCultureIgnoreCase) ||
                //                //                                              olci.Email1Address.Equals(duplicate.OutlookNote.Email3Address, StringComparison.InvariantCultureIgnoreCase)
                //                //                                              ) ||
                //                //!string.IsNullOrEmpty(olci.Email2Address) && (olci.Email2Address.Equals(duplicate.OutlookNote.Email1Address, StringComparison.InvariantCultureIgnoreCase) ||
                //                //                                              olci.Email2Address.Equals(duplicate.OutlookNote.Email2Address, StringComparison.InvariantCultureIgnoreCase) ||
                //                //                                              olci.Email2Address.Equals(duplicate.OutlookNote.Email3Address, StringComparison.InvariantCultureIgnoreCase)
                //                //                                              ) ||
                //                //!string.IsNullOrEmpty(olci.Email3Address) && (olci.Email3Address.Equals(duplicate.OutlookNote.Email1Address, StringComparison.InvariantCultureIgnoreCase) ||
                //                //                                              olci.Email3Address.Equals(duplicate.OutlookNote.Email2Address, StringComparison.InvariantCultureIgnoreCase) ||
                //                //                                              olci.Email3Address.Equals(duplicate.OutlookNote.Email3Address, StringComparison.InvariantCultureIgnoreCase)
                //                //                                              ) ||
                //                olci.MobileTelephoneNumber != null && olci.MobileTelephoneNumber.Equals(duplicate.OutlookNote.MobileTelephoneNumber) ||
                //                !string.IsNullOrEmpty(olci.FileAs) && string.IsNullOrEmpty(duplicate.GoogleNote.Title) && duplicate.GoogleNote.Organizations.Count > 0 && olci.FileAs.Equals(duplicate.GoogleNote.Organizations[0].Name, StringComparison.InvariantCultureIgnoreCase)
                //               )
                //            {
                //                duplicateFound = true;
                //                sync.OutlookNoteDuplicates.Add(match);
                //                if (string.IsNullOrEmpty(duplicateOutlookNotes))
                //                    duplicateOutlookNotes = "Outlook note found that has been already identified as duplicate Google note (either same email, Mobile or FullName) and cannot be synchronized. Please delete or resolve duplicates of:";

                //                string str = olci.FileAs + " (" + olci.Email1Address + ", " + olci.MobileTelephoneNumber + ")";
                //                if (!duplicateOutlookNotes.Contains(str))
                //                    duplicateOutlookNotes += Environment.NewLine + str;
                //            }
                //        }

                //        if (!duplicateFound)
                if (match.GoogleNote == null)
                {
                    Logger.Log(string.Format("No match found for outlook note ({0}) => {1}", match.OutlookNote.Subject, (NotePropertiesUtils.GetOutlookGoogleNoteId(sync, match.OutlookNote) != null ? "Delete from Outlook" : "Add to Google")), EventType.Information);
                }

                //    }
                //    else
                //    {
                //        //Remember Google duplicates to later react to it when resetting matches or syncing
                //        //ResetMatches: Also reset the duplicates
                //        //Sync: Skip duplicates (don't sync duplicates to be fail safe)
                //        if (match.AllGoogleNoteMatches.Count > 1)
                //        {
                //            sync.GoogleNoteDuplicates.Add(match);
                //            foreach (Note entry in match.AllGoogleNoteMatches)
                //            {
                //                //Create message for duplicatesFound exception
                //                if (string.IsNullOrEmpty(duplicateGoogleMatches))
                //                    duplicateGoogleMatches = "Outlook notes matching with multiple Google notes have been found (either same email, Mobile, FullName or company) and cannot be synchronized. Please delete or resolve duplicates of:";

                //                string str = olci.FileAs + " (" + olci.Email1Address + ", " + olci.MobileTelephoneNumber + ")";
                //                if (!duplicateGoogleMatches.Contains(str))
                //                    duplicateGoogleMatches += Environment.NewLine + str;
                //            }
                //        }



                //    }

                result.Add(match);
            }
            #endregion

            //if (!string.IsNullOrEmpty(duplicateGoogleMatches) || !string.IsNullOrEmpty(duplicateOutlookNotes))
            //    duplicatesFound = new DuplicateDataException(duplicateGoogleMatches + Environment.NewLine + Environment.NewLine + duplicateOutlookNotes);
            //else
            //    duplicatesFound = null;

            //return result;

            //for each google note that's left (they will be nonmatched) create a new match pair without outlook note.
            for (int i = 0; i < sync.GoogleNotes.Count; i++)
            {
                Document entry = sync.GoogleNotes[i];
                if (NotificationReceived != null)
                {
                    NotificationReceived(String.Format("Adding new Google note {0} of {1} by unique properties: {2} ...", i + 1, sync.GoogleNotes.Count, entry.Title));
                }

                //string googleOutlookId = NotePropertiesUtils.GetGoogleOutlookNoteId(sync.SyncProfile, entry);
                //if (!String.IsNullOrEmpty(googleOutlookId) && skippedOutlookIds.Contains(googleOutlookId))
                //{
                //    Logger.Log("Skipped GoogleNote because Outlook note couldn't be matched beacause of previous problem (see log): " + entry.Title, EventType.Warning);
                //}
                //else
                if (string.IsNullOrEmpty(entry.Title) && string.IsNullOrEmpty(entry.Content))
                {
                    // no title or content
                    sync.SkippedCount++;
                    sync.SkippedCountNotMatches++;
                    Logger.Log("Skipped GoogleNote because no unique property found (Title or Content):" + entry.Title, EventType.Warning);
                }
                else
                {
                    Logger.Log(string.Format("No match found for google note ({0}) => {1}", entry.Title, (NotePropertiesUtils.NoteFileExists(entry.Id, sync.SyncProfile) ? "Delete from Google" : "Add to Outlook")), EventType.Information);
                    var match = new NoteMatch(null, entry);
                    result.Add(match);
                }
            }
            return(result);
        }
        public static void SyncNote(NoteMatch match, Synchronizer sync)
        {
            Outlook.NoteItem outlookNoteItem = match.OutlookNote;

            //try
            //{
                if (match.GoogleNote == null && match.OutlookNote != null)
                {
                    //no Google note
                    string googleNotetId = NotePropertiesUtils.GetOutlookGoogleNoteId(sync, outlookNoteItem);
                    if (!string.IsNullOrEmpty(googleNotetId))
                    {
                        //Redundant check if exist, but in case an error occurred in MatchNotes
                        Document matchingGoogleNote = sync.GetGoogleNoteById(googleNotetId);
                        if (matchingGoogleNote == null)
                        {
                            if (sync.SyncOption == SyncOption.OutlookToGoogleOnly || !sync.SyncDelete)
                                return;
                            else if (!sync.PromptDelete)
                                sync.DeleteOutlookResolution = DeleteResolution.DeleteOutlookAlways;
                            else if (sync.DeleteOutlookResolution != DeleteResolution.DeleteOutlookAlways &&
                                     sync.DeleteOutlookResolution != DeleteResolution.KeepOutlookAlways)
                            {
                                var r = new ConflictResolver();
                                sync.DeleteOutlookResolution = r.ResolveDelete(match.OutlookNote);
                            }
                            switch (sync.DeleteOutlookResolution)
                            {
                                case DeleteResolution.KeepOutlook:
                                case DeleteResolution.KeepOutlookAlways:
                                    NotePropertiesUtils.ResetOutlookGoogleNoteId(sync, match.OutlookNote);
                                    break;
                                case DeleteResolution.DeleteOutlook:
                                case DeleteResolution.DeleteOutlookAlways:
                                    //Avoid recreating a GoogleNote already existing
                                    //==> Delete this outlookNote instead if previous match existed but no match exists anymore
                                    return;
                                default:
                                    throw new ApplicationException("Cancelled");
                            }
                        }
                    }

                    if (sync.SyncOption == SyncOption.GoogleToOutlookOnly)
                    {
                        sync.SkippedCount++;
                        Logger.Log(string.Format("Outlook Note not added to Google, because of SyncOption " + sync.SyncOption.ToString() + ": {0}", match.OutlookNote.Subject), EventType.Information);
                        return;
                    }

                    //create a Google note from Outlook note
                    match.GoogleNote = new Document();
                    match.GoogleNote.Type = Document.DocumentType.Document;
                    //match.GoogleNote.Categories.Add(new AtomCategory("http://schemas.google.com/docs/2007#document"));
                    //match.GoogleNote.Categories.Add(new AtomCategory("document"));

                    sync.UpdateNote(outlookNoteItem, match.GoogleNote);

                }
                else if (match.OutlookNote == null && match.GoogleNote != null)
                {

                    // no outlook note
                    if (NotePropertiesUtils.NoteFileExists(match.GoogleNote.Id, sync.SyncProfile))
                    {
                        if (sync.SyncOption == SyncOption.GoogleToOutlookOnly || !sync.SyncDelete)
                            return;
                        else if (!sync.PromptDelete)
                            sync.DeleteGoogleResolution = DeleteResolution.DeleteGoogleAlways;
                        else if (sync.DeleteGoogleResolution != DeleteResolution.DeleteGoogleAlways &&
                                 sync.DeleteGoogleResolution != DeleteResolution.KeepGoogleAlways)
                        {
                            var r = new ConflictResolver();
                            sync.DeleteGoogleResolution = r.ResolveDelete(match.GoogleNote, sync);
                        }
                        switch (sync.DeleteGoogleResolution)
                        {
                            case DeleteResolution.KeepGoogle:
                            case DeleteResolution.KeepGoogleAlways:
                                System.IO.File.Delete(NotePropertiesUtils.GetFileName(match.GoogleNote.Id, sync.SyncProfile));
                                break;
                            case DeleteResolution.DeleteGoogle:
                            case DeleteResolution.DeleteGoogleAlways:
                                //Avoid recreating a OutlookNote already existing
                                //==> Delete this googleNote instead if previous match existed but no match exists anymore
                                return;
                            default:
                                throw new ApplicationException("Cancelled");
                        }
                    }

                    if (sync.SyncOption == SyncOption.OutlookToGoogleOnly)
                    {
                        sync.SkippedCount++;
                        Logger.Log(string.Format("Google Note not added to Outlook, because of SyncOption " + sync.SyncOption.ToString() + ": {0}", match.GoogleNote.Title), EventType.Information);
                        return;
                    }

                    //create a Outlook note from Google note
                    outlookNoteItem = Synchronizer.CreateOutlookNoteItem(Synchronizer.SyncNotesFolder);

                    sync.UpdateNote(match.GoogleNote, outlookNoteItem);
                    match.OutlookNote = outlookNoteItem;
                }
                else if (match.OutlookNote != null && match.GoogleNote != null)
                {
                    //merge note details

                    //determine if this note pair were synchronized
                    //DateTime? lastUpdated = GetOutlookPropertyValueDateTime(match.OutlookNote, sync.OutlookPropertyNameUpdated);
                    DateTime? lastSynced = NotePropertiesUtils.GetOutlookLastSync(sync,outlookNoteItem);
                    if (lastSynced.HasValue)
                    {
                        //note pair was syncronysed before.

                        //determine if google note was updated since last sync

                        //lastSynced is stored without seconds. take that into account.
                        DateTime lastUpdatedOutlook = match.OutlookNote.LastModificationTime.AddSeconds(-match.OutlookNote.LastModificationTime.Second);
                        DateTime lastUpdatedGoogle = match.GoogleNote.Updated.AddSeconds(-match.GoogleNote.Updated.Second);

                        //check if both outlok and google notes where updated sync last sync
                        if (lastUpdatedOutlook.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance
                            && lastUpdatedGoogle.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance)
                        {
                            //both notes were updated.
                            //options: 1) ignore 2) loose one based on SyncOption
                            //throw new Exception("Both notes were updated!");

                            switch (sync.SyncOption)
                            {
                                case SyncOption.MergeOutlookWins:
                                case SyncOption.OutlookToGoogleOnly:
                                    //overwrite google note
                                    Logger.Log("Outlook and Google note have been updated, Outlook note is overwriting Google because of SyncOption " + sync.SyncOption + ": " + match.OutlookNote.Subject + ".", EventType.Information);
                                    sync.UpdateNote(outlookNoteItem, match.GoogleNote);
                                    break;
                                case SyncOption.MergeGoogleWins:
                                case SyncOption.GoogleToOutlookOnly:
                                    //overwrite outlook note
                                    Logger.Log("Outlook and Google note have been updated, Google note is overwriting Outlook because of SyncOption " + sync.SyncOption + ": " + match.OutlookNote.Subject + ".", EventType.Information);
                                    sync.UpdateNote(match.GoogleNote, outlookNoteItem);
                                    break;
                                case SyncOption.MergePrompt:
                                    //promp for sync option
                                    if (sync.ConflictResolution != ConflictResolution.GoogleWinsAlways &&
                                        sync.ConflictResolution != ConflictResolution.OutlookWinsAlways &&
                                        sync.ConflictResolution != ConflictResolution.SkipAlways)
                                    {
                                        var r = new ConflictResolver();
                                        sync.ConflictResolution = r.Resolve(outlookNoteItem, match.GoogleNote, sync, false);
                                    }
                                    switch (sync.ConflictResolution)
                                    {
                                        case ConflictResolution.Skip:
                                        case ConflictResolution.SkipAlways:
                                            Logger.Log(string.Format("User skipped note ({0}).", match.ToString()), EventType.Information);
                                            sync.SkippedCount++;
                                            break;
                                        case ConflictResolution.OutlookWins:
                                        case ConflictResolution.OutlookWinsAlways:
                                            sync.UpdateNote(outlookNoteItem, match.GoogleNote);
                                            break;
                                        case ConflictResolution.GoogleWins:
                                        case ConflictResolution.GoogleWinsAlways:
                                            sync.UpdateNote(match.GoogleNote, outlookNoteItem);
                                            break;
                                        default:
                                            throw new ApplicationException("Canceled");
                                    }
                                    break;
                            }
                            return;
                        }

                        //check if outlook note was updated (with X second tolerance)
                        if (sync.SyncOption != SyncOption.GoogleToOutlookOnly &&
                            (lastUpdatedOutlook.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance ||
                             lastUpdatedGoogle.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance &&
                             sync.SyncOption == SyncOption.OutlookToGoogleOnly
                            )
                           )
                        {
                            //outlook note was changed or changed Google note will be overwritten

                            if (lastUpdatedGoogle.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance &&
                                sync.SyncOption == SyncOption.OutlookToGoogleOnly)
                                Logger.Log("Google note has been updated since last sync, but Outlook note is overwriting Google because of SyncOption " + sync.SyncOption + ": " + match.OutlookNote.Subject + ".", EventType.Information);

                            sync.UpdateNote(outlookNoteItem, match.GoogleNote);

                            //at the moment use outlook as "master" source of notes - in the event of a conflict google note will be overwritten.
                            //TODO: control conflict resolution by SyncOption
                            return;
                        }

                        //check if google note was updated (with X second tolerance)
                        if (sync.SyncOption != SyncOption.OutlookToGoogleOnly &&
                            (lastUpdatedGoogle.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance ||
                             lastUpdatedOutlook.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance &&
                             sync.SyncOption == SyncOption.GoogleToOutlookOnly
                            )
                           )
                        {
                            //google note was changed or changed Outlook note will be overwritten

                            if (lastUpdatedOutlook.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance &&
                                sync.SyncOption == SyncOption.GoogleToOutlookOnly)
                                Logger.Log("Outlook note has been updated since last sync, but Google note is overwriting Outlook because of SyncOption " + sync.SyncOption + ": " + match.OutlookNote.Subject + ".", EventType.Information);

                            sync.UpdateNote(match.GoogleNote, outlookNoteItem);
                        }
                    }
                    else
                    {
                        //notes were never synced.
                        //merge notes.
                        switch (sync.SyncOption)
                        {
                            case SyncOption.MergeOutlookWins:
                            case SyncOption.OutlookToGoogleOnly:
                                //overwrite google note
                                sync.UpdateNote(outlookNoteItem, match.GoogleNote);
                                break;
                            case SyncOption.MergeGoogleWins:
                            case SyncOption.GoogleToOutlookOnly:
                                //overwrite outlook note
                                sync.UpdateNote(match.GoogleNote, outlookNoteItem);
                                break;
                            case SyncOption.MergePrompt:
                                //promp for sync option
                                if (sync.ConflictResolution != ConflictResolution.GoogleWinsAlways &&
                                    sync.ConflictResolution != ConflictResolution.OutlookWinsAlways &&
                                        sync.ConflictResolution != ConflictResolution.SkipAlways)
                                {
                                    var r = new ConflictResolver();
                                    sync.ConflictResolution = r.Resolve(outlookNoteItem, match.GoogleNote, sync, true);
                                }
                                switch (sync.ConflictResolution)
                                {
                                    case ConflictResolution.Skip:
                                    case ConflictResolution.SkipAlways: //Keep both, Google AND Outlook
                                        sync.Notes.Add(new NoteMatch(match.OutlookNote, null));
                                        sync.Notes.Add(new NoteMatch(null, match.GoogleNote));
                                        break;
                                    case ConflictResolution.OutlookWins:
                                    case ConflictResolution.OutlookWinsAlways:
                                        sync.UpdateNote(outlookNoteItem, match.GoogleNote);
                                        break;
                                    case ConflictResolution.GoogleWins:
                                    case ConflictResolution.GoogleWinsAlways:
                                        sync.UpdateNote(match.GoogleNote, outlookNoteItem);
                                        break;
                                    default:
                                        throw new ApplicationException("Canceled");
                                }
                                break;
                        }
                    }

                }
                else
                    throw new ArgumentNullException("NotetMatch has all peers null.");
            //}
            //finally
            //{
                //if (outlookNoteItem != null &&
                //    match.OutlookNote != null)
                //{
                //    match.OutlookNote.Update(outlookNoteItem, sync);
                //    Marshal.ReleaseComObject(outlookNoteItem);
                //    outlookNoteItem = null;
                //}
            //}
        }
        /// <summary>
        /// Matches outlook and google note by a) google id b) properties.
        /// </summary>
        /// <param name="sync">Syncronizer instance</param>
        /// <returns>Returns a list of match pairs (outlook note + google note) for all note. Those that weren't matche will have it's peer set to null</returns>
        public static List<NoteMatch> MatchNotes(Synchronizer sync)
        {
            Logger.Log("Matching Outlook and Google notes...", EventType.Information);
            var result = new List<NoteMatch>();

            //string duplicateGoogleMatches = "";
            //string duplicateOutlookNotes = "";
            //sync.GoogleNoteDuplicates = new Collection<NoteMatch>();
            //sync.OutlookNoteDuplicates = new Collection<NoteMatch>();

            //for each outlook note try to get google note id from user properties
            //if no match - try to match by properties
            //if no match - create a new match pair without google note.
            //foreach (Outlook._NoteItem olc in outlookNotes)
            var outlookNotesWithoutOutlookGoogleId = new Collection<Outlook.NoteItem>();
            #region Match first all outlookNotes by sync id
            for (int i = 1; i <= sync.OutlookNotes.Count; i++)
            {
                Outlook.NoteItem oln;
                try
                {
                    oln = sync.OutlookNotes[i] as Outlook.NoteItem;
                    if (oln == null || string.IsNullOrEmpty(oln.Body))
                    {
                        Logger.Log("Empty Outlook note found. Skipping", EventType.Warning);
                        sync.SkippedCount++;
                        sync.SkippedCountNotMatches++;
                        continue;
                    }
                }
                catch (Exception ex)
                {
                    //this is needed because some notes throw exceptions
                    Logger.Log("Accessing Outlook note threw and exception. Skipping: " + ex.Message, EventType.Warning);
                    sync.SkippedCount++;
                    sync.SkippedCountNotMatches++;
                    continue;
                }

                //try
                //{

                    if (NotificationReceived != null)
                        NotificationReceived(String.Format("Matching note {0} of {1} by id: {2} ...", i, sync.OutlookNotes.Count, oln.Subject));

                    // Create our own info object to go into collections/lists, so we can free the Outlook objects and not run out of resources / exceed policy limits.
                    //OutlookNoteInfo olci = new OutlookNoteInfo(oln, sync);

                    //try to match this note to one of google notes
                    Outlook.ItemProperties userProperties = oln.ItemProperties;
                    Outlook.ItemProperty idProp = userProperties[sync.OutlookPropertyNameId];
                    try
                    {
                        if (idProp != null)
                        {
                            string googleNoteId = string.Copy((string)idProp.Value);
                            Document foundNote = sync.GetGoogleNoteById(googleNoteId);
                            var match = new NoteMatch(oln, null);

                            //Check first, that this is not a duplicate
                            //e.g. by copying an existing Outlook note
                            //or by Outlook checked this as duplicate, but the user selected "Add new"
                        //    Collection<OutlookNoteInfo> duplicates = sync.OutlookNoteByProperty(sync.OutlookPropertyNameId, googleNoteId);
                        //    if (duplicates.Count > 1)
                        //    {
                        //        foreach (OutlookNoteInfo duplicate in duplicates)
                        //        {
                        //            if (!string.IsNullOrEmpty(googleNoteId))
                        //            {
                        //                Logger.Log("Duplicate Outlook note found, resetting match and try to match again: " + duplicate.FileAs, EventType.Warning);
                        //                idProp.Value = "";
                        //            }
                        //        }

                        //        if (foundNote != null && !foundNote.Deleted)
                        //        {
                        //            NotePropertiesUtils.ResetGoogleOutlookNoteId(sync.SyncProfile, foundNote);
                        //        }

                        //        outlookNotesWithoutOutlookGoogleId.Add(olci);
                        //    }
                        //    else
                        //    {

                            if (foundNote != null)
                            {
                                //we found a match by google id, that is not deleted yet
                                match.AddGoogleNote(foundNote);
                                result.Add(match);
                                //Remove the note from the list to not sync it twice
                                sync.GoogleNotes.Remove(foundNote);
                            }
                            else
                            {
                                ////If no match found, is the note either deleted on Google side or was a copy on Outlook side
                                ////If it is a copy on Outlook side, the idProp.Value must be emptied to assure, the note is created on Google side and not deleted on Outlook side
                                ////bool matchIsDuplicate = false;
                                //foreach (NoteMatch existingMatch in result)
                                //{
                                //    if (existingMatch.OutlookNote.UserProperties[sync.OutlookPropertyNameId].Value.Equals(idProp.Value))
                                //    {
                                //        //matchIsDuplicate = true;
                                //        idProp.Value = "";
                                //        break;
                                //    }

                                //}
                                outlookNotesWithoutOutlookGoogleId.Add(oln);

                                //if (!matchIsDuplicate)
                                //    result.Add(match);
                            }
                        //    }
                        }
                        else
                            outlookNotesWithoutOutlookGoogleId.Add(oln);
                    }
                    finally
                    {
                        if (idProp != null)
                            Marshal.ReleaseComObject(idProp);
                        Marshal.ReleaseComObject(userProperties);
                    }
                //}

                //finally
                //{
                //    Marshal.ReleaseComObject(oln);
                //    oln = null;
                //}

            }
            #endregion
            #region Match the remaining notes by properties

            for (int i = 0; i < outlookNotesWithoutOutlookGoogleId.Count; i++)
            {
                Outlook.NoteItem oln = outlookNotesWithoutOutlookGoogleId[i];

                if (NotificationReceived != null)
                    NotificationReceived(String.Format("Matching note {0} of {1} by unique properties: {2} ...", i + 1, outlookNotesWithoutOutlookGoogleId.Count, oln.Subject));

                //no match found by id => match by subject/title
                //create a default match pair with just outlook note.
                var match = new NoteMatch(oln, null);

                //foreach google contact try to match and create a match pair if found some match(es)
                for (int j = sync.GoogleNotes.Count - 1; j >= 0; j--)
                {
                    Document entry = sync.GoogleNotes[j];

                    string body = NotePropertiesUtils.GetBody(sync, entry);
                    if (!string.IsNullOrEmpty(body))
                        body = body.Replace("\r\n", string.Empty).Replace(" ", string.Empty).Replace("�", string.Empty);

                    string outlookBody = null;
                    if (!string.IsNullOrEmpty(oln.Body))
                        outlookBody = oln.Body.Replace("\t", "        ").Replace("\r\n", string.Empty).Replace(" ", string.Empty).Replace("�", string.Empty);

                    // only match if there is a note body, else
                    // a matching google note will be created at each sync
                    if (!string.IsNullOrEmpty(outlookBody) && !string.IsNullOrEmpty(body) && outlookBody.Equals(body, StringComparison.InvariantCultureIgnoreCase)
                        )
                    {
                        match.AddGoogleNote(entry);
                        sync.GoogleNotes.Remove(entry);
                    }

                }

                #region find duplicates not needed now
                //if (match.GoogleNote == null && match.OutlookNote != null)
                //{//If GoogleNote, we have to expect a conflict because of Google insert of duplicates
                //    foreach (Note entry in sync.GoogleNotes)
                //    {
                //        if (!string.IsNullOrEmpty(olc.FullName) && olc.FullName.Equals(entry.Title, StringComparison.InvariantCultureIgnoreCase) ||
                //         !string.IsNullOrEmpty(olc.FileAs) && olc.FileAs.Equals(entry.Title, StringComparison.InvariantCultureIgnoreCase) ||
                //         !string.IsNullOrEmpty(olc.Email1Address) && FindEmail(olc.Email1Address, entry.Emails) != null ||
                //         !string.IsNullOrEmpty(olc.Email2Address) && FindEmail(olc.Email1Address, entry.Emails) != null ||
                //         !string.IsNullOrEmpty(olc.Email3Address) && FindEmail(olc.Email1Address, entry.Emails) != null ||
                //         olc.MobileTelephoneNumber != null && FindPhone(olc.MobileTelephoneNumber, entry.Phonenumbers) != null
                //         )
                //    }
                //// check for each email 1,2 and 3 if a duplicate exists with same email, because Google doesn't like inserting new notes with same email
                //Collection<Outlook.NoteItem> duplicates1 = new Collection<Outlook.NoteItem>();
                //Collection<Outlook.NoteItem> duplicates2 = new Collection<Outlook.NoteItem>();
                //Collection<Outlook.NoteItem> duplicates3 = new Collection<Outlook.NoteItem>();
                //if (!string.IsNullOrEmpty(olc.Email1Address))
                //    duplicates1 = sync.OutlookNoteByEmail(olc.Email1Address);

                //if (!string.IsNullOrEmpty(olc.Email2Address))
                //    duplicates2 = sync.OutlookNoteByEmail(olc.Email2Address);

                //if (!string.IsNullOrEmpty(olc.Email3Address))
                //    duplicates3 = sync.OutlookNoteByEmail(olc.Email3Address);

                //if (duplicates1.Count > 1 || duplicates2.Count > 1 || duplicates3.Count > 1)
                //{
                //    if (string.IsNullOrEmpty(duplicatesEmailList))
                //        duplicatesEmailList = "Outlook notes with the same email have been found and cannot be synchronized. Please delete duplicates of:";

                //    if (duplicates1.Count > 1)
                //        foreach (Outlook.NoteItem duplicate in duplicates1)
                //        {
                //            string str = olc.FileAs + " (" + olc.Email1Address + ")";
                //            if (!duplicatesEmailList.Contains(str))
                //                duplicatesEmailList += Environment.NewLine + str;
                //        }
                //    if (duplicates2.Count > 1)
                //        foreach (Outlook.NoteItem duplicate in duplicates2)
                //        {
                //            string str = olc.FileAs + " (" + olc.Email2Address + ")";
                //            if (!duplicatesEmailList.Contains(str))
                //                duplicatesEmailList += Environment.NewLine + str;
                //        }
                //    if (duplicates3.Count > 1)
                //        foreach (Outlook.NoteItem duplicate in duplicates3)
                //        {
                //            string str = olc.FileAs + " (" + olc.Email3Address + ")";
                //            if (!duplicatesEmailList.Contains(str))
                //                duplicatesEmailList += Environment.NewLine + str;
                //        }
                //    continue;
                //}
                //else if (!string.IsNullOrEmpty(olc.Email1Address))
                //{
                //    NoteMatch dup = result.Find(delegate(NoteMatch match)
                //    {
                //        return match.OutlookNote != null && match.OutlookNote.Email1Address == olc.Email1Address;
                //    });
                //    if (dup != null)
                //    {
                //        Logger.Log(string.Format("Duplicate note found by Email1Address ({0}). Skipping", olc.FileAs), EventType.Information);
                //        continue;
                //    }
                //}

                //// check for unique mobile phone, because this sync tool uses the also the mobile phone to identify matches between Google and Outlook
                //Collection<Outlook.NoteItem> duplicatesMobile = new Collection<Outlook.NoteItem>();
                //if (!string.IsNullOrEmpty(olc.MobileTelephoneNumber))
                //    duplicatesMobile = sync.OutlookNoteByProperty("MobileTelephoneNumber", olc.MobileTelephoneNumber);

                //if (duplicatesMobile.Count > 1)
                //{
                //    if (string.IsNullOrEmpty(duplicatesMobileList))
                //        duplicatesMobileList = "Outlook notes with the same mobile phone have been found and cannot be synchronized. Please delete duplicates of:";

                //    foreach (Outlook.NoteItem duplicate in duplicatesMobile)
                //    {
                //        sync.OutlookNoteDuplicates.Add(olc);
                //        string str = olc.FileAs + " (" + olc.MobileTelephoneNumber + ")";
                //        if (!duplicatesMobileList.Contains(str))
                //            duplicatesMobileList += Environment.NewLine + str;
                //    }
                //    continue;
                //}
                //else if (!string.IsNullOrEmpty(olc.MobileTelephoneNumber))
                //{
                //    NoteMatch dup = result.Find(delegate(NoteMatch match)
                //    {
                //        return match.OutlookNote != null && match.OutlookNote.MobileTelephoneNumber == olc.MobileTelephoneNumber;
                //    });
                //    if (dup != null)
                //    {
                //        Logger.Log(string.Format("Duplicate note found by MobileTelephoneNumber ({0}). Skipping", olc.FileAs), EventType.Information);
                //        continue;
                //    }
                //}

                #endregion

            //    if (match.AllGoogleNoteMatches == null || match.AllGoogleNoteMatches.Count == 0)
            //    {
            //        //Check, if this Outlook note has a match in the google duplicates
            //        bool duplicateFound = false;
            //        foreach (NoteMatch duplicate in sync.GoogleNoteDuplicates)
            //        {
            //            if (duplicate.AllGoogleNoteMatches.Count > 0 &&
            //                (!string.IsNullOrEmpty(olci.FileAs) && !string.IsNullOrEmpty(duplicate.AllGoogleNoteMatches[0].Title) && olci.FileAs.Equals(duplicate.AllGoogleNoteMatches[0].Title.Replace("\r\n", "\n").Replace("\n", "\r\n"), StringComparison.InvariantCultureIgnoreCase) ||  //Replace twice to not replace a \r\n by \r\r\n. This is necessary because \r\n are saved as \n only to Google
            //                 !string.IsNullOrEmpty(olci.FileAs) && !string.IsNullOrEmpty(duplicate.AllGoogleNoteMatches[0].Name.FullName) && olci.FileAs.Equals(duplicate.AllGoogleNoteMatches[0].Name.FullName.Replace("\r\n", "\n").Replace("\n", "\r\n"), StringComparison.InvariantCultureIgnoreCase) ||
            //                 !string.IsNullOrEmpty(olci.FullName) && !string.IsNullOrEmpty(duplicate.AllGoogleNoteMatches[0].Name.FullName) && olci.FullName.Equals(duplicate.AllGoogleNoteMatches[0].Name.FullName.Replace("\r\n", "\n").Replace("\n", "\r\n"), StringComparison.InvariantCultureIgnoreCase) ||
            //                 !string.IsNullOrEmpty(olci.Email1Address) && duplicate.AllGoogleNoteMatches[0].Emails.Count > 0 && olci.Email1Address.Equals(duplicate.AllGoogleNoteMatches[0].Emails[0].Address, StringComparison.InvariantCultureIgnoreCase) ||
            //                //!string.IsNullOrEmpty(olci.Email2Address) && FindEmail(olci.Email2Address, duplicate.AllGoogleNoteMatches[0].Emails) != null ||
            //                //!string.IsNullOrEmpty(olci.Email3Address) && FindEmail(olci.Email3Address, duplicate.AllGoogleNoteMatches[0].Emails) != null ||
            //                 olci.MobileTelephoneNumber != null && FindPhone(olci.MobileTelephoneNumber, duplicate.AllGoogleNoteMatches[0].Phonenumbers) != null ||
            //                 !string.IsNullOrEmpty(olci.FileAs) && string.IsNullOrEmpty(duplicate.AllGoogleNoteMatches[0].Title) && duplicate.AllGoogleNoteMatches[0].Organizations.Count > 0 && olci.FileAs.Equals(duplicate.AllGoogleNoteMatches[0].Organizations[0].Name, StringComparison.InvariantCultureIgnoreCase)
            //                ) ||
            //                !string.IsNullOrEmpty(olci.FileAs) && olci.FileAs.Equals(duplicate.OutlookNote.Subject, StringComparison.InvariantCultureIgnoreCase) ||
            //                !string.IsNullOrEmpty(olci.FullName) && olci.FullName.Equals(duplicate.OutlookNote.FullName, StringComparison.InvariantCultureIgnoreCase) ||
            //                !string.IsNullOrEmpty(olci.Email1Address) && olci.Email1Address.Equals(duplicate.OutlookNote.Email1Address, StringComparison.InvariantCultureIgnoreCase) ||
            //                //                                              olci.Email1Address.Equals(duplicate.OutlookNote.Email2Address, StringComparison.InvariantCultureIgnoreCase) ||
            //                //                                              olci.Email1Address.Equals(duplicate.OutlookNote.Email3Address, StringComparison.InvariantCultureIgnoreCase)
            //                //                                              ) ||
            //                //!string.IsNullOrEmpty(olci.Email2Address) && (olci.Email2Address.Equals(duplicate.OutlookNote.Email1Address, StringComparison.InvariantCultureIgnoreCase) ||
            //                //                                              olci.Email2Address.Equals(duplicate.OutlookNote.Email2Address, StringComparison.InvariantCultureIgnoreCase) ||
            //                //                                              olci.Email2Address.Equals(duplicate.OutlookNote.Email3Address, StringComparison.InvariantCultureIgnoreCase)
            //                //                                              ) ||
            //                //!string.IsNullOrEmpty(olci.Email3Address) && (olci.Email3Address.Equals(duplicate.OutlookNote.Email1Address, StringComparison.InvariantCultureIgnoreCase) ||
            //                //                                              olci.Email3Address.Equals(duplicate.OutlookNote.Email2Address, StringComparison.InvariantCultureIgnoreCase) ||
            //                //                                              olci.Email3Address.Equals(duplicate.OutlookNote.Email3Address, StringComparison.InvariantCultureIgnoreCase)
            //                //                                              ) ||
            //                olci.MobileTelephoneNumber != null && olci.MobileTelephoneNumber.Equals(duplicate.OutlookNote.MobileTelephoneNumber) ||
            //                !string.IsNullOrEmpty(olci.FileAs) && string.IsNullOrEmpty(duplicate.GoogleNote.Title) && duplicate.GoogleNote.Organizations.Count > 0 && olci.FileAs.Equals(duplicate.GoogleNote.Organizations[0].Name, StringComparison.InvariantCultureIgnoreCase)
            //               )
            //            {
            //                duplicateFound = true;
            //                sync.OutlookNoteDuplicates.Add(match);
            //                if (string.IsNullOrEmpty(duplicateOutlookNotes))
            //                    duplicateOutlookNotes = "Outlook note found that has been already identified as duplicate Google note (either same email, Mobile or FullName) and cannot be synchronized. Please delete or resolve duplicates of:";

            //                string str = olci.FileAs + " (" + olci.Email1Address + ", " + olci.MobileTelephoneNumber + ")";
            //                if (!duplicateOutlookNotes.Contains(str))
            //                    duplicateOutlookNotes += Environment.NewLine + str;
            //            }
            //        }

            //        if (!duplicateFound)
            if (match.GoogleNote == null)
                Logger.Log(string.Format("No match found for outlook note ({0}) => {1}", match.OutlookNote.Subject, (NotePropertiesUtils.GetOutlookGoogleNoteId(sync, match.OutlookNote) != null ? "Delete from Outlook" : "Add to Google")), EventType.Information);

            //    }
            //    else
            //    {
            //        //Remember Google duplicates to later react to it when resetting matches or syncing
            //        //ResetMatches: Also reset the duplicates
            //        //Sync: Skip duplicates (don't sync duplicates to be fail safe)
            //        if (match.AllGoogleNoteMatches.Count > 1)
            //        {
            //            sync.GoogleNoteDuplicates.Add(match);
            //            foreach (Note entry in match.AllGoogleNoteMatches)
            //            {
            //                //Create message for duplicatesFound exception
            //                if (string.IsNullOrEmpty(duplicateGoogleMatches))
            //                    duplicateGoogleMatches = "Outlook notes matching with multiple Google notes have been found (either same email, Mobile, FullName or company) and cannot be synchronized. Please delete or resolve duplicates of:";

            //                string str = olci.FileAs + " (" + olci.Email1Address + ", " + olci.MobileTelephoneNumber + ")";
            //                if (!duplicateGoogleMatches.Contains(str))
            //                    duplicateGoogleMatches += Environment.NewLine + str;
            //            }
            //        }

            //    }

                result.Add(match);
            }
            #endregion

            //if (!string.IsNullOrEmpty(duplicateGoogleMatches) || !string.IsNullOrEmpty(duplicateOutlookNotes))
            //    duplicatesFound = new DuplicateDataException(duplicateGoogleMatches + Environment.NewLine + Environment.NewLine + duplicateOutlookNotes);
            //else
            //    duplicatesFound = null;

            //return result;

            //for each google note that's left (they will be nonmatched) create a new match pair without outlook note.
            for (int i = 0; i < sync.GoogleNotes.Count; i++)
            {
                Document entry = sync.GoogleNotes[i];
                if (NotificationReceived != null)
                    NotificationReceived(String.Format("Adding new Google note {0} of {1} by unique properties: {2} ...", i + 1, sync.GoogleNotes.Count, entry.Title));

                //string googleOutlookId = NotePropertiesUtils.GetGoogleOutlookNoteId(sync.SyncProfile, entry);
                //if (!String.IsNullOrEmpty(googleOutlookId) && skippedOutlookIds.Contains(googleOutlookId))
                //{
                //    Logger.Log("Skipped GoogleNote because Outlook note couldn't be matched because of previous problem (see log): " + entry.Title, EventType.Warning);
                //}
                //else
                if (string.IsNullOrEmpty(entry.Title) && string.IsNullOrEmpty(entry.Content))
                {
                    // no title or content
                    sync.SkippedCount++;
                    sync.SkippedCountNotMatches++;
                    Logger.Log("Skipped GoogleNote because no unique property found (Title or Content):" + entry.Title, EventType.Warning);
                }
                else
                {
                    Logger.Log(string.Format("No match found for Google note ({0}) => {1}", entry.Title, (NotePropertiesUtils.NoteFileExists(entry.Id, sync.SyncProfile) ? "Delete from Google" : "Add to Outlook")), EventType.Information);
                    var match = new NoteMatch(null, entry);
                    result.Add(match);
                }
            }
            return result;
        }