def get_lines_from_to(strings: List[str],
                      firstlinestart: str,
                      list_of_lastline_starts: Iterable[Optional[str]]) \
        -> List[str]:
    """
    Takes a list of ``strings``. Returns a list of strings FROM
    ``firstlinestart`` (inclusive) TO the first of ``list_of_lastline_starts``
    (exclusive).

    To search to the end of the list, use ``list_of_lastline_starts = []``.

    To search to a blank line, use ``list_of_lastline_starts = [None]``
    """
    start_index = find_line_beginning(strings, firstlinestart)
    # log.debug("start_index: {}", start_index)
    if start_index == -1:
        return []
    end_offset = None  # itself a valid slice index
    for lls in list_of_lastline_starts:
        possible_end_offset = find_line_beginning(strings[start_index:], lls)
        # log.debug("lls {!r} -> possible_end_offset {}",
        #           lls, possible_end_offset)
        if possible_end_offset != -1:  # found one
            if end_offset is None or possible_end_offset < end_offset:
                end_offset = possible_end_offset
    end_index = None if end_offset is None else (start_index + end_offset)
    # log.debug("end_index: {}", end_index)
    return strings[start_index:end_index]