func verifyContainerOrderingStatusResolvable(target *apicontainer.Container, existingContainers map[string]*apicontainer.Container,
	resolves func(*apicontainer.Container, *apicontainer.Container, string) bool) (*apicontainer.DependsOn, error) {

	targetGoal := target.GetDesiredStatus()
	targetKnown := target.GetKnownStatus()
	if targetGoal != target.GetSteadyStateStatus() && targetGoal != apicontainerstatus.ContainerCreated {
		// A container can always stop, die, or reach whatever other state it
		// wants regardless of what dependencies it has
		return nil, nil
	}

	for _, dependency := range target.DependsOn {
		dependencyContainer, ok := existingContainers[dependency.ContainerName]
		if !ok {
			return nil, fmt.Errorf("dependency graph: container ordering dependency [%v] for target [%v] does not exist.", dependencyContainer, target)
		}

		// We want to check whether the dependency container has timed out only if target has not been created yet.
		// If the target is already created, then everything is normal and dependency can be and is resolved.
		// However, if dependency container has already stopped, then it cannot time out.
		if targetKnown < apicontainerstatus.ContainerCreated && dependencyContainer.GetKnownStatus() != apicontainerstatus.ContainerStopped {
			if hasDependencyTimedOut(dependencyContainer, dependency.Condition) {
				return nil, fmt.Errorf("dependency graph: container ordering dependency [%v] for target [%v] has timed out.", dependencyContainer, target)
			}
		}

		// We want to fail fast if the dependency container did not exit successfully' because target container
		// can then never progress to its desired state when the dependency condition is 'SUCCESS'
		if dependency.Condition == successCondition && dependencyContainer.GetKnownExitCode() != nil {
			if !hasDependencyStoppedSuccessfully(dependencyContainer, dependency.Condition) {
				return nil, fmt.Errorf("dependency graph: failed to resolve container ordering dependency [%v] for target [%v] as dependency did not exit successfully.", dependencyContainer, target)
			}
		}

		if !resolves(target, dependencyContainer, dependency.Condition) {
			return &dependency, fmt.Errorf("dependency graph: failed to resolve the container ordering dependency [%v] for target [%v]", dependencyContainer, target)
		}
	}
	return nil, nil
}
func verifyContainerOrderingStatusResolvable(target *apicontainer.Container, existingContainers map[string]*apicontainer.Container,
	resolves func(*apicontainer.Container, *apicontainer.Container, string) bool) (*apicontainer.DependsOn, error) {

	targetGoal := target.GetDesiredStatus()
	targetKnown := target.GetKnownStatus()
	if targetGoal != target.GetSteadyStateStatus() && targetGoal != apicontainerstatus.ContainerCreated {
		// A container can always stop, die, or reach whatever other state it
		// wants regardless of what dependencies it has
		return nil, nil
	}

	for _, dependency := range target.DependsOn {
		dependencyContainer, ok := existingContainers[dependency.ContainerName]
		if !ok {
			return nil, fmt.Errorf("dependency graph: container ordering dependency [%v] for target [%v] does not exist.", dependencyContainer, target)
		}

		// We want to check whether the dependency container has timed out only if target has not been created yet.
		// If the target is already created, then everything is normal and dependency can be and is resolved.
		// However, if dependency container has already stopped, then it cannot time out.
		if targetKnown < apicontainerstatus.ContainerCreated && dependencyContainer.GetKnownStatus() != apicontainerstatus.ContainerStopped {
			if hasDependencyTimedOut(dependencyContainer, dependency.Condition) {
				return nil, fmt.Errorf("dependency graph: container ordering dependency [%v] for target [%v] has timed out.", dependencyContainer, target)
			}
		}

		// We want to fail fast if the dependency container did not exit successfully' because target container
		// can then never progress to its desired state when the dependency condition is 'SUCCESS'
		if dependency.Condition == successCondition && dependencyContainer.GetKnownExitCode() != nil {
			if !hasDependencyStoppedSuccessfully(dependencyContainer, dependency.Condition) {
				return nil, fmt.Errorf("dependency graph: failed to resolve container ordering dependency [%v] for target [%v] as dependency did not exit successfully.", dependencyContainer, target)
			}
		}

		if !resolves(target, dependencyContainer, dependency.Condition) {
			return &dependency, fmt.Errorf("dependency graph: failed to resolve the container ordering dependency [%v] for target [%v]", dependencyContainer, target)
		}
	}
	return nil, nil
}
// verifyContainerOrderingStatusResolvable validates that `target` can be resolved given that
// the dependsOn containers are resolved and there are `existingContainers`
// (map from name to container). The `resolves` function passed should return true if the named container is resolved.