app/src/main/java/com/franktan/popularmovies/data/movie/MovieSelection.java
public class MovieSelection extends AbstractSelection<MovieSelection> {
    @Override
    protected Uri baseUri() {
        return MovieColumns.CONTENT_URI;
    }

    /**
     * Query the given content resolver using this selection.
     *
     * @param contentResolver The content resolver to query.
     * @param projection A list of which columns to return. Passing null will return all columns, which is inefficient.
     * @return A {@code MovieCursor} object, which is positioned before the first entry, or null.
     */
    public MovieCursor query(ContentResolver contentResolver, String[] projection) {
        Cursor cursor = contentResolver.query(uri(), projection, sel(), args(), order());
        if (cursor == null) return null;
        return new MovieCursor(cursor);
    }

    /**
     * Equivalent of calling {@code query(contentResolver, null)}.
     */
    public MovieCursor query(ContentResolver contentResolver) {
        return query(contentResolver, null);
    }

    /**
     * Query the given content resolver using this selection.
     *
     * @param context The context to use for the query.
     * @param projection A list of which columns to return. Passing null will return all columns, which is inefficient.
     * @return A {@code MovieCursor} object, which is positioned before the first entry, or null.
     */
    public MovieCursor query(Context context, String[] projection) {
        Cursor cursor = context.getContentResolver().query(uri(), projection, sel(), args(), order());
        if (cursor == null) return null;
        return new MovieCursor(cursor);
    }

    /**
     * Equivalent of calling {@code query(context, null)}.
     */
    public MovieCursor query(Context context) {
        return query(context, null);
    }


    public MovieSelection id(long... value) {
        addEquals("movie." + MovieColumns._ID, toObjectArray(value));
        return this;
    }

    public MovieSelection idNot(long... value) {
        addNotEquals("movie." + MovieColumns._ID, toObjectArray(value));
        return this;
    }

    public MovieSelection orderById(boolean desc) {
        orderBy("movie." + MovieColumns._ID, desc);
        return this;
    }

    public MovieSelection orderById() {
        return orderById(false);
    }

    public MovieSelection movieMoviedbId(long... value) {
        addEquals(MovieColumns.MOVIE_MOVIEDB_ID, toObjectArray(value));
        return this;
    }

    public MovieSelection movieMoviedbIdNot(long... value) {
        addNotEquals(MovieColumns.MOVIE_MOVIEDB_ID, toObjectArray(value));
        return this;
    }

    public MovieSelection movieMoviedbIdGt(long value) {
        addGreaterThan(MovieColumns.MOVIE_MOVIEDB_ID, value);
        return this;
    }

    public MovieSelection movieMoviedbIdGtEq(long value) {
        addGreaterThanOrEquals(MovieColumns.MOVIE_MOVIEDB_ID, value);
        return this;
    }

    public MovieSelection movieMoviedbIdLt(long value) {
        addLessThan(MovieColumns.MOVIE_MOVIEDB_ID, value);
        return this;
    }

    public MovieSelection movieMoviedbIdLtEq(long value) {
        addLessThanOrEquals(MovieColumns.MOVIE_MOVIEDB_ID, value);
        return this;
    }

    public MovieSelection orderByMovieMoviedbId(boolean desc) {
        orderBy(MovieColumns.MOVIE_MOVIEDB_ID, desc);
        return this;
    }

    public MovieSelection orderByMovieMoviedbId() {
        orderBy(MovieColumns.MOVIE_MOVIEDB_ID, false);
        return this;
    }

    public MovieSelection title(String... value) {
        addEquals(MovieColumns.TITLE, value);
        return this;
    }

    public MovieSelection titleNot(String... value) {
        addNotEquals(MovieColumns.TITLE, value);
        return this;
    }

    public MovieSelection titleLike(String... value) {
        addLike(MovieColumns.TITLE, value);
        return this;
    }

    public MovieSelection titleContains(String... value) {
        addContains(MovieColumns.TITLE, value);
        return this;
    }

    public MovieSelection titleStartsWith(String... value) {
        addStartsWith(MovieColumns.TITLE, value);
        return this;
    }

    public MovieSelection titleEndsWith(String... value) {
        addEndsWith(MovieColumns.TITLE, value);
        return this;
    }

    public MovieSelection orderByTitle(boolean desc) {
        orderBy(MovieColumns.TITLE, desc);
        return this;
    }

    public MovieSelection orderByTitle() {
        orderBy(MovieColumns.TITLE, false);
        return this;
    }

    public MovieSelection backdropPath(String... value) {
        addEquals(MovieColumns.BACKDROP_PATH, value);
        return this;
    }

    public MovieSelection backdropPathNot(String... value) {
        addNotEquals(MovieColumns.BACKDROP_PATH, value);
        return this;
    }

    public MovieSelection backdropPathLike(String... value) {
        addLike(MovieColumns.BACKDROP_PATH, value);
        return this;
    }

    public MovieSelection backdropPathContains(String... value) {
        addContains(MovieColumns.BACKDROP_PATH, value);
        return this;
    }

    public MovieSelection backdropPathStartsWith(String... value) {
        addStartsWith(MovieColumns.BACKDROP_PATH, value);
        return this;
    }

    public MovieSelection backdropPathEndsWith(String... value) {
        addEndsWith(MovieColumns.BACKDROP_PATH, value);
        return this;
    }

    public MovieSelection orderByBackdropPath(boolean desc) {
        orderBy(MovieColumns.BACKDROP_PATH, desc);
        return this;
    }

    public MovieSelection orderByBackdropPath() {
        orderBy(MovieColumns.BACKDROP_PATH, false);
        return this;
    }

    public MovieSelection originalLan(String... value) {
        addEquals(MovieColumns.ORIGINAL_LAN, value);
        return this;
    }

    public MovieSelection originalLanNot(String... value) {
        addNotEquals(MovieColumns.ORIGINAL_LAN, value);
        return this;
    }

    public MovieSelection originalLanLike(String... value) {
        addLike(MovieColumns.ORIGINAL_LAN, value);
        return this;
    }

    public MovieSelection originalLanContains(String... value) {
        addContains(MovieColumns.ORIGINAL_LAN, value);
        return this;
    }

    public MovieSelection originalLanStartsWith(String... value) {
        addStartsWith(MovieColumns.ORIGINAL_LAN, value);
        return this;
    }

    public MovieSelection originalLanEndsWith(String... value) {
        addEndsWith(MovieColumns.ORIGINAL_LAN, value);
        return this;
    }

    public MovieSelection orderByOriginalLan(boolean desc) {
        orderBy(MovieColumns.ORIGINAL_LAN, desc);
        return this;
    }

    public MovieSelection orderByOriginalLan() {
        orderBy(MovieColumns.ORIGINAL_LAN, false);
        return this;
    }

    public MovieSelection originalTitle(String... value) {
        addEquals(MovieColumns.ORIGINAL_TITLE, value);
        return this;
    }

    public MovieSelection originalTitleNot(String... value) {
        addNotEquals(MovieColumns.ORIGINAL_TITLE, value);
        return this;
    }

    public MovieSelection originalTitleLike(String... value) {
        addLike(MovieColumns.ORIGINAL_TITLE, value);
        return this;
    }

    public MovieSelection originalTitleContains(String... value) {
        addContains(MovieColumns.ORIGINAL_TITLE, value);
        return this;
    }

    public MovieSelection originalTitleStartsWith(String... value) {
        addStartsWith(MovieColumns.ORIGINAL_TITLE, value);
        return this;
    }

    public MovieSelection originalTitleEndsWith(String... value) {
        addEndsWith(MovieColumns.ORIGINAL_TITLE, value);
        return this;
    }

    public MovieSelection orderByOriginalTitle(boolean desc) {
        orderBy(MovieColumns.ORIGINAL_TITLE, desc);
        return this;
    }

    public MovieSelection orderByOriginalTitle() {
        orderBy(MovieColumns.ORIGINAL_TITLE, false);
        return this;
    }

    public MovieSelection overview(String... value) {
        addEquals(MovieColumns.OVERVIEW, value);
        return this;
    }

    public MovieSelection overviewNot(String... value) {
        addNotEquals(MovieColumns.OVERVIEW, value);
        return this;
    }

    public MovieSelection overviewLike(String... value) {
        addLike(MovieColumns.OVERVIEW, value);
        return this;
    }

    public MovieSelection overviewContains(String... value) {
        addContains(MovieColumns.OVERVIEW, value);
        return this;
    }

    public MovieSelection overviewStartsWith(String... value) {
        addStartsWith(MovieColumns.OVERVIEW, value);
        return this;
    }

    public MovieSelection overviewEndsWith(String... value) {
        addEndsWith(MovieColumns.OVERVIEW, value);
        return this;
    }

    public MovieSelection orderByOverview(boolean desc) {
        orderBy(MovieColumns.OVERVIEW, desc);
        return this;
    }

    public MovieSelection orderByOverview() {
        orderBy(MovieColumns.OVERVIEW, false);
        return this;
    }

    public MovieSelection releaseDate(Long... value) {
        addEquals(MovieColumns.RELEASE_DATE, value);
        return this;
    }

    public MovieSelection releaseDateNot(Long... value) {
        addNotEquals(MovieColumns.RELEASE_DATE, value);
        return this;
    }

    public MovieSelection releaseDateGt(long value) {
        addGreaterThan(MovieColumns.RELEASE_DATE, value);
        return this;
    }

    public MovieSelection releaseDateGtEq(long value) {
        addGreaterThanOrEquals(MovieColumns.RELEASE_DATE, value);
        return this;
    }

    public MovieSelection releaseDateLt(long value) {
        addLessThan(MovieColumns.RELEASE_DATE, value);
        return this;
    }

    public MovieSelection releaseDateLtEq(long value) {
        addLessThanOrEquals(MovieColumns.RELEASE_DATE, value);
        return this;
    }

    public MovieSelection orderByReleaseDate(boolean desc) {
        orderBy(MovieColumns.RELEASE_DATE, desc);
        return this;
    }

    public MovieSelection orderByReleaseDate() {
        orderBy(MovieColumns.RELEASE_DATE, false);
        return this;
    }

    public MovieSelection posterPath(String... value) {
        addEquals(MovieColumns.POSTER_PATH, value);
        return this;
    }

    public MovieSelection posterPathNot(String... value) {
        addNotEquals(MovieColumns.POSTER_PATH, value);
        return this;
    }

    public MovieSelection posterPathLike(String... value) {
        addLike(MovieColumns.POSTER_PATH, value);
        return this;
    }

    public MovieSelection posterPathContains(String... value) {
        addContains(MovieColumns.POSTER_PATH, value);
        return this;
    }

    public MovieSelection posterPathStartsWith(String... value) {
        addStartsWith(MovieColumns.POSTER_PATH, value);
        return this;
    }

    public MovieSelection posterPathEndsWith(String... value) {
        addEndsWith(MovieColumns.POSTER_PATH, value);
        return this;
    }

    public MovieSelection orderByPosterPath(boolean desc) {
        orderBy(MovieColumns.POSTER_PATH, desc);
        return this;
    }

    public MovieSelection orderByPosterPath() {
        orderBy(MovieColumns.POSTER_PATH, false);
        return this;
    }

    public MovieSelection popularity(Double... value) {
        addEquals(MovieColumns.POPULARITY, value);
        return this;
    }

    public MovieSelection popularityNot(Double... value) {
        addNotEquals(MovieColumns.POPULARITY, value);
        return this;
    }

    public MovieSelection popularityGt(double value) {
        addGreaterThan(MovieColumns.POPULARITY, value);
        return this;
    }

    public MovieSelection popularityGtEq(double value) {
        addGreaterThanOrEquals(MovieColumns.POPULARITY, value);
        return this;
    }

    public MovieSelection popularityLt(double value) {
        addLessThan(MovieColumns.POPULARITY, value);
        return this;
    }

    public MovieSelection popularityLtEq(double value) {
        addLessThanOrEquals(MovieColumns.POPULARITY, value);
        return this;
    }

    public MovieSelection orderByPopularity(boolean desc) {
        orderBy(MovieColumns.POPULARITY, desc);
        return this;
    }

    public MovieSelection orderByPopularity() {
        orderBy(MovieColumns.POPULARITY, false);
        return this;
    }

    public MovieSelection voteAverage(Double... value) {
        addEquals(MovieColumns.VOTE_AVERAGE, value);
        return this;
    }

    public MovieSelection voteAverageNot(Double... value) {
        addNotEquals(MovieColumns.VOTE_AVERAGE, value);
        return this;
    }

    public MovieSelection voteAverageGt(double value) {
        addGreaterThan(MovieColumns.VOTE_AVERAGE, value);
        return this;
    }

    public MovieSelection voteAverageGtEq(double value) {
        addGreaterThanOrEquals(MovieColumns.VOTE_AVERAGE, value);
        return this;
    }

    public MovieSelection voteAverageLt(double value) {
        addLessThan(MovieColumns.VOTE_AVERAGE, value);
        return this;
    }

    public MovieSelection voteAverageLtEq(double value) {
        addLessThanOrEquals(MovieColumns.VOTE_AVERAGE, value);
        return this;
    }

    public MovieSelection orderByVoteAverage(boolean desc) {
        orderBy(MovieColumns.VOTE_AVERAGE, desc);
        return this;
    }

    public MovieSelection orderByVoteAverage() {
        orderBy(MovieColumns.VOTE_AVERAGE, false);
        return this;
    }

    public MovieSelection voteCount(Integer... value) {
        addEquals(MovieColumns.VOTE_COUNT, value);
        return this;
    }

    public MovieSelection voteCountNot(Integer... value) {
        addNotEquals(MovieColumns.VOTE_COUNT, value);
        return this;
    }

    public MovieSelection voteCountGt(int value) {
        addGreaterThan(MovieColumns.VOTE_COUNT, value);
        return this;
    }

    public MovieSelection voteCountGtEq(int value) {
        addGreaterThanOrEquals(MovieColumns.VOTE_COUNT, value);
        return this;
    }

    public MovieSelection voteCountLt(int value) {
        addLessThan(MovieColumns.VOTE_COUNT, value);
        return this;
    }

    public MovieSelection voteCountLtEq(int value) {
        addLessThanOrEquals(MovieColumns.VOTE_COUNT, value);
        return this;
    }

    public MovieSelection orderByVoteCount(boolean desc) {
        orderBy(MovieColumns.VOTE_COUNT, desc);
        return this;
    }

    public MovieSelection orderByVoteCount() {
        orderBy(MovieColumns.VOTE_COUNT, false);
        return this;
    }
}
app/src/main/java/com/franktan/popularmovies/data/trailer/TrailerColumns.java
public class TrailerColumns implements BaseColumns {
    public static final String TABLE_NAME = "trailer";
    public static final Uri CONTENT_URI = Uri.parse(MovieProvider.CONTENT_URI_BASE + "/" + TABLE_NAME);

    /**
     * Primary key.
     */
    public static final String _ID = BaseColumns._ID;

    /**
     * the title of the trailer
     */
    public static final String NAME = "name";

    /**
     * HD, SD, etc.
     */
    public static final String SIZE = "size";

    /**
     * the youtube id
     */
    public static final String SOURCE = "source";

    /**
     * trailer, video, etc.
     */
    public static final String TYPE = "type";

    /**
     * the movie id
     */
    public static final String MOVIE_ID = "movie_id";


    public static final String DEFAULT_ORDER = TABLE_NAME + "." +_ID;

    // @formatter:off
    public static final String[] ALL_COLUMNS = new String[] {
            _ID,
            NAME,
            SIZE,
            SOURCE,
            TYPE,
            MOVIE_ID
    };
    // @formatter:on

    public static boolean hasColumns(String[] projection) {
        if (projection == null) return true;
        for (String c : projection) {
            if (c.equals(NAME) || c.contains("." + NAME)) return true;
            if (c.equals(SIZE) || c.contains("." + SIZE)) return true;
            if (c.equals(SOURCE) || c.contains("." + SOURCE)) return true;
            if (c.equals(TYPE) || c.contains("." + TYPE)) return true;
            if (c.equals(MOVIE_ID) || c.contains("." + MOVIE_ID)) return true;
        }
        return false;
    }

    public static final String PREFIX_MOVIE = TABLE_NAME + "__" + MovieColumns.TABLE_NAME;
}
app/src/main/java/com/franktan/popularmovies/data/movie/MovieCursor.java
@SuppressWarnings("UnnecessaryLocalVariable")
public class MovieCursor extends AbstractCursor implements MovieModel {
    public MovieCursor(Cursor cursor) {
        super(cursor);
    }

    /**
     * Primary key.
     */
    public long getId() {
        Long res = getLongOrNull(MovieColumns._ID);
        if (res == null)
            throw new NullPointerException("The value of '_id' in the database was null, which is not allowed according to the model definition");
        return res;
    }

    /**
     * The id of the movie in MovieDB
     */
    public long getMovieMoviedbId() {
        Long res = getLongOrNull(MovieColumns.MOVIE_MOVIEDB_ID);
        if (res == null)
            throw new NullPointerException("The value of 'movie_moviedb_id' in the database was null, which is not allowed according to the model definition");
        return res;
    }

    /**
     * Get the {@code title} value.
     * Cannot be {@code null}.
     */
    @NonNull
    public String getTitle() {
        String res = getStringOrNull(MovieColumns.TITLE);
        if (res == null)
            throw new NullPointerException("The value of 'title' in the database was null, which is not allowed according to the model definition");
        return res;
    }

    /**
     * Get the {@code backdrop_path} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getBackdropPath() {
        String res = getStringOrNull(MovieColumns.BACKDROP_PATH);
        return res;
    }

    /**
     * Get the {@code original_lan} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getOriginalLan() {
        String res = getStringOrNull(MovieColumns.ORIGINAL_LAN);
        return res;
    }

    /**
     * Get the {@code original_title} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getOriginalTitle() {
        String res = getStringOrNull(MovieColumns.ORIGINAL_TITLE);
        return res;
    }

    /**
     * Get the {@code overview} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getOverview() {
        String res = getStringOrNull(MovieColumns.OVERVIEW);
        return res;
    }

    /**
     * Get the {@code release_date} value.
     * Can be {@code null}.
     */
    @Nullable
    public Long getReleaseDate() {
        Long res = getLongOrNull(MovieColumns.RELEASE_DATE);
        return res;
    }

    /**
     * Get the {@code poster_path} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getPosterPath() {
        String res = getStringOrNull(MovieColumns.POSTER_PATH);
        return res;
    }

    /**
     * Get the {@code popularity} value.
     * Can be {@code null}.
     */
    @Nullable
    public Double getPopularity() {
        Double res = getDoubleOrNull(MovieColumns.POPULARITY);
        return res;
    }

    /**
     * Get the {@code vote_average} value.
     * Can be {@code null}.
     */
    @Nullable
    public Double getVoteAverage() {
        Double res = getDoubleOrNull(MovieColumns.VOTE_AVERAGE);
        return res;
    }

    /**
     * Get the {@code vote_count} value.
     * Can be {@code null}.
     */
    @Nullable
    public Integer getVoteCount() {
        Integer res = getIntegerOrNull(MovieColumns.VOTE_COUNT);
        return res;
    }
}
app/src/main/java/com/franktan/popularmovies/data/movie/MovieColumns.java
public class MovieColumns implements BaseColumns {
    public static final String TABLE_NAME = "movie";
    public static final Uri CONTENT_URI = Uri.parse(MovieProvider.CONTENT_URI_BASE + "/" + TABLE_NAME);

    /**
     * Primary key.
     */
    public static final String _ID = BaseColumns._ID;

    /**
     * The id of the movie in MovieDB
     */
    public static final String MOVIE_MOVIEDB_ID = "movie_moviedb_id";

    public static final String TITLE = "title";

    public static final String BACKDROP_PATH = "backdrop_path";

    public static final String ORIGINAL_LAN = "original_lan";

    public static final String ORIGINAL_TITLE = "original_title";

    public static final String OVERVIEW = "overview";

    public static final String RELEASE_DATE = "release_date";

    public static final String POSTER_PATH = "poster_path";

    public static final String POPULARITY = "popularity";

    public static final String VOTE_AVERAGE = "vote_average";

    public static final String VOTE_COUNT = "vote_count";


    public static final String DEFAULT_ORDER = TABLE_NAME + "." +_ID;

    // @formatter:off
    public static final String[] ALL_COLUMNS = new String[] {
            _ID,
            MOVIE_MOVIEDB_ID,
            TITLE,
            BACKDROP_PATH,
            ORIGINAL_LAN,
            ORIGINAL_TITLE,
            OVERVIEW,
            RELEASE_DATE,
            POSTER_PATH,
            POPULARITY,
            VOTE_AVERAGE,
            VOTE_COUNT
    };
    // @formatter:on

    public static boolean hasColumns(String[] projection) {
        if (projection == null) return true;
        for (String c : projection) {
            if (c.equals(MOVIE_MOVIEDB_ID) || c.contains("." + MOVIE_MOVIEDB_ID)) return true;
            if (c.equals(TITLE) || c.contains("." + TITLE)) return true;
            if (c.equals(BACKDROP_PATH) || c.contains("." + BACKDROP_PATH)) return true;
            if (c.equals(ORIGINAL_LAN) || c.contains("." + ORIGINAL_LAN)) return true;
            if (c.equals(ORIGINAL_TITLE) || c.contains("." + ORIGINAL_TITLE)) return true;
            if (c.equals(OVERVIEW) || c.contains("." + OVERVIEW)) return true;
            if (c.equals(RELEASE_DATE) || c.contains("." + RELEASE_DATE)) return true;
            if (c.equals(POSTER_PATH) || c.contains("." + POSTER_PATH)) return true;
            if (c.equals(POPULARITY) || c.contains("." + POPULARITY)) return true;
            if (c.equals(VOTE_AVERAGE) || c.contains("." + VOTE_AVERAGE)) return true;
            if (c.equals(VOTE_COUNT) || c.contains("." + VOTE_COUNT)) return true;
        }
        return false;
    }

}
app/src/main/java/com/franktan/popularmovies/util/Constants.java
public class Constants {
    public static final int PAGES_NEEDED = 3;
    public static final String POSTER_BASE_PATH = "http://image.tmdb.org/t/p/w185";
    public static final String BACKDROP_BASE_PATH = "http://image.tmdb.org/t/p/w500";
    public static final String APP_NAME = "popularmovies";
    public static final String MOVIEDB_BASE_URL = "https://api.themoviedb.org";
    public static final String MOVIEDB_ID = "moviedbId";

    public static final String YOUTUBE_ID = "youtubeId";
    public static final String YOUTUBE_URL = "https://www.youtube.com/watch?v=";
}
app/src/main/java/com/franktan/popularmovies/data/moviegenre/MovieGenreColumns.java
public class MovieGenreColumns implements BaseColumns {
    public static final String TABLE_NAME = "movie_genre";
    public static final Uri CONTENT_URI = Uri.parse(MovieProvider.CONTENT_URI_BASE + "/" + TABLE_NAME);

    /**
     * Primary key.
     */
    public static final String _ID = BaseColumns._ID;

    /**
     * the movie id
     */
    public static final String MOVIE_ID = "movie_id";

    /**
     * the genre id
     */
    public static final String GENRE_ID = "genre_id";


    public static final String DEFAULT_ORDER = TABLE_NAME + "." +_ID;

    // @formatter:off
    public static final String[] ALL_COLUMNS = new String[] {
            _ID,
            MOVIE_ID,
            GENRE_ID
    };
    // @formatter:on

    public static boolean hasColumns(String[] projection) {
        if (projection == null) return true;
        for (String c : projection) {
            if (c.equals(MOVIE_ID) || c.contains("." + MOVIE_ID)) return true;
            if (c.equals(GENRE_ID) || c.contains("." + GENRE_ID)) return true;
        }
        return false;
    }

    public static final String PREFIX_MOVIE = TABLE_NAME + "__" + MovieColumns.TABLE_NAME;
    public static final String PREFIX_GENRE = TABLE_NAME + "__" + GenreColumns.TABLE_NAME;
}
app/src/main/java/com/franktan/popularmovies/data/favorite/FavoriteCursor.java
@SuppressWarnings("UnnecessaryLocalVariable")
public class FavoriteCursor extends AbstractCursor implements FavoriteModel {
    public FavoriteCursor(Cursor cursor) {
        super(cursor);
    }

    /**
     * Primary key.
     */
    public long getId() {
        Long res = getLongOrNull(FavoriteColumns._ID);
        if (res == null)
            throw new NullPointerException("The value of '_id' in the database was null, which is not allowed according to the model definition");
        return res;
    }

    /**
     * the moviedb id of the favorite movie
     */
    public long getFavoriteMoviedbId() {
        Long res = getLongOrNull(FavoriteColumns.FAVORITE_MOVIEDB_ID);
        if (res == null)
            throw new NullPointerException("The value of 'favorite_moviedb_id' in the database was null, which is not allowed according to the model definition");
        return res;
    }

    /**
     * The id of the movie in MovieDB
     */
    public long getMovieMovieMoviedbId() {
        Long res = getLongOrNull(MovieColumns.MOVIE_MOVIEDB_ID);
        if (res == null)
            throw new NullPointerException("The value of 'movie_moviedb_id' in the database was null, which is not allowed according to the model definition");
        return res;
    }

    /**
     * Get the {@code title} value.
     * Cannot be {@code null}.
     */
    @NonNull
    public String getMovieTitle() {
        String res = getStringOrNull(MovieColumns.TITLE);
        if (res == null)
            throw new NullPointerException("The value of 'title' in the database was null, which is not allowed according to the model definition");
        return res;
    }

    /**
     * Get the {@code backdrop_path} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getMovieBackdropPath() {
        String res = getStringOrNull(MovieColumns.BACKDROP_PATH);
        return res;
    }

    /**
     * Get the {@code original_lan} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getMovieOriginalLan() {
        String res = getStringOrNull(MovieColumns.ORIGINAL_LAN);
        return res;
    }

    /**
     * Get the {@code original_title} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getMovieOriginalTitle() {
        String res = getStringOrNull(MovieColumns.ORIGINAL_TITLE);
        return res;
    }

    /**
     * Get the {@code overview} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getMovieOverview() {
        String res = getStringOrNull(MovieColumns.OVERVIEW);
        return res;
    }

    /**
     * Get the {@code release_date} value.
     * Can be {@code null}.
     */
    @Nullable
    public Long getMovieReleaseDate() {
        Long res = getLongOrNull(MovieColumns.RELEASE_DATE);
        return res;
    }

    /**
     * Get the {@code poster_path} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getMoviePosterPath() {
        String res = getStringOrNull(MovieColumns.POSTER_PATH);
        return res;
    }

    /**
     * Get the {@code popularity} value.
     * Can be {@code null}.
     */
    @Nullable
    public Double getMoviePopularity() {
        Double res = getDoubleOrNull(MovieColumns.POPULARITY);
        return res;
    }

    /**
     * Get the {@code vote_average} value.
     * Can be {@code null}.
     */
    @Nullable
    public Double getMovieVoteAverage() {
        Double res = getDoubleOrNull(MovieColumns.VOTE_AVERAGE);
        return res;
    }

    /**
     * Get the {@code vote_count} value.
     * Can be {@code null}.
     */
    @Nullable
    public Integer getMovieVoteCount() {
        Integer res = getIntegerOrNull(MovieColumns.VOTE_COUNT);
        return res;
    }

    /**
     * the date and time when user favorites this movie
     * Can be {@code null}.
     */
    @Nullable
    public Long getCreated() {
        Long res = getLongOrNull(FavoriteColumns.CREATED);
        return res;
    }
}
app/src/main/java/com/franktan/popularmovies/data/genre/GenreColumns.java
public class GenreColumns implements BaseColumns {
    public static final String TABLE_NAME = "genre";
    public static final Uri CONTENT_URI = Uri.parse(MovieProvider.CONTENT_URI_BASE + "/" + TABLE_NAME);

    /**
     * Primary key.
     */
    public static final String _ID = BaseColumns._ID;

    /**
     * the id of the genre on movieDB
     */
    public static final String GENRE_MOVIEDB_ID = "genre_moviedb_id";

    /**
     * name
     */
    public static final String NAME = "name";


    public static final String DEFAULT_ORDER = TABLE_NAME + "." +_ID;

    // @formatter:off
    public static final String[] ALL_COLUMNS = new String[] {
            _ID,
            GENRE_MOVIEDB_ID,
            NAME
    };
    // @formatter:on

    public static boolean hasColumns(String[] projection) {
        if (projection == null) return true;
        for (String c : projection) {
            if (c.equals(GENRE_MOVIEDB_ID) || c.contains("." + GENRE_MOVIEDB_ID)) return true;
            if (c.equals(NAME) || c.contains("." + NAME)) return true;
        }
        return false;
    }

}
app/src/main/java/com/franktan/popularmovies/data/moviegenre/MovieGenreCursor.java
@SuppressWarnings("UnnecessaryLocalVariable")
public class MovieGenreCursor extends AbstractCursor implements MovieGenreModel {
    public MovieGenreCursor(Cursor cursor) {
        super(cursor);
    }

    /**
     * Primary key.
     */
    public long getId() {
        Long res = getLongOrNull(MovieGenreColumns._ID);
        if (res == null)
            throw new NullPointerException("The value of '_id' in the database was null, which is not allowed according to the model definition");
        return res;
    }

    /**
     * the movie id
     */
    public long getMovieId() {
        Long res = getLongOrNull(MovieGenreColumns.MOVIE_ID);
        if (res == null)
            throw new NullPointerException("The value of 'movie_id' in the database was null, which is not allowed according to the model definition");
        return res;
    }

    /**
     * The id of the movie in MovieDB
     */
    public long getMovieMovieMoviedbId() {
        Long res = getLongOrNull(MovieColumns.MOVIE_MOVIEDB_ID);
        if (res == null)
            throw new NullPointerException("The value of 'movie_moviedb_id' in the database was null, which is not allowed according to the model definition");
        return res;
    }

    /**
     * Get the {@code title} value.
     * Cannot be {@code null}.
     */
    @NonNull
    public String getMovieTitle() {
        String res = getStringOrNull(MovieColumns.TITLE);
        if (res == null)
            throw new NullPointerException("The value of 'title' in the database was null, which is not allowed according to the model definition");
        return res;
    }

    /**
     * Get the {@code backdrop_path} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getMovieBackdropPath() {
        String res = getStringOrNull(MovieColumns.BACKDROP_PATH);
        return res;
    }

    /**
     * Get the {@code original_lan} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getMovieOriginalLan() {
        String res = getStringOrNull(MovieColumns.ORIGINAL_LAN);
        return res;
    }

    /**
     * Get the {@code original_title} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getMovieOriginalTitle() {
        String res = getStringOrNull(MovieColumns.ORIGINAL_TITLE);
        return res;
    }

    /**
     * Get the {@code overview} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getMovieOverview() {
        String res = getStringOrNull(MovieColumns.OVERVIEW);
        return res;
    }

    /**
     * Get the {@code release_date} value.
     * Can be {@code null}.
     */
    @Nullable
    public Long getMovieReleaseDate() {
        Long res = getLongOrNull(MovieColumns.RELEASE_DATE);
        return res;
    }

    /**
     * Get the {@code poster_path} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getMoviePosterPath() {
        String res = getStringOrNull(MovieColumns.POSTER_PATH);
        return res;
    }

    /**
     * Get the {@code popularity} value.
     * Can be {@code null}.
     */
    @Nullable
    public Double getMoviePopularity() {
        Double res = getDoubleOrNull(MovieColumns.POPULARITY);
        return res;
    }

    /**
     * Get the {@code vote_average} value.
     * Can be {@code null}.
     */
    @Nullable
    public Double getMovieVoteAverage() {
        Double res = getDoubleOrNull(MovieColumns.VOTE_AVERAGE);
        return res;
    }

    /**
     * Get the {@code vote_count} value.
     * Can be {@code null}.
     */
    @Nullable
    public Integer getMovieVoteCount() {
        Integer res = getIntegerOrNull(MovieColumns.VOTE_COUNT);
        return res;
    }

    /**
     * the genre id
     */
    public long getGenreId() {
        Long res = getLongOrNull(MovieGenreColumns.GENRE_ID);
        if (res == null)
            throw new NullPointerException("The value of 'genre_id' in the database was null, which is not allowed according to the model definition");
        return res;
    }

    /**
     * the id of the genre on movieDB
     */
    public int getGenreGenreMoviedbId() {
        Integer res = getIntegerOrNull(GenreColumns.GENRE_MOVIEDB_ID);
        if (res == null)
            throw new NullPointerException("The value of 'genre_moviedb_id' in the database was null, which is not allowed according to the model definition");
        return res;
    }

    /**
     * name
     * Cannot be {@code null}.
     */
    @NonNull
    public String getGenreName() {
        String res = getStringOrNull(GenreColumns.NAME);
        if (res == null)
            throw new NullPointerException("The value of 'name' in the database was null, which is not allowed according to the model definition");
        return res;
    }
}
app/src/main/java/com/franktan/popularmovies/data/review/ReviewColumns.java
public class ReviewColumns implements BaseColumns {
    public static final String TABLE_NAME = "review";
    public static final Uri CONTENT_URI = Uri.parse(MovieProvider.CONTENT_URI_BASE + "/" + TABLE_NAME);

    /**
     * Primary key.
     */
    public static final String _ID = BaseColumns._ID;

    /**
     * the id of the reivew on movieDB
     */
    public static final String REVIEW_MOVIEDB_ID = "review_moviedb_id";

    /**
     * author
     */
    public static final String AUTHOR = "author";

    /**
     * content of the review
     */
    public static final String CONTENT = "content";

    /**
     * url of the original review
     */
    public static final String URL = "url";

    /**
     * the movie id
     */
    public static final String MOVIE_ID = "movie_id";


    public static final String DEFAULT_ORDER = TABLE_NAME + "." +_ID;

    // @formatter:off
    public static final String[] ALL_COLUMNS = new String[] {
            _ID,
            REVIEW_MOVIEDB_ID,
            AUTHOR,
            CONTENT,
            URL,
            MOVIE_ID
    };
    // @formatter:on

    public static boolean hasColumns(String[] projection) {
        if (projection == null) return true;
        for (String c : projection) {
            if (c.equals(REVIEW_MOVIEDB_ID) || c.contains("." + REVIEW_MOVIEDB_ID)) return true;
            if (c.equals(AUTHOR) || c.contains("." + AUTHOR)) return true;
            if (c.equals(CONTENT) || c.contains("." + CONTENT)) return true;
            if (c.equals(URL) || c.contains("." + URL)) return true;
            if (c.equals(MOVIE_ID) || c.contains("." + MOVIE_ID)) return true;
        }
        return false;
    }

    public static final String PREFIX_MOVIE = TABLE_NAME + "__" + MovieColumns.TABLE_NAME;
}
app/src/main/java/com/franktan/popularmovies/data/moviegenre/MovieGenreSelection.java
public class MovieGenreSelection extends AbstractSelection<MovieGenreSelection> {
    @Override
    protected Uri baseUri() {
        return MovieGenreColumns.CONTENT_URI;
    }

    /**
     * Query the given content resolver using this selection.
     *
     * @param contentResolver The content resolver to query.
     * @param projection A list of which columns to return. Passing null will return all columns, which is inefficient.
     * @return A {@code MovieGenreCursor} object, which is positioned before the first entry, or null.
     */
    public MovieGenreCursor query(ContentResolver contentResolver, String[] projection) {
        Cursor cursor = contentResolver.query(uri(), projection, sel(), args(), order());
        if (cursor == null) return null;
        return new MovieGenreCursor(cursor);
    }

    /**
     * Equivalent of calling {@code query(contentResolver, null)}.
     */
    public MovieGenreCursor query(ContentResolver contentResolver) {
        return query(contentResolver, null);
    }

    /**
     * Query the given content resolver using this selection.
     *
     * @param context The context to use for the query.
     * @param projection A list of which columns to return. Passing null will return all columns, which is inefficient.
     * @return A {@code MovieGenreCursor} object, which is positioned before the first entry, or null.
     */
    public MovieGenreCursor query(Context context, String[] projection) {
        Cursor cursor = context.getContentResolver().query(uri(), projection, sel(), args(), order());
        if (cursor == null) return null;
        return new MovieGenreCursor(cursor);
    }

    /**
     * Equivalent of calling {@code query(context, null)}.
     */
    public MovieGenreCursor query(Context context) {
        return query(context, null);
    }


    public MovieGenreSelection id(long... value) {
        addEquals("movie_genre." + MovieGenreColumns._ID, toObjectArray(value));
        return this;
    }

    public MovieGenreSelection idNot(long... value) {
        addNotEquals("movie_genre." + MovieGenreColumns._ID, toObjectArray(value));
        return this;
    }

    public MovieGenreSelection orderById(boolean desc) {
        orderBy("movie_genre." + MovieGenreColumns._ID, desc);
        return this;
    }

    public MovieGenreSelection orderById() {
        return orderById(false);
    }

    public MovieGenreSelection movieId(long... value) {
        addEquals(MovieGenreColumns.MOVIE_ID, toObjectArray(value));
        return this;
    }

    public MovieGenreSelection movieIdNot(long... value) {
        addNotEquals(MovieGenreColumns.MOVIE_ID, toObjectArray(value));
        return this;
    }

    public MovieGenreSelection movieIdGt(long value) {
        addGreaterThan(MovieGenreColumns.MOVIE_ID, value);
        return this;
    }

    public MovieGenreSelection movieIdGtEq(long value) {
        addGreaterThanOrEquals(MovieGenreColumns.MOVIE_ID, value);
        return this;
    }

    public MovieGenreSelection movieIdLt(long value) {
        addLessThan(MovieGenreColumns.MOVIE_ID, value);
        return this;
    }

    public MovieGenreSelection movieIdLtEq(long value) {
        addLessThanOrEquals(MovieGenreColumns.MOVIE_ID, value);
        return this;
    }

    public MovieGenreSelection orderByMovieId(boolean desc) {
        orderBy(MovieGenreColumns.MOVIE_ID, desc);
        return this;
    }

    public MovieGenreSelection orderByMovieId() {
        orderBy(MovieGenreColumns.MOVIE_ID, false);
        return this;
    }

    public MovieGenreSelection movieMovieMoviedbId(long... value) {
        addEquals(MovieColumns.MOVIE_MOVIEDB_ID, toObjectArray(value));
        return this;
    }

    public MovieGenreSelection movieMovieMoviedbIdNot(long... value) {
        addNotEquals(MovieColumns.MOVIE_MOVIEDB_ID, toObjectArray(value));
        return this;
    }

    public MovieGenreSelection movieMovieMoviedbIdGt(long value) {
        addGreaterThan(MovieColumns.MOVIE_MOVIEDB_ID, value);
        return this;
    }

    public MovieGenreSelection movieMovieMoviedbIdGtEq(long value) {
        addGreaterThanOrEquals(MovieColumns.MOVIE_MOVIEDB_ID, value);
        return this;
    }

    public MovieGenreSelection movieMovieMoviedbIdLt(long value) {
        addLessThan(MovieColumns.MOVIE_MOVIEDB_ID, value);
        return this;
    }

    public MovieGenreSelection movieMovieMoviedbIdLtEq(long value) {
        addLessThanOrEquals(MovieColumns.MOVIE_MOVIEDB_ID, value);
        return this;
    }

    public MovieGenreSelection orderByMovieMovieMoviedbId(boolean desc) {
        orderBy(MovieColumns.MOVIE_MOVIEDB_ID, desc);
        return this;
    }

    public MovieGenreSelection orderByMovieMovieMoviedbId() {
        orderBy(MovieColumns.MOVIE_MOVIEDB_ID, false);
        return this;
    }

    public MovieGenreSelection movieTitle(String... value) {
        addEquals(MovieColumns.TITLE, value);
        return this;
    }

    public MovieGenreSelection movieTitleNot(String... value) {
        addNotEquals(MovieColumns.TITLE, value);
        return this;
    }

    public MovieGenreSelection movieTitleLike(String... value) {
        addLike(MovieColumns.TITLE, value);
        return this;
    }

    public MovieGenreSelection movieTitleContains(String... value) {
        addContains(MovieColumns.TITLE, value);
        return this;
    }

    public MovieGenreSelection movieTitleStartsWith(String... value) {
        addStartsWith(MovieColumns.TITLE, value);
        return this;
    }

    public MovieGenreSelection movieTitleEndsWith(String... value) {
        addEndsWith(MovieColumns.TITLE, value);
        return this;
    }

    public MovieGenreSelection orderByMovieTitle(boolean desc) {
        orderBy(MovieColumns.TITLE, desc);
        return this;
    }

    public MovieGenreSelection orderByMovieTitle() {
        orderBy(MovieColumns.TITLE, false);
        return this;
    }

    public MovieGenreSelection movieBackdropPath(String... value) {
        addEquals(MovieColumns.BACKDROP_PATH, value);
        return this;
    }

    public MovieGenreSelection movieBackdropPathNot(String... value) {
        addNotEquals(MovieColumns.BACKDROP_PATH, value);
        return this;
    }

    public MovieGenreSelection movieBackdropPathLike(String... value) {
        addLike(MovieColumns.BACKDROP_PATH, value);
        return this;
    }

    public MovieGenreSelection movieBackdropPathContains(String... value) {
        addContains(MovieColumns.BACKDROP_PATH, value);
        return this;
    }

    public MovieGenreSelection movieBackdropPathStartsWith(String... value) {
        addStartsWith(MovieColumns.BACKDROP_PATH, value);
        return this;
    }

    public MovieGenreSelection movieBackdropPathEndsWith(String... value) {
        addEndsWith(MovieColumns.BACKDROP_PATH, value);
        return this;
    }

    public MovieGenreSelection orderByMovieBackdropPath(boolean desc) {
        orderBy(MovieColumns.BACKDROP_PATH, desc);
        return this;
    }

    public MovieGenreSelection orderByMovieBackdropPath() {
        orderBy(MovieColumns.BACKDROP_PATH, false);
        return this;
    }

    public MovieGenreSelection movieOriginalLan(String... value) {
        addEquals(MovieColumns.ORIGINAL_LAN, value);
        return this;
    }

    public MovieGenreSelection movieOriginalLanNot(String... value) {
        addNotEquals(MovieColumns.ORIGINAL_LAN, value);
        return this;
    }

    public MovieGenreSelection movieOriginalLanLike(String... value) {
        addLike(MovieColumns.ORIGINAL_LAN, value);
        return this;
    }

    public MovieGenreSelection movieOriginalLanContains(String... value) {
        addContains(MovieColumns.ORIGINAL_LAN, value);
        return this;
    }

    public MovieGenreSelection movieOriginalLanStartsWith(String... value) {
        addStartsWith(MovieColumns.ORIGINAL_LAN, value);
        return this;
    }

    public MovieGenreSelection movieOriginalLanEndsWith(String... value) {
        addEndsWith(MovieColumns.ORIGINAL_LAN, value);
        return this;
    }

    public MovieGenreSelection orderByMovieOriginalLan(boolean desc) {
        orderBy(MovieColumns.ORIGINAL_LAN, desc);
        return this;
    }

    public MovieGenreSelection orderByMovieOriginalLan() {
        orderBy(MovieColumns.ORIGINAL_LAN, false);
        return this;
    }

    public MovieGenreSelection movieOriginalTitle(String... value) {
        addEquals(MovieColumns.ORIGINAL_TITLE, value);
        return this;
    }

    public MovieGenreSelection movieOriginalTitleNot(String... value) {
        addNotEquals(MovieColumns.ORIGINAL_TITLE, value);
        return this;
    }

    public MovieGenreSelection movieOriginalTitleLike(String... value) {
        addLike(MovieColumns.ORIGINAL_TITLE, value);
        return this;
    }

    public MovieGenreSelection movieOriginalTitleContains(String... value) {
        addContains(MovieColumns.ORIGINAL_TITLE, value);
        return this;
    }

    public MovieGenreSelection movieOriginalTitleStartsWith(String... value) {
        addStartsWith(MovieColumns.ORIGINAL_TITLE, value);
        return this;
    }

    public MovieGenreSelection movieOriginalTitleEndsWith(String... value) {
        addEndsWith(MovieColumns.ORIGINAL_TITLE, value);
        return this;
    }

    public MovieGenreSelection orderByMovieOriginalTitle(boolean desc) {
        orderBy(MovieColumns.ORIGINAL_TITLE, desc);
        return this;
    }

    public MovieGenreSelection orderByMovieOriginalTitle() {
        orderBy(MovieColumns.ORIGINAL_TITLE, false);
        return this;
    }

    public MovieGenreSelection movieOverview(String... value) {
        addEquals(MovieColumns.OVERVIEW, value);
        return this;
    }

    public MovieGenreSelection movieOverviewNot(String... value) {
        addNotEquals(MovieColumns.OVERVIEW, value);
        return this;
    }

    public MovieGenreSelection movieOverviewLike(String... value) {
        addLike(MovieColumns.OVERVIEW, value);
        return this;
    }

    public MovieGenreSelection movieOverviewContains(String... value) {
        addContains(MovieColumns.OVERVIEW, value);
        return this;
    }

    public MovieGenreSelection movieOverviewStartsWith(String... value) {
        addStartsWith(MovieColumns.OVERVIEW, value);
        return this;
    }

    public MovieGenreSelection movieOverviewEndsWith(String... value) {
        addEndsWith(MovieColumns.OVERVIEW, value);
        return this;
    }

    public MovieGenreSelection orderByMovieOverview(boolean desc) {
        orderBy(MovieColumns.OVERVIEW, desc);
        return this;
    }

    public MovieGenreSelection orderByMovieOverview() {
        orderBy(MovieColumns.OVERVIEW, false);
        return this;
    }

    public MovieGenreSelection movieReleaseDate(Long... value) {
        addEquals(MovieColumns.RELEASE_DATE, value);
        return this;
    }

    public MovieGenreSelection movieReleaseDateNot(Long... value) {
        addNotEquals(MovieColumns.RELEASE_DATE, value);
        return this;
    }

    public MovieGenreSelection movieReleaseDateGt(long value) {
        addGreaterThan(MovieColumns.RELEASE_DATE, value);
        return this;
    }

    public MovieGenreSelection movieReleaseDateGtEq(long value) {
        addGreaterThanOrEquals(MovieColumns.RELEASE_DATE, value);
        return this;
    }

    public MovieGenreSelection movieReleaseDateLt(long value) {
        addLessThan(MovieColumns.RELEASE_DATE, value);
        return this;
    }

    public MovieGenreSelection movieReleaseDateLtEq(long value) {
        addLessThanOrEquals(MovieColumns.RELEASE_DATE, value);
        return this;
    }

    public MovieGenreSelection orderByMovieReleaseDate(boolean desc) {
        orderBy(MovieColumns.RELEASE_DATE, desc);
        return this;
    }

    public MovieGenreSelection orderByMovieReleaseDate() {
        orderBy(MovieColumns.RELEASE_DATE, false);
        return this;
    }

    public MovieGenreSelection moviePosterPath(String... value) {
        addEquals(MovieColumns.POSTER_PATH, value);
        return this;
    }

    public MovieGenreSelection moviePosterPathNot(String... value) {
        addNotEquals(MovieColumns.POSTER_PATH, value);
        return this;
    }

    public MovieGenreSelection moviePosterPathLike(String... value) {
        addLike(MovieColumns.POSTER_PATH, value);
        return this;
    }

    public MovieGenreSelection moviePosterPathContains(String... value) {
        addContains(MovieColumns.POSTER_PATH, value);
        return this;
    }

    public MovieGenreSelection moviePosterPathStartsWith(String... value) {
        addStartsWith(MovieColumns.POSTER_PATH, value);
        return this;
    }

    public MovieGenreSelection moviePosterPathEndsWith(String... value) {
        addEndsWith(MovieColumns.POSTER_PATH, value);
        return this;
    }

    public MovieGenreSelection orderByMoviePosterPath(boolean desc) {
        orderBy(MovieColumns.POSTER_PATH, desc);
        return this;
    }

    public MovieGenreSelection orderByMoviePosterPath() {
        orderBy(MovieColumns.POSTER_PATH, false);
        return this;
    }

    public MovieGenreSelection moviePopularity(Double... value) {
        addEquals(MovieColumns.POPULARITY, value);
        return this;
    }

    public MovieGenreSelection moviePopularityNot(Double... value) {
        addNotEquals(MovieColumns.POPULARITY, value);
        return this;
    }

    public MovieGenreSelection moviePopularityGt(double value) {
        addGreaterThan(MovieColumns.POPULARITY, value);
        return this;
    }

    public MovieGenreSelection moviePopularityGtEq(double value) {
        addGreaterThanOrEquals(MovieColumns.POPULARITY, value);
        return this;
    }

    public MovieGenreSelection moviePopularityLt(double value) {
        addLessThan(MovieColumns.POPULARITY, value);
        return this;
    }

    public MovieGenreSelection moviePopularityLtEq(double value) {
        addLessThanOrEquals(MovieColumns.POPULARITY, value);
        return this;
    }

    public MovieGenreSelection orderByMoviePopularity(boolean desc) {
        orderBy(MovieColumns.POPULARITY, desc);
        return this;
    }

    public MovieGenreSelection orderByMoviePopularity() {
        orderBy(MovieColumns.POPULARITY, false);
        return this;
    }

    public MovieGenreSelection movieVoteAverage(Double... value) {
        addEquals(MovieColumns.VOTE_AVERAGE, value);
        return this;
    }

    public MovieGenreSelection movieVoteAverageNot(Double... value) {
        addNotEquals(MovieColumns.VOTE_AVERAGE, value);
        return this;
    }

    public MovieGenreSelection movieVoteAverageGt(double value) {
        addGreaterThan(MovieColumns.VOTE_AVERAGE, value);
        return this;
    }

    public MovieGenreSelection movieVoteAverageGtEq(double value) {
        addGreaterThanOrEquals(MovieColumns.VOTE_AVERAGE, value);
        return this;
    }

    public MovieGenreSelection movieVoteAverageLt(double value) {
        addLessThan(MovieColumns.VOTE_AVERAGE, value);
        return this;
    }

    public MovieGenreSelection movieVoteAverageLtEq(double value) {
        addLessThanOrEquals(MovieColumns.VOTE_AVERAGE, value);
        return this;
    }

    public MovieGenreSelection orderByMovieVoteAverage(boolean desc) {
        orderBy(MovieColumns.VOTE_AVERAGE, desc);
        return this;
    }

    public MovieGenreSelection orderByMovieVoteAverage() {
        orderBy(MovieColumns.VOTE_AVERAGE, false);
        return this;
    }

    public MovieGenreSelection movieVoteCount(Integer... value) {
        addEquals(MovieColumns.VOTE_COUNT, value);
        return this;
    }

    public MovieGenreSelection movieVoteCountNot(Integer... value) {
        addNotEquals(MovieColumns.VOTE_COUNT, value);
        return this;
    }

    public MovieGenreSelection movieVoteCountGt(int value) {
        addGreaterThan(MovieColumns.VOTE_COUNT, value);
        return this;
    }

    public MovieGenreSelection movieVoteCountGtEq(int value) {
        addGreaterThanOrEquals(MovieColumns.VOTE_COUNT, value);
        return this;
    }

    public MovieGenreSelection movieVoteCountLt(int value) {
        addLessThan(MovieColumns.VOTE_COUNT, value);
        return this;
    }

    public MovieGenreSelection movieVoteCountLtEq(int value) {
        addLessThanOrEquals(MovieColumns.VOTE_COUNT, value);
        return this;
    }

    public MovieGenreSelection orderByMovieVoteCount(boolean desc) {
        orderBy(MovieColumns.VOTE_COUNT, desc);
        return this;
    }

    public MovieGenreSelection orderByMovieVoteCount() {
        orderBy(MovieColumns.VOTE_COUNT, false);
        return this;
    }

    public MovieGenreSelection genreId(long... value) {
        addEquals(MovieGenreColumns.GENRE_ID, toObjectArray(value));
        return this;
    }

    public MovieGenreSelection genreIdNot(long... value) {
        addNotEquals(MovieGenreColumns.GENRE_ID, toObjectArray(value));
        return this;
    }

    public MovieGenreSelection genreIdGt(long value) {
        addGreaterThan(MovieGenreColumns.GENRE_ID, value);
        return this;
    }

    public MovieGenreSelection genreIdGtEq(long value) {
        addGreaterThanOrEquals(MovieGenreColumns.GENRE_ID, value);
        return this;
    }

    public MovieGenreSelection genreIdLt(long value) {
        addLessThan(MovieGenreColumns.GENRE_ID, value);
        return this;
    }

    public MovieGenreSelection genreIdLtEq(long value) {
        addLessThanOrEquals(MovieGenreColumns.GENRE_ID, value);
        return this;
    }

    public MovieGenreSelection orderByGenreId(boolean desc) {
        orderBy(MovieGenreColumns.GENRE_ID, desc);
        return this;
    }

    public MovieGenreSelection orderByGenreId() {
        orderBy(MovieGenreColumns.GENRE_ID, false);
        return this;
    }

    public MovieGenreSelection genreGenreMoviedbId(int... value) {
        addEquals(GenreColumns.GENRE_MOVIEDB_ID, toObjectArray(value));
        return this;
    }

    public MovieGenreSelection genreGenreMoviedbIdNot(int... value) {
        addNotEquals(GenreColumns.GENRE_MOVIEDB_ID, toObjectArray(value));
        return this;
    }

    public MovieGenreSelection genreGenreMoviedbIdGt(int value) {
        addGreaterThan(GenreColumns.GENRE_MOVIEDB_ID, value);
        return this;
    }

    public MovieGenreSelection genreGenreMoviedbIdGtEq(int value) {
        addGreaterThanOrEquals(GenreColumns.GENRE_MOVIEDB_ID, value);
        return this;
    }

    public MovieGenreSelection genreGenreMoviedbIdLt(int value) {
        addLessThan(GenreColumns.GENRE_MOVIEDB_ID, value);
        return this;
    }

    public MovieGenreSelection genreGenreMoviedbIdLtEq(int value) {
        addLessThanOrEquals(GenreColumns.GENRE_MOVIEDB_ID, value);
        return this;
    }

    public MovieGenreSelection orderByGenreGenreMoviedbId(boolean desc) {
        orderBy(GenreColumns.GENRE_MOVIEDB_ID, desc);
        return this;
    }

    public MovieGenreSelection orderByGenreGenreMoviedbId() {
        orderBy(GenreColumns.GENRE_MOVIEDB_ID, false);
        return this;
    }

    public MovieGenreSelection genreName(String... value) {
        addEquals(GenreColumns.NAME, value);
        return this;
    }

    public MovieGenreSelection genreNameNot(String... value) {
        addNotEquals(GenreColumns.NAME, value);
        return this;
    }

    public MovieGenreSelection genreNameLike(String... value) {
        addLike(GenreColumns.NAME, value);
        return this;
    }

    public MovieGenreSelection genreNameContains(String... value) {
        addContains(GenreColumns.NAME, value);
        return this;
    }

    public MovieGenreSelection genreNameStartsWith(String... value) {
        addStartsWith(GenreColumns.NAME, value);
        return this;
    }

    public MovieGenreSelection genreNameEndsWith(String... value) {
        addEndsWith(GenreColumns.NAME, value);
        return this;
    }

    public MovieGenreSelection orderByGenreName(boolean desc) {
        orderBy(GenreColumns.NAME, desc);
        return this;
    }

    public MovieGenreSelection orderByGenreName() {
        orderBy(GenreColumns.NAME, false);
        return this;
    }
}
app/src/main/java/com/franktan/popularmovies/data/favorite/FavoriteColumns.java
public class FavoriteColumns implements BaseColumns {
    public static final String TABLE_NAME = "favorite";
    public static final Uri CONTENT_URI = Uri.parse(MovieProvider.CONTENT_URI_BASE + "/" + TABLE_NAME);

    /**
     * Primary key.
     */
    public static final String _ID = BaseColumns._ID;

    /**
     * the moviedb id of the favorite movie
     */
    public static final String FAVORITE_MOVIEDB_ID = "favorite_moviedb_id";

    /**
     * the date and time when user favorites this movie
     */
    public static final String CREATED = "created";


    public static final String DEFAULT_ORDER = TABLE_NAME + "." +_ID;

    // @formatter:off
    public static final String[] ALL_COLUMNS = new String[] {
            _ID,
            FAVORITE_MOVIEDB_ID,
            CREATED
    };
    // @formatter:on

    public static boolean hasColumns(String[] projection) {
        if (projection == null) return true;
        for (String c : projection) {
            if (c.equals(FAVORITE_MOVIEDB_ID) || c.contains("." + FAVORITE_MOVIEDB_ID)) return true;
            if (c.equals(CREATED) || c.contains("." + CREATED)) return true;
        }
        return false;
    }

    public static final String PREFIX_MOVIE = TABLE_NAME + "__" + MovieColumns.TABLE_NAME;
}
app/src/main/java/com/franktan/popularmovies/data/favorite/FavoriteSelection.java
public class FavoriteSelection extends AbstractSelection<FavoriteSelection> {
    @Override
    protected Uri baseUri() {
        return FavoriteColumns.CONTENT_URI;
    }

    /**
     * Query the given content resolver using this selection.
     *
     * @param contentResolver The content resolver to query.
     * @param projection A list of which columns to return. Passing null will return all columns, which is inefficient.
     * @return A {@code FavoriteCursor} object, which is positioned before the first entry, or null.
     */
    public FavoriteCursor query(ContentResolver contentResolver, String[] projection) {
        Cursor cursor = contentResolver.query(uri(), projection, sel(), args(), order());
        if (cursor == null) return null;
        return new FavoriteCursor(cursor);
    }

    /**
     * Equivalent of calling {@code query(contentResolver, null)}.
     */
    public FavoriteCursor query(ContentResolver contentResolver) {
        return query(contentResolver, null);
    }

    /**
     * Query the given content resolver using this selection.
     *
     * @param context The context to use for the query.
     * @param projection A list of which columns to return. Passing null will return all columns, which is inefficient.
     * @return A {@code FavoriteCursor} object, which is positioned before the first entry, or null.
     */
    public FavoriteCursor query(Context context, String[] projection) {
        Cursor cursor = context.getContentResolver().query(uri(), projection, sel(), args(), order());
        if (cursor == null) return null;
        return new FavoriteCursor(cursor);
    }

    /**
     * Equivalent of calling {@code query(context, null)}.
     */
    public FavoriteCursor query(Context context) {
        return query(context, null);
    }


    public FavoriteSelection id(long... value) {
        addEquals("favorite." + FavoriteColumns._ID, toObjectArray(value));
        return this;
    }

    public FavoriteSelection idNot(long... value) {
        addNotEquals("favorite." + FavoriteColumns._ID, toObjectArray(value));
        return this;
    }

    public FavoriteSelection orderById(boolean desc) {
        orderBy("favorite." + FavoriteColumns._ID, desc);
        return this;
    }

    public FavoriteSelection orderById() {
        return orderById(false);
    }

    public FavoriteSelection favoriteMoviedbId(long... value) {
        addEquals(FavoriteColumns.FAVORITE_MOVIEDB_ID, toObjectArray(value));
        return this;
    }

    public FavoriteSelection favoriteMoviedbIdNot(long... value) {
        addNotEquals(FavoriteColumns.FAVORITE_MOVIEDB_ID, toObjectArray(value));
        return this;
    }

    public FavoriteSelection favoriteMoviedbIdGt(long value) {
        addGreaterThan(FavoriteColumns.FAVORITE_MOVIEDB_ID, value);
        return this;
    }

    public FavoriteSelection favoriteMoviedbIdGtEq(long value) {
        addGreaterThanOrEquals(FavoriteColumns.FAVORITE_MOVIEDB_ID, value);
        return this;
    }

    public FavoriteSelection favoriteMoviedbIdLt(long value) {
        addLessThan(FavoriteColumns.FAVORITE_MOVIEDB_ID, value);
        return this;
    }

    public FavoriteSelection favoriteMoviedbIdLtEq(long value) {
        addLessThanOrEquals(FavoriteColumns.FAVORITE_MOVIEDB_ID, value);
        return this;
    }

    public FavoriteSelection orderByFavoriteMoviedbId(boolean desc) {
        orderBy(FavoriteColumns.FAVORITE_MOVIEDB_ID, desc);
        return this;
    }

    public FavoriteSelection orderByFavoriteMoviedbId() {
        orderBy(FavoriteColumns.FAVORITE_MOVIEDB_ID, false);
        return this;
    }

    public FavoriteSelection movieMovieMoviedbId(long... value) {
        addEquals(MovieColumns.MOVIE_MOVIEDB_ID, toObjectArray(value));
        return this;
    }

    public FavoriteSelection movieMovieMoviedbIdNot(long... value) {
        addNotEquals(MovieColumns.MOVIE_MOVIEDB_ID, toObjectArray(value));
        return this;
    }

    public FavoriteSelection movieMovieMoviedbIdGt(long value) {
        addGreaterThan(MovieColumns.MOVIE_MOVIEDB_ID, value);
        return this;
    }

    public FavoriteSelection movieMovieMoviedbIdGtEq(long value) {
        addGreaterThanOrEquals(MovieColumns.MOVIE_MOVIEDB_ID, value);
        return this;
    }

    public FavoriteSelection movieMovieMoviedbIdLt(long value) {
        addLessThan(MovieColumns.MOVIE_MOVIEDB_ID, value);
        return this;
    }

    public FavoriteSelection movieMovieMoviedbIdLtEq(long value) {
        addLessThanOrEquals(MovieColumns.MOVIE_MOVIEDB_ID, value);
        return this;
    }

    public FavoriteSelection orderByMovieMovieMoviedbId(boolean desc) {
        orderBy(MovieColumns.MOVIE_MOVIEDB_ID, desc);
        return this;
    }

    public FavoriteSelection orderByMovieMovieMoviedbId() {
        orderBy(MovieColumns.MOVIE_MOVIEDB_ID, false);
        return this;
    }

    public FavoriteSelection movieTitle(String... value) {
        addEquals(MovieColumns.TITLE, value);
        return this;
    }

    public FavoriteSelection movieTitleNot(String... value) {
        addNotEquals(MovieColumns.TITLE, value);
        return this;
    }

    public FavoriteSelection movieTitleLike(String... value) {
        addLike(MovieColumns.TITLE, value);
        return this;
    }

    public FavoriteSelection movieTitleContains(String... value) {
        addContains(MovieColumns.TITLE, value);
        return this;
    }

    public FavoriteSelection movieTitleStartsWith(String... value) {
        addStartsWith(MovieColumns.TITLE, value);
        return this;
    }

    public FavoriteSelection movieTitleEndsWith(String... value) {
        addEndsWith(MovieColumns.TITLE, value);
        return this;
    }

    public FavoriteSelection orderByMovieTitle(boolean desc) {
        orderBy(MovieColumns.TITLE, desc);
        return this;
    }

    public FavoriteSelection orderByMovieTitle() {
        orderBy(MovieColumns.TITLE, false);
        return this;
    }

    public FavoriteSelection movieBackdropPath(String... value) {
        addEquals(MovieColumns.BACKDROP_PATH, value);
        return this;
    }

    public FavoriteSelection movieBackdropPathNot(String... value) {
        addNotEquals(MovieColumns.BACKDROP_PATH, value);
        return this;
    }

    public FavoriteSelection movieBackdropPathLike(String... value) {
        addLike(MovieColumns.BACKDROP_PATH, value);
        return this;
    }

    public FavoriteSelection movieBackdropPathContains(String... value) {
        addContains(MovieColumns.BACKDROP_PATH, value);
        return this;
    }

    public FavoriteSelection movieBackdropPathStartsWith(String... value) {
        addStartsWith(MovieColumns.BACKDROP_PATH, value);
        return this;
    }

    public FavoriteSelection movieBackdropPathEndsWith(String... value) {
        addEndsWith(MovieColumns.BACKDROP_PATH, value);
        return this;
    }

    public FavoriteSelection orderByMovieBackdropPath(boolean desc) {
        orderBy(MovieColumns.BACKDROP_PATH, desc);
        return this;
    }

    public FavoriteSelection orderByMovieBackdropPath() {
        orderBy(MovieColumns.BACKDROP_PATH, false);
        return this;
    }

    public FavoriteSelection movieOriginalLan(String... value) {
        addEquals(MovieColumns.ORIGINAL_LAN, value);
        return this;
    }

    public FavoriteSelection movieOriginalLanNot(String... value) {
        addNotEquals(MovieColumns.ORIGINAL_LAN, value);
        return this;
    }

    public FavoriteSelection movieOriginalLanLike(String... value) {
        addLike(MovieColumns.ORIGINAL_LAN, value);
        return this;
    }

    public FavoriteSelection movieOriginalLanContains(String... value) {
        addContains(MovieColumns.ORIGINAL_LAN, value);
        return this;
    }

    public FavoriteSelection movieOriginalLanStartsWith(String... value) {
        addStartsWith(MovieColumns.ORIGINAL_LAN, value);
        return this;
    }

    public FavoriteSelection movieOriginalLanEndsWith(String... value) {
        addEndsWith(MovieColumns.ORIGINAL_LAN, value);
        return this;
    }

    public FavoriteSelection orderByMovieOriginalLan(boolean desc) {
        orderBy(MovieColumns.ORIGINAL_LAN, desc);
        return this;
    }

    public FavoriteSelection orderByMovieOriginalLan() {
        orderBy(MovieColumns.ORIGINAL_LAN, false);
        return this;
    }

    public FavoriteSelection movieOriginalTitle(String... value) {
        addEquals(MovieColumns.ORIGINAL_TITLE, value);
        return this;
    }

    public FavoriteSelection movieOriginalTitleNot(String... value) {
        addNotEquals(MovieColumns.ORIGINAL_TITLE, value);
        return this;
    }

    public FavoriteSelection movieOriginalTitleLike(String... value) {
        addLike(MovieColumns.ORIGINAL_TITLE, value);
        return this;
    }

    public FavoriteSelection movieOriginalTitleContains(String... value) {
        addContains(MovieColumns.ORIGINAL_TITLE, value);
        return this;
    }

    public FavoriteSelection movieOriginalTitleStartsWith(String... value) {
        addStartsWith(MovieColumns.ORIGINAL_TITLE, value);
        return this;
    }

    public FavoriteSelection movieOriginalTitleEndsWith(String... value) {
        addEndsWith(MovieColumns.ORIGINAL_TITLE, value);
        return this;
    }

    public FavoriteSelection orderByMovieOriginalTitle(boolean desc) {
        orderBy(MovieColumns.ORIGINAL_TITLE, desc);
        return this;
    }

    public FavoriteSelection orderByMovieOriginalTitle() {
        orderBy(MovieColumns.ORIGINAL_TITLE, false);
        return this;
    }

    public FavoriteSelection movieOverview(String... value) {
        addEquals(MovieColumns.OVERVIEW, value);
        return this;
    }

    public FavoriteSelection movieOverviewNot(String... value) {
        addNotEquals(MovieColumns.OVERVIEW, value);
        return this;
    }

    public FavoriteSelection movieOverviewLike(String... value) {
        addLike(MovieColumns.OVERVIEW, value);
        return this;
    }

    public FavoriteSelection movieOverviewContains(String... value) {
        addContains(MovieColumns.OVERVIEW, value);
        return this;
    }

    public FavoriteSelection movieOverviewStartsWith(String... value) {
        addStartsWith(MovieColumns.OVERVIEW, value);
        return this;
    }

    public FavoriteSelection movieOverviewEndsWith(String... value) {
        addEndsWith(MovieColumns.OVERVIEW, value);
        return this;
    }

    public FavoriteSelection orderByMovieOverview(boolean desc) {
        orderBy(MovieColumns.OVERVIEW, desc);
        return this;
    }

    public FavoriteSelection orderByMovieOverview() {
        orderBy(MovieColumns.OVERVIEW, false);
        return this;
    }

    public FavoriteSelection movieReleaseDate(Long... value) {
        addEquals(MovieColumns.RELEASE_DATE, value);
        return this;
    }

    public FavoriteSelection movieReleaseDateNot(Long... value) {
        addNotEquals(MovieColumns.RELEASE_DATE, value);
        return this;
    }

    public FavoriteSelection movieReleaseDateGt(long value) {
        addGreaterThan(MovieColumns.RELEASE_DATE, value);
        return this;
    }

    public FavoriteSelection movieReleaseDateGtEq(long value) {
        addGreaterThanOrEquals(MovieColumns.RELEASE_DATE, value);
        return this;
    }

    public FavoriteSelection movieReleaseDateLt(long value) {
        addLessThan(MovieColumns.RELEASE_DATE, value);
        return this;
    }

    public FavoriteSelection movieReleaseDateLtEq(long value) {
        addLessThanOrEquals(MovieColumns.RELEASE_DATE, value);
        return this;
    }

    public FavoriteSelection orderByMovieReleaseDate(boolean desc) {
        orderBy(MovieColumns.RELEASE_DATE, desc);
        return this;
    }

    public FavoriteSelection orderByMovieReleaseDate() {
        orderBy(MovieColumns.RELEASE_DATE, false);
        return this;
    }

    public FavoriteSelection moviePosterPath(String... value) {
        addEquals(MovieColumns.POSTER_PATH, value);
        return this;
    }

    public FavoriteSelection moviePosterPathNot(String... value) {
        addNotEquals(MovieColumns.POSTER_PATH, value);
        return this;
    }

    public FavoriteSelection moviePosterPathLike(String... value) {
        addLike(MovieColumns.POSTER_PATH, value);
        return this;
    }

    public FavoriteSelection moviePosterPathContains(String... value) {
        addContains(MovieColumns.POSTER_PATH, value);
        return this;
    }

    public FavoriteSelection moviePosterPathStartsWith(String... value) {
        addStartsWith(MovieColumns.POSTER_PATH, value);
        return this;
    }

    public FavoriteSelection moviePosterPathEndsWith(String... value) {
        addEndsWith(MovieColumns.POSTER_PATH, value);
        return this;
    }

    public FavoriteSelection orderByMoviePosterPath(boolean desc) {
        orderBy(MovieColumns.POSTER_PATH, desc);
        return this;
    }

    public FavoriteSelection orderByMoviePosterPath() {
        orderBy(MovieColumns.POSTER_PATH, false);
        return this;
    }

    public FavoriteSelection moviePopularity(Double... value) {
        addEquals(MovieColumns.POPULARITY, value);
        return this;
    }

    public FavoriteSelection moviePopularityNot(Double... value) {
        addNotEquals(MovieColumns.POPULARITY, value);
        return this;
    }

    public FavoriteSelection moviePopularityGt(double value) {
        addGreaterThan(MovieColumns.POPULARITY, value);
        return this;
    }

    public FavoriteSelection moviePopularityGtEq(double value) {
        addGreaterThanOrEquals(MovieColumns.POPULARITY, value);
        return this;
    }

    public FavoriteSelection moviePopularityLt(double value) {
        addLessThan(MovieColumns.POPULARITY, value);
        return this;
    }

    public FavoriteSelection moviePopularityLtEq(double value) {
        addLessThanOrEquals(MovieColumns.POPULARITY, value);
        return this;
    }

    public FavoriteSelection orderByMoviePopularity(boolean desc) {
        orderBy(MovieColumns.POPULARITY, desc);
        return this;
    }

    public FavoriteSelection orderByMoviePopularity() {
        orderBy(MovieColumns.POPULARITY, false);
        return this;
    }

    public FavoriteSelection movieVoteAverage(Double... value) {
        addEquals(MovieColumns.VOTE_AVERAGE, value);
        return this;
    }

    public FavoriteSelection movieVoteAverageNot(Double... value) {
        addNotEquals(MovieColumns.VOTE_AVERAGE, value);
        return this;
    }

    public FavoriteSelection movieVoteAverageGt(double value) {
        addGreaterThan(MovieColumns.VOTE_AVERAGE, value);
        return this;
    }

    public FavoriteSelection movieVoteAverageGtEq(double value) {
        addGreaterThanOrEquals(MovieColumns.VOTE_AVERAGE, value);
        return this;
    }

    public FavoriteSelection movieVoteAverageLt(double value) {
        addLessThan(MovieColumns.VOTE_AVERAGE, value);
        return this;
    }

    public FavoriteSelection movieVoteAverageLtEq(double value) {
        addLessThanOrEquals(MovieColumns.VOTE_AVERAGE, value);
        return this;
    }

    public FavoriteSelection orderByMovieVoteAverage(boolean desc) {
        orderBy(MovieColumns.VOTE_AVERAGE, desc);
        return this;
    }

    public FavoriteSelection orderByMovieVoteAverage() {
        orderBy(MovieColumns.VOTE_AVERAGE, false);
        return this;
    }

    public FavoriteSelection movieVoteCount(Integer... value) {
        addEquals(MovieColumns.VOTE_COUNT, value);
        return this;
    }

    public FavoriteSelection movieVoteCountNot(Integer... value) {
        addNotEquals(MovieColumns.VOTE_COUNT, value);
        return this;
    }

    public FavoriteSelection movieVoteCountGt(int value) {
        addGreaterThan(MovieColumns.VOTE_COUNT, value);
        return this;
    }

    public FavoriteSelection movieVoteCountGtEq(int value) {
        addGreaterThanOrEquals(MovieColumns.VOTE_COUNT, value);
        return this;
    }

    public FavoriteSelection movieVoteCountLt(int value) {
        addLessThan(MovieColumns.VOTE_COUNT, value);
        return this;
    }

    public FavoriteSelection movieVoteCountLtEq(int value) {
        addLessThanOrEquals(MovieColumns.VOTE_COUNT, value);
        return this;
    }

    public FavoriteSelection orderByMovieVoteCount(boolean desc) {
        orderBy(MovieColumns.VOTE_COUNT, desc);
        return this;
    }

    public FavoriteSelection orderByMovieVoteCount() {
        orderBy(MovieColumns.VOTE_COUNT, false);
        return this;
    }

    public FavoriteSelection created(Long... value) {
        addEquals(FavoriteColumns.CREATED, value);
        return this;
    }

    public FavoriteSelection createdNot(Long... value) {
        addNotEquals(FavoriteColumns.CREATED, value);
        return this;
    }

    public FavoriteSelection createdGt(long value) {
        addGreaterThan(FavoriteColumns.CREATED, value);
        return this;
    }

    public FavoriteSelection createdGtEq(long value) {
        addGreaterThanOrEquals(FavoriteColumns.CREATED, value);
        return this;
    }

    public FavoriteSelection createdLt(long value) {
        addLessThan(FavoriteColumns.CREATED, value);
        return this;
    }

    public FavoriteSelection createdLtEq(long value) {
        addLessThanOrEquals(FavoriteColumns.CREATED, value);
        return this;
    }

    public FavoriteSelection orderByCreated(boolean desc) {
        orderBy(FavoriteColumns.CREATED, desc);
        return this;
    }

    public FavoriteSelection orderByCreated() {
        orderBy(FavoriteColumns.CREATED, false);
        return this;
    }
}


Question: package com.franktan.popularmovies.data;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.database.Cursor;
import android.net.Uri;
import android.test.AndroidTestCase;
import android.util.Log;
import com.franktan.popularmovies.data.favorite.FavoriteColumns;
import com.franktan.popularmovies.data.favorite.FavoriteCursor;
import com.franktan.popularmovies.data.favorite.FavoriteSelection;
import com.franktan.popularmovies.data.genre.GenreColumns;
import com.franktan.popularmovies.data.movie.MovieColumns;
import com.franktan.popularmovies.data.movie.MovieCursor;
import com.franktan.popularmovies.data.movie.MovieSelection;
import com.franktan.popularmovies.data.moviegenre.MovieGenreColumns;
import com.franktan.popularmovies.data.moviegenre.MovieGenreCursor;
import com.franktan.popularmovies.data.moviegenre.MovieGenreSelection;
import com.franktan.popularmovies.data.review.ReviewColumns;
import com.franktan.popularmovies.data.trailer.TrailerColumns;
import com.franktan.popularmovies.util.Constants;



/**
 * Created by tan on 15/08/2015.
 */
public class MovieProviderTest extends AndroidTestCase {

    static private final int BULK_INSERT_RECORDS_TO_INSERT = 10;
    private static final String TYPE_CURSOR_ITEM = "vnd.android.cursor.item/";
    private static final String TYPE_CURSOR_DIR = "vnd.android.cursor.dir/";

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        deleteAllRecords();
    }

    /**
     * Test content provider is registered properly
     */
    public void testProviderRegistry() {
        PackageManager pm = mContext.getPackageManager();

        // We define the component name based on the package name from the context and the
        // WeatherProvider class.
        ComponentName componentName = new ComponentName(mContext.getPackageName(),
                MovieProvider.class.getName());
        try {
            // Fetch the provider info using the component name from the PackageManager
            // This throws an exception if the provider isn't registered.
            ProviderInfo providerInfo = pm.getProviderInfo(componentName, 0);

            // Make sure that the registered authority matches the authority from the Contract.
            assertEquals("Error: MovieProvider registered with authority: " + providerInfo.authority +
                            " instead of authority: " + MovieProvider.AUTHORITY,
                    providerInfo.authority, MovieProvider.AUTHORITY);
        } catch (PackageManager.NameNotFoundException e) {
            // I guess the provider isn't registered correctly.
            assertTrue("Error: MovieProvider not registered at " + mContext.getPackageName(),
                    false);
        }
    }

    /**
     * Test getType on movie uri
     */
    public void testProviderGetTypeMovie() {
        // content://com.franktan.popularmovies/movie/
        String type = mContext.getContentResolver().getType(MovieColumns.CONTENT_URI);

        // vnd.android.cursor.dir/movie
        assertTrue("the Movie CONTENT_URI should return correct CONTENT_TYPE",
                type.equals(TYPE_CURSOR_DIR + MovieColumns.TABLE_NAME));

        int id = 1;
        // content://com.franktan.popularmovie/movie/1
        type = mContext.getContentResolver().getType(
                ContentUris.withAppendedId(MovieColumns.CONTENT_URI,id));
        Log.d(Constants.APP_NAME, type);
        // vnd.android.cursor.item/movie/1
        assertTrue("Movie uri content type should be parsed",
                type.equals(TYPE_CURSOR_ITEM+MovieColumns.TABLE_NAME));
    }

    /**
     * Test getType on trailer uri
     */
    public void testProviderGetTypeTrailer() {
        String type = mContext.getContentResolver().getType(TrailerColumns.CONTENT_URI);

        assertTrue("the Trailer CONTENT_URI should return correct CONTENT_TYPE",
                type.equals(TYPE_CURSOR_DIR + TrailerColumns.TABLE_NAME));

        int id = 1;
        type = mContext.getContentResolver().getType(
                ContentUris.withAppendedId(TrailerColumns.CONTENT_URI,id));
        Log.d(Constants.APP_NAME,type);
        assertTrue("Trailer uri content type should be parsed",
                type.equals(TYPE_CURSOR_ITEM+TrailerColumns.TABLE_NAME));
    }

    /**
     * Test getType on review uri
     */
    public void testProviderGetTypeReview() {
        String type = mContext.getContentResolver().getType(ReviewColumns.CONTENT_URI);

        assertTrue("the Review CONTENT_URI should return correct CONTENT_TYPE",
                type.equals(TYPE_CURSOR_DIR + ReviewColumns.TABLE_NAME));

        int id = 1;
        type = mContext.getContentResolver().getType(
                ContentUris.withAppendedId(ReviewColumns.CONTENT_URI,id));
        Log.d(Constants.APP_NAME,type);
        assertTrue("Review uri content type should be parsed",
                type.equals(TYPE_CURSOR_ITEM+ReviewColumns.TABLE_NAME));
    }

    /**
     * Test getType on Genre uri
     */
    public void testProviderGetTypeGenre() {
        String type = mContext.getContentResolver().getType(GenreColumns.CONTENT_URI);

        assertTrue("the Genre CONTENT_URI should return correct CONTENT_TYPE",
                type.equals(TYPE_CURSOR_DIR + GenreColumns.TABLE_NAME));

        int id = 1;
        type = mContext.getContentResolver().getType(
                ContentUris.withAppendedId(GenreColumns.CONTENT_URI,id));
        Log.d(Constants.APP_NAME, type);
        assertTrue("Genre uri content type should be parsed",
                type.equals(TYPE_CURSOR_ITEM + GenreColumns.TABLE_NAME));
    }

    /**
     * Test getType on movie_genre uri
     */
    public void testProviderGetTypeMovieGenre() {
        String type = mContext.getContentResolver().getType(MovieGenreColumns.CONTENT_URI);

        assertTrue("the MovieGenre CONTENT_URI should return correct CONTENT_TYPE",
                type.equals(TYPE_CURSOR_DIR + MovieGenreColumns.TABLE_NAME));

        int id = 1;
        type = mContext.getContentResolver().getType(
                ContentUris.withAppendedId(MovieGenreColumns.CONTENT_URI,id));
        Log.d(Constants.APP_NAME,type);
        assertTrue("MovieGenre uri content type should be parsed",
                type.equals(TYPE_CURSOR_ITEM+MovieGenreColumns.TABLE_NAME));
    }

    /**
     * Test getType on favorite uri
     */
    public void testProviderGetTypeFavorite() {
        String type = mContext.getContentResolver().getType(FavoriteColumns.CONTENT_URI);

        assertTrue("the favorite CONTENT_URI should return correct CONTENT_TYPE",
                type.equals(TYPE_CURSOR_DIR + FavoriteColumns.TABLE_NAME));

        int id = 1;
        type = mContext.getContentResolver().getType(
                ContentUris.withAppendedId(FavoriteColumns.CONTENT_URI,id));
        Log.d(Constants.APP_NAME, type);
        assertTrue("favorite uri content type should be parsed",
                type.equals(TYPE_CURSOR_ITEM + FavoriteColumns.TABLE_NAME));
    }

    /**
     * Insert using direct SQLiteDbHelper and test query using content provider
     */
    public void testProviderQuery() {

        long movieRowId = DataTestUtilities.insertMovieTestEntry(mContext);

        // Test the basic content provider query
        Cursor movieCursor = mContext.getContentResolver().query(
                MovieColumns.CONTENT_URI,
                null,
                null,
                null,
                null
        );

        // Make sure we get the correct cursor out of the database
        DataTestUtilities.validateMovieCursor("basic movie query", movieCursor, DataTestUtilities.createMovieEntry());

        movieCursor.close();

        MovieSelection where = new MovieSelection();
        where.id(movieRowId);
        Cursor cursorById = mContext.getContentResolver().query(MovieColumns.CONTENT_URI,null,where.sel(),where.args(),null);
        DataTestUtilities.validateMovieCursor("query by id using library's syntax", cursorById, DataTestUtilities.createMovieEntry());

Answer:         MovieCursor mc = new MovieCursor(cursorById);