@Override
 public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
   final ListView listView = getListView();
   switch (item.getItemId()) {
     case R.id.delete:
       {
         final Expression where =
             Expression.in(
                 new Column(Filters._ID), new RawItemArray(listView.getCheckedItemIds()));
         mResolver.delete(getContentUri(), where.getSQL(), null);
         break;
       }
     case R.id.inverse_selection:
       {
         final SparseBooleanArray positions = listView.getCheckedItemPositions();
         for (int i = 0, j = listView.getCount(); i < j; i++) {
           listView.setItemChecked(i, !positions.get(i));
         }
         return true;
       }
     default:
       {
         return false;
       }
   }
   mode.finish();
   return true;
 }
 @Override
 public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
   final Uri uri = DirectMessages.ConversationEntries.CONTENT_URI;
   final long[] accountIds = getAccountIds();
   final Expression account_where =
       Expression.in(new Column(Statuses.ACCOUNT_ID), new RawItemArray(accountIds));
   return new CursorLoader(getActivity(), uri, null, account_where.getSQL(), null, null);
 }
 @Override
 protected Loader<List<ParcelableStatus>> onCreateStatusesLoader(
     final Context context, final Bundle args, final boolean fromUser) {
   final Uri uri = getContentUri();
   final String table = getTableNameByUri(uri);
   final String sortOrder = getSortOrder();
   final long[] accountIds = getAccountIds();
   final Expression accountWhere =
       Expression.in(new Column(Statuses.ACCOUNT_ID), new RawItemArray(accountIds));
   final Expression filterWhere = getFiltersWhere(table), where;
   if (filterWhere != null) {
     where = Expression.and(accountWhere, filterWhere);
   } else {
     where = accountWhere;
   }
   final String selection = processWhere(where).getSQL();
   final AbsStatusesAdapter<List<ParcelableStatus>> adapter = getAdapter();
   adapter.setShowAccountsColor(accountIds.length > 1);
   final String[] projection = Statuses.COLUMNS;
   return new ObjectCursorLoader<>(
       context, ParcelableStatus.CursorIndices.class, uri, projection, selection, null, sortOrder);
 }
  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);
  }