/**
  * Deletes a contact from the platform contacts provider.
  *
  * @param context the Authenticator Activity context
  * @param rawContactId the unique Id for this rawContact in contacts provider
  */
 private static void deleteContact(
     Context context, long rawContactId, BatchOperation batchOperation) {
   batchOperation.add(
       ContactOperations.newDeleteCpo(
               ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId), true)
           .build());
 }
  /**
   * Add a list of status messages to the contacts provider.
   *
   * @param context the context to use
   * @param accountName the username of the logged in user
   * @param statuses the list of statuses to store
   */
  public static void insertStatuses(Context context, String username, List<User.Status> list) {
    final ContentValues values = new ContentValues();
    final ContentResolver resolver = context.getContentResolver();

    final ArrayList<String> processedUsers = new ArrayList<String>();

    final BatchOperation batchOperation = new BatchOperation(context, resolver);
    for (final User.Status status : list) {
      // Look up the user's sample SyncAdapter data row
      final String userName = status.getUserName();

      if (!processedUsers.contains(userName)) {
        final long profileId = lookupProfile(resolver, userName);

        // Insert the activity into the stream
        if (profileId > 0) {
          values.put(StatusUpdates.DATA_ID, profileId);
          values.put(StatusUpdates.STATUS, status.getStatus());
          values.put(StatusUpdates.PROTOCOL, Im.PROTOCOL_CUSTOM);
          values.put(StatusUpdates.CUSTOM_PROTOCOL, CUSTOM_IM_PROTOCOL);
          values.put(StatusUpdates.IM_ACCOUNT, username);
          values.put(StatusUpdates.IM_HANDLE, status.getUserName());
          values.put(StatusUpdates.STATUS_TIMESTAMP, status.getTimeStamp().getTime());
          values.put(StatusUpdates.STATUS_RES_PACKAGE, context.getPackageName());
          values.put(StatusUpdates.STATUS_ICON, R.drawable.ic_main);
          values.put(StatusUpdates.STATUS_LABEL, R.string.label);

          batchOperation.add(
              ContactOperations.newInsertCpo(StatusUpdates.CONTENT_URI, true)
                  .withValues(values)
                  .build());
          // A sync adapter should batch operations on multiple contacts,
          // because it will make a dramatic performance difference.
          if (batchOperation.size() >= 50) {
            batchOperation.execute();
          }
        }

        processedUsers.add(userName);
      }
    }
    batchOperation.execute();
  }
  /**
   * Add a list of status messages to the contacts provider.
   *
   * @param context the context to use
   * @param accountName the username of the logged in user
   * @param statuses the list of statuses to store
   */
  @TargetApi(15)
  public static void insertStreamStatuses(Context context, String username) {
    final ContentValues values = new ContentValues();
    final ContentResolver resolver = context.getContentResolver();
    final BatchOperation batchOperation = new BatchOperation(context, resolver);
    List<Long> currentContacts = lookupAllContacts(resolver);

    for (long id : currentContacts) {

      String friendUsername = lookupUsername(resolver, id);
      long watermark = lookupHighWatermark(resolver, id);
      long newWatermark = watermark;

      try {
        List<Status> statuses = DeliciousFeed.fetchFriendStatuses(friendUsername);

        for (Status status : statuses) {

          if (status.getTimeStamp().getTime() > watermark) {

            if (status.getTimeStamp().getTime() > newWatermark)
              newWatermark = status.getTimeStamp().getTime();

            values.clear();
            values.put(StreamItems.RAW_CONTACT_ID, id);
            values.put(StreamItems.TEXT, status.getStatus());
            values.put(StreamItems.TIMESTAMP, status.getTimeStamp().getTime());
            values.put(StreamItems.ACCOUNT_NAME, username);
            values.put(StreamItems.ACCOUNT_TYPE, Constants.ACCOUNT_TYPE);
            values.put(StreamItems.RES_ICON, R.drawable.ic_main);
            values.put(StreamItems.RES_PACKAGE, context.getPackageName());
            values.put(StreamItems.RES_LABEL, R.string.label);

            batchOperation.add(
                ContactOperations.newInsertCpo(StreamItems.CONTENT_URI, false)
                    .withValues(values)
                    .build());
            // A sync adapter should batch operations on multiple contacts,
            // because it will make a dramatic performance difference.
            if (batchOperation.size() >= 50) {
              batchOperation.execute();
            }
          }
        }

        values.clear();
        values.put(RawContacts.SYNC1, Long.toString(newWatermark));
        batchOperation.add(
            ContactOperations.newUpdateCpo(RawContacts.CONTENT_URI, false)
                .withValues(values)
                .withSelection(RawContacts._ID + "=?", new String[] {Long.toString(id)})
                .build());

        batchOperation.execute();

      } catch (AuthenticationException e) {
        e.printStackTrace();
      } catch (JSONException e) {
        e.printStackTrace();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }