class AgentManagementConstraint implements SystemConstraint {

    @Override
    public Result evaluate(TaskRequest taskRequest, VirtualMachineCurrentState targetVM, TaskTrackerState taskTrackerState) {
        V3QueueableTask v3QueueableTask = (V3QueueableTask) taskRequest;
        Optional<AgentInstance> instanceOpt = SchedulerUtils.findInstance(agentManagementService, schedulerConfiguration.getInstanceAttributeName(), targetVM);
        if (!instanceOpt.isPresent()) {
            return Failure.INSTANCE_NOT_FOUND.toResult();
        }

        AgentInstance instance = instanceOpt.get();
        String instanceGroupId = instance.getInstanceGroupId();

        Optional<AgentInstanceGroup> instanceGroupOpt = agentManagementService.findInstanceGroup(instanceGroupId);
        if (!instanceGroupOpt.isPresent()) {
            return Failure.INSTANCE_GROUP_NOT_FOUND.toResult();
        }

        AgentInstanceGroup instanceGroup = instanceGroupOpt.get();
        Result instanceGroupEvaluationResult = evaluateInstanceGroup(instanceGroup);
        if (instanceGroupEvaluationResult != VALID) {
            return instanceGroupEvaluationResult;
        }

        Result instanceEvaluationResult = evaluateInstance(instance);
        if (instanceEvaluationResult != VALID) {
            return instanceEvaluationResult;
        }

        return evaluateTask(v3QueueableTask, instanceGroup, instance);
    }

    @Inject public  AgentManagementConstraint(SchedulerConfiguration schedulerConfiguration,
                                     AgentManagementService agentManagementService,
                                     AgentStatusMonitor agentStatusMonitor);

}