def check_stop_times(
    feed: "Feed", *, as_df: bool = False, include_warnings: bool = False
) -> List:
    """
    Analog of :func:`check_agency` for ``feed.stop_times``.
    """
    table = "stop_times"
    problems = []

    # Preliminary checks
    if feed.stop_times is None:
        problems.append(["error", "Missing table", table, []])
    else:
        f = feed.stop_times.copy().sort_values(["trip_id", "stop_sequence"])
        problems = check_for_required_columns(problems, table, f)
    if problems:
        return format_problems(problems, as_df=as_df)

    if include_warnings:
        problems = check_for_invalid_columns(problems, table, f)

    # Check trip_id
    problems = check_column_linked_id(
        problems, table, f, "trip_id", feed.trips
    )

    # Check arrival_time and departure_time
    v = lambda x: pd.isnull(x) or valid_time(x)
    for col in ["arrival_time", "departure_time"]:
        problems = check_column(problems, table, f, col, v)

    # Check that arrival and departure times exist for the first and last
    # stop of each trip and for each timepoint.
    # For feeds with many trips, iterating through the stop time rows is
    # faster than uisg groupby.
    if "timepoint" not in f.columns:
        f["timepoint"] = np.nan  # This will not mess up later timepoint check

    indices = []
    prev_tid = None
    prev_atime = 1
    prev_dtime = 1
    for i, tid, atime, dtime, tp in f[
        ["trip_id", "arrival_time", "departure_time", "timepoint"]
    ].itertuples():
        if tid != prev_tid:
            # Check last stop of previous trip
            if pd.isnull(prev_atime) or pd.isnull(prev_dtime):
                indices.append(i - 1)
            # Check first stop of current trip
            if pd.isnull(atime) or pd.isnull(dtime):
                indices.append(i)
        elif tp == 1 and (pd.isnull(atime) or pd.isnull(dtime)):
            # Failure at timepoint
            indices.append(i)

        prev_tid = tid
        prev_atime = atime
        prev_dtime = dtime

    if indices:
        problems.append(
            [
                "error",
                "First/last/time point arrival/departure time missing",
                table,
                indices,
            ]
        )

    # Check stop_id
    problems = check_column_linked_id(
        problems, table, f, "stop_id", feed.stops
    )

    # Check for duplicated (trip_id, stop_sequence) pairs
    cond = f[["trip_id", "stop_sequence"]].dropna().duplicated()
    problems = check_table(
        problems, table, f, cond, "Repeated pair (trip_id, stop_sequence)"
    )

    # Check stop_headsign
    problems = check_column(
        problems, table, f, "stop_headsign", valid_str, column_required=False
    )

    # Check pickup_type and drop_off_type
    for col in ["pickup_type", "drop_off_type"]:
        v = lambda x: x in range(4)
        problems = check_column(
            problems, table, f, col, v, column_required=False
        )

    # Check if shape_dist_traveled decreases on a trip
    if "shape_dist_traveled" in f.columns:
        g = f.dropna(subset=["shape_dist_traveled"])
        indices = []
        prev_tid = None
        prev_dist = -1
        for i, tid, dist in g[["trip_id", "shape_dist_traveled"]].itertuples():
            if tid == prev_tid and dist < prev_dist:
                indices.append(i)

            prev_tid = tid
            prev_dist = dist

        if indices:
            problems.append(
                [
                    "error",
                    "shape_dist_traveled decreases on a trip",
                    table,
                    indices,
                ]
            )

    # Check timepoint
    v = lambda x: x in range(2)
    problems = check_column(
        problems, table, f, "timepoint", v, column_required=False
    )

    if include_warnings:
        # Check for duplicated (trip_id, departure_time) pairs
        cond = f[["trip_id", "departure_time"]].duplicated()
        problems = check_table(
            problems,
            table,
            f,
            cond,
            "Repeated pair (trip_id, departure_time)",
            "warning",
        )

    return format_problems(problems, as_df=as_df)
Analog of :func:`check_agency` for ``feed.stop_times``.