public static ConverterConfigurator <TSourceRoot, TSourceChild, TDestRoot, TDestChild, TDestValue> NullifyIf <TSourceRoot, TSourceChild, TDestRoot, TDestChild, TDestValue>(
     this ConverterConfigurator <TSourceRoot, TSourceChild, TDestRoot, TDestChild, TDestValue> configurator,
     Expression <Func <TDestChild, bool?> > condition)
 {
     configurator.SetMutator(NullifyIfConfiguration.Create(condition));
     return(configurator);
 }
 public static MutatorsConfigurator <TRoot, TChild, TValue> NullifyIf <TRoot, TChild, TValue>(
     this MutatorsConfigurator <TRoot, TChild, TValue> configurator,
     Expression <Func <TChild, bool?> > condition)
 {
     configurator.SetMutator(NullifyIfConfiguration.Create(configurator.Root.ConfiguratorType, condition));
     return(configurator);
 }
        public void TestNullifyIf()
        {
            configurator.Target(d => d.RootS).NullifyIf(d => d.A.S == "null");
            var nullifyIfConfiguration = NullifyIfConfiguration.Create <DestRoot>(null, d => d.A.S == "null");

            AssertEquivalentConfigurations(nullifyIfConfiguration);
            AssertEquivalentPaths(d => d.RootS);
        }
        public void TestBatchSet()
        {
            configurator.GoTo(d => d.A).BatchSet((d, s) => new Batch
            {
                { d.S.NotNull(), s.RootS },
                { d.Bs[0].S, s.As[0].S },
                { d.Bs[1].S.NotNull(), s.As[1].S },
                { d.Bs.Each().S, s.As.Each().S }
            });

            AssertEquivalentConfigurations(
                EqualsToConfiguration.Create <DestRoot>((Expression <Func <SourceRoot, string> >)(s => s.RootS)),
                EqualsToConfiguration.Create <DestRoot>((Expression <Func <SourceRoot, string> >)(s => s.As[0].S)),
                EqualsToConfiguration.Create <DestRoot>((Expression <Func <SourceRoot, string> >)(s => s.As[1].S)),
                EqualsToConfiguration.Create <DestRoot>((Expression <Func <SourceRoot, string> >)(s => s.As.Current().S)),
                NullifyIfConfiguration.Create <DestRoot>(null, (d => d.A.S == null && d.A.Bs[1].S == null)),
                NullifyIfConfiguration.Create <DestRoot>(null, (d => d.A.S == null && d.A.Bs[1].S == null))
                );
            AssertEquivalentPathBodies(d => d.A.S, d => d.A.Bs[0].S, d => d.A.Bs[1].S, d => d.A.Bs.Each().S, d => d.A.Bs[0].S, d => d.A.Bs.Each().S);
        }
        public static void BatchSet <TSourceRoot, TSourceChild, TDestRoot, TDestChild, TDestValue>(
            this ConverterConfigurator <TSourceRoot, TSourceChild, TDestRoot, TDestChild, TDestValue> configurator,
            Expression <Func <TDestValue, TSourceChild, Batch> > batch)
        {
            var        methodReplacer    = new MethodReplacer(MutatorsHelperFunctions.EachMethod, MutatorsHelperFunctions.CurrentMethod);
            var        pathToSourceChild = (Expression <Func <TSourceRoot, TSourceChild> >)methodReplacer.Visit(configurator.PathToSourceChild);
            var        pathToChild       = (Expression <Func <TDestRoot, TDestChild> >)methodReplacer.Visit(configurator.PathToChild);
            var        merger            = new ExpressionMerger(pathToSourceChild);
            var        initializers      = ((ListInitExpression)batch.Body).Initializers;
            Expression primaryKeyIsEmpty = null;

            foreach (var initializer in initializers)
            {
                Expression dest        = initializer.Arguments[0];
                var        clearedDest = ClearNotNull(dest);
                if (clearedDest != null)
                {
                    var current = Expression.Equal(clearedDest, Expression.Constant(null, clearedDest.Type));
                    primaryKeyIsEmpty = primaryKeyIsEmpty == null ? current : Expression.AndAlso(primaryKeyIsEmpty, current);
                }

                dest = clearedDest ?? dest;
                if (dest.Type != typeof(object))
                {
                    dest = Expression.Convert(dest, typeof(object));
                }
                Expression source = methodReplacer.Visit(initializer.Arguments[1]);
//                if(source.Type != typeof(object))
//                    source = Expression.Convert(source, typeof(object));
                LambdaExpression value = merger.Merge(Expression.Lambda(source, batch.Parameters[1]));
                if (dest.NodeType == ExpressionType.Convert)
                {
                    dest = ((UnaryExpression)dest).Operand;
                }
                dest = pathToChild.Merge(Expression.Lambda(dest, batch.Parameters[0])).Body;
                configurator.ToRoot().SetMutator(dest, EqualsToConfiguration.Create(typeof(TDestRoot), value, null));
                //configurator.Target(Expression.Lambda<Func<TDestValue, object>>(dest, batch.Parameters[0])).SetMutator(EqualsToConfiguration.Create(typeof(TDestRoot), value, null));
            }

            if (primaryKeyIsEmpty == null)
            {
                return;
            }
            var condition = (Expression <Func <TDestRoot, bool?> >)pathToChild.Merge(Expression.Lambda(Expression.Convert(methodReplacer.Visit(primaryKeyIsEmpty), typeof(bool?)), batch.Parameters[0]));

            foreach (var initializer in initializers)
            {
                Expression dest = initializer.Arguments[0];
                if (ClearNotNull(dest) != null)
                {
                    continue;
                }
                if (dest.Type != typeof(object))
                {
                    dest = Expression.Convert(dest, typeof(object));
                }
                if (dest.NodeType == ExpressionType.Convert)
                {
                    dest = ((UnaryExpression)dest).Operand;
                }
                dest = pathToChild.Merge(Expression.Lambda(dest, batch.Parameters[0])).Body;
                configurator.ToRoot().SetMutator(dest, NullifyIfConfiguration.Create(condition));

                //configurator.Target(Expression.Lambda<Func<TDestValue, object>>(dest, batch.Parameters[0])).SetMutator(NullifyIfConfiguration.Create(condition));
            }
        }