Inheritance: NodeBase
        public void CreateExpression_DateOutsideOfWindowAndIsMonday_BuildsExpression(int year, int month, int day, bool validates, int numberOfErrorMsg)
        {
            // Test: (DateTime d) => (d < floorDate | d > ceilingDate) & d.DayOfWeek == DayOfWeek.Monday
            var floorDate = new DateTime(2010, 2, 1);
            var ceilingDate = new DateTime(2010, 3, 1);
            var testDate = new DateTime(year, month, day);

            // build rule / rule node for "d.DayOfWeek == DayOfWeek.Monday
            var dateOneMondayRule = new CustomRule<CalendarEvent, DateTime>((c, d) => d.DayOfWeek == DayOfWeek.Monday);
            dateOneMondayRule.Message = "Date does not fall on a Monday.";
            var dateOneMondayRuleNode = new RuleNode(dateOneMondayRule);

            // build rules / rule nodes for "d < floorDate | d > ceilingDate"
            var rangeRuleNode = new RuleNode(new LessThan<CalendarEvent, DateTime>(floorDate));
            rangeRuleNode.OrChild(new RuleNode(new GreaterThan<CalendarEvent, DateTime>(ceilingDate)));

            // put the rules / rule nodes together using a group to enforce the "or" precidence over the "and"
            var groupNode = new GroupNode(rangeRuleNode);
            groupNode.AndChild(dateOneMondayRuleNode);

            var tree = new RuleTree<CalendarEvent, DateTime>(groupNode);

            Assert.That(tree.LambdaExpression, Is.Not.Null);

            var context = BuildContextForCalendarEventStartDate(testDate);
            var notification = new ValidationNotification();
            var isValid = tree.LambdaExpression(context, null, notification);

            Assert.That(isValid, Is.EqualTo(validates));
        }
        private List<RuleValidator> GetAllRuleValidatorsForProperty(RuleNode node)
        {
            //TODO: Don't add anything with stuff we can't handle (OR,GROUP)
            var rules = new List<RuleValidator>();
            rules.Add(node.Rule);

            var childRuleNode = node.ChildNode as RuleNode;

            if (childRuleNode != null)
            {
                //rules.Add(childRuleNode.Rule);
                rules.AddRange(GetAllRuleValidatorsForProperty(childRuleNode));
            }

            return rules;
        }
        private Expression buildRuleNodeExpression(RuleNode ruleNode, ParameterExpression contextParam, ParameterExpression specContainerParam, ParameterExpression specNotificationParam)
        {
            var validateMethod = ruleNode.Rule.GetType().GetMethod("Validate");

            if (!ruleNode.HasChild)
            {
                return(Expression.Call(Expression.Constant(ruleNode.Rule), validateMethod,
                                       contextParam, specContainerParam, specNotificationParam));
            }
            else
            {
                var leftExp = Expression.Call(Expression.Constant(ruleNode.Rule), validateMethod,
                                              contextParam, specContainerParam, specNotificationParam);
                if (ruleNode.ChildHasAndRelationship)
                {
                    if (ruleNode.ChildRelationshipIsConditional)
                    {
                        return(Expression.AndAlso(leftExp,
                                                  BuildExpression(ruleNode.ChildNode, contextParam, specContainerParam,
                                                                  specNotificationParam)));
                    }
                    else
                    {
                        return(Expression.And(leftExp,
                                              BuildExpression(ruleNode.ChildNode, contextParam, specContainerParam,
                                                              specNotificationParam)));
                    }
                }
                else
                {
                    if (ruleNode.ChildRelationshipIsConditional)
                    {
                        return(Expression.OrElse(leftExp,
                                                 BuildExpression(ruleNode.ChildNode, contextParam, specContainerParam,
                                                                 specNotificationParam)));
                    }
                    else
                    {
                        return(Expression.Or(leftExp,
                                             BuildExpression(ruleNode.ChildNode, contextParam, specContainerParam,
                                                             specNotificationParam)));
                    }
                }
            }
        }