Expression AssertBoolContext(Expression expression)
        {
            var type = GetExpressionType(expression);

            if (TypeSystemServices.IsNumberOrBool(type) || type.IsEnum)
            {
                return(expression);
            }

            var op_Implicit = TypeSystemServices.FindImplicitConversionOperator(type, TypeSystemServices.BoolType);

            if (op_Implicit != null)
            {
                //return [| $op_Implicit($expression) |]
                return(CodeBuilder.CreateMethodInvocation(op_Implicit, expression));
            }

            // nullable types can be used in bool context
            if (TypeSystemServices.IsNullable(type))
            {
                //return [| $(expression).HasValue |]
                return(CodeBuilder.CreateMethodInvocation(expression, NameResolutionService.ResolveMethod(type, "get_HasValue")));
            }

            // string in a boolean context means string.IsNullOrEmpty (BOO-1035)
            if (TypeSystemServices.StringType == type)
            {
                //return [| not string.IsNullOrEmpty($expression) |]
                var notIsNullOrEmpty = new UnaryExpression(
                    UnaryOperatorType.LogicalNot,
                    CodeBuilder.CreateMethodInvocation(String_IsNullOrEmpty, expression));
                BindExpressionType(notIsNullOrEmpty, TypeSystemServices.BoolType);
                return(notIsNullOrEmpty);
            }

            // reference types can be used in bool context
            if (!type.IsValueType)
            {
                return(expression);
            }

            Error(CompilerErrorFactory.BoolExpressionRequired(expression, type.ToString()));
            return(expression);
        }