/// <summary>
        /// Selects all elements of a `IEnumerable` property for validation.
        /// </summary>
        /// <typeparam name="T">The type of the current value.</typeparam>
        /// <typeparam name="TItem">The type of an individual item in the `IEnumerable` property.</typeparam>
        /// <param name="validator">The current validator context.</param>
        /// <param name="selector">
        ///     The property selector expression.
        ///     <para>
        ///         The expression must be a `MemberExpression` (e.g. `x => x.Property`) or a `ParameterExpression`
        ///         to select all elements of the current value (e.g. `x => x`).
        ///     </para>
        /// </param>
        /// <param name="action">The action to perform for each item of the selected `IEnumerable` property.</param>
        /// <returns>The unmodified validator context.</returns>
        public static IValidatorContext <T> ForEach <T, TItem>(this IValidatorContext <T> validator,
                                                               Expression <Func <T, IEnumerable <TItem> > > selector, Action <IValidatorContext <TItem> > action)
        {
            ValidationInternals.ValidateNotNull(validator, nameof(validator));
            ValidationInternals.ValidateNotNull(selector, nameof(selector));
            ValidationInternals.ValidateNotNull(action, nameof(action));

            var name = (selector.Body is ParameterExpression)
                ? null
                : ValidationInternals.GetPropertyName(selector);
            var value = selector.Compile().Invoke(validator.Value);

            if (value is null)
            {
                return(validator);
            }

            int i = 0;

            foreach (var item in value)
            {
                var context = (name is null)
                    ? new ValidatorContext <TItem>(item, $"{ValidationInternals.FormatName(validator.Path, null)}[{i++}]")
                    : new ValidatorContext <TItem>(item, validator.Path, $"{name}[{i++}]");
                action.Invoke(context);
            }

            return(validator);
        }
        /// <summary>
        /// Selects a property for validation.
        /// </summary>
        /// <typeparam name="T">The type of the current value.</typeparam>
        /// <typeparam name="TNext">The type of the selected property.</typeparam>
        /// <param name="validator">The current validator context.</param>
        /// <param name="selector">
        ///     The property selector expression.
        ///     <para>
        ///         The expression must be a `MemberExpression` (e.g. `x => x.Property`).
        ///     </para>
        /// </param>
        /// <param name="action">The action to perform for the selected property.</param>
        /// <returns>The unmodified validator context.</returns>
        public static IValidatorContext <T> For <T, TNext>(this IValidatorContext <T> validator,
                                                           Expression <Func <T, TNext> > selector, Action <IValidatorContext <TNext> > action)
        {
            ValidationInternals.ValidateNotNull(validator, nameof(validator));
            ValidationInternals.ValidateNotNull(selector, nameof(selector));
            ValidationInternals.ValidateNotNull(action, nameof(action));

            var name  = ValidationInternals.GetPropertyName(selector);
            var value = selector.Compile().Invoke(validator.Value);

            var context = new ValidatorContext <TNext>(value, validator.Path, name);

            action.Invoke(context);

            return(validator);
        }