public static void RegisterMessage(FluentScope fluentScope, FluentBuilderToken token)
        {
            var sourceType   = fluentScope.Get(RegistryKeys.SourceType);
            var messageEntry = new MessageEntry(
                sourceType,
                fluentScope.Get(RegistryKeys.SetupExpression, Utilities.ReturnSelf(sourceType)),
                fluentScope.Get(RegistryKeys.Rule, null),
                fluentScope.Get(RegistryKeys.Message));

            token.ErrorResolver.AddEntry(messageEntry);
        }
        public static void RegisterEnumerableComposition(FluentScope fluentScope, FluentBuilderToken token)
        {
            var usingEngine           = fluentScope.Get(RegistryKeys.UsingEngine, token.RootEngine);
            var compositionExpression = fluentScope.Get(RegistryKeys.SetupExpression);
            var sourceType            = compositionExpression.Parameters[0].Type;
            var resultType            = compositionExpression.ReturnType;

            var result = (IRuleInvoker)Utilities.CreateType(typeof(EnumerableCompositionInvoker <,>), sourceType, resultType)
                         .CreateInstance(usingEngine, compositionExpression);

            token.CurrentEngine.InvokerRegistry.RegisterInvoker(result);
        }
        public static TEndIf CreateEndIf <TEndIf>(FluentScope fluentScope)
        {
            var tmpScope = fluentScope.CreateChild(fluentScope.Get(RegistryKeys.IfScope));

            //TODO: Make all IFluentNodes have a new() constructor and an Initialize(FluentScope2) method
            return(CreateFluentNode <TEndIf>(tmpScope));
        }
        public ForClass <T> EndSetup()
        {
            //TODO: Use the same concept as for the IfScope (see RegistryKeys). And have EndSetup on all setup nodes, or none at all!.
            var parentNode = _fluentScope.Get(RegistryKeys.FluentNodeParent);
            //Create a new child, but get values from the parent for class
            var tmpScope = _fluentScope.CreateChild(parentNode.FluentScope);

            return(new ForClass <T>(tmpScope));
        }
        public static void RegisterConditional(FluentScope fluentScope, FluentBuilderToken token)
        {
            var conditionalExpression = fluentScope.Get(RegistryKeys.ConditionalExpression);
            var sourceType            = conditionalExpression.Parameters[0].Type;
            var engine           = token.CurrentEngine;
            var conditionalToken = token.Condition();

            var invoker = (IRuleInvoker)Utilities.CreateType(typeof(ConditionalInvoker <>), sourceType)
                          .CreateInstance(conditionalExpression, conditionalToken.IfTrueEngine, conditionalToken.IfFalseEngine);

            engine.InvokerRegistry.RegisterInvoker(invoker);
        }
        public static void RegisterRule(FluentScope fluentScope, FluentBuilderToken token)
        {
            var rule                            = fluentScope.Get(RegistryKeys.Rule);
            var sourceType                      = fluentScope.Get(RegistryKeys.SourceType);
            var setupExpression                 = fluentScope.Get(RegistryKeys.SetupExpression, Utilities.ReturnSelf(sourceType));
            var valueResolverFactory            = token.ValueResolverFactory;
            var isCrossField                    = fluentScope.Get(RegistryKeys.IsCrossField, false);
            var expressionToInvokeForValidation = isCrossField ? Utilities.ReturnSelf(sourceType) : fluentScope.Get(RegistryKeys.SetupExpression);
            var resultType                      = expressionToInvokeForValidation.ReturnType;
            var valueToValidateResolver         = valueResolverFactory.CreateResolver(expressionToInvokeForValidation);

            var culpritResolver = fluentScope.Get(RegistryKeys.CulpritResolver, token.CulpritResolverFactory.Create(null, setupExpression));
            var result          = (IRuleInvoker)Utilities.CreateType(typeof(RuleInvoker <,>), sourceType, resultType)
                                  .CreateInstance(rule
                                                  , valueToValidateResolver
                                                  , new EquatableExpression(setupExpression)
                                                  , culpritResolver
                                                  );

            token.CurrentEngine.InvokerRegistry.RegisterInvoker(result);
        }