func ListWatchUntil(timeout time.Duration, lw ListerWatcher, conditions ...ConditionFunc) (*Event, error) {
	if len(conditions) == 0 {
		return nil, nil
	}
	list, err := lw.List(api.ListOptions{})
	if err != nil {
		return nil, err
	}
	initialItems, err := meta.ExtractList(list)
	if err != nil {
		return nil, err
	}
	var lastEvent *Event
	currIndex := 0
	passedConditions := 0
	for _, condition := range conditions {
		if lastEvent != nil {
			done, err := condition(*lastEvent)
			if err != nil {
				return lastEvent, err
			}
			if done {
				passedConditions = passedConditions + 1
				continue
			}
		}
	ConditionSucceeded:
		for currIndex < len(initialItems) {
			lastEvent = &Event{Type: Added, Object: initialItems[currIndex]}
			currIndex++
			done, err := condition(*lastEvent)
			if err != nil {
				return lastEvent, err
			}
			if done {
				passedConditions = passedConditions + 1
				break ConditionSucceeded
			}
		}
	}
	if passedConditions == len(conditions) {
		return lastEvent, nil
	}
	remainingConditions := conditions[passedConditions:]
	metaObj, err := meta.ListAccessor(list)
	if err != nil {
		return nil, err
	}
	currResourceVersion := metaObj.GetResourceVersion()
	watch, err := lw.Watch(api.ListOptions{ResourceVersion: currResourceVersion})
	if err != nil {
		return nil, err
	}
	return Until(timeout, watch, remainingConditions...)
}
TODO: check for watch expired error and retry watch from latest point?  Same issue exists for Until.
package watch
import (
	"time"
	"k8s.io/client-go/pkg/api"
	"k8s.io/client-go/pkg/api/meta"
	"k8s.io/client-go/pkg/runtime"
	"k8s.io/client-go/pkg/util/wait"
)
type ConditionFunc func(event Event) (bool, error)
func Until(timeout time.Duration, watcher Interface, conditions ...ConditionFunc) (*Event, error) {
	ch := watcher.ResultChan()
	defer watcher.Stop()
	var after <-chan time.Time
	if timeout > 0 {
		after = time.After(timeout)
	} else {
		ch := make(chan time.Time)
		defer close(ch)
		after = ch
	}
	var lastEvent *Event
	for _, condition := range conditions {
		if lastEvent != nil {
			done, err := condition(*lastEvent)
			if err != nil {
				return lastEvent, err
			}
			if done {
				continue
			}
		}
	ConditionSucceeded:
		for {
			select {
			case event, ok := <-ch:
				if !ok {
					return lastEvent, wait.ErrWaitTimeout
				}
				lastEvent = &event
				done, err := condition(event)
				if err != nil {
					return lastEvent, err
				}
				if done {
					break ConditionSucceeded
				}
			case <-after:
				return lastEvent, wait.ErrWaitTimeout
			}
		}
	}
	return lastEvent, nil
}
type ListerWatcher interface {
	List(options api.ListOptions) (runtime.Object, error)
	Watch(options api.ListOptions) (Interface, error)
}