public InconsistentConditionalExpression(JSToCSharpExceptionType type, RelinqScriptExpression root, ConditionalExpression expression, RelinqScriptType inferredTypeOfTest, RelinqScriptType inferredTypeOfIfTrue, RelinqScriptType inferredTypeOfIfFalse) 
     : base(type, root, expression)
 {
     InferredTypeOfTest = inferredTypeOfTest;
     InferredTypeOfIfTrue = inferredTypeOfIfTrue;
     InferredTypeOfIfFalse = inferredTypeOfIfFalse;
 }
        private void InferConditional(ConditionalExpression ce, TypeInferenceCache cache)
        {
            ce.Children.ForEach(child => InferTypes(child, cache));
            var typeofTest = cache[ce.Test];
            var typeofFalse = cache[ce.IfFalse];
            var typeofTrue = cache[ce.IfTrue];

            if (typeofTest is Variant || typeofFalse is Variant || typeofTrue is Variant)
            {
                cache.Add(ce, new Variant());
            }
            else
            {
                if (!(typeofTest is ClrType &&
                    typeofTest.HasImplicitCastTo(typeof(bool))))
                {
                    throw new InconsistentConditionalExpression(
                        JSToCSharpExceptionType.ConditionalTestInvalidType,
                        Root, ce, typeofTest, typeofTrue, typeofFalse);
                }

                var f2t = typeofFalse.HasImplicitCastTo(typeofTrue);
                var t2f = typeofTrue.HasImplicitCastTo(typeofFalse);

                if (!f2t && !t2f)
                {
                    if (typeofFalse is Lambda || typeofTrue is Lambda)
                    {
                        throw new NotImplementedException(String.Format(
                            "Don't know how to infer the '{0} ? {1} : {2}' conditional expression.",
                            typeofTest, typeofTrue, typeofFalse));
                    }
                    else
                    {
                        throw new InconsistentConditionalExpression(
                            JSToCSharpExceptionType.ConditionalClausesNoCommonTypeWithOnlyOneClauseBeingCast,
                            Root, ce, typeofTest, typeofTrue, typeofFalse);
                    }
                }
                else if (f2t && t2f && typeofFalse != typeofTrue)
                {
                    throw new InconsistentConditionalExpression(
                        JSToCSharpExceptionType.ConditionalClausesAmbiguousCommonType,
                        Root, ce, typeofTest, typeofTrue, typeofFalse);
                }
                else
                {
                    cache.Add(ce, f2t ? typeofTrue : typeofFalse);
                }
            }
        }
        private LinqExpression CompileConditional(ConditionalExpression ce, CompilationContext ctx)
        {
            // todo. conditional has to have a CLR type inferred.

            // cba to check this stuff
            var typeofTest = ctx.Types[ce.Test];
            var typeofFalse = ctx.Types[ce.IfFalse];
            var typeofTrue = ctx.Types[ce.IfTrue];

            var castTest = Cast.Lookup(typeofTest, typeof(bool));
            if (typeofTest is ClrType)
            {
                if (castTest == null)
                {
                    throw new CSharpBuilderException(
                        JSToCSharpExceptionType.UnexpectedInferredAst, Ast, ce, ctx);
                }
            }
            else
            {
                throw new CSharpBuilderException(
                    JSToCSharpExceptionType.UnexpectedInferredAst, Ast, ce, ctx);
            }

            var f2tCast = Cast.Lookup(typeofFalse, typeofTrue);
            var t2fCast = Cast.Lookup(typeofTrue, typeofFalse);

            if (f2tCast == null && t2fCast == null)
            {
                throw new CSharpBuilderException(
                    JSToCSharpExceptionType.UnexpectedInferredAst, Ast, ce, ctx);
            }
            else if (f2tCast != null && t2fCast != null && typeofFalse != typeofTrue)
            {
                throw new CSharpBuilderException(
                    JSToCSharpExceptionType.UnexpectedInferredAst, Ast, ce, ctx);
            }

            return LinqExpression.Condition(
                CompileCast(castTest, ce.Test, ctx),
                f2tCast == null ? Compile(ce.IfFalse, ctx) : CompileCast(f2tCast, ce.IfFalse, ctx),
                t2fCast == null ? Compile(ce.IfTrue, ctx) : CompileCast(t2fCast, ce.IfTrue, ctx));
        }