class ApkProvider extends FDroidProvider {

    @Override
    public Cursor query(@NonNull Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {

        QuerySelection query = new QuerySelection(selection, selectionArgs);

        switch (MATCHER.match(uri)) {
            case CODE_REPO_APP:
                List<String> uriSegments = uri.getPathSegments();
                Long repoId = Long.parseLong(uriSegments.get(1));
                String packageName = uriSegments.get(2);
                query = query.add(queryRepo(repoId)).add(queryPackage(packageName));
                break;

            case CODE_LIST:
                break;

            case CODE_APK_FROM_ANY_REPO:
                query = query.add(querySingleFromAnyRepo(uri));
                break;

            case CODE_APK_ROW_ID:
                query = query.add(querySingle(Long.parseLong(uri.getLastPathSegment())));
                break;

            case CODE_PACKAGE:
                query = query.add(queryPackage(uri.getLastPathSegment()));
                break;

            case CODE_APKS:
                query = query.add(queryApks(uri.getLastPathSegment()));
                break;

            case CODE_REPO:
                query = query.add(queryRepo(Long.parseLong(uri.getLastPathSegment())));
                break;

            default:
                Log.e(TAG, "Invalid URI for apk content provider: " + uri);
                throw new UnsupportedOperationException("Invalid URI for apk content provider: " + uri);
        }

        Query queryBuilder = new Query();
        for (final String field : projection) {
            queryBuilder.addField(field);
        }
        queryBuilder.addSelection(query);
        queryBuilder.addOrderBy(sortOrder);

        Cursor cursor = LoggingQuery.rawQuery(db(), queryBuilder.toString(), queryBuilder.getArgs());
        cursor.setNotificationUri(getContext().getContentResolver(), uri);
        return cursor;
    }

}