@Override
 public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
   switch (requestCode) {
     case REQUEST_SELECT_USER:
       {
         if (resultCode != FragmentActivity.RESULT_OK || !data.hasExtra(EXTRA_USER)) return;
         final ParcelableUser user = data.getParcelableExtra(EXTRA_USER);
         final ContentValues values = ContentValuesCreator.createFilteredUser(user);
         final ContentResolver resolver = getContentResolver();
         resolver.delete(
             Filters.Users.CONTENT_URI,
             Expression.equals(Filters.Users.USER_ID, user.id).getSQL(),
             null);
         resolver.insert(Filters.Users.CONTENT_URI, values);
         break;
       }
   }
 }
  private void sendMessage(long accountId, long recipientId, String text, String imageUri) {
    if (accountId <= 0 || recipientId <= 0 || isEmpty(text)) return;
    final String title = getString(R.string.sending_direct_message);
    final Builder builder = new Builder(this);
    builder.setSmallIcon(R.drawable.ic_stat_send);
    builder.setProgress(100, 0, true);
    builder.setTicker(title);
    builder.setContentTitle(title);
    builder.setContentText(text);
    builder.setOngoing(true);
    final Notification notification = builder.build();
    startForeground(NOTIFICATION_ID_SEND_DIRECT_MESSAGE, notification);
    final SingleResponse<ParcelableDirectMessage> result =
        sendDirectMessage(builder, accountId, recipientId, text, imageUri);

    if (result.getData() != null && result.getData().id > 0) {
      final ContentValues values = ContentValuesCreator.createDirectMessage(result.getData());
      final String delete_where =
          DirectMessages.ACCOUNT_ID
              + " = "
              + accountId
              + " AND "
              + DirectMessages.MESSAGE_ID
              + " = "
              + result.getData().id;
      mResolver.delete(DirectMessages.Outbox.CONTENT_URI, delete_where, null);
      mResolver.insert(DirectMessages.Outbox.CONTENT_URI, values);
      showOkMessage(R.string.direct_message_sent, false);

    } else {
      final ContentValues values = createMessageDraft(accountId, recipientId, text, imageUri);
      mResolver.insert(Drafts.CONTENT_URI, values);
      showErrorMessage(R.string.action_sending_direct_message, result.getException(), true);
    }
    stopForeground(false);
    mNotificationManager.cancel(NOTIFICATION_ID_SEND_DIRECT_MESSAGE);
  }
  private void updateStatuses(ParcelableStatusUpdate... statuses) {
    final Builder builder = new Builder(this);
    startForeground(
        NOTIFICATION_ID_UPDATE_STATUS, updateUpdateStatusNotification(this, builder, 0, null));
    for (final ParcelableStatusUpdate item : statuses) {
      mNotificationManager.notify(
          NOTIFICATION_ID_UPDATE_STATUS, updateUpdateStatusNotification(this, builder, 0, item));
      final ContentValues draftValues =
          ContentValuesCreator.createStatusDraft(
              item, ParcelableAccount.getAccountIds(item.accounts));
      final Uri draftUri = mResolver.insert(Drafts.CONTENT_URI, draftValues);
      final long draftId = ParseUtils.parseLong(draftUri.getLastPathSegment(), -1);
      mTwitter.addSendingDraftId(draftId);
      final List<SingleResponse<ParcelableStatus>> result = updateStatus(builder, item);
      boolean failed = false;
      Exception exception = null;
      final Expression where = Expression.equals(Drafts._ID, draftId);
      final List<Long> failedAccountIds =
          ListUtils.fromArray(ParcelableAccount.getAccountIds(item.accounts));

      for (final SingleResponse<ParcelableStatus> response : result) {

        if (response.getData() == null) {
          failed = true;
          if (exception == null) {
            exception = response.getException();
          }
        } else if (response.getData().account_id > 0) {
          failedAccountIds.remove(response.getData().account_id);
          // spice
          if (response.getData().media == null) {
            SpiceProfilingUtil.log(
                response.getData().id
                    + ",Tweet,"
                    + response.getData().account_id
                    + ","
                    + response.getData().in_reply_to_user_id
                    + ","
                    + response.getData().in_reply_to_status_id);
            SpiceProfilingUtil.profile(
                this.getBaseContext(),
                response.getData().account_id,
                response.getData().id
                    + ",Tweet,"
                    + response.getData().account_id
                    + ","
                    + response.getData().in_reply_to_user_id
                    + ","
                    + response.getData().in_reply_to_status_id);
          } else
            for (final ParcelableMedia spiceMedia : response.getData().media) {
              SpiceProfilingUtil.log(
                  response.getData().id
                      + ",Media,"
                      + response.getData().account_id
                      + ","
                      + response.getData().in_reply_to_user_id
                      + ","
                      + response.getData().in_reply_to_status_id
                      + ","
                      + spiceMedia.media_url
                      + ","
                      + TypeMappingUtil.getMediaType(spiceMedia.type));
              SpiceProfilingUtil.profile(
                  this.getBaseContext(),
                  response.getData().account_id,
                  response.getData().id
                      + ",Media,"
                      + response.getData().account_id
                      + ","
                      + response.getData().in_reply_to_user_id
                      + ","
                      + response.getData().in_reply_to_status_id
                      + ","
                      + spiceMedia.media_url
                      + ","
                      + TypeMappingUtil.getMediaType(spiceMedia.type));
            }
          // end
        }
      }

      if (result.isEmpty()) {
        showErrorMessage(
            R.string.action_updating_status, getString(R.string.no_account_selected), false);
      } else if (failed) {
        // If the status is a duplicate, there's no need to save it to
        // drafts.
        if (exception instanceof TwitterException
            && ((TwitterException) exception).getErrorCode()
                == StatusCodeMessageUtils.STATUS_IS_DUPLICATE) {
          showErrorMessage(getString(R.string.status_is_duplicate), false);
        } else {
          final ContentValues accountIdsValues = new ContentValues();
          accountIdsValues.put(
              Drafts.ACCOUNT_IDS, ListUtils.toString(failedAccountIds, ',', false));
          mResolver.update(Drafts.CONTENT_URI, accountIdsValues, where.getSQL(), null);
          showErrorMessage(R.string.action_updating_status, exception, true);
          final ContentValues notifValues = new ContentValues();
          notifValues.put(BaseColumns._ID, draftId);
          mResolver.insert(Drafts.CONTENT_URI_NOTIFICATIONS, notifValues);
        }
      } else {
        showOkMessage(R.string.status_updated, false);
        mResolver.delete(Drafts.CONTENT_URI, where.getSQL(), null);
        if (item.media != null) {
          for (final ParcelableMediaUpdate media : item.media) {
            final String path = getImagePathFromUri(this, Uri.parse(media.uri));
            if (path != null) {
              if (!new File(path).delete()) {
                Log.d(LOGTAG, String.format("unable to delete %s", path));
              }
            }
          }
        }
      }
      mTwitter.removeSendingDraftId(draftId);
      if (mPreferences.getBoolean(KEY_REFRESH_AFTER_TWEET, false)) {
        mHandler.post(
            new Runnable() {
              @Override
              public void run() {
                mTwitter.refreshAll();
              }
            });
      }
    }
    stopForeground(false);
    mNotificationManager.cancel(NOTIFICATION_ID_UPDATE_STATUS);
  }
  private void storeStatus(
      long accountId,
      List<org.mariotaku.twidere.api.twitter.model.Status> statuses,
      long sinceId,
      long maxId,
      boolean notify,
      int loadItemLimit) {
    if (statuses == null || statuses.isEmpty() || accountId <= 0) {
      return;
    }
    final Uri uri = getDatabaseUri();
    final Context context = twitterWrapper.getContext();
    final ContentResolver resolver = context.getContentResolver();
    final boolean noItemsBefore = DataStoreUtils.getStatusCount(context, uri, accountId) <= 0;
    final ContentValues[] values = new ContentValues[statuses.size()];
    final long[] statusIds = new long[statuses.size()];
    long minId = -1;
    int minIdx = -1;
    boolean hasIntersection = false;
    for (int i = 0, j = statuses.size(); i < j; i++) {
      final org.mariotaku.twidere.api.twitter.model.Status status = statuses.get(i);
      values[i] = ContentValuesCreator.createStatus(status, accountId);
      values[i].put(Statuses.INSERTED_DATE, System.currentTimeMillis());
      final long id = status.getId();
      if (sinceId > 0 && id <= sinceId) {
        hasIntersection = true;
      }
      if (minId == -1 || id < minId) {
        minId = id;
        minIdx = i;
      }
      statusIds[i] = id;
    }
    // Delete all rows conflicting before new data inserted.
    final Expression accountWhere = Expression.equals(Statuses.ACCOUNT_ID, accountId);
    final Expression statusWhere =
        Expression.in(new Columns.Column(Statuses.STATUS_ID), new RawItemArray(statusIds));
    final String countWhere = Expression.and(accountWhere, statusWhere).getSQL();
    final String[] projection = {SQLFunctions.COUNT()};
    final int rowsDeleted;
    final Cursor countCur = resolver.query(uri, projection, countWhere, null, null);
    try {
      if (countCur != null && countCur.moveToFirst()) {
        rowsDeleted = countCur.getInt(0);
      } else {
        rowsDeleted = 0;
      }
    } finally {
      Utils.closeSilently(countCur);
    }

    // BEGIN HotMobi
    final RefreshEvent event = RefreshEvent.create(context, statusIds, getTimelineType());
    HotMobiLogger.getInstance(context).log(accountId, event);
    // END HotMobi

    // Insert a gap.
    final boolean deletedOldGap = rowsDeleted > 0 && ArrayUtils.contains(statusIds, maxId);
    final boolean noRowsDeleted = rowsDeleted == 0;
    final boolean insertGap =
        minId > 0 && (noRowsDeleted || deletedOldGap) && !noItemsBefore && !hasIntersection;
    if (insertGap && minIdx != -1) {
      values[minIdx].put(Statuses.IS_GAP, true);
    }
    // Insert previously fetched items.
    final Uri insertUri = UriUtils.appendQueryParameters(uri, QUERY_PARAM_NOTIFY, notify);
    ContentResolverUtils.bulkInsert(resolver, insertUri, values);
  }