Estimate remaining time for all tasks in this channel.

    :param channel: txkoji.channel.Channel
    :param list states: list of task_states ints, eg [task_states.OPEN]
    :returns: deferred that when fired returns a list of
              (task, est_remaining) tuples

def task_estimates(channel, states):
    """
    Estimate remaining time for all tasks in this channel.

    :param channel: txkoji.channel.Channel
    :param list states: list of task_states ints, eg [task_states.OPEN]
    :returns: deferred that when fired returns a list of
              (task, est_remaining) tuples
    """
    for state in states:
        if state != task_states.OPEN:
            raise NotImplementedError('only estimate OPEN tasks')
    tasks = yield channel.tasks(state=states)
    # Estimate all the unique packages.
    packages = set([task.package for task in tasks])
    print('checking avg build duration for %i packages:' % len(packages))
    packages = list(packages)
    durations = yield average_build_durations(channel.connection, packages)
    avg_package_durations = dict(zip(packages, durations))
    # pprint(avg_package_durations)
    # Determine estimates for all our tasks.
    results = []
    utcnow = datetime.utcnow()
    for task in tasks:
        avg_duration = avg_package_durations[task.package]
        est_complete = task.started + avg_duration
        est_remaining = est_complete - utcnow
        result = (task, est_remaining)
        results.append(result)
    defer.returnValue(results)