// Delete clicked: Delete selected contact private void button_deleteContact_Click(object sender, RoutedEventArgs e) { // Check that non-empty row has been selected if (dataGrid_contacts.SelectedItem != null && dataGrid_contacts.SelectedItem is ContactEntry) { // Prompt for confirmation before deleting MessageBoxResult deleteConfirm = MessageBox.Show ("Are you sure you want to delete the contact?", "Confirm deletion", MessageBoxButton.YesNo); if (deleteConfirm == MessageBoxResult.Yes) { // Get the contact ID from the selected row data // and delete the contact ContactEntry contact = new ContactEntry(); contact = (ContactEntry)dataGrid_contacts.SelectedItem; ContactService.DeleteContact(contact.Id); } } }
public void ContactDeleteExternalID() { string id = null; string dn = Guid.NewGuid().ToString(); ContactEntry e = new ContactEntry { BillingInformation = "test", Birthday = "2001-01-01", DirectoryServer = "test", Initials = "test", Location = "test", MaidenName = "test", Mileage = "test", Nickname = "test", Occupation = "test", Sensitivity = "normal", ShortName = "test", Subject = "test", }; e.ExternalIds.Add(new ExternalId() { Label = "work", Value = "test" }); e.Organizations.Add(new Organization() { Rel = "http://schemas.google.com/g/2005#work", Name = "test", Title = "test", Department = "test", Symbol = "test", JobDescription = "test", Location = "test", }); e.Phonenumbers.Add(new PhoneNumber() { Primary = true, Rel = "http://schemas.google.com/g/2005#home", Value = "test" }); e.ExtendedProperties.Add(new ExtendedProperty(dn, ApiInterfaceContact.DNAttributeName)); e = UnitTestControl.TestParameters.ContactsService.Add(e, UnitTestControl.TestParameters.Domain); id = e.SelfUri.Content; CSEntryChange cs = CSEntryChange.Create(); cs.ObjectModificationType = ObjectModificationType.Update; cs.DN = Guid.NewGuid().ToString(); cs.ObjectType = SchemaConstants.Contact; cs.AnchorAttributes.Add(AnchorAttribute.Create("id", id)); cs.AttributeChanges.Add(AttributeChange.CreateAttributeDelete("externalIds_work")); try { CSEntryChangeResult result = ExportProcessor.PutCSEntryChange(cs, UnitTestControl.Schema.GetSchema().Types[SchemaConstants.Contact], UnitTestControl.TestParameters); if (result.ErrorCode != MAExportError.Success) { Assert.Fail(result.ErrorName); } System.Threading.Thread.Sleep(5000); e = UnitTestControl.TestParameters.ContactsService.GetContact(id); Assert.AreEqual(0, e.ExternalIds.Count); } finally { if (id != null) { UnitTestControl.TestParameters.ContactsService.Delete(id); } } }
public void ContactUpdate() { string id = null; string dn = Guid.NewGuid().ToString(); ContactEntry e = new ContactEntry { BillingInformation = "test", Birthday = "2001-01-01", DirectoryServer = "test", Initials = "test", Location = "test", MaidenName = "test", Mileage = "test", Nickname = "test", Occupation = "test", Sensitivity = "normal", ShortName = "test", Subject = "test", }; e.ExternalIds.Add(new ExternalId() { Label = "work", Value = "test" }); e.Organizations.Add(new Organization() { Rel = "http://schemas.google.com/g/2005#work", Name = "test", Title = "test", Department = "test", Symbol = "test", JobDescription = "test", Location = "test", }); e.Phonenumbers.Add(new PhoneNumber() { Primary = true, Rel = "http://schemas.google.com/g/2005#home", Value = "test" }); e.ExtendedProperties.Add(new ExtendedProperty(dn, ApiInterfaceContact.DNAttributeName)); e = UnitTestControl.TestParameters.ContactsService.Add(e, UnitTestControl.TestParameters.Domain); id = e.SelfUri.Content; CSEntryChange cs = CSEntryChange.Create(); cs.ObjectModificationType = ObjectModificationType.Update; cs.DN = Guid.NewGuid().ToString(); cs.ObjectType = SchemaConstants.Contact; cs.AnchorAttributes.Add(AnchorAttribute.Create("id", id)); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("billingInformation", "billingInformation")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("birthday", "2000-01-01")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("directoryServer", "directoryServer")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("initials", "initials")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("location", "location")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("maidenName", "maidenName")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("mileage", "mileage")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("nickname", "nickname")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("occupation", "occupation")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("sensitivity", "private")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("shortName", "shortName")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("subject", "subject")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("externalIds_work", "eidwork")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("externalIds_home", "eidhome")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("organizations_work_name", "name")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("organizations_work_title", "title")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("organizations_work_department", "department")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("organizations_work_symbol", "symbol")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("organizations_work_jobDescription", "jobDescription")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("organizations_work_location", "location")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("phones_work", "phwork")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("phones_home", "phhome")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("email_work", "*****@*****.**")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("email_home", "*****@*****.**")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("ims_work_address", "*****@*****.**")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("ims_work_protocol", "proto")); try { CSEntryChangeResult result = ExportProcessor.PutCSEntryChange(cs, UnitTestControl.Schema.GetSchema().Types[SchemaConstants.Contact], UnitTestControl.TestParameters); if (result.ErrorCode != MAExportError.Success) { Assert.Fail(result.ErrorName); } System.Threading.Thread.Sleep(5000); e = UnitTestControl.TestParameters.ContactsService.GetContact(id); Assert.AreEqual("billingInformation", e.BillingInformation); Assert.AreEqual("2000-01-01", e.Birthday); Assert.AreEqual("directoryServer", e.DirectoryServer); Assert.AreEqual("initials", e.Initials); Assert.AreEqual("location", e.Location); Assert.AreEqual("maidenName", e.MaidenName); Assert.AreEqual("mileage", e.Mileage); Assert.AreEqual("nickname", e.Nickname); Assert.AreEqual("occupation", e.Occupation); Assert.AreEqual("private", e.Sensitivity); Assert.AreEqual("shortName", e.ShortName); Assert.AreEqual("subject", e.Subject); Assert.AreEqual(2, e.ExternalIds.Count); Assert.AreEqual("eidwork", e.ExternalIds[0].Value); Assert.AreEqual("eidhome", e.ExternalIds[1].Value); Assert.AreEqual(1, e.Organizations.Count); Assert.AreEqual("name", e.Organizations[0].Name); Assert.AreEqual("title", e.Organizations[0].Title); Assert.AreEqual("department", e.Organizations[0].Department); Assert.AreEqual("symbol", e.Organizations[0].Symbol); Assert.AreEqual("jobDescription", e.Organizations[0].JobDescription); Assert.AreEqual("location", e.Organizations[0].Location); Assert.AreEqual(2, e.Phonenumbers.Count); Assert.AreEqual("phwork", e.Phonenumbers.First(t => t.Rel == "http://schemas.google.com/g/2005#work").Value); Assert.AreEqual(true, e.Phonenumbers.First(t => t.Rel == "http://schemas.google.com/g/2005#work").Primary); Assert.AreEqual("phhome", e.Phonenumbers.First(t => t.Rel == "http://schemas.google.com/g/2005#home").Value); Assert.AreEqual(2, e.Emails.Count); Assert.AreEqual("*****@*****.**", e.Emails[0].Address); Assert.AreEqual("*****@*****.**", e.Emails[1].Address); Assert.AreEqual("*****@*****.**", e.PrimaryEmail.Address); Assert.AreEqual(1, e.IMs.Count); Assert.AreEqual("*****@*****.**", e.IMs[0].Address); Assert.AreEqual("proto", e.IMs[0].Protocol); } finally { if (id != null) { UnitTestControl.TestParameters.ContactsService.Delete(id); } } }
public void ContactAdd() { CSEntryChange cs = CSEntryChange.Create(); cs.ObjectModificationType = ObjectModificationType.Add; cs.DN = Guid.NewGuid().ToString(); cs.ObjectType = SchemaConstants.Contact; cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("billingInformation", "billingInformation")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("birthday", "2000-01-01")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("directoryServer", "directoryServer")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("initials", "initials")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("location", "location")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("maidenName", "maidenName")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("mileage", "mileage")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("nickname", "nickname")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("occupation", "occupation")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("sensitivity", "private")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("shortName", "shortName")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("subject", "subject")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("externalIds_work", "eidwork")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("externalIds_home", "eidhome")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("organizations_work_name", "name")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("organizations_work_title", "title")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("organizations_work_department", "department")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("organizations_work_symbol", "symbol")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("organizations_work_jobDescription", "jobDescription")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("organizations_work_location", "location")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("phones_work", "phwork")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("phones_home", "phhome")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("email_work", "*****@*****.**")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("email_home", "*****@*****.**")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("ims_work_address", "*****@*****.**")); cs.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("ims_work_protocol", "proto")); string id = null; try { CSEntryChangeResult result = ExportProcessor.PutCSEntryChange(cs, UnitTestControl.Schema.GetSchema().Types[SchemaConstants.Contact], UnitTestControl.TestParameters); id = result.AnchorAttributes["id"].GetValueAdd <string>(); if (result.ErrorCode != MAExportError.Success) { Assert.Fail(result.ErrorName); } ContactEntry e = UnitTestControl.TestParameters.ContactsService.GetContact(id); Assert.AreEqual("billingInformation", e.BillingInformation); Assert.AreEqual("2000-01-01", e.Birthday); Assert.AreEqual("directoryServer", e.DirectoryServer); Assert.AreEqual("initials", e.Initials); Assert.AreEqual("location", e.Location); Assert.AreEqual("maidenName", e.MaidenName); Assert.AreEqual("mileage", e.Mileage); Assert.AreEqual("nickname", e.Nickname); Assert.AreEqual("occupation", e.Occupation); Assert.AreEqual("private", e.Sensitivity); Assert.AreEqual("shortName", e.ShortName); Assert.AreEqual("subject", e.Subject); Assert.AreEqual(2, e.ExternalIds.Count); Assert.AreEqual("eidwork", e.ExternalIds[0].Value); Assert.AreEqual("eidhome", e.ExternalIds[1].Value); Assert.AreEqual(1, e.Organizations.Count); Assert.AreEqual("name", e.Organizations[0].Name); Assert.AreEqual("title", e.Organizations[0].Title); Assert.AreEqual("department", e.Organizations[0].Department); Assert.AreEqual("symbol", e.Organizations[0].Symbol); Assert.AreEqual("jobDescription", e.Organizations[0].JobDescription); Assert.AreEqual("location", e.Organizations[0].Location); Assert.AreEqual(2, e.Phonenumbers.Count); Assert.AreEqual("phwork", e.Phonenumbers[0].Value); Assert.AreEqual("phhome", e.Phonenumbers[1].Value); Assert.AreEqual(2, e.Emails.Count); Assert.AreEqual("*****@*****.**", e.Emails[0].Address); Assert.AreEqual("*****@*****.**", e.Emails[1].Address); Assert.AreEqual("*****@*****.**", e.PrimaryEmail.Address); Assert.AreEqual(1, e.IMs.Count); Assert.AreEqual("*****@*****.**", e.IMs[0].Address); Assert.AreEqual("proto", e.IMs[0].Protocol); } finally { if (id != null) { UnitTestControl.TestParameters.ContactsService.Delete(id); } } }
// Edit clicked: Open EditContactWindow, // and display the selected contact private void button_editContact_Click(object sender, RoutedEventArgs e) { // Check that non-empty row has been selected if (dataGrid_contacts.SelectedItem != null && dataGrid_contacts.SelectedItem is ContactEntry) { // Create edit contact window EditContactWindow editContactWindow = new EditContactWindow(); editContactWindow.Title = "Edit Contact"; editContactWindow.Owner = this; editContactWindow.Show(); // Get row data and display it in edit window ContactEntry contact = new ContactEntry(); contact = (ContactEntry)dataGrid_contacts.SelectedItem; editContactWindow.DisplayContactEntry(contact); } }
///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// /// <summary>creates a new, in memory atom entry</summary> /// <returns>the new AtomEntry </returns> ////////////////////////////////////////////////////////////////////// public static ContactEntry CreateContactEntry(int iCount) { ContactEntry entry = new ContactEntry(); // some unicode chars Char[] chars = new Char[] { '\u0023', // # '\u0025', // % '\u03a0', // Pi '\u03a3', // Sigma '\u03d1', // beta }; // if unicode needs to be disabled for testing, just uncomment this line // chars = new Char[] { 'a', 'b', 'c', 'd', 'e'}; AtomPerson author = new AtomPerson(AtomPersonType.Author); author.Name = "John Doe" + chars[0] + chars[1] + chars[2] + chars[3]; author.Email = "*****@*****.**"; entry.Authors.Add(author); entry.Content.Content = "this is the default note for a contact entry"; entry.Published = new DateTime(2001, 11, 20, 22, 30, 0); entry.Title.Text = "This is a contact number: " + iCount; entry.Updated = DateTime.Now; // add an email. EMail email = new EMail("*****@*****.**" + Guid.NewGuid().ToString()); email.Primary = true; email.Rel = ContactsRelationships.IsWork; entry.Emails.Add(email); email = new EMail("*****@*****.**" + Guid.NewGuid().ToString()); email.Label = "some email"; entry.Emails.Add(email); IMAddress im = new IMAddress("*****@*****.**"); im.Primary = true; im.Rel = ContactsRelationships.IsWork; entry.IMs.Add(im); im = new IMAddress("*****@*****.**"); im.Rel = ContactsRelationships.IsHome; PhoneNumber p = new PhoneNumber("123-3453457"); p.Primary = true; p.Rel = ContactsRelationships.IsWork; entry.Phonenumbers.Add(p); p = new PhoneNumber("123-3334445"); p.Label = "some other thing"; entry.Phonenumbers.Add(p); StructuredPostalAddress pa = ContactsTestSuite.CreatePostalAddress(); pa.Rel = ContactsRelationships.IsHome; entry.PostalAddresses.Add(pa); Organization org = new Organization(); org.Name = "This Test Org.Com"; org.Title = "Junior guy"; org.Label = "volunteer stuff"; entry.Organizations.Add(org); return(entry); }
public void ConflictContactsTest() { const int numberOfInserts = 50; const int numberWithAdds = 60; Tracing.TraceMsg("Entering InsertContactsTest"); ContactsQuery query = new ContactsQuery(ContactsQuery.CreateContactsUri(this.userName)); ContactsService service = new ContactsService("unittests"); if (this.userName != null) { service.Credentials = new GDataCredentials(this.userName, this.passWord); } // clean the contacts feed DeleteAllContacts(); ContactsFeed feed = service.Query(query); int originalCount = feed.Entries.Count; string email = Guid.NewGuid().ToString(); List <ContactEntry> inserted = new List <ContactEntry>(); // insert a number of guys for (int i = 0; i < numberOfInserts; i++) { ContactEntry entry = ObjectModelHelper.CreateContactEntry(i); entry.PrimaryEmail.Address = email + i.ToString() + "@doe.com"; entry = feed.Insert(entry); AddContactPhoto(entry, service); inserted.Add(entry); } if (feed != null) { for (int x = numberOfInserts; x <= numberWithAdds; x++) { for (int i = 0; i < x; i++) { ContactEntry entry = ObjectModelHelper.CreateContactEntry(i); entry.PrimaryEmail.Address = email + i.ToString() + "@doe.com"; try { entry = feed.Insert(entry); AddContactPhoto(entry, service); inserted.Add(entry); } catch (GDataRequestException) { } } } } List <ContactEntry> list = new List <ContactEntry>(); feed = service.Query(query); foreach (ContactEntry e in feed.Entries) { list.Add(e); } while (feed.NextChunk != null) { ContactsQuery nq = new ContactsQuery(feed.NextChunk); feed = service.Query(nq); foreach (ContactEntry e in feed.Entries) { list.Add(e); } } Assert.AreEqual(list.Count, numberWithAdds - originalCount, "We should have added new entries"); // clean the contacts feed DeleteAllContacts(); }
///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////// /// <summary>runs an basic auth test against the groups feed test</summary> ////////////////////////////////////////////////////////////////////// [Test] public void GroupsAuthenticationTest() { Tracing.TraceMsg("Entering GroupsAuthenticationTest"); GroupsQuery query = new GroupsQuery(ContactsQuery.CreateGroupsUri(this.userName + "@googlemail.com")); ContactsService service = new ContactsService("unittests"); if (this.userName != null) { service.Credentials = new GDataCredentials(this.userName, this.passWord); } GroupsFeed feed = service.Query(query); ObjectModelHelper.DumpAtomObject(feed, CreateDumpFileName("GroupsAuthTest")); GroupEntry newGroup = new GroupEntry(); newGroup.Title.Text = "Private Data"; GroupEntry insertedGroup = feed.Insert(newGroup); GroupEntry g2 = new GroupEntry(); g2.Title.Text = "Another Private Group"; GroupEntry insertedGroup2 = feed.Insert(g2); // now insert a new contact that belongs to that group ContactsQuery q = new ContactsQuery(ContactsQuery.CreateContactsUri(this.userName + "@googlemail.com")); ContactsFeed cf = service.Query(q); ContactEntry entry = ObjectModelHelper.CreateContactEntry(1); GroupMembership member = new GroupMembership(); member.HRef = insertedGroup.Id.Uri.ToString(); GroupMembership member2 = new GroupMembership(); member2.HRef = insertedGroup2.Id.Uri.ToString(); ContactEntry insertedEntry = cf.Insert(entry); // now change the group membership insertedEntry.GroupMembership.Add(member); insertedEntry.GroupMembership.Add(member2); ContactEntry currentEntry = insertedEntry.Update(); Assert.IsTrue(currentEntry.GroupMembership.Count == 2, "The entry should be in 2 groups"); currentEntry.GroupMembership.Clear(); currentEntry = currentEntry.Update(); // now we should have 2 new groups and one new entry with no groups anymore int oldCountGroups = feed.Entries.Count; int oldCountContacts = cf.Entries.Count; currentEntry.Delete(); insertedGroup.Delete(); insertedGroup2.Delete(); feed = service.Query(query); cf = service.Query(q); Assert.AreEqual(oldCountContacts, cf.Entries.Count, "Contacts count should be the same"); Assert.AreEqual(oldCountGroups, feed.Entries.Count, "Groups count should be the same"); }
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."); } }
public ContactMatch(Outlook.ContactItem outlookContact, ContactEntry googleContact) { OutlookContact = outlookContact; GoogleContact = googleContact; }
/// <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); }
public static void MergeContacts(ContactEntry master, Outlook.ContactItem slave) { //// if no email or number, contact will be updated at each sync //if (master.Emails.Count == 0 && master.Phonenumbers.Count == 0) // return; if (!string.IsNullOrEmpty(master.Title.Text)) { slave.FileAs = master.Title.Text; slave.FullName = master.Title.Text; } else { slave.FileAs = master.Emails[0].Address; } SetEmails(master, slave); foreach (PhoneNumber phone in master.Phonenumbers) { SetPhoneNumber(phone, slave); } foreach (PostalAddress address in master.PostalAddresses) { SetPostalAddress(address, slave); } slave.Companies = string.Empty; foreach (Organization company in master.Organizations) { if (string.IsNullOrEmpty(company.Title)) { continue; } if (company.Primary) { slave.CompanyName = company.Title; } if (!string.IsNullOrEmpty(slave.Companies)) { slave.Companies += "; "; } slave.Companies += company.Title; } slave.IMAddress = ""; foreach (IMAddress im in master.IMs) { if (!string.IsNullOrEmpty(slave.IMAddress)) { slave.IMAddress += "; "; } if (!string.IsNullOrEmpty(im.Protocol)) { slave.IMAddress += im.Protocol + ": " + im.Address; } slave.IMAddress += im.Address; } slave.Body = master.Content.Content; }
public static void SetPhoneNumbers(Outlook.ContactItem source, ContactEntry destination) { if (!string.IsNullOrEmpty(source.PrimaryTelephoneNumber)) { PhoneNumber phoneNumber = new PhoneNumber(source.PrimaryTelephoneNumber); phoneNumber.Primary = destination.Phonenumbers.Count == 0; phoneNumber.Rel = ContactsRelationships.IsMobile; destination.Phonenumbers.Add(phoneNumber); } if (!string.IsNullOrEmpty(source.MobileTelephoneNumber)) { PhoneNumber phoneNumber = new PhoneNumber(source.MobileTelephoneNumber); phoneNumber.Primary = destination.Phonenumbers.Count == 0; phoneNumber.Rel = ContactsRelationships.IsMobile; destination.Phonenumbers.Add(phoneNumber); } if (!string.IsNullOrEmpty(source.HomeTelephoneNumber)) { PhoneNumber phoneNumber = new PhoneNumber(source.HomeTelephoneNumber); phoneNumber.Primary = destination.Phonenumbers.Count == 0; phoneNumber.Rel = ContactsRelationships.IsHome; destination.Phonenumbers.Add(phoneNumber); } if (!string.IsNullOrEmpty(source.BusinessTelephoneNumber)) { PhoneNumber phoneNumber = new PhoneNumber(source.BusinessTelephoneNumber); phoneNumber.Primary = destination.Phonenumbers.Count == 0; phoneNumber.Rel = ContactsRelationships.IsWork; destination.Phonenumbers.Add(phoneNumber); } if (!string.IsNullOrEmpty(source.Business2TelephoneNumber)) { PhoneNumber phoneNumber = new PhoneNumber(source.Business2TelephoneNumber); phoneNumber.Primary = destination.Phonenumbers.Count == 0; phoneNumber.Rel = ContactsRelationships.IsWork; destination.Phonenumbers.Add(phoneNumber); } if (!string.IsNullOrEmpty(source.HomeFaxNumber)) { PhoneNumber phoneNumber = new PhoneNumber(source.HomeFaxNumber); phoneNumber.Primary = destination.Phonenumbers.Count == 0; phoneNumber.Rel = ContactsRelationships.IsHomeFax; destination.Phonenumbers.Add(phoneNumber); } if (!string.IsNullOrEmpty(source.BusinessFaxNumber)) { PhoneNumber phoneNumber = new PhoneNumber(source.BusinessFaxNumber); phoneNumber.Primary = destination.Phonenumbers.Count == 0; phoneNumber.Rel = ContactsRelationships.IsWorkFax; destination.Phonenumbers.Add(phoneNumber); } if (!string.IsNullOrEmpty(source.OtherTelephoneNumber)) { PhoneNumber phoneNumber = new PhoneNumber(source.OtherTelephoneNumber); phoneNumber.Primary = destination.Phonenumbers.Count == 0; phoneNumber.Rel = ContactsRelationships.IsOther; destination.Phonenumbers.Add(phoneNumber); } if (!string.IsNullOrEmpty(source.RadioTelephoneNumber)) { PhoneNumber phoneNumber = new PhoneNumber(source.RadioTelephoneNumber); phoneNumber.Primary = destination.Phonenumbers.Count == 0; phoneNumber.Rel = ContactsRelationships.IsMobile; destination.Phonenumbers.Add(phoneNumber); } if (!string.IsNullOrEmpty(source.PagerNumber)) { PhoneNumber phoneNumber = new PhoneNumber(source.PagerNumber); phoneNumber.Primary = destination.Phonenumbers.Count == 0; phoneNumber.Rel = ContactsRelationships.IsPager; destination.Phonenumbers.Add(phoneNumber); } if (!string.IsNullOrEmpty(source.CarTelephoneNumber)) { PhoneNumber phoneNumber = new PhoneNumber(source.CarTelephoneNumber); phoneNumber.Primary = destination.Phonenumbers.Count == 0; phoneNumber.Rel = ContactsRelationships.IsCar; destination.Phonenumbers.Add(phoneNumber); } }
public void CreateContactEntry(Contact contact) { ContactEntry contactEntry = new ContactEntry(); contactEntry.Name = new Name(); }
////////////////////////////////////////////////////////////////////// /// <summary>runs an authentication test, inserts a new contact</summary> ////////////////////////////////////////////////////////////////////// [Test] public void InsertContactsTest() { const int numberOfInserts = 37; Tracing.TraceMsg("Entering InsertContactsTest"); ContactsQuery query = new ContactsQuery(ContactsQuery.CreateContactsUri(this.userName)); ContactsService service = new ContactsService("unittests"); if (this.userName != null) { service.Credentials = new GDataCredentials(this.userName, this.passWord); } ContactsFeed feed = service.Query(query); int originalCount = feed.Entries.Count; PhoneNumber p = null; List <ContactEntry> inserted = new List <ContactEntry>(); if (feed != null) { Assert.IsTrue(feed.Entries != null, "the contacts needs entries"); for (int i = 0; i < numberOfInserts; i++) { ContactEntry entry = ObjectModelHelper.CreateContactEntry(i); entry.PrimaryEmail.Address = "joe" + i.ToString() + "@doe.com"; p = entry.PrimaryPhonenumber; inserted.Add(feed.Insert(entry)); } } List <ContactEntry> list = new List <ContactEntry>(); feed = service.Query(query); foreach (ContactEntry e in feed.Entries) { list.Add(e); } while (feed.NextChunk != null) { ContactsQuery nq = new ContactsQuery(feed.NextChunk); feed = service.Query(nq); foreach (ContactEntry e in feed.Entries) { list.Add(e); } } if (inserted.Count > 0) { int iVer = numberOfInserts; // let's find those guys for (int i = 0; i < inserted.Count; i++) { ContactEntry test = inserted[i] as ContactEntry; foreach (ContactEntry e in list) { if (e.Id == test.Id) { iVer--; // verify we got the phonenumber back.... Assert.IsTrue(e.PrimaryPhonenumber != null, "They should have a primary phonenumber"); Assert.AreEqual(e.PrimaryPhonenumber.Value, p.Value, "They should be identical"); } } } Assert.IsTrue(iVer == 0, "The new entries should all be part of the feed now, we have " + iVer + " now"); } // now delete them again foreach (ContactEntry e in inserted) { e.Delete(); } // now make sure they are gone if (inserted.Count > 0) { feed = service.Query(query); // let's find those guys, we should not find ANY for (int i = 0; i < inserted.Count; i++) { ContactEntry test = inserted[i] as ContactEntry; foreach (ContactEntry e in feed.Entries) { Assert.IsTrue(e.Id != test.Id, "The new entries should all be deleted now"); } } Assert.IsTrue(feed.Entries.Count == originalCount, "The count should be correct as well"); } }
public bool ValidateContactEntry(ContactEntry entry) { return(CheckStringValue(entry.Value)); }
public void TestPrimaryContactsProperties() { Tracing.TraceMsg("Entering TestPrimaryContactsProperties"); ContactEntry entry = new ContactEntry(); EMail e = new EMail(); e.Primary = true; e.Address = "*****@*****.**"; Assert.IsTrue(entry.PrimaryEmail == null, "Entry should have no primary Email"); entry.Emails.Add(e); Assert.IsTrue(entry.PrimaryEmail == e, "Entry should have one primary Email"); entry.Emails.Remove(e); Assert.IsTrue(entry.PrimaryEmail == null, "Entry should have no primary Email"); entry.Emails.Add(e); Assert.IsTrue(entry.PrimaryEmail == e, "Entry should have one primary Email"); entry.Emails.RemoveAt(0); Assert.IsTrue(entry.PrimaryEmail == null, "Entry should have no primary Email"); foreach (Object o in entry.ExtensionElements) { if (o is EMail) { Assert.IsTrue(o == null, "There should be no email in the collection"); } } StructuredPostalAddress p = CreatePostalAddress(); Assert.IsTrue(entry.PrimaryPostalAddress == null, "Entry should have no primary Postal"); entry.PostalAddresses.Add(p); Assert.IsTrue(entry.PrimaryPostalAddress == p, "Entry should have one primary Postal"); entry.PostalAddresses.Remove(p); Assert.IsTrue(entry.PrimaryPostalAddress == null, "Entry should have no primary Postal"); PhoneNumber n = new PhoneNumber("123345"); n.Primary = true; Assert.IsTrue(entry.PrimaryPhonenumber == null, "Entry should have no primary Phonenumber"); entry.Phonenumbers.Add(n); Assert.IsTrue(entry.PrimaryPhonenumber == n, "Entry should have one primary Phonenumber"); entry.Phonenumbers.Remove(n); Assert.IsTrue(entry.PrimaryPhonenumber == null, "Entry should have no primary Phonenumber"); IMAddress i = new IMAddress("*****@*****.**"); i.Primary = true; Assert.IsTrue(entry.PrimaryIMAddress == null, "Entry should have no primary IM"); entry.IMs.Add(new IMAddress()); entry.IMs.Add(i); Assert.IsTrue(entry.PrimaryIMAddress == i, "Entry should have one primary IMAddress"); entry.IMs.Remove(i); Assert.IsTrue(entry.PrimaryIMAddress == null, "Entry should have no primary IM"); }
// Method to add contract entry to the list // Input is the contact to add public static void AddContact(ContactEntry contact) { ContactList.Add(contact); }
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); } } }