@Override
  public Uri insert(Uri uri, ContentValues values) {
    Log.v(TAG, "insert: " + uri + " with " + values);
    final int match = ProviderConstants.MATCHER.match(uri);
    final String table;
    switch (match) {
      case AMRevolutionContract.News.TOKEN:
        table = AMRevolutionContract.News.PATH;
        break;
      case AMRevolutionContract.Snippets.TOKEN:
        table = AMRevolutionContract.Snippets.PATH;
        break;
      case AMRevolutionStateContract.TOKEN:
      case AMRevolutionContract.Snippets.ITEM_TOKEN:
      case AMRevolutionContract.News.ITEM_TOKEN:
      default:
        throw unsupportedUri(uri);
    }

    final SQLiteDatabase db = mDB.getWritableDatabase();
    final long id = db.insert(table, "", values);
    if (id == -1) return null;
    getContext().getContentResolver().notifyChange(uri, null);
    return ContentUris.withAppendedId(uri, id);
  }
  @Override
  public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    Log.v(TAG, "update: " + uri);
    final int match = ProviderConstants.MATCHER.match(uri);
    final String table;
    final String where;
    switch (match) {
      case AMRevolutionContract.News.TOKEN:
        table = AMRevolutionContract.News.PATH;
        where = selection;
        break;
      case AMRevolutionContract.Snippets.TOKEN:
        table = AMRevolutionContract.Snippets.PATH;
        where = selection;
        break;
      case AMRevolutionContract.Snippets.ITEM_TOKEN:
        table = AMRevolutionContract.Snippets.PATH;
        where =
            TextUtils.isEmpty(selection)
                ? getWhereId(uri)
                : (getWhereId(uri) + " AND (" + selection + ')');
        break;
      case AMRevolutionContract.News.ITEM_TOKEN:
        table = AMRevolutionContract.News.PATH;
        where =
            TextUtils.isEmpty(selection)
                ? getWhereId(uri)
                : (getWhereId(uri) + " AND (" + selection + ')');
        break;
      case AMRevolutionStateContract.TOKEN:
        table = AMRevolutionStateContract.PATH;
        where =
            TextUtils.isEmpty(selection)
                ? STATE_RECORD_MATCH
                : (STATE_RECORD_MATCH + " AND (" + selection + ')');
        // Prevent id update
        values.remove(AMRevolutionStateContract.Columns.ID);
        break;
      default:
        throw unsupportedUri(uri);
    }

    final SQLiteDatabase db = mDB.getWritableDatabase();
    final int updates = db.update(table, values, where, selectionArgs);
    if (updates > 0) {
      getContext().getContentResolver().notifyChange(uri, null);
    }
    return updates;
  }
  @Override
  public int delete(Uri uri, String selection, String[] selectionArgs) {
    Log.v(TAG, "delete: " + uri);
    final int match = ProviderConstants.MATCHER.match(uri);
    final String table;
    final String where;
    switch (match) {
      case AMRevolutionContract.News.TOKEN:
        table = AMRevolutionContract.News.PATH;
        where = selection;
        break;
      case AMRevolutionContract.Snippets.TOKEN:
        table = AMRevolutionContract.Snippets.PATH;
        where = selection;
        break;
      case AMRevolutionContract.Snippets.ITEM_TOKEN:
        table = AMRevolutionContract.Snippets.PATH;
        where =
            TextUtils.isEmpty(selection)
                ? getWhereId(uri)
                : (getWhereId(uri) + " AND (" + selection + ')');
        break;
      case AMRevolutionContract.News.ITEM_TOKEN:
        table = AMRevolutionContract.News.PATH;
        where =
            TextUtils.isEmpty(selection)
                ? getWhereId(uri)
                : (getWhereId(uri) + " AND (" + selection + ')');
        break;
      case AMRevolutionStateContract.TOKEN:
        return update(uri, ProviderConstants.INITIAL_STATE, selection, selectionArgs);
      default:
        throw unsupportedUri(uri);
    }

    final SQLiteDatabase db = mDB.getWritableDatabase();
    final int deleted = db.delete(table, where, selectionArgs);
    if (deleted > 0) {
      getContext().getContentResolver().notifyChange(uri, null);
    }
    return deleted;
  }