コード例 #1
0
        public void SaveGoogleContact(ContactMatch match)
        {
            //check if this contact was not yet inserted on google.
            if (match.GoogleContact.Id.Uri == null)
            {
                //insert contact.
                Uri feedUri = new Uri(ContactsQuery.CreateContactsUri("default"));

                try
                {
                    ContactPropertiesUtils.SetGoogleOutlookContactId(SyncProfile, match.GoogleContact, match.OutlookContact);

                    ContactEntry createdEntry = (ContactEntry)_googleService.Insert(feedUri, match.GoogleContact);
                    match.GoogleContact = createdEntry;

                    ContactPropertiesUtils.SetOutlookGoogleContactId(this, match.OutlookContact, match.GoogleContact);
                    match.OutlookContact.Save();
                }
                catch (Exception ex)
                {
                    MemoryStream ms = new MemoryStream();
                    match.GoogleContact.SaveToXml(ms);

                    StreamReader sr = new StreamReader(ms);

                    ms.Seek(0, SeekOrigin.Begin);
                    Debug.WriteLine(String.Format("Error saving google contact: {0}", ex.Message));
                    Debug.WriteLine(sr.ReadToEnd());
                    //TODO: save google contact xml for diagnistics
                    throw;
                }
            }
            else
            {
                try
                {
                    //contact already present in google. just update
                    ContactPropertiesUtils.SetGoogleOutlookContactId(SyncProfile, match.GoogleContact, match.OutlookContact);

                    //TODO: this will fail if original contact had an empty name or rpimary email address.
                    ContactEntry updatedEntry = match.GoogleContact.Update() as ContactEntry;
                    match.GoogleContact = updatedEntry;

                    ContactPropertiesUtils.SetOutlookGoogleContactId(this, match.OutlookContact, match.GoogleContact);
                    match.OutlookContact.Save();
                }
                catch (Exception ex)
                {
                    //TODO: save google contact xml for diagnistics
                    throw;
                }
            }
        }
コード例 #2
0
 public void ResetMatch(ContactMatch match)
 {
     if (match.GoogleContact != null)
     {
         ContactPropertiesUtils.ResetGoogleOutlookContactId(SyncProfile, match.GoogleContact);
         SaveGoogleContact(match.GoogleContact);
     }
     if (match.OutlookContact != null)
     {
         ContactPropertiesUtils.ResetOutlookGoogleContactId(this, match.OutlookContact);
         match.OutlookContact.Save();
     }
 }
コード例 #3
0
        public void SaveContactPhotos(ContactMatch match)
        {
            bool hasGooglePhoto  = Utilities.HasPhoto(match.GoogleContact);
            bool hasOutlookPhoto = Utilities.HasPhoto(match.OutlookContact);

            if (!hasGooglePhoto && !hasOutlookPhoto)
            {
                return;
            }
            else if (hasGooglePhoto && !hasOutlookPhoto)
            {
                // add google photo to outlook
                Image googlePhoto = Utilities.GetGooglePhoto(this, match.GoogleContact);
                Utilities.SetOutlookPhoto(match.OutlookContact, googlePhoto);
                match.OutlookContact.Save();

                googlePhoto.Dispose();
            }
            else if (!hasGooglePhoto && hasOutlookPhoto)
            {
                // add outlook photo to google
                Image outlookPhoto = Utilities.GetOutlookPhoto(match.OutlookContact);
                outlookPhoto = Utilities.CropImageGoogleFormat(outlookPhoto);
                bool saved = Utilities.SaveGooglePhoto(this, match.GoogleContact, outlookPhoto);
                if (!saved)
                {
                    throw new Exception("Could not save");
                }

                outlookPhoto.Dispose();
            }
            else
            {
                // TODO: if both contacts have photos and one is updated, the
                // other will not be updated.
            }

            //Utilities.DeleteTempPhoto();
        }
コード例 #4
0
        public static void SyncContact(ContactMatch match, Syncronizer sync)
        {
            if (match.GoogleContact == null && match.OutlookContact != null)
            {
                //no google contact

                //TODO: check SyncOption
                //TODO: found that when a contacts doesn't have anything other that the name - it's not returned in the google contacts list.
                Outlook.UserProperty idProp = match.OutlookContact.UserProperties[sync.OutlookPropertyNameId];
                if (idProp != null && (string)idProp.Value != "")
                {
                    AtomId       id = new AtomId((string)idProp.Value);
                    ContactEntry matchingGoogleContact = sync.GoogleContacts.FindById(id) as ContactEntry;
                    if (matchingGoogleContact == null)
                    {
                        //TODO: make sure that outlook contacts don't get deleted when deleting corresponding google contact when testing.
                        //solution: use ResetMatching() method to unlink this relation
                        //sync.ResetMatches();
                        return;
                    }
                }

                //create a Google contact from Outlook contact
                match.GoogleContact = new ContactEntry();

                ContactSync.UpdateContact(match.OutlookContact, match.GoogleContact);
                sync.OverwriteContactGroups(match.OutlookContact, match.GoogleContact);
            }
            else if (match.OutlookContact == null && match.GoogleContact != null)
            {
                // no outlook contact
                string outlookId = ContactPropertiesUtils.GetGoogleOutlookContactId(sync.SyncProfile, match.GoogleContact);
                if (outlookId != null)
                {
                    //TODO: make sure that google contacts don't get deleted when deleting corresponding outlook contact when testing.
                    //solution: use ResetMatching() method to unlink this relation
                    //sync.ResetMatches();
                    return;
                }

                //TODO: check SyncOption
                //create a Outlook contact from Google contact
                match.OutlookContact = sync.OutlookApplication.CreateItem(Outlook.OlItemType.olContactItem) as Outlook.ContactItem;

                ContactSync.MergeContacts(match.GoogleContact, match.OutlookContact);
                sync.OverwriteContactGroups(match.GoogleContact, match.OutlookContact);
            }
            else if (match.OutlookContact != null && match.GoogleContact != null)
            {
                //merge contact details


                //TODO: check if there are multiple matches
                if (match.AllGoogleContactMatches.Count > 1)
                {
                    //loop from 2-nd item
                    for (int m = 1; m < match.AllGoogleContactMatches.Count; m++)
                    {
                        ContactEntry entry = match.AllGoogleContactMatches[m];
                        try
                        {
                            Outlook.ContactItem item = sync.OutlookContacts.Find("[" + sync.OutlookPropertyNameId + "] = \"" + entry.Id.Uri.Content + "\"") as Outlook.ContactItem;
                            //Outlook.ContactItem item = sync.OutlookContacts.Find("[myTest] = \"value\"") as Outlook.ContactItem;
                            if (item != null)
                            {
                                //do something
                            }
                        }
                        catch (Exception)
                        {
                            //TODO: should not get here.
                        }
                    }

                    //TODO: add info to Outlook contact from extra Google contacts before deleting extra Google contacts.

                    for (int m = 1; m < match.AllGoogleContactMatches.Count; m++)
                    {
                        match.AllGoogleContactMatches[m].Delete();
                    }
                }

                //determine if this contact pair were syncronized
                //DateTime? lastUpdated = GetOutlookPropertyValueDateTime(match.OutlookContact, sync.OutlookPropertyNameUpdated);
                DateTime?lastSynced = GetOutlookPropertyValueDateTime(match.OutlookContact, sync.OutlookPropertyNameSynced);
                if (lastSynced.HasValue)
                {
                    //contact pair was syncronysed before.

                    //determine if google contact was updated since last sync

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

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

                        switch (sync.SyncOption)
                        {
                        case SyncOption.MergeOutlookWins:
                            //overwrite google contact
                            ContactSync.MergeContacts(match.OutlookContact, match.GoogleContact);
                            sync.OverwriteContactGroups(match.OutlookContact, match.GoogleContact);
                            break;

                        case SyncOption.MergeGoogleWins:
                            //overwrite outlook contact
                            ContactSync.MergeContacts(match.GoogleContact, match.OutlookContact);
                            sync.OverwriteContactGroups(match.GoogleContact, match.OutlookContact);
                            break;

                        case SyncOption.MergePrompt:
                            //promp for sync option
                            ConflictResolver   r   = new ConflictResolver();
                            ConflictResolution res = r.Resolve(match.OutlookContact, match.GoogleContact);
                            switch (res)
                            {
                            case ConflictResolution.Cancel:
                                break;

                            case ConflictResolution.OutlookWins:
                                //TODO: what about categories/groups?
                                ContactSync.MergeContacts(match.OutlookContact, match.GoogleContact);
                                sync.OverwriteContactGroups(match.OutlookContact, match.GoogleContact);
                                break;

                            case ConflictResolution.GoogleWins:
                                //TODO: what about categories/groups?
                                ContactSync.MergeContacts(match.GoogleContact, match.OutlookContact);
                                sync.OverwriteContactGroups(match.GoogleContact, match.OutlookContact);
                                break;

                            default:
                                break;
                            }
                            break;

                        case SyncOption.GoogleToOutlookOnly:
                            ContactSync.MergeContacts(match.GoogleContact, match.OutlookContact);
                            sync.OverwriteContactGroups(match.GoogleContact, match.OutlookContact);
                            break;

                        case SyncOption.OutlookToGoogleOnly:
                            ContactSync.MergeContacts(match.OutlookContact, match.GoogleContact);
                            sync.OverwriteContactGroups(match.OutlookContact, match.GoogleContact);
                            break;
                        }
                        return;
                    }

                    //check if outlook contact was updated (with X second tolerance)
                    if (lastUpdatedOutlook.Subtract(lastSynced.Value).TotalSeconds >= TimeTolerance)
                    {
                        //outlook contact was changed

                        //merge contacts.
                        if (sync.SyncOption != SyncOption.GoogleToOutlookOnly)
                        {
                            //TODO: use UpdateContact instead?
                            ContactSync.MergeContacts(match.OutlookContact, match.GoogleContact);
                            sync.OverwriteContactGroups(match.OutlookContact, match.GoogleContact);

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

                    //check if google contact was updated (with X second tolerance)
                    if (lastUpdatedGoogle.Subtract(lastSynced.Value).TotalSeconds >= TimeTolerance)
                    {
                        //google contact was updated
                        //update outlook contact
                        if (sync.SyncOption != SyncOption.OutlookToGoogleOnly)
                        {
                            ContactSync.MergeContacts(match.GoogleContact, match.OutlookContact);
                            sync.OverwriteContactGroups(match.GoogleContact, match.OutlookContact);
                        }
                    }
                }
                else
                {
                    //contacts were never synced.
                    //merge contacts.
                    switch (sync.SyncOption)
                    {
                    case SyncOption.MergeOutlookWins:
                        //overwrite google contact
                        ContactSync.MergeContacts(match.OutlookContact, match.GoogleContact);
                        sync.OverwriteContactGroups(match.OutlookContact, match.GoogleContact);
                        break;

                    case SyncOption.MergeGoogleWins:
                        //overwrite outlook contact
                        ContactSync.MergeContacts(match.GoogleContact, match.OutlookContact);
                        sync.OverwriteContactGroups(match.GoogleContact, match.OutlookContact);
                        break;

                    case SyncOption.MergePrompt:
                        //promp for sync option
                        ConflictResolver   r   = new ConflictResolver();
                        ConflictResolution res = r.Resolve(match.OutlookContact, match.GoogleContact);
                        switch (res)
                        {
                        case ConflictResolution.Cancel:
                            break;

                        case ConflictResolution.OutlookWins:
                            ContactSync.MergeContacts(match.OutlookContact, match.GoogleContact);
                            sync.OverwriteContactGroups(match.OutlookContact, match.GoogleContact);
                            break;

                        case ConflictResolution.GoogleWins:
                            ContactSync.MergeContacts(match.GoogleContact, match.OutlookContact);
                            sync.OverwriteContactGroups(match.GoogleContact, match.OutlookContact);
                            break;

                        default:
                            break;
                        }
                        break;

                    case SyncOption.GoogleToOutlookOnly:
                        ContactSync.MergeContacts(match.GoogleContact, match.OutlookContact);
                        sync.OverwriteContactGroups(match.GoogleContact, match.OutlookContact);
                        break;

                    case SyncOption.OutlookToGoogleOnly:
                        ContactSync.MergeContacts(match.OutlookContact, match.GoogleContact);
                        sync.OverwriteContactGroups(match.OutlookContact, match.GoogleContact);
                        break;
                    }
                }
            }
            else
            {
                throw new ArgumentNullException("ContactMatch has all peers null.");
            }
        }
コード例 #5
0
        /// <summary>
        /// Matches outlook and google contact by a) google id b) properties.
        /// </summary>
        /// <param name="outlookContacts"></param>
        /// <param name="googleContacts"></param>
        /// <returns>Returns a list of match pairs (outlook contact + google contact) for all contact. Those that weren't matche will have it's peer set to null</returns>
        public static ContactMatchList MatchContacts(Syncronizer sync)
        {
            ContactMatchList result      = new ContactMatchList(Math.Max(sync.OutlookContacts.Count, sync.GoogleContacts.Capacity));
            int    googleContactsMatched = 0;
            bool   listingDuplicates     = false;
            string duplicatesList        = "";

            //for each outlook contact try to get google contact id from user properties
            //if no match - try to match by properties
            //if no match - create a new match pair without google contact.
            //foreach (Outlook._ContactItem olc in outlookContacts)
            for (int i = 1; i <= sync.OutlookContacts.Count; i++)
            {
                try
                {
                    if (!(sync.OutlookContacts[i] is Outlook.ContactItem))
                    {
                        continue;
                    }
                }
                catch (Exception ex)
                {
                    //this is needed because some contacts throw exceptions
                    continue;
                }

                Outlook.ContactItem olc = sync.OutlookContacts[i] as Outlook.ContactItem;

                // check if a duplicate
                Collection <Outlook.ContactItem> duplicates;
                if (!string.IsNullOrEmpty(olc.Email1Address))
                {
                    duplicates = sync.OutlookContactByEmail(olc.Email1Address);
                    if (duplicates.Count > 1)
                    {
                        if (!listingDuplicates)
                        {
                            duplicatesList    = "Outlook contacts with the same email have been found. Please delete duplicates of:";
                            listingDuplicates = true;
                        }
                        string str = olc.FileAs + " (" + olc.Email1Address + ")";
                        if (!duplicatesList.Contains(str))
                        {
                            duplicatesList += Environment.NewLine + str;
                        }
                        continue;
                    }
                    else
                    {
                        ContactMatch dup = result.Find(delegate(ContactMatch match)
                        {
                            return(match.OutlookContact != null && match.OutlookContact.Email1Address == olc.Email1Address);
                        });
                        if (dup != null)
                        {
                            if (sync.Logger != null)
                            {
                                sync.Logger.Log(string.Format("Duplicate contact found ({0}). Skipping", olc.FileAs), EventType.Information);
                            }
                            continue;
                        }
                    }
                }
                //if (duplicates.Count != 1)
                //{
                //    // if this is the first item in the duplicates
                //    // collection, then proceed, otherwise skip.
                //    int index = sync.IndexOf(duplicates, olc); //duplicates.IndexOf(olc);
                //    if (index == -1)
                //        throw new Exception("Did not find self in duplicates");
                //    if (index != 0)
                //        continue;
                //}

                if (!IsContactValid(olc))
                {
                    if (sync.Logger != null)
                    {
                        sync.Logger.Log(string.Format("Invalid outlook contact ({0}). Skipping", olc.FileAs), EventType.Warning);
                    }
                    continue;
                }

                // only match if there is either an email or telephone or else
                // a matching google contact will be created at each sync
                if (olc.Email1Address != null ||
                    olc.Email2Address != null ||
                    olc.Email3Address != null ||
                    olc.PrimaryTelephoneNumber != null ||
                    olc.HomeTelephoneNumber != null ||
                    olc.MobileTelephoneNumber != null ||
                    olc.BusinessTelephoneNumber != null
                    )
                {
                    //create a default match pair with just outlook contact.
                    ContactMatch match = new ContactMatch(olc, null);
                    #region Match by google id
                    //try to match this contact to one of google contacts.
                    Outlook.UserProperty idProp = olc.UserProperties[sync.OutlookPropertyNameId];
                    if (idProp != null)
                    {
                        AtomId       id           = new AtomId((string)idProp.Value);
                        ContactEntry foundContact = sync.GoogleContacts.FindById(id) as ContactEntry;

                        if (foundContact != null && foundContact.Deleted)
                        {
                            //google contact was deleted, but outlook contact is still referencing it.
                            idProp.Value = "";

                            //TODO: delete outlook contact too?
                        }
                        if (foundContact == null)
                        {
                            //google contact not found. delete property.
                            idProp.Value = "";
                        }
                        else if (foundContact != null)
                        {
                            //we found a match by google id
                            match.AddGoogleContact(foundContact);
                        }
                    }
                    #endregion

                    if (match.GoogleContact == null)
                    {
                        //no match found. match by common properties

                        #region Match by properties

                        //foreach google contac try to match and create a match pair if found some match(es)
                        foreach (ContactEntry entry in sync.GoogleContacts)
                        {
                            //Console.WriteLine(" - "+entry.Title.Text);
                            if (entry.Deleted)
                            {
                                continue;
                            }

                            //1. try to match by name
                            if (!string.IsNullOrEmpty(olc.FullName) && olc.FullName.Equals(entry.Title.Text, StringComparison.InvariantCultureIgnoreCase))
                            {
                                match.AddGoogleContact(entry);
                                continue;
                            }

                            //1.1 try to match by file as
                            if (!string.IsNullOrEmpty(olc.FileAs) && olc.FileAs.Equals(entry.Title.Text, StringComparison.InvariantCultureIgnoreCase))
                            {
                                match.AddGoogleContact(entry);
                                continue;
                            }

                            //2. try to match by emails
                            if (FindEmail(olc.Email1Address, entry.Emails) != null)
                            {
                                match.AddGoogleContact(entry);
                                continue;
                            }

                            if (FindEmail(olc.Email2Address, entry.Emails) != null)
                            {
                                match.AddGoogleContact(entry);
                                continue;
                            }

                            if (FindEmail(olc.Email3Address, entry.Emails) != null)
                            {
                                match.AddGoogleContact(entry);
                                continue;
                            }

                            #region Phone numbers
                            //3. try to match by phone numbers
                            if (FindPhone(olc.MobileTelephoneNumber, entry.Phonenumbers) != null)
                            {
                                match.AddGoogleContact(entry);
                                continue;
                            }

                            //don't match by home or business bumbers, because several people may share the saem home or business number
                            continue;

                            //if (FindPhone(olc.PrimaryTelephoneNumber, entry.Phonenumbers) != null)
                            //{
                            //    match.AddGoogleContact(entry);
                            //    continue;
                            //}


                            if (FindPhone(olc.HomeTelephoneNumber, entry.Phonenumbers) != null)
                            {
                                match.AddGoogleContact(entry);
                                continue;
                            }

                            if (FindPhone(olc.BusinessTelephoneNumber, entry.Phonenumbers) != null)
                            {
                                match.AddGoogleContact(entry);
                                continue;
                            }

                            if (FindPhone(olc.BusinessFaxNumber, entry.Phonenumbers) != null)
                            {
                                match.AddGoogleContact(entry);
                                //continue;
                            }

                            if (FindPhone(olc.HomeFaxNumber, entry.Phonenumbers) != null)
                            {
                                match.AddGoogleContact(entry);
                                //continue;
                            }

                            if (FindPhone(olc.PagerNumber, entry.Phonenumbers) != null)
                            {
                                match.AddGoogleContact(entry);
                                //continue;
                            }

                            if (FindPhone(olc.RadioTelephoneNumber, entry.Phonenumbers) != null)
                            {
                                match.AddGoogleContact(entry);
                                //continue;
                            }

                            if (FindPhone(olc.OtherTelephoneNumber, entry.Phonenumbers) != null)
                            {
                                match.AddGoogleContact(entry);
                                //continue;
                            }

                            if (FindPhone(olc.CarTelephoneNumber, entry.Phonenumbers) != null)
                            {
                                match.AddGoogleContact(entry);
                                //continue;
                            }

                            if (FindPhone(olc.Business2TelephoneNumber, entry.Phonenumbers) != null)
                            {
                                match.AddGoogleContact(entry);
                                //continue;
                            }
                            #endregion
                        }
                        #endregion
                    }

                    //check if a match was found.
                    if (match.AllGoogleContactMatches.Count > 0)
                    {
                        googleContactsMatched += match.AllGoogleContactMatches.Count;

                        //remove google contact from the list so it's not matched twice.
                        foreach (ContactEntry contact in match.AllGoogleContactMatches)
                        {
                            sync.GoogleContacts.Remove(contact);
                        }
                    }
                    else
                    {
                        if (sync.Logger != null)
                        {
                            sync.Logger.Log(string.Format("No match found for outlook contact ({0})", olc.FileAs), EventType.Information);
                        }
                    }

                    result.Add(match);
                }
                else
                {
                    // no telephone and email
                    if (sync.Logger != null)
                    {
                        sync.Logger.Log(string.Format("Skipping outlook contact ({0})", olc.FileAs), EventType.Warning);
                    }
                }
            }

            if (listingDuplicates)
            {
                throw new DuplicateDataException(duplicatesList);
            }

            //return result;

            if (sync.SyncOption != SyncOption.OutlookToGoogleOnly)
            {
                //for each google contact that's left (they will be nonmatched) create a new match pair without outlook contact.
                foreach (ContactEntry entry in sync.GoogleContacts)
                {
                    // only match if there is either an email or telephone or else
                    // a matching google contact will be created at each sync
                    if (entry.Emails.Count != 0 || entry.Phonenumbers.Count != 0)
                    {
                        ContactMatch match = new ContactMatch(null, entry);;
                        result.Add(match);
                    }
                    else
                    {
                        // no telephone and email
                    }
                }
            }
            return(result);
        }
コード例 #6
0
        public void SaveContact(ContactMatch match)
        {
            if (match.GoogleContact != null && match.OutlookContact != null)
            {
                //bool googleChanged, outlookChanged;
                //SaveContactGroups(match, out googleChanged, out outlookChanged);

                if (match.GoogleContact.IsDirty() || !match.OutlookContact.Saved)
                {
                    _syncedCount++;
                }

                if (match.GoogleContact.IsDirty())// || googleChanged)
                {
                    //google contact was modified. save.
                    SaveGoogleContact(match);
                    if (Logger != null)
                    {
                        Logger.Log("Saved Google contact: \"" + match.GoogleContact.Title.Text + "\"", EventType.Information);
                    }
                }

                if (!match.OutlookContact.Saved)// || outlookChanged)
                {
                    match.OutlookContact.Save();
                    ContactPropertiesUtils.SetGoogleOutlookContactId(SyncProfile, match.GoogleContact, match.OutlookContact);

                    ContactEntry updatedEntry = match.GoogleContact.Update() as ContactEntry;
                    match.GoogleContact = updatedEntry;

                    ContactPropertiesUtils.SetOutlookGoogleContactId(this, match.OutlookContact, match.GoogleContact);
                    match.OutlookContact.Save();
                    if (Logger != null)
                    {
                        Logger.Log("Saved Outlook contact: \"" + match.OutlookContact.FileAs + "\"", EventType.Information);
                    }

                    //TODO: this will cause the google contact to be updated on next run because Outlook's contact will be marked as saved later that Google's contact.
                }

                // save photos
                SaveContactPhotos(match);
            }
            else if (match.GoogleContact == null && match.OutlookContact != null)
            {
                if (ContactPropertiesUtils.GetOutlookGoogleContactId(this, match.OutlookContact) != null && _syncDelete)
                {
                    _deletedCount++;
                    string name = match.OutlookContact.FileAs;
                    // peer google contact was deleted, delete outlook contact
                    match.OutlookContact.Delete();
                    if (Logger != null)
                    {
                        Logger.Log("Deleted Outlook contact: \"" + name + "\"", EventType.Information);
                    }
                }
            }
            else if (match.GoogleContact != null && match.OutlookContact == null)
            {
                if (ContactPropertiesUtils.GetGoogleOutlookContactId(SyncProfile, match.GoogleContact) != null && _syncDelete)
                {
                    _deletedCount++;
                    // peer outlook contact was deleted, delete google contact
                    match.GoogleContact.Delete();
                    if (Logger != null)
                    {
                        Logger.Log("Deleted Google contact: \"" + match.GoogleContact.Title.Text + "\"", EventType.Information);
                    }
                }
            }
            else
            {
                //TODO: ignore for now: throw new ArgumentNullException("To save contacts both ContactMatch peers must be present.");
                if (Logger != null)
                {
                    Logger.Log("Both Google and Outlook contact: \"" + match.GoogleContact.Title.Text + "\" have been changed! Not implemented yet.", EventType.Warning);
                }
            }
        }