private void processContactResult(SyncRequestEvent event, int itemId, Stats stats)
     throws ServiceException {
   Contact contact = pushedContacts.get(itemId);
   if (event.isAddContact()) {
     SuccessResult result = (SuccessResult) event.getResult();
     contact.setId(result.getContactId());
     updateContactMapping(itemId, contact);
     stats.added++;
   } else if (event.isUpdateContact()) {
     updateContactMapping(itemId, contact);
     stats.updated++;
   } else if (event.isRemoveContact()) {
     deleteContact(itemId, stats);
   }
 }
 private SyncRequestEvent getContactEvent(Change change) throws ServiceException {
   int itemId = change.getItemId();
   if (change.isAdd() || change.isUpdate()) {
     com.zimbra.cs.mailbox.Contact zcontact = localData.getContact(itemId);
     if (ContactGroup.isContactGroup(zcontact)) {
       // Delete mapping so contact group will no longer be sync'd
       localData.deleteMapping(itemId);
     } else {
       ContactData cd = new ContactData(zcontact);
       if (change.isAdd()) {
         Contact contact = cd.getContact();
         pushedContacts.put(itemId, contact);
         return SyncRequestEvent.addContact(contact);
       } else {
         // LOG.debug("count = " + cd.getCategories().size());
         Contact newContact = cd.getContact();
         Contact oldContact = getContact(localData.getMapping(itemId));
         // LOG.debug("oldContact: " + oldContact);
         // LOG.debug("newContact: " + newContact);
         newContact.setId(oldContact.getId());
         // Add categories so we can track updates
         for (Category category : oldContact.getCategories()) {
           newContact.addCategory(category);
         }
         pushedContacts.put(itemId, newContact);
         ContactChange cc = cd.getContactChange(oldContact);
         return cc.isEmpty() ? null : SyncRequestEvent.updateContact(cc);
       }
     }
   } else if (change.isDelete()) {
     DataSourceItem dsi = localData.getMapping(itemId);
     RemoteId rid = RemoteId.parse(dsi.remoteId);
     if (rid.isContact()) {
       pushedContacts.put(itemId, new Contact(rid.getId()));
       return SyncRequestEvent.removeContact(rid.getId());
     } else {
       // Remove mapping for deleted contact group
       localData.deleteMapping(rid.getId());
     }
   }
   return null;
 }