/**
  * Build an {@link RawContactDelta} using the given {@link RawContact} as a starting point; the
  * "before" snapshot.
  */
 public static RawContactDelta fromBefore(RawContact before) {
   final RawContactDelta rawContactDelta = new RawContactDelta();
   rawContactDelta.mValues = ValuesDelta.fromBefore(before.getValues());
   rawContactDelta.mValues.setIdColumn(RawContacts._ID);
   for (final ContentValues values : before.getContentValues()) {
     rawContactDelta.addEntry(ValuesDelta.fromBefore(values));
   }
   return rawContactDelta;
 }
  /**
   * Merge the "after" values from the given {@link RawContactDelta} onto the "before" state
   * represented by this {@link RawContactDelta}, discarding any existing "after" states. This is
   * typically used when re-parenting changes onto an updated {@link Entity}.
   */
  public static RawContactDelta mergeAfter(RawContactDelta local, RawContactDelta remote) {
    // Bail early if trying to merge delete with missing local
    final ValuesDelta remoteValues = remote.mValues;
    if (local == null && (remoteValues.isDelete() || remoteValues.isTransient())) return null;

    // Create local version if none exists yet
    if (local == null) local = new RawContactDelta();

    if (LOGV) {
      final Long localVersion =
          (local.mValues == null) ? null : local.mValues.getAsLong(RawContacts.VERSION);
      final Long remoteVersion = remote.mValues.getAsLong(RawContacts.VERSION);
      Log.d(TAG, "Re-parenting from original version " + remoteVersion + " to " + localVersion);
    }

    // Create values if needed, and merge "after" changes
    local.mValues = ValuesDelta.mergeAfter(local.mValues, remote.mValues);

    // Find matching local entry for each remote values, or create
    for (ArrayList<ValuesDelta> mimeEntries : remote.mEntries.values()) {
      for (ValuesDelta remoteEntry : mimeEntries) {
        final Long childId = remoteEntry.getId();

        // Find or create local match and merge
        final ValuesDelta localEntry = local.getEntry(childId);
        final ValuesDelta merged = ValuesDelta.mergeAfter(localEntry, remoteEntry);

        if (localEntry == null && merged != null) {
          // No local entry before, so insert
          local.addEntry(merged);
        }
      }
    }

    return local;
  }