'Filters the tasks of the job.
Pass in task_type and task_state as sets; None for "all".
task_text is used to search in the state, mostRecentState, and the ID.'

def filter_tasks(self, task_types=None, task_states=None, task_text=None):

    assert ((task_types is None) or job_tracker.VALID_TASK_TYPES.issuperset(task_types))
    assert ((task_states is None) or job_tracker.VALID_TASK_STATES.issuperset(task_states))
    def is_good_match(t):
        if (task_types is not None):
            if (t.task.taskID.taskTypeAsString.lower() not in task_types):
                return False
        if (task_states is not None):
            if (t.state.lower() not in task_states):
                return False
        if (task_text is not None):
            tt_lower = task_text.lower()
            if ((tt_lower not in t.state.lower()) and (tt_lower not in t.mostRecentState.lower()) and (tt_lower not in t.task.taskID.asString.lower())):
                return False
        return True
    return [t for t in self.tasks if is_good_match(t)]
