/// <summary>Adds an <see cref="InlineConstraint{TProperty}" /> of EqualTo to the Rule.</summary>
        /// <typeparam name="TContext">Type of <see cref="IRuleEngineContext" /> of the rule.</typeparam>
        /// <typeparam name="TProperty">Type of property of the subject of the rule.</typeparam>
        /// <param name="itemSkippingRuleBuilder">
        ///     <see cref="IItemSkippingRuleBuilder{TContext,TProperty}" /> currently configuring
        ///     the rule.
        /// </param>
        /// <param name="compareValue">Value to compare to value of property.</param>
        /// <returns>A <see cref="IItemSkippingRuleBuilder{TContext,TProperty}" /></returns>
        public static IItemSkippingRuleBuilder <TContext, TProperty> EqualTo <TContext, TProperty> (
            this IItemSkippingRuleBuilder <TContext, TProperty> itemSkippingRuleBuilder,
            TProperty compareValue) where TContext : RuleEngineContext <AssessmentInstance>
        {
            var message = Messages.Constraints_Comparison_Message.FormatCompareRuleEngineMessage(compareValue, "=");

            itemSkippingRuleBuilder.Constrain(new InlineConstraint <TProperty> (lhs => Comparer <TProperty> .Default.Compare(compareValue, lhs) == 0, message));
            return(itemSkippingRuleBuilder);
        }
        /// <summary>
        /// Determines whether contains the specified compare value.
        /// </summary>
        /// <typeparam name="TContext">The type of the context.</typeparam>
        /// <typeparam name="TProperty">The type of the property.</typeparam>
        /// <param name="itemSkippingRuleBuilder">The item skipping rule builder.</param>
        /// <param name="compareValue">The compare value.</param>
        /// <returns>A <see cref="IItemSkippingRuleBuilder{TContext,TProperty}" /></returns>
        public static IItemSkippingRuleBuilder <TContext, TProperty> Contains <TContext, TProperty>(
            this IItemSkippingRuleBuilder <TContext, TProperty> itemSkippingRuleBuilder,
            Lookup compareValue)
            where TContext : RuleEngineContext <AssessmentInstance>
            where TProperty : IEnumerable <Lookup>
        {
            var message = Messages.Constraints_Comparison_Message.FormatCompareRuleEngineMessage(compareValue, "!=");

            itemSkippingRuleBuilder.Constrain(new InlineConstraint <TProperty>(lhs => lhs != null && lhs.Contains(compareValue), message));
            return(itemSkippingRuleBuilder);
        }
        /// <summary>Adds an <see cref="InlineConstraint{TProperty}" /> of Regex Match to the Rule.</summary>
        /// <typeparam name="TContext">Type of <see cref="IRuleEngineContext" /> of the rule.</typeparam>
        /// <typeparam name="TProperty">Type of property of the subject of the rule.</typeparam>
        /// <param name="itemSkippingRuleBuilder">
        ///     <see cref="IItemSkippingRuleBuilder{TContext,TProperty}" /> currently configuring
        ///     the rule.
        /// </param>
        /// <param name="regexString">Regex string to check match on property value.</param>
        /// <returns>A <see cref="IItemSkippingRuleBuilder{TContext,TProperty}" /></returns>
        public static IItemSkippingRuleBuilder <TContext, TProperty> MatchesRegex <TContext, TProperty> (
            this IItemSkippingRuleBuilder <TContext, TProperty> itemSkippingRuleBuilder,
            string regexString) where TContext : RuleEngineContext <AssessmentInstance>
        {
            var message = Messages.Constraints_Regex_Message.FormatRuleEngineMessage(new Dictionary <string, string> {
                { "RegexString", regexString }
            });

            itemSkippingRuleBuilder.Constrain(new InlineConstraint <TProperty> (lhs => Regex.IsMatch(lhs.ToString(), regexString), message));
            return(itemSkippingRuleBuilder);
        }
        /// <summary>Adds an <see cref="InlineConstraint{TProperty}" /> of InList to the Rule.</summary>
        /// <typeparam name="TContext">The type of the context.</typeparam>
        /// <typeparam name="TProperty">The type of the property.</typeparam>
        /// <param name="itemSkippingRuleBuilder">The property rule builder.</param>
        /// <param name="list">The list to check.</param>
        /// <returns>A <see cref="IItemSkippingRuleBuilder{TContext,TProperty}" /></returns>
        public static IItemSkippingRuleBuilder <TContext, TProperty> InList <TContext, TProperty> (
            this IItemSkippingRuleBuilder <TContext, TProperty> itemSkippingRuleBuilder,
            params TProperty[] list) where TContext : RuleEngineContext <AssessmentInstance>
        {
            Check.IsNotNull(list, "list is required.");
            var message = Messages.Constraints_InList_Message.FormatRuleEngineMessage(new Dictionary <string, string> {
                { "ListString", string.Join(", ", list) }
            });

            itemSkippingRuleBuilder.Constrain(new InlineConstraint <TProperty> (list.Contains, message));
            return(itemSkippingRuleBuilder);
        }
        /// <summary>Adds an <see cref="InlineConstraint{TProperty}" /> of Specification to the Rule.</summary>
        /// <typeparam name="TContext">Type of <see cref="IRuleEngineContext" /> of the rule.</typeparam>
        /// <typeparam name="TProperty">Type of property of the subject of the rule.</typeparam>
        /// <param name="itemSkippingRuleBuilder">
        ///     <see cref="IItemSkippingRuleBuilder{TContext,TProperty}" /> currently configuring
        ///     the rule.
        /// </param>
        /// <param name="specification"><see cref="ISpecification{TEntity}" /> to use in Constraint.</param>
        /// <param name="violationMessage">Violation message to use in Constraint.</param>
        /// <returns>A <see cref="IItemSkippingRuleBuilder{TContext,TProperty}" /></returns>
        public static IItemSkippingRuleBuilder <TContext, TProperty> MeetsSpecification <TContext, TProperty> (
            this IItemSkippingRuleBuilder <TContext, TProperty> itemSkippingRuleBuilder,
            ISpecification <TProperty> specification,
            string violationMessage = null)
            where TContext : RuleEngineContext <AssessmentInstance>
        {
            var message = violationMessage ??
                          Messages.Constraint_Specification_Message.FormatRuleEngineMessage(new Dictionary <string, string> {
                { "Specification", specification.ToString() }
            });

            itemSkippingRuleBuilder.Constrain(new InlineConstraint <TProperty> (specification.IsSatisfiedBy, message));
            return(itemSkippingRuleBuilder);
        }
        /// <summary>Adds an <see cref="InlineConstraint{TProperty}" /> of InclusiveBetween to the Rule.</summary>
        /// <typeparam name="TContext">Type of <see cref="IRuleEngineContext" /> of the rule.</typeparam>
        /// <typeparam name="TProperty">Type of property of the subject of the rule.</typeparam>
        /// <param name="itemSkippingRuleBuilder">
        ///     <see cref="IItemSkippingRuleBuilder{TContext,TProperty}" /> currently configuring
        ///     the rule.
        /// </param>
        /// <param name="startValue">Start Value to use in comparison to property value.</param>
        /// <param name="endValue">End Value to use in comparison to property value.</param>
        /// <returns>A <see cref="IItemSkippingRuleBuilder{TContext,TProperty}" /></returns>
        public static IItemSkippingRuleBuilder <TContext, TProperty> InclusiveBetween <TContext, TProperty> (
            this IItemSkippingRuleBuilder <TContext, TProperty> itemSkippingRuleBuilder,
            IComparable startValue,
            IComparable endValue)
            where TContext : RuleEngineContext <AssessmentInstance>
        {
            var message =
                Messages.Constraints_InclusiveBetween_Message.FormatRuleEngineMessage(
                    new Dictionary <string, string>
            {
                { "StartValue", startValue.ToString() },
                { "EndValue", startValue.ToString() }
            });

            itemSkippingRuleBuilder.Constrain(new InlineConstraint <TProperty> (lhs => startValue.CompareTo(lhs) <= 0 && endValue.CompareTo(lhs) >= 0, message));
            return(itemSkippingRuleBuilder);
        }
        /// <summary>Adds an <see cref="InlineConstraint{TProperty}" /> of ExclusiveBetween to the Rule.</summary>
        /// <typeparam name="TContext">Type of <see cref="IRuleEngineContext" /> of the rule.</typeparam>
        /// <typeparam name="TProperty">Type of property of the subject of the rule.</typeparam>
        /// <param name="itemSkippingRuleBuilder">
        ///     <see cref="IItemSkippingRuleBuilder{TContext,TProperty}" /> currently configuring
        ///     the rule.
        /// </param>
        /// <param name="startValue">Start Value to use in comparison to property value.</param>
        /// <param name="endValue">End Value to use in comparison to property value.</param>
        /// <returns>A <see cref="IItemSkippingRuleBuilder{TContext,TProperty}" /></returns>
        public static IItemSkippingRuleBuilder <TContext, TProperty> ExclusiveBetween <TContext, TProperty> (
            this IItemSkippingRuleBuilder <TContext, TProperty> itemSkippingRuleBuilder,
            TProperty startValue,
            TProperty endValue)
            where TContext : RuleEngineContext <AssessmentInstance>
        {
            var message =
                Messages.Constraints_ExclusiveBetween_Message.FormatRuleEngineMessage(
                    new Dictionary <string, string>
            {
                { "StartValue", startValue.ToString() },
                { "EndValue", startValue.ToString() }
            });

            itemSkippingRuleBuilder.Constrain(
                new InlineConstraint <TProperty> (
                    lhs => Comparer <TProperty> .Default.Compare(startValue, lhs) < 0 && Comparer <TProperty> .Default.Compare(endValue, lhs) > 0,
                    message));
            return(itemSkippingRuleBuilder);
        }
 /// <summary>Adds a <see cref="NullConstraint" /> to the Rule.</summary>
 /// <typeparam name="TContext">Type of <see cref="IRuleEngineContext" /> of the rule.</typeparam>
 /// <typeparam name="TProperty">Type of property of the subject of the rule.</typeparam>
 /// <param name="itemSkippingRuleBuilder">
 ///     <see cref="IItemSkippingRuleBuilder{TContext,TProperty}" /> currently configuring
 ///     the rule.
 /// </param>
 /// <returns>A <see cref="IItemSkippingRuleBuilder{TContext,TProperty}" />.</returns>
 public static IItemSkippingRuleBuilder <TContext, TProperty> Null <TContext, TProperty> (
     this IItemSkippingRuleBuilder <TContext, TProperty> itemSkippingRuleBuilder) where TContext : RuleEngineContext <AssessmentInstance>
 {
     itemSkippingRuleBuilder.Constrain(new NullConstraint());
     return(itemSkippingRuleBuilder);
 }