public RecordValuesCommandValidator(
            IProjectValidator projectValidator,
            ITagValidator tagValidator,
            IFieldValidator fieldValidator)
        {
            CascadeMode = CascadeMode.Stop;

            RuleFor(command => command)
            .MustAsync((command, token) => NotBeAClosedProjectForTagAsync(command.TagId, token))
            .WithMessage(command => $"Project for tag is closed! Tag={command.TagId}")
            .MustAsync(BeAnExistingRequirementAsync)
            .WithMessage(command => "Tag and/or requirement doesn't exist!")
            .MustAsync((command, token) => NotBeAVoidedTagAsync(command.TagId, token))
            .WithMessage(command => $"Tag is voided! Tag={command.TagId}")
            .MustAsync((command, token) => HasRequirementWithActivePeriodAsync(command.TagId, command.RequirementId, token))
            .WithMessage(command =>
                         $"Tag doesn't have this requirement with active period! Tag={command.TagId}. Requirement={command.RequirementId}");

            When(command => command.NumberValues.Any(), () =>
            {
                RuleForEach(command => command.NumberValues)
                .MustAsync((command, fv, token) => BeAnExistingFieldForRequirementAsync(command, fv.FieldId, token))
                .WithMessage(command => "Field doesn't exist in requirement!")
                .MustAsync((_, fv, token) => BeAFieldForRecordingAsync(fv.FieldId, token))
                .WithMessage((_, fv) => $"Field values can not be recorded for field type! Field={fv.FieldId}")
                .MustAsync((_, fv, token) => NotBeAVoidedFieldAsync(fv.FieldId, token))
                .WithMessage((_, fv) => $"Field is voided! Field={fv.FieldId}");
            });

            When(command => command.CheckBoxValues.Any(), () =>
            {
                RuleForEach(command => command.CheckBoxValues)
                .MustAsync((command, fv, token) => BeAnExistingFieldForRequirementAsync(command, fv.FieldId, token))
                .WithMessage(command => "Field doesn't exist in requirement!")
                .MustAsync((_, fv, token) => BeAFieldForRecordingAsync(fv.FieldId, token))
                .WithMessage((_, fv) => $"Field values can not be recorded for field type! Field={fv.FieldId}")
                .MustAsync((_, fv, token) => NotBeAVoidedFieldAsync(fv.FieldId, token))
                .WithMessage((_, fv) => $"Field is voided! Field={fv.FieldId}");
            });

            async Task <bool> NotBeAClosedProjectForTagAsync(int tagId, CancellationToken token)
            => !await projectValidator.IsClosedForTagAsync(tagId, token);

            async Task <bool> BeAnExistingRequirementAsync(RecordValuesCommand command, CancellationToken token)
            => await tagValidator.ExistsRequirementAsync(command.TagId, command.RequirementId, token);

            async Task <bool> NotBeAVoidedTagAsync(int tagId, CancellationToken token)
            => !await tagValidator.IsVoidedAsync(tagId, token);

            async Task <bool> HasRequirementWithActivePeriodAsync(int tagId, int requirementId, CancellationToken token)
            => await tagValidator.HasRequirementWithActivePeriodAsync(tagId, requirementId, token);

            async Task <bool> BeAnExistingFieldForRequirementAsync(RecordValuesCommand command, int fieldId, CancellationToken token)
            => await tagValidator.ExistsFieldForRequirementAsync(command.TagId, command.RequirementId, fieldId, token);

            async Task <bool> NotBeAVoidedFieldAsync(int fieldId, CancellationToken token)
            => !await fieldValidator.IsVoidedAsync(fieldId, token);

            async Task <bool> BeAFieldForRecordingAsync(int fieldId, CancellationToken token)
            => await fieldValidator.IsValidForRecordingAsync(fieldId, token);
        }