def find_sel_range(y, sline, eline=None, first=None, last=None, EF=None):
    """ Returns the first and last nodes in AST for given line range.

        y: module in the AST
        sline: start line number
        eline: end line number
        first: a tuple of the first module and line
        last: a tuple of the last module and line
        EF: an optional callback for using EndFinder to find the true endline of a module.

    """
    if EF is None:
        EF = lambda x: x

    if eline is None:
        eline = sline

    def helper(M, first=None, last=None):
        for n, stmt in enumerate(M):
            if sline <= EF(stmt.lineno):
                if stmt.lineno <= eline:
                    last = (M, n)  # last found statement in range
                    if first is None:
                        first = (M, n) # first found statement in rangef
            first, last = find_sel_range(stmt, sline, eline, first, last, EF)
        return first, last

    for elt in ['body', 'orelse', 'handlers', 'finalbody']:
        M = getattr(y, elt, None)
        if M is not None:
            first, last = helper(M, first, last)

    return first, last