SemanticAnalyzer.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataEntity / System / Data / Common / EntitySql / SemanticAnalyzer.cs / 1 / SemanticAnalyzer.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....]
// @backup [....] 
//--------------------------------------------------------------------- 

namespace System.Data.Common.EntitySql 
{
    using System;
    using System.Globalization;
    using System.Collections.Generic; 
    using System.Diagnostics;
 
    using System.Data.Common.CommandTrees; 
    using System.Data.Metadata.Edm;
    using System.Data.Entity; 

    /// 
    /// Implements Semantic Analysis and Conversion
    /// Provides the translation service between an abstract syntax tree to a canonical command tree 
    /// For complete documentation of the language syntax and semantics, refer to http://sqlweb/default.asp?specDirId=764
    /// The class was designed to be type system agnostic by delegating to a given SemanticResolver instance all type related services as well as to TypeHelper class, however 
    /// we rely on the assumption that metadata was pre-loaded and is relevant to the query. 
    /// 
    internal sealed class SemanticAnalyzer 
    {
        private SemanticResolver _sr;

        ///  
        /// Initializes semantic analyzer
        ///  
        /// initialized SemanticResolver instance for a given typespace/type system 
        internal SemanticAnalyzer( SemanticResolver sr )
        { 
            EntityUtil.CheckArgumentNull(sr, "sr");
            _sr = sr;
        }
 
        /// 
        /// Entry point to semantic analysis. Converts astTree into DbExpression. 
        ///  
        /// ast tree
        /// command tree to build the expression 
        /// 
        /// Thrown when Syntatic or Semantic rules are violated and the query cannot be accepted
        /// Thrown when metadata related service requests fail
        /// Thrown when mapping related service requests fail 
        /// 
        /// DbExpression 
        internal DbExpression Analyze(Expr astExpr, DbCommandTree commandTree) 
        {
            CommandExpr command = Initialize(astExpr, commandTree); 
            DbExpression converted = ConvertRootExpression(command.QueryExpr, _sr);
            return converted;
        }
 
        /// 
        /// Entry point to semantic analysis. Converts astTree into command tree. 
        ///  
        /// ast tree
        ///  
        /// Thrown when Syntatic or Semantic rules are violated and the query cannot be accepted
        /// Thrown when metadata related service requests fail
        /// Thrown when mapping related service requests fail
        ///  
        /// DbCommandTree
        internal DbCommandTree Analyze( Expr astExpr ) 
        { 
            CommandExpr astCommandExpr = Initialize(astExpr, null);
 
            //
            // Convert query Expression
            //
            DbCommandTree commandTree = ConvertCommand(astCommandExpr, _sr); 

            Debug.Assert(null != commandTree,"null != commandTree"); 
 
            return commandTree;
        } 

        /// 
        /// Common initialization required whether the semantic analysis process
        /// is producing a command tree or only an expression. Validates that the 
        /// parse phase did in fact produce a command AST.
        ///  
        /// The root of the abstract syntax tree produced by the parse phase 
        /// 
        ///     An optional command tree to use, only provided when constructing an expression. 
        ///     When constructing a command tree, an instance of the appropriate command tree
        ///     class will be created and returned by semantic analysis.
        /// 
        /// The  that is the root of the AST specified by  
        private CommandExpr Initialize(Expr astExpr, DbCommandTree tree)
        { 
            CommandExpr astCommandExpr = astExpr as CommandExpr; 
            if (null == astCommandExpr)
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.UnknownAstCommandExpression);
            }

            // 
            // Sets DbCommandTree Factory
            // 
            if (tree == null) 
            {
                _sr.SetCommandTreeFactory(astCommandExpr); 
            }
            else
            {
                _sr.SetCommandTreeFactory(astCommandExpr, tree); 
            }
 
            // 
            // Declare Canonical Namespace
            // 
            _sr.DeclareCanonicalNamespace();

            //
            // Declare Namespaces 
            //
            _sr.DeclareNamespaces(astCommandExpr.NamespaceDeclList); 
 
            return astCommandExpr;
        } 

        #region command converter delegates
        delegate DbCommandTree CommandConverter( Expr astExpr, SemanticResolver sr );
        static CommandConverter[] commandConverters = 
        {
            /* ExprKind.Generic */ ConvertGeneralExpression, 
            /* ExprKind.Query   */ ConvertGeneralExpression, 
        };
        #endregion 


        /// 
        /// Dispatches/Converts top command expressions. 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static DbCommandTree ConvertCommand( CommandExpr astCommandExpr, SemanticResolver sr ) 
        {
            EntityUtil.CheckArgumentNull(astCommandExpr, "astCommandExpr");

            Expr queryExpr = astCommandExpr.QueryExpr; 

            return commandConverters[(int)queryExpr.ExprKind](queryExpr, sr); 
        } 

 
        /// 
        /// Converts {Query|General} Expression
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        ///  
        private static DbCommandTree ConvertGeneralExpression( Expr astExpr, SemanticResolver sr ) 
        {
            DbExpression converted = ConvertRootExpression(astExpr, sr); 

            DbQueryCommandTree qryCmdTree = (DbQueryCommandTree)sr.CmdTree;

            qryCmdTree.Query = converted; 

            Debug.Assert(null != qryCmdTree,"null != qryCmdTree"); 
 
            return qryCmdTree;
        } 

        /// 
        /// Converts the expression that is the 'root' of a query AST to a
        /// normalized and validated . This entry 
        /// point to the semantic analysis phase is used when producing a
        /// query command tree (from a Query or General AST expression) or 
        /// producing only a . 
        /// 
        /// The root AST node for this query 
        /// The  instance to use
        /// 
        ///     An instance of , adjusted to handle 'inline' projections
        ///     and validated to produce a result type appropriate for the root of a query command tree. 
        /// 
        private static DbExpression ConvertRootExpression(Expr astExpr, SemanticResolver sr) 
        { 
            DbExpression converted = Convert(astExpr, sr);
 
            //
            // ensure converted expression is not untyped-null
            //
            if (TypeSemantics.IsNullType(converted.ResultType)) 
            {
                throw EntityUtil.EntitySqlError(astExpr.ErrCtx, System.Data.Entity.Strings.ResultingExpressionTypeCannotBeNull); 
            } 

            // 
            // Handles the "inline" projection case
            //
            if (converted is DbScanExpression)
            { 
                DbExpressionBinding source = sr.CmdTree.CreateExpressionBinding(converted, sr.GenerateInternalName("extent"));
 
                converted = sr.CmdTree.CreateProjectExpression(source, source.Variable); 
            }
 
            //
            // ensure return type is valid for query. for V1, association types are the only
            // type that cannot be at 'top' level result. Note that this is only applicable in
            // general queries and association types are valid in view gen mode queries 
            //
            if (sr.ParserOptions.ParserCompilationMode == ParserOptions.CompilationMode.NormalMode) 
            { 
                SemanticResolver.ValidateQueryResultType(converted.ResultType, astExpr.ErrCtx);
            } 

            return converted;
        }
 
        /// 
        /// Dispatches/Converts general expressions 
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static DbExpression Convert( Expr astExpr, SemanticResolver sr )
        {
            if (null == astExpr) 
            {
                return null; 
            } 

            AstExprConverter converter = _astExprConverters[astExpr.GetType()]; 

            if (null == converter)
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.UnknownAstExpressionType); 
            }
 
            DbExpression converted = converter(astExpr, sr); 

            Debug.Assert(null != converted,"null != converted"); 

            return converted;
        }
 

        ///  
        /// Converts Literal Expression 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpression ConvertLiteral( Expr expr, SemanticResolver sr )
        { 
            Literal literal = (Literal)expr;
 
            if (literal.IsNullLiteral) 
            {
                // 
                // if it is literal null, return untyped null
                // untyped nulls will later have their type inferred depending on the
                // especific expression in which it participates
                // 
                return new UntypedNullExpression(sr.CmdTree);
            } 
            else 
            {
                return sr.CmdTree.CreateConstantExpression(literal.Value, 
                                                           sr.TypeResolver.GetLiteralTypeUsage(literal));
            }
        }
 

        ///  
        /// Converts Simple Identifier 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpression ConvertIdentifier( Expr expr, SemanticResolver sr )
        { 
            Identifier idExpr = (Identifier)expr;
 
            DbExpression converted = sr.ResolveIdentifier(new string[] { idExpr.Name }, expr.ErrCtx); 

            if (null == converted) 
            {
                CqlErrorHelper.ReportIdentifierError(expr, sr);
            }
 
            return converted;
        } 
 

        ///  
        /// Converts DotExpression
        /// 
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static DbExpression ConvertDotExpr( Expr expr, SemanticResolver sr ) 
        { 
            DotExpr dotExpr = (DotExpr)expr;
 
            DbExpression converted = null;

            if (dotExpr.IsDottedIdentifier)
            { 
                converted = sr.ResolveIdentifier(dotExpr.Names, dotExpr.ErrCtx);
 
                if (null == converted) 
                {
                    CqlErrorHelper.ReportIdentifierError(expr, sr); 
                }
            }
            else
            { 
                converted = ConvertDotExpressionProcess(dotExpr, sr);
            } 
 
            Debug.Assert(null != converted,"null != converted");
 
            return converted;
        }

 
        /// 
        /// converts dot expression. dotted id case is handled by resolveId 
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        /// 
        /// 
        ///  
        /// 
        static private DbExpression ConvertDotExpressionProcess( DotExpr dotExpr, SemanticResolver sr ) 
        { 
            Debug.Assert(!dotExpr.IsDottedIdentifier,"!dotExpr.IsDottedIdentifier");
 
            return sr.ResolveIdentifierChain(dotExpr.Names, 0, Convert(dotExpr.LeftMostExpression, sr), dotExpr.ErrCtx);
        }

 
        /// 
        /// Converts methods, functions and type constructors 
        /// methods (instance or static) can be in the form: (expr).chain.of.names(args) or chain.of.names(args) 
        /// Functions are chain.of.names(args)
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpression ConvertMethodExpr( Expr expr, SemanticResolver sr ) 
        {
            MethodExpr methodExpr = (MethodExpr)expr; 
 
            DbExpression converted = null;
 
            DotExpr dotExpr = methodExpr.MethodPrefixExpr;

            //
            // resolve base expression if one exists 
            //
            DbExpression baseExpr = (null != dotExpr.LeftMostExpression) ? Convert(dotExpr.LeftMostExpression, sr) : null; 
 
            //
            // If base expression is still unresolved, check if leftmost name element is in in scope 
            //
            int prefixIndex = 0;
            KeyValuePair varInfo;
            if (null == baseExpr && dotExpr.IsDottedIdentifier && dotExpr.Names.Length > 0) 
            {
                ScopeEntry scopeEntry; 
 
                if (sr.TryScopeLookup(dotExpr.Names[0], out scopeEntry))
                { 
                    //
                    // make sure is a valid type for method call
                    //
                    if (TypeResolver.IsValidTypeForMethodCall(scopeEntry.Expression.ResultType)) 
                    {
                        baseExpr = scopeEntry.Expression; 
                        prefixIndex = 1; 
                    }
                    else 
                    {
                        throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.DefiningTypeDoesNotSupportMethodCalls);
                    }
                } 
                else if (sr.Variables.TryGetValue(dotExpr.Names[0], out varInfo))
                { 
                    baseExpr = sr.CmdTree.CreateVariableReferenceExpression(varInfo.Key, varInfo.Value); 
                    prefixIndex = 1;
                } 
            }

            //
            // check if base expression if is untyped null 
            //
            if (baseExpr is UntypedNullExpression) 
            { 
                throw EntityUtil.EntitySqlError(dotExpr.LeftMostExpression.ErrCtx, System.Data.Entity.Strings.ExpressionCannotBeNull);
            } 

            //
            // dispatches methodExpr to static or instance kind of method conversion
            // 
            if (null == baseExpr)
            { 
                // 
                // if base expression is still unresolved, it should be a function(aggregates included), static method or type constructor
                // 
                converted = ConvertStaticMethodOrFunction(methodExpr, sr);
            }
            else
            { 
                //
                // otherwise, should be an instance method invocation 
                // 
                converted = ConvertMethodInstance(baseExpr, methodExpr, prefixIndex, sr);
            } 

            Debug.Assert(null != converted,"null != converted");

            return converted; 
        }
 
 
        /// 
        /// Converts a method expr into a Static Method, Type Constructor or EdmFunction call (including aggregates) 
        /// 
        /// 
        /// 
        ///  
        private static DbExpression ConvertStaticMethodOrFunction( MethodExpr methodExpr, SemanticResolver sr )
        { 
            DbExpression converted = null; 

            // 
            // Find out if given name path is a Static Method, Type Constructor or EdmFunction call (including aggregates)
            //
            TypeUsage constructorType;
            TypeUsage staticMethodType; 
            IList functionType;
 
            // 
            // Resolve methodExpr
            // 
            sr.ResolveNameAsStaticMethodOrFunction(methodExpr, out constructorType, out staticMethodType, out functionType);

            //
            // at this point, only one of the three must be not null 
            // that is ensured by ResolveNameAsStaticMethodOrFunction()
            // 
            Debug.Assert(constructorType != null || staticMethodType != null || functionType != null,"constructorType != null || staticMethodType != null || functionType != null"); 

            // 
            // if it is a constructorType, create an instance of it
            //
            if (null != constructorType)
            { 
                List relshipExprList = null;
 
                // 
                // convert relationships if present
                // 
                if (methodExpr.HasRelationships)
                {
                    if (ParserOptions.CompilationMode.NormalMode == sr.ParserOptions.ParserCompilationMode)
                    { 
                        throw EntityUtil.EntitySqlError(methodExpr.Relationships.ErrCtx, System.Data.Entity.Strings.InvalidModeForWithRelationshipClause);
                    } 
 
                    HashSet targetEnds = new HashSet();
                    relshipExprList = new List(methodExpr.Relationships.Count); 
                    for (int i = 0; i < methodExpr.Relationships.Count; i++)
                    {
                        RelshipNavigationExpr relshipExpr = methodExpr.Relationships[i];
 
                        DbRelatedEntityRef relshipTarget = ConvertRelatedEntityRef(relshipExpr, sr);
 
                        string targetEndId = String.Join(":", new String[] { relshipTarget.TargetEnd.DeclaringType.Identity, relshipTarget.TargetEnd.Identity }); 
                        if (targetEnds.Contains(targetEndId))
                        { 
                            throw EntityUtil.EntitySqlError(relshipExpr.ErrCtx,
                                                        System.Data.Entity.Strings.RelationshipTargetMustBeUnique(relshipTarget.TargetEntityReference.ResultType.EdmType.Identity));
                        }
 
                        targetEnds.Add(targetEndId);
 
                        relshipExprList.Add(relshipTarget); 
                    }
                } 

                converted = sr.CreateInstanceOfType(constructorType,
                                                    ConvertFunctionArguments(methodExpr.Args, sr),
                                                    relshipExprList, 
                                                    methodExpr);
            } 
            // 
            // if it is staticMethodType, create method call expression
            // 
            else if (null != staticMethodType)
            {
                converted = SemanticResolver.CreateStaticMethod(staticMethodType, ConvertFunctionArguments(methodExpr.Args, sr), methodExpr);
            } 
            //
            // if it is functionType 
            // 
            else if (null != functionType && 0 < functionType.Count)
            { 
                //
                // decide if it is an ordinary function or group aggreagate
                //
                if (TypeSemantics.IsAggregateFunction(functionType[0]) && sr.IsInAnyGroupScope()) 
                {
                    // 
                    // if it is an aggreagate function inside a group scope, dispatch to ConvertGroupAggregate() 
                    //
                    converted = ConvertAggregateFunctionInGroupScope(methodExpr, functionType, sr); 
                }
                else
                {
                    // 
                    // else, is just an ordinary function call (including collection aggregates)
                    // 
                    converted = sr.CreateFunction(functionType, ConvertFunctionArguments(methodExpr.Args, sr), methodExpr); 
                }
 
            }
            else
            {
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.CannotResolveNameToFunction(methodExpr.MethodPrefixExpr.FullName)); 
            }
 
            Debug.Assert(null != converted,"null != converted"); 

            return converted; 
        }


        ///  
        /// Converts Group Aggregates
        ///  
        ///  
        /// 
        ///  
        /// 
        /// 
        /// This method convert group aggregates in two phases:
        /// Phase 1 - it will resolve the actual inner (argument) expression and then anotate the ast node and add the resolved aggregate 
        /// to the scope
        /// Phase 2 - if ast node was annotated, just extract the precomputed expression from the scope. 
        ///  
        private static DbExpression ConvertAggregateFunctionInGroupScope( MethodExpr methodExpr, IList functionTypes, SemanticResolver sr )
        { 
            DbExpression converted = null;

            //
            // first, try if aggregate was already pre resolved 
            //
            if (TryConvertAsResolvedGroupAggregate(methodExpr, sr, out converted)) 
            { 
                return converted;
            } 

            //
            // then, try to resolve as Ordinary function (collection aggregate)
            // 
            if (TryConvertAsOrdinaryFunctionInGroup(methodExpr, functionTypes, sr, out converted))
            { 
                return converted; 
            }
 
            //
            // finally, try to convert as group aggregate
            //
            if (TryConvertAsGroupAggregateFunction(methodExpr, functionTypes, sr, out converted)) 
            {
                return converted; 
            } 

            // 
            // if we reach this point, means the resolution failed
            //
            throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.FailedToResolveAggregateFunction(methodExpr.MethodPrefixExpr.FullName));
        } 

 
        ///  
        /// try to convert as pre resolved aggregate function
        ///  
        /// 
        /// 
        /// 
        ///  
        private static bool TryConvertAsResolvedGroupAggregate( MethodExpr methodExpr, SemanticResolver sr, out DbExpression converted )
        { 
            converted = null; 

            // 
            // if ast node was annotated in a previous pass, means it was already resolved and should be in scope
            //
            if (methodExpr.WasResolved)
            { 
                sr.CurrentScopeRegionFlags.DecrementGroupAggregateNestingCount();
 
                ScopeEntry scopeEntry; 

                SemanticResolver.ScopeViewKind saveScopeView = sr.GetScopeView(); 

                sr.SetScopeView(SemanticResolver.ScopeViewKind.All);

                int scopeIndex; 
                if (!sr.TryScopeLookup(methodExpr.InternalAggregateName, out scopeEntry, out scopeIndex))
                { 
                    Debug.Assert(methodExpr.DummyExpression != null, "resolved aggregate dummy expression must not be null"); 

                    converted = methodExpr.DummyExpression; 

                    return true;
                }
                else 
                {
                    // 
                    // Sets correlation flag 
                    //
                    sr.SetScopeRegionCorrelationFlag(scopeIndex); 
                }

                sr.SetScopeView(saveScopeView);
 
                converted = scopeEntry.Expression;
 
                return true; 
            }
 
            return false;
        }

 
        /// 
        /// Try convert method expr in a group scope as an ordinary function (collection aggregate) 
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        private static bool TryConvertAsOrdinaryFunctionInGroup( MethodExpr methodExpr          , 
                                                                 IList functionTypes   ,
                                                                 SemanticResolver sr            , 
                                                                 out DbExpression converted       ) 
        {
            converted = null; 

            //
            // save scope view
            // 
            SemanticResolver.ScopeViewKind saveScopeView = sr.GetScopeView();
 
            // 
            // convert aggregate arguments
            // 
            List args = ConvertFunctionArguments(methodExpr.Args, sr);

            //
            // collect argument types 
            //
            List argTypes = new List(args.Count); 
            for (int i = 0 ; i < args.Count ; i++) 
            {
                argTypes.Add(args[i].ResultType); 
            }

            //
            // try to see if there is a overload match 
            //
            bool isAmbiguous = false; 
            EdmFunction functionType = TypeResolver.ResolveFunctionOverloads( functionTypes, 
                                                                              argTypes,
                                                                              false /* isGroupAggregateFunction */, 
                                                                              out isAmbiguous);

            //
            // if there is more then one overload that matches given arguments, throw 
            //
            if (isAmbiguous) 
            { 
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.AmbiguousFunctionArguments);
            } 

            //
            // if not null, means a match was found as an ordinary function
            // 
            if (null != functionType)
            { 
                // 
                // make sure all referenced vars are from group scope only
                // 
                if (!sr.CurrentScopeRegionFlags.IsImplicitGroup)
                {
                    sr.SetScopeView(SemanticResolver.ScopeViewKind.CurrentScope);
                } 

                // 
                // convert aggregate arguments 
                //
                args = ConvertFunctionArguments(methodExpr.Args, sr); 

                //
                // restore previous scope view
                // 
                sr.SetScopeView(saveScopeView);
 
                // 
                // return function
                // 
                converted = sr.CmdTree.CreateFunctionExpression(functionType, args);

            }
 
            return (null != functionType);
        } 
 

        ///  
        ///
        /// 
        /// 
        ///  
        /// 
        ///  
        ///  
        private static bool TryConvertAsGroupAggregateFunction( MethodExpr methodExpr,
                                                                IList functionTypeList, 
                                                                SemanticResolver sr,
                                                                out DbExpression converted )
        {
            converted = null; 

            // 
            // save scope view 
            //
            SemanticResolver.ScopeViewKind saveScopeView = sr.GetScopeView(); 

            //
            // Aggregates in groups can refer to all scopes
            // 
            sr.SetScopeView(SemanticResolver.ScopeViewKind.All);
 
            // 
            // flag that it is inside a group aggregate
            // 
            sr.CurrentScopeRegionFlags.IsInsideGroupAggregate = true;

            //
            // reset nested references flag 
            //
            sr.CurrentScopeRegionFlags.WasNestedGroupAggregateReferredByInnerExpressions = false; 
 
            //
            // pushes candidate aggregate ast node 
            //
            sr.PushAggregateAstNode(methodExpr);

 
            sr.CurrentScopeRegionFlags.DecrementGroupAggregateNestingCount();
 
            // 
            // convert aggregate arguments
            // 
            List args = ConvertFunctionArguments(methodExpr.Args, sr);

            //
            // clear inside group aggregate flag 
            //
            sr.CurrentScopeRegionFlags.IsInsideGroupAggregate = false; 
 
            //
            // collect argument types 
            //
            List argTypes = new List(args.Count);
            for (int i = 0 ; i < args.Count ; i++)
            { 
                argTypes.Add(args[i].ResultType);
            } 
 
            //
            // try to find an overload match as group aggregate 
            //
            bool isAmbiguous = false;
            EdmFunction functionType = TypeResolver.ResolveFunctionOverloads(functionTypeList,
                                                                             argTypes, 
                                                                             true /* isGroupAggregateFunction */,
                                                                             out isAmbiguous); 
 
            //
            // if there is more then one overload that matches given arguments, throw 
            //
            if (isAmbiguous)
            {
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.AmbiguousFunctionArguments); 
            }
 
            // 
            // if it still null, then there is no overload as an ordinary function or group aggregate function
            // 
            if (null == functionType)
            {
                CqlErrorHelper.ReportFunctionOverloadError(methodExpr, functionTypeList[0], argTypes);
            } 

            // 
            // ensure that group aggregate was not referenced by inner sub-expression 
            //
            if (sr.CurrentScopeRegionFlags.WasNestedGroupAggregateReferredByInnerExpressions) 
            {
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.NestedAggregatesCannotBeUsedInAggregateFunctions);
            }
 
            //
            // ensure it is not a nested group aggregate call 
            // 
            if (sr.CurrentScopeRegionFlags.GroupAggregateNestingCount < -1)
            { 
                throw EntityUtil.EntitySqlError(methodExpr.MethodIdentifier.ErrCtx, System.Data.Entity.Strings.InvalidNestedGroupAggregateCall);
            }

            // 
            // aggregate functions in the current release can have only one argument and must of of collectio type
            // 
            Debug.Assert((1 == functionType.Parameters.Count), "(1 == functionType.Parameters.Count)"); // we only support monadic aggregate functions 
            Debug.Assert(TypeSemantics.IsCollectionType(functionType.Parameters[0].TypeUsage), "functionType.Parameters[0].Type is CollectionType");
            TypeUsage argumentType = TypeHelpers.GetElementTypeUsage(functionType.Parameters[0].TypeUsage); 
            if (TypeSemantics.IsNullType(args[0].ResultType))
            {
                args[0] = sr.CmdTree.CreateNullExpression(argumentType);
            } 

            // 
            // create function aggregate expression 
            //
            DbFunctionAggregate functionAggregate; 

            // create distinct expression if espeficied
            if (methodExpr.DistinctKind == DistinctKind.Distinct)
            { 
                functionAggregate = sr.CmdTree.CreateDistinctFunctionAggregate(functionType, args[0]);
            } 
            else 
            {
                functionAggregate = sr.CmdTree.CreateFunctionAggregate(functionType, args[0]); 
            }

            //
            // generate name for the aggregate 'property'. this name will the internal name of the pre-computed expression in the scope and 
            // annotated ast node in the ast tree
            // 
            string internalAggregateName = sr.GenerateInternalName("groupAgg" + functionType.Name); 

            // 
            // add aggreate to aggreate list
            //
            AggregateAstNodeInfo aggrAstInfo = sr.PopAggregateAstNode();
            aggrAstInfo.AssertMethodExprEquivalent(methodExpr); 
            sr.AddGroupAggregateInfoToScopeRegion(methodExpr, internalAggregateName, functionAggregate, aggrAstInfo.ScopeIndex);
 
            // 
            // return 'dummy' expression with same type as aggregate function
            // 
            converted = sr.CmdTree.CreateNullExpression(functionType.ReturnParameter.TypeUsage);

            //
            // anotate method expression node as aggregate 
            //
            methodExpr.SetAggregateInfo(internalAggregateName, converted); 
 
            //
            // restore visibility to group scope only 
            //
            sr.SetScopeView(saveScopeView);

            // 
            // increment nesting count
            // 
            sr.CurrentScopeRegionFlags.IncrementGroupAggregateNestingCount(); 

            return true; 
        }


 
        /// 
        /// Converted a instance method. 
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        private static DbExpression ConvertMethodInstance( DbExpression baseExpr, MethodExpr methodExpr, int prefixIndex, SemanticResolver sr ) 
        {
            DbExpression converted = null; 
 
            Debug.Assert(null != baseExpr,"null != baseExpr");
 
            DotExpr dotExpr = methodExpr.MethodPrefixExpr;

            //
            // ensure methods are not called on Scalar type instances 
            //
            if (TypeSemantics.IsPrimitiveType(baseExpr.ResultType)) 
            { 
                throw EntityUtil.EntitySqlError(dotExpr.LeftMostExpression.ErrCtx, System.Data.Entity.Strings.MethodNotAllowedOnScalars);
            } 

            //
            // build the instance property references chain up to the method name
            // 
            DbExpression innerExpression = baseExpr;
            for (int i = prefixIndex ; i < dotExpr.Length - 1 ; i++) 
            { 

                innerExpression = sr.ResolveIdentifierElement(innerExpression.ResultType, innerExpression, dotExpr.Names[i], dotExpr.ErrCtx); 

                //
                // if this point is reached, means that an element in the path name is not a valid property
                // such as name[ i + 1 ] is not a valid property/member of defining type resolved previosly for name[ i ] 
                //
                if (null == innerExpression) 
                { 
                    throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.InvalidMethodPathElement(dotExpr.Names[i], innerExpression.ResultType.EdmType.FullName));
                } 
            }

            //
            // convert method arguments 
            //
            List args = ConvertFunctionArguments(methodExpr.Args, sr); 
 
            //
            // Resolve/Validate overloads and create method expression 
            //
            converted = SemanticResolver.CreateInstanceMethod(innerExpression, args, methodExpr);

            Debug.Assert(null != converted,"null != converted"); 

            return converted; 
        } 

 
        /// 
        /// Converts EdmFunction Arguments representes a list of astExpr nodes
        /// 
        ///  
        /// 
        ///  
        private static List ConvertFunctionArguments( ExprList astExprList, SemanticResolver sr ) 
        {
            List convertedArgs = new List(); 

            if (null != astExprList)
            {
                for (int i = 0 ; i < astExprList.Count ; i++) 
                {
                    convertedArgs.Add(Convert(astExprList[i], sr)); 
                } 
            }
 
            return convertedArgs;
        }

 
        /// 
        /// Convert Paramerters 
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static DbExpression ConvertParameter( Expr expr, SemanticResolver sr )
        {
            Parameter parameter = (Parameter)expr; 
            TypeUsage paramType = null;
            KeyValuePair varInfo; 
 
            if (sr.Variables != null && sr.Variables.TryGetValue(parameter.Name, out varInfo))
            { 
                return sr.CmdTree.CreateVariableReferenceExpression(varInfo.Key, varInfo.Value);
            }

            if (null == sr.Parameters || !sr.Parameters.TryGetValue(parameter.Name, out paramType)) 
            {
                throw EntityUtil.EntitySqlError(parameter.ErrCtx, System.Data.Entity.Strings.ParameterWasNotDefined(parameter.Name)); 
            } 

            sr.CmdTree.AddParameter(parameter.Name, TypeHelpers.GetReadOnlyType(paramType)); 

            return sr.CmdTree.CreateParameterReferenceExpression(parameter.Name);
        }
 
        /// 
        /// Validate a relationship-traversal - used for both Navigate expressions 
        /// and for entity construction with related entity refs. 
        ///
        /// For "related entity refs", "isTargetEnd" is true - for Navigate expressions, 
        /// this parameter is "false".
        ///
        /// 
        /// the relationshipExpr AST 
        /// 
        /// resolver context 
        /// the source/target expression 
        /// the relationship type
        /// from end of the relationship 
        /// to-end of the relationship
        private static void ValidateRelationshipTraversal(RelshipNavigationExpr relshipExpr,
                                                          bool isTargetEnd,
                                                          SemanticResolver sr, 
                                                          out DbExpression refExpr,
                                                          out RelationshipType relationshipType, 
                                                          out RelationshipEndMember refEnd, 
                                                          out RelationshipEndMember otherEnd)
        { 
            relationshipType = null;
            refEnd = null;
            otherEnd = null;
            refExpr = null; 

            // 
            // resolve relationship type 
            //
            relationshipType = sr.ResolveNameAsType(relshipExpr.RelationTypeNames, relshipExpr.RelationTypeNameIdentifier).EdmType as RelationshipType; 
            if (null == relationshipType)
            {
                throw EntityUtil.EntitySqlError(relshipExpr.RelationTypeNameIdentifier.ErrCtx, System.Data.Entity.Strings.InvalidRelationshipTypeName(relshipExpr.RelationTypeFullName));
            } 

            // 
            // convert relationship 'instance' expression 
            //
            refExpr = Convert(relshipExpr.RelationshipSource, sr); 

            //
            // if is entity, create entity ref out if it
            // 
            if (!isTargetEnd && TypeSemantics.IsEntityType(refExpr.ResultType))
            { 
                refExpr = sr.CmdTree.CreateEntityRefExpression(refExpr); 
            }
 
            //
            // make sure is ref type
            //
            if (!TypeSemantics.IsReferenceType(refExpr.ResultType)) 
            {
                throw EntityUtil.EntitySqlError(relshipExpr.RelationshipSource.ErrCtx, System.Data.Entity.Strings.InvalidRelationshipSourceType); 
            } 

            // 
            // ensure entity 'participates' in the given relationship type
            //
            if (!TypeSemantics.IsTypeValidForRelationship(TypeHelpers.GetElementTypeUsage(refExpr.ResultType), relationshipType))
            { 
                throw EntityUtil.EntitySqlError(relshipExpr.RelationTypeNameIdentifier.ErrCtx, System.Data.Entity.Strings.RelationshipTypeIsNotCompatibleWithEntity(
                    TypeHelpers.GetFullName(TypeHelpers.GetElementTypeUsage(refExpr.ResultType)), 
                    TypeHelpers.GetFullName(relationshipType))); 
            }
 
            //
            // ensure relationship ends are valid
            // metadata ensures that there will never happen to have two equal end names
            // 
            TypeUsage fromEndType = null;
            int fromEndMatchCount = 0; 
            TypeUsage elementType = TypeHelpers.GetElementTypeUsage(refExpr.ResultType); 
            for (int i = 0; i < relationshipType.Members.Count; i++)
            { 
                //
                // check 'to' end
                //
                if (relationshipType.Members[i].Name.Equals(relshipExpr.ToEndIdentifierName, StringComparison.OrdinalIgnoreCase)) 
                {
                    otherEnd = (RelationshipEndMember)relationshipType.Members[i]; 
                    continue; 
                }
 
                //
                // check 'from' end
                //
                if ( 
                    (null != relshipExpr.FromEndIdentifier && relationshipType.Members[i].Name.Equals(relshipExpr.FromEndIdentifierName, StringComparison.OrdinalIgnoreCase)) ||
                    (null == relshipExpr.FromEndIdentifier && TypeSemantics.IsEquivalentOrPromotableTo(elementType, TypeHelpers.GetElementTypeUsage(relationshipType.Members[i].TypeUsage))) 
                   ) 
                {
                    fromEndMatchCount++; 

                    if (fromEndMatchCount > 1)
                    {
                        ErrorContext errCtx = (null == relshipExpr.FromEndIdentifier) ? relshipExpr.ErrCtx : relshipExpr.FromEndIdentifier.ErrCtx; 

                        throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.RelationshipFromEndIsAmbiguos); 
                    } 

                    refEnd = (RelationshipEndMember)relationshipType.Members[i]; 
                    fromEndType = relationshipType.Members[i].TypeUsage;
                }
            }
 
            //
            // ensure relationship 'To' end contains given property 
            // 
            if (null == otherEnd)
            { 
                if (null != relshipExpr.ToEndIdentifier)
                {
                    throw EntityUtil.EntitySqlError(relshipExpr.ToEndIdentifier.ErrCtx, System.Data.Entity.Strings.InvalidRelationshipMember(relshipExpr.ToEndIdentifierName, relshipExpr.RelationTypeFullName));
                } 

                if (2 != relationshipType.Members.Count) 
                { 
                    throw EntityUtil.EntitySqlError(relshipExpr.ErrCtx, System.Data.Entity.Strings.InvalidImplicitRelationshipToEnd(relshipExpr.RelationTypeFullName));
                } 

                Debug.Assert(null != refEnd, "null!=fromEnd");

                otherEnd = (RelationshipEndMember)(refEnd.Name.Equals(relationshipType.Members[0].Name, StringComparison.OrdinalIgnoreCase) ? relationshipType.Members[1] : relationshipType.Members[0]); 
            }
 
            // 
            // ensure relationship 'From' end contains given entity
            // 
            if (null == refEnd || null == fromEndType)
            {
                ErrorContext errCtx = (null == relshipExpr.FromEndIdentifier) ? relshipExpr.ErrCtx : relshipExpr.FromEndIdentifier.ErrCtx;
 
                if (null == relshipExpr.FromEndIdentifier)
                { 
                    throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.InvalidImplicitRelationshipFromEnd(relshipExpr.RelationTypeFullName)); 
                }
                else 
                {
                    throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.InvalidRelationshipMember(relshipExpr.FromEndIdentifierName, relshipExpr.RelationTypeFullName));
                }
            } 

            // 
            // check if source is promotable to from end type 
            //
            if (!TypeSemantics.IsValidPolymorphicCast(TypeHelpers.GetElementTypeUsage(refExpr.ResultType), 
                                                      TypeHelpers.GetElementTypeUsage(refEnd.TypeUsage)))
            {
                ErrorContext errCtx = (null == relshipExpr.FromEndIdentifier) ? relshipExpr.ErrCtx : relshipExpr.FromEndIdentifier.ErrCtx;
 
                throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.SourceTypeMustBePromotoableToFromEndRelationType(TypeHelpers.GetElementTypeUsage(refExpr.ResultType).EdmType.FullName, TypeHelpers.GetElementTypeUsage(fromEndType).EdmType.FullName));
            } 
 
            return;
        } 

        /// 
        /// Build out a RelatedEntityRef
        ///  
        /// the ast expression
        /// the Semantic Resolver context 
        /// a DbRelatedEntityRef instance 
        private static DbRelatedEntityRef ConvertRelatedEntityRef(RelshipNavigationExpr relshipExpr, SemanticResolver sr)
        { 
            //
            // Validate the relationship traversal
            //
            DbExpression targetRef; 
            RelationshipEndMember targetRefEnd;
            RelationshipEndMember otherEnd; 
            RelationshipType relationshipType; 

            ValidateRelationshipTraversal(relshipExpr, 
                                          true /* targetEnd */ ,
                                          sr,
                                          out targetRef,
                                          out relationshipType, 
                                          out targetRefEnd,
                                          out otherEnd); 
 
            //
            // ensure is *..{0|1} 
            //
            if (RelationshipMultiplicity.One != targetRefEnd.RelationshipMultiplicity &&
                RelationshipMultiplicity.ZeroOrOne != targetRefEnd.RelationshipMultiplicity)
            { 
                throw EntityUtil.EntitySqlError(relshipExpr.ErrCtx,
                                            System.Data.Entity.Strings.InvalidWithRelationshipTargetEndMultiplicity(targetRefEnd.Identity, 
                                                                                                                    targetRefEnd.RelationshipMultiplicity.ToString())); 
            }
 
            DbRelatedEntityRef relatedEntityRef = sr.CmdTree.CreateRelatedEntityRef(otherEnd, targetRefEnd, targetRef);

            return relatedEntityRef;
        } 

        ///  
        /// converts Relationship Navigation operator 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpression ConvertRelshipNavigationExpr( Expr astExpr, SemanticResolver sr )
        { 
            RelshipNavigationExpr relshipExpr = (RelshipNavigationExpr)astExpr;
 
            // 
            // Validate the relationship traversal
            // 
            DbExpression relationshipSource;
            RelationshipEndMember fromEnd;
            RelationshipEndMember toEnd;
            RelationshipType relationshipType; 

            ValidateRelationshipTraversal(relshipExpr, 
                                          false /* !targetEnd */, 
                                          sr,
                                          out relationshipSource, 
                                          out relationshipType,
                                          out fromEnd,
                                          out toEnd);
 
            //
            // create cqt expression 
            // 
            DbExpression converted = sr.CmdTree.CreateRelationshipNavigationExpression(fromEnd, toEnd, relationshipSource);
 
            Debug.Assert(null != converted,"null != converted");

            return converted;
        } 

 
        ///  
        /// converts REF operator
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpression ConvertRefExpr( Expr astExpr, SemanticResolver sr ) 
        {
            RefExpr refExpr = (RefExpr)astExpr; 
 
            DbExpression converted = Convert(refExpr.RefArgExpr, sr);
 
            //
            // check if is entity type
            //
            if (!TypeSemantics.IsEntityType(converted.ResultType)) 
            {
                throw EntityUtil.EntitySqlError(refExpr.RefArgExpr.ErrCtx, System.Data.Entity.Strings.RefArgIsNotOfEntityType(converted.ResultType.EdmType.FullName)); 
            } 

            // 
            // create ref expression
            //
            converted = sr.CmdTree.CreateEntityRefExpression(converted);
 
            Debug.Assert(null != converted,"null != converted");
 
            return converted; 
        }
 

        /// 
        /// converts DEREF operator
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        ///  
        private static DbExpression ConvertDeRefExpr( Expr astExpr, SemanticResolver sr )
        { 
            DerefExpr deRefExpr = (DerefExpr)astExpr;

            DbExpression converted = null;
 
            converted = Convert(deRefExpr.RefExpr, sr);
 
            // 
            // check if return type is RefType
            // 
            if (!TypeSemantics.IsReferenceType(converted.ResultType))
            {
                throw EntityUtil.EntitySqlError(deRefExpr.RefExpr.ErrCtx, System.Data.Entity.Strings.DeRefArgIsNotOfRefType(converted.ResultType.EdmType.FullName));
            } 

            // 
            // create DeRef expression 
            //
            converted = sr.CmdTree.CreateDerefExpression(converted); 

            Debug.Assert(null != converted,"null != converted");

            return converted; 
        }
 
 
        /// 
        /// converts CREATEREF operator 
        /// 
        /// 
        /// SemanticResolver instance relative to a especif typespace/system
        ///  
        private static DbExpression ConvertCreateRefExpr( Expr astExpr, SemanticResolver sr )
        { 
            CreateRefExpr createRefExpr = (CreateRefExpr)astExpr; 

            DbExpression converted = null; 

            //
            // Convert the entity set, also, ensure that we get back an extent expression
            // 
            DbScanExpression entitySetExpr = Convert(createRefExpr.EntitySet, sr) as DbScanExpression;
            if (entitySetExpr == null) 
            { 
                throw EntityUtil.EntitySqlError(createRefExpr.EntitySet.ErrCtx, System.Data.Entity.Strings.ExprIsNotValidEntitySetForCreateRef);
            } 

            //
            // Ensure that the extent is an entity set
            // 
            EntitySet entitySet = entitySetExpr.Target as EntitySet;
            if (entitySet == null) 
            { 
                throw EntityUtil.EntitySqlError(createRefExpr.EntitySet.ErrCtx, System.Data.Entity.Strings.ExprIsNotValidEntitySetForCreateRef);
            } 

            DbExpression keyRowExpression = Convert(createRefExpr.Keys, sr);

            SemanticResolver.EnsureIsNotUntypedNull(keyRowExpression, createRefExpr.Keys.ErrCtx); 

            RowType inputKeyRowType = keyRowExpression.ResultType.EdmType as RowType; 
            if (null == inputKeyRowType) 
            {
                throw EntityUtil.EntitySqlError(createRefExpr.Keys.ErrCtx,System.Data.Entity.Strings.InvalidCreateRefKeyType); 
            }

            RowType entityKeyRowType = TypeHelpers.CreateKeyRowType(entitySet.ElementType, sr.CmdTree.MetadataWorkspace);
 
            if (entityKeyRowType.Members.Count != inputKeyRowType.Members.Count)
            { 
                throw EntityUtil.EntitySqlError(createRefExpr.Keys.ErrCtx, System.Data.Entity.Strings.ImcompatibleCreateRefKeyType); 
            }
 
            if (!TypeSemantics.IsEquivalentOrPromotableTo(keyRowExpression.ResultType, TypeUsage.Create(entityKeyRowType)))
            {
                throw EntityUtil.EntitySqlError(createRefExpr.Keys.ErrCtx, System.Data.Entity.Strings.ImcompatibleCreateRefKeyElementType);
            } 

            // 
            // if CREATEREF specifies a type, resolve and validate the type 
            //
            if (null != createRefExpr.TypeIdentifier) 
            {
                TypeUsage targetTypeUsage = ConvertTypeIdentifier(createRefExpr.TypeIdentifier, sr);

                // 
                // ensure type is entity
                // 
                if (!TypeSemantics.IsEntityType(targetTypeUsage)) 
                {
 
                    throw EntityUtil.EntitySqlError(createRefExpr.TypeIdentifier.ErrCtx,
                                                System.Data.Entity.Strings.CreateRefTypeIdentifierMustSpecifyAnEntityType(
                                                                    targetTypeUsage.EdmType.Identity,
                                                                    targetTypeUsage.EdmType.BuiltInTypeKind.ToString())); 
                }
 
                if (!TypeSemantics.IsValidPolymorphicCast(entitySet.ElementType, targetTypeUsage.EdmType)) 
                {
                    throw EntityUtil.EntitySqlError(createRefExpr.TypeIdentifier.ErrCtx, 
                                                System.Data.Entity.Strings.CreateRefTypeIdentifierMustBeASubOrSuperType(
                                                                    entitySet.ElementType.Identity,
                                                                    targetTypeUsage.EdmType.FullName));
                } 

                converted = sr.CmdTree.CreateRefExpression(entitySet, 
                                                           keyRowExpression, 
                                                           (EntityType)targetTypeUsage.EdmType);
            } 
            else
            {
                //
                // finally creates the expression 
                //
                converted = sr.CmdTree.CreateRefExpression(entitySet, keyRowExpression); 
            } 

            Debug.Assert(null != converted,"null != converted"); 

            return converted;
        }
 

        ///  
        /// converts KEY operator 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpression ConvertKeyExpr( Expr astExpr, SemanticResolver sr )
        { 
            KeyExpr keyExpr = (KeyExpr)astExpr;
 
            DbExpression converted = Convert(keyExpr.RefExpr, sr); 

            SemanticResolver.EnsureIsNotUntypedNull(converted, keyExpr.RefExpr.ErrCtx); 

            if (TypeSemantics.IsEntityType(converted.ResultType))
            {
                converted = sr.CmdTree.CreateEntityRefExpression(converted); 
            }
            else if (!TypeSemantics.IsReferenceType(converted.ResultType)) 
            { 
                throw EntityUtil.EntitySqlError(keyExpr.RefExpr.ErrCtx,System.Data.Entity.Strings.InvalidKeyArgument(TypeHelpers.GetFullName(converted.ResultType)));
            } 

            converted = sr.CmdTree.CreateRefKeyExpression(converted);

            Debug.Assert(null != converted, "null != converted"); 

            return converted; 
        } 

 
        /// 
        /// Dispatches/Converts BuiltIn Expressions
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        ///  
        private static DbExpression ConvertBuiltIn( Expr astExpr, SemanticResolver sr ) 
        {
            if (null == astExpr) 
            {
                return null;
            }
 
            BuiltInExpr bltInExpr = (BuiltInExpr)astExpr;
 
            BuiltInExprConverter builtInConverter = _builtInExprConverter[bltInExpr.Kind]; 

            if (null == builtInConverter) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.UnknownBuiltInAstExpressionType);
            }
 
            DbExpression converted = builtInConverter(bltInExpr, sr);
 
            Debug.Assert(null != converted,"null != converted"); 

            return converted; 
        }


        ///  
        /// Converts Arithmetic Expressions Args
        ///  
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        ///  
        private static Pair ConvertArithmeticArgs( BuiltInExpr astBuiltInExpr, SemanticResolver sr )
        {
            DbExpression leftExpr = Convert(astBuiltInExpr.Arg1, sr);
            if (!(TypeSemantics.IsNumericType(leftExpr.ResultType) || SemanticResolver.IsNullExpression(leftExpr))) 
            {
                throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.ExpressionMustBeNumericType); 
            } 

            DbExpression rightExpr = null; 
            if (null != astBuiltInExpr.Arg2)
            {
                rightExpr = Convert(astBuiltInExpr.Arg2, sr);
 
                if (!(TypeSemantics.IsNumericType(rightExpr.ResultType) || SemanticResolver.IsNullExpression(rightExpr)))
                { 
                    throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.ExpressionMustBeNumericType); 
                }
 
                if (null == TypeHelpers.GetCommonTypeUsage(leftExpr.ResultType, rightExpr.ResultType))
                {
                    throw EntityUtil.EntitySqlError(astBuiltInExpr.ErrCtx, System.Data.Entity.Strings.ArgumentTypesAreIncompatible(leftExpr.ResultType.EdmType.FullName, rightExpr.ResultType.EdmType.FullName));
                } 
            }
 
            return sr.EnsureTypedNulls(leftExpr, rightExpr, astBuiltInExpr.ErrCtx, () => Strings.InvalidNullArithmetic); 
        }
 
        /// 
        /// Converts Plus Args - specific case since string type is an allowed type for '+'
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        ///  
        private static Pair ConvertPlusOperands( BuiltInExpr astBuiltInExpr, SemanticResolver sr ) 
        {
            DbExpression leftExpr = Convert(astBuiltInExpr.Arg1, sr); 
            if (!(TypeSemantics.IsNumericType(leftExpr.ResultType) ||
                  TypeSemantics.IsPrimitiveType(leftExpr.ResultType,PrimitiveTypeKind.String) ||
                  SemanticResolver.IsNullExpression(leftExpr)))
            { 
                throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.PlusLeftExpressionInvalidType);
            } 
 
            DbExpression rightExpr = Convert(astBuiltInExpr.Arg2, sr);
            if (!(TypeSemantics.IsNumericType(rightExpr.ResultType) || 
                  TypeSemantics.IsPrimitiveType(rightExpr.ResultType, PrimitiveTypeKind.String) ||
                  SemanticResolver.IsNullExpression(rightExpr)))
            {
                throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.PlusRightExpressionInvalidType); 
            }
 
            if (null == TypeHelpers.GetCommonTypeUsage(leftExpr.ResultType, rightExpr.ResultType)) 
            {
                throw EntityUtil.EntitySqlError(astBuiltInExpr.ErrCtx, System.Data.Entity.Strings.ArgumentTypesAreIncompatible(leftExpr.ResultType.EdmType.FullName, rightExpr.ResultType.EdmType.FullName)); 
            }

            return sr.EnsureTypedNulls(leftExpr, rightExpr, astBuiltInExpr.ErrCtx, () => Strings.InvalidNullArithmetic);
        } 

 
        ///  
        /// Converts Logical Expression Args
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static Pair ConvertLogicalArgs( BuiltInExpr astBuiltInExpr, SemanticResolver sr ) 
        {
            DbExpression leftExpr = Convert(astBuiltInExpr.Arg1, sr); 
            if (leftExpr is UntypedNullExpression) 
            {
                leftExpr = sr.CmdTree.CreateNullExpression(sr.TypeResolver.BooleanType); 
            }

            DbExpression rightExpr = Convert(astBuiltInExpr.Arg2, sr);
            if (rightExpr is UntypedNullExpression) 
            {
                rightExpr = sr.CmdTree.CreateNullExpression(sr.TypeResolver.BooleanType); 
            } 

            // 
            // ensure left expression type is boolean
            //
            if (!TypeResolver.IsBooleanType(leftExpr.ResultType))
            { 
                throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.ExpressionTypeMustBeBoolean);
            } 
 
            //
            // ensure right expression type is boolean 
            //
            if (null != rightExpr && !TypeResolver.IsBooleanType(rightExpr.ResultType))
            {
                throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.ExpressionTypeMustBeBoolean); 
            }
 
            return new Pair(leftExpr, rightExpr); 
        }
 

        /// 
        /// Converts Equal Comparison Expression Args
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        ///  
        private static Pair ConvertEqualCompArgs( BuiltInExpr astBuiltInExpr, SemanticResolver sr )
        { 
            //
            // convert left and right types and infer null types
            //
            Pair compArgs = sr.EnsureTypedNulls( Convert(astBuiltInExpr.Arg1, sr), 
                                                                         Convert(astBuiltInExpr.Arg2, sr),
                                                                         astBuiltInExpr.ErrCtx, 
                                                                         () => Strings.InvalidNullComparison); 

            // 
            // ensure both operand types are equal-comparable
            //
            if (!TypeSemantics.IsEqualComparableTo(compArgs.Left.ResultType, compArgs.Right.ResultType))
            { 
                throw EntityUtil.EntitySqlError(astBuiltInExpr.ErrCtx, System.Data.Entity.Strings.ArgumentTypesAreIncompatible(compArgs.Left.ResultType.EdmType.FullName, compArgs.Right.ResultType.EdmType.FullName));
            } 
 
            return compArgs;
        } 


        /// 
        /// Converts Order Comparison Expression Args 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static Pair ConvertOrderCompArgs( BuiltInExpr astBuiltInExpr, SemanticResolver sr ) 
        {
            Pair compArgs = sr.EnsureTypedNulls(
                                                            Convert(astBuiltInExpr.Arg1, sr),
                                                            Convert(astBuiltInExpr.Arg2, sr), 
                                                            astBuiltInExpr.ErrCtx,
                                                            () => Strings.InvalidNullComparison); 
 
            //
            // ensure both operand types are order-comparable 
            //
            if (!TypeSemantics.IsOrderComparableTo(compArgs.Left.ResultType, compArgs.Right.ResultType))
            {
                throw EntityUtil.EntitySqlError(astBuiltInExpr.ErrCtx, System.Data.Entity.Strings.ArgumentTypesAreIncompatible(compArgs.Left.ResultType.EdmType.FullName, compArgs.Right.ResultType.EdmType.FullName)); 
            }
 
            return compArgs; 
        }
 

        /// 
        /// Converts Set Expression Args
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        ///  
        private static Pair ConvertSetArgs( BuiltInExpr astBuiltInExpr, SemanticResolver sr )
        { 
            //
            // convert left expression
            //
            DbExpression leftExpr = Convert(astBuiltInExpr.Arg1, sr); 

            // 
            // convert right expression if binary set op kind 
            //
            DbExpression rightExpr = null; 
            if (null != astBuiltInExpr.Arg2)
            {
                //
                // binary set op 
                //
 
                // 
                // make sure left expression type is of sequence type (ICollection or Extent)
                // 
                if (!TypeSemantics.IsCollectionType(leftExpr.ResultType))
                {
                    throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.LeftSetExpressionArgsMustBeCollection);
                } 

                // 
                // convert right expression 
                //
                rightExpr = Convert(astBuiltInExpr.Arg2, sr); 

                //
                // make sure right expression type is of sequence type (ICollection or Extent)
                // 
                if (!TypeSemantics.IsCollectionType(rightExpr.ResultType))
                { 
                    throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.RightSetExpressionArgsMustBeCollection); 
                }
 
                TypeUsage commonType;
                TypeUsage leftElemType = TypeHelpers.GetElementTypeUsage(leftExpr.ResultType);
                TypeUsage rightElemType = TypeHelpers.GetElementTypeUsage(rightExpr.ResultType);
                if (!TypeSemantics.TryGetCommonType(leftElemType, rightElemType, out commonType)) 
                {
                    CqlErrorHelper.ReportIncompatibleCommonType(astBuiltInExpr.ErrCtx, leftElemType, rightElemType); 
                } 

                if (astBuiltInExpr.Kind != BuiltInKind.UnionAll) 
                {
                    //
                    // ensure left argument is set op comparable
                    // 
                    if (!TypeHelpers.IsSetComparableOpType(TypeHelpers.GetElementTypeUsage(leftExpr.ResultType)))
                    { 
                        throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg1.ErrCtx, 
                                             System.Data.Entity.Strings.PlaceholderSetArgTypeIsNotEqualComparable(
                                                           astBuiltInExpr.Kind.ToString().ToUpperInvariant(), 
                                                           System.Data.Entity.Strings.LocalizedLeft,
                                                           TypeHelpers.GetElementTypeUsage(leftExpr.ResultType).EdmType.FullName));
                    }
 
                    //
                    // ensure right argument is set op comparable 
                    // 
                    if (!TypeHelpers.IsSetComparableOpType(TypeHelpers.GetElementTypeUsage(rightExpr.ResultType)))
                    { 
                        throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg2.ErrCtx,
                                             System.Data.Entity.Strings.PlaceholderSetArgTypeIsNotEqualComparable(
                                                           astBuiltInExpr.Kind.ToString().ToUpperInvariant(),
                                                           System.Data.Entity.Strings.LocalizedRight, 
                                                           TypeHelpers.GetElementTypeUsage(rightExpr.ResultType).EdmType.FullName));
                    } 
                } 
                else
                { 
                    if (Helper.IsAssociationType(leftElemType.EdmType))
                    {
                        throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.InvalidAssociationTypeForUnion(leftElemType.Identity));
                    } 

                    if (Helper.IsAssociationType(rightElemType.EdmType)) 
                    { 
                        throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.InvalidAssociationTypeForUnion(rightElemType.Identity));
                    } 
                }
            }
            else
            { 
                //
                // unary set op 
                // 

                // 
                // make sure expression type is of sequence type (ICollection or Extent)
                //
                if (!TypeSemantics.IsCollectionType(leftExpr.ResultType))
                { 
                    throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.InvalidUnarySetOpArgument(astBuiltInExpr.Name));
                } 
 
                //
                // make sure that if is distinct unary operator, arg element type must be equal-comparable 
                //
                if (astBuiltInExpr.Kind == BuiltInKind.Distinct && !TypeHelpers.IsValidDistinctOpType(TypeHelpers.GetElementTypeUsage(leftExpr.ResultType)))
                {
                    throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.ExpressionTypeMustBeEqualComparable); 
                }
            } 
 
            return new Pair(leftExpr, rightExpr);
        } 


        /// 
        /// Converts Set 'IN' expression args 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static Pair ConvertInExprArgs( BuiltInExpr astBuiltInExpr, SemanticResolver sr ) 
        {
            DbExpression leftExpr = Convert(astBuiltInExpr.Arg1, sr);
            if (TypeSemantics.IsCollectionType(leftExpr.ResultType))
            { 
                throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.ExpressionTypeMustNotBeCollection);
            } 
 
            DbExpression rightExpr = Convert(astBuiltInExpr.Arg2, sr);
            if (!TypeSemantics.IsCollectionType(rightExpr.ResultType)) 
            {
                throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.RightSetExpressionArgsMustBeCollection);
            }
 
            //
            // if left expression type is null, infer its type from the collection element type 
            // 
            if (SemanticResolver.IsNullExpression(leftExpr))
            { 
                TypeUsage elementType = TypeHelpers.GetElementTypeUsage(rightExpr.ResultType);

                SemanticResolver.EnsureValidTypeForNullExpression(elementType, astBuiltInExpr.Arg1.ErrCtx);
 
                leftExpr = sr.CmdTree.CreateNullExpression(elementType);
            } 
            else 
            {
                // 
                // ensure that if left and right are typed expressions then their types must be comparable for IN op
                //
                TypeUsage commonElemType = TypeHelpers.GetCommonTypeUsage(leftExpr.ResultType, TypeHelpers.GetElementTypeUsage(rightExpr.ResultType));
                if (null == commonElemType || !TypeHelpers.IsValidInOpType(commonElemType)) 
                {
                    throw EntityUtil.EntitySqlError(astBuiltInExpr.ErrCtx, System.Data.Entity.Strings.InvalidInExprArgs(leftExpr.ResultType.EdmType.FullName, rightExpr.ResultType.EdmType.FullName)); 
                } 
            }
 
            return new Pair(leftExpr, rightExpr);
        }

 
        /// 
        /// Converts Type Expression Args 
        ///  
        /// 
        /// SemanticResolver instance relative to a specific typespace/system 
        /// 
        private static Pair ConvertTypeExprArgs( BuiltInExpr astBuiltInExpr, SemanticResolver sr )
        {
            return new Pair(Convert(astBuiltInExpr.Arg1, sr), 
                                                     ConvertTypeIdentifier(astBuiltInExpr.Arg2, sr));
        } 
 

        ///  
        /// Converts TypeIdentifier
        /// TypeIdentifier can have the 'shape' of a simple identifier (product), a dotted identifier (namespace.bar) or a methodExpr ( edm.decimal(10,4) )
        /// 
        ///  
        /// 
        ///  
        private static TypeUsage ConvertTypeIdentifier(Expr typeIdentifierExpr, SemanticResolver sr) 
        {
            MethodExpr methodExpr = null; 
            string[] typeNames;

            //
            // if it is dot id get full id name 
            //
            DotExpr dotExpr = typeIdentifierExpr as DotExpr; 
            if (null != dotExpr && dotExpr.IsDottedIdentifier) 
            {
                typeNames = dotExpr.Names; 
            }
            else
            {
                // 
                // method expression, type with parameters
                // 
                methodExpr = typeIdentifierExpr as MethodExpr; 
                if (null != methodExpr)
                { 
                    typeNames = methodExpr.MethodPrefixExpr.Names;
                    Debug.Assert(methodExpr.Args.Count == 1 || methodExpr.Args.Count == 2, "decimal type must have one or two arguments");
                    Debug.Assert(methodExpr.Args[0] is Literal, "type expression must have literal arg");
                    Debug.Assert((methodExpr.Args.Count == 2) ? methodExpr.Args[1] is Literal : true, "type expression must have literal arg"); 
                }
                else 
                { 
                    //
                    // if it is single id, get it is name 
                    //
                    Identifier id = typeIdentifierExpr as Identifier;
                    if (null != id)
                    { 
                        typeNames = new string[] { id.Name };
                    } 
                    else 
                    {
                        throw EntityUtil.EntitySqlError(typeIdentifierExpr.ErrCtx, System.Data.Entity.Strings.InvalidTypeNameExpression); 
                    }
                }
            }
 
            //
            // Resolve type 
            // 
            TypeUsage typeUsage = sr.ResolveNameAsType(typeNames, typeIdentifierExpr);
 
            return typeUsage;
        }

 
        /// 
        /// Converts Row type constructor expression 
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static DbExpression ConvertRowConstructor( Expr expr, SemanticResolver sr )
        {
            RowConstructorExpr rowExpr = (RowConstructorExpr)expr; 
            Dictionary rowColumns = new Dictionary(sr.ScopeStringComparer);
            List fieldExprs = new List(rowExpr.AliasExprList.Count); 
 
            for (int i = 0 ; i < rowExpr.AliasExprList.Count ; i++)
            { 
                AliasExpr aliasExpr = rowExpr.AliasExprList[i];

                DbExpression colExpr = Convert(aliasExpr.Expr, sr);
 
                string aliasName = sr.InferAliasName(aliasExpr, colExpr);
 
                if (rowColumns.ContainsKey(aliasName)) 
                {
                    if (aliasExpr.HasAlias) 
                    {
                        CqlErrorHelper.ReportAliasAlreadyUsedError(aliasName, aliasExpr.AliasIdentifier.ErrCtx, System.Data.Entity.Strings.InRowConstructor);
                    }
                    else 
                    {
                        aliasName = sr.GenerateInternalName("autoRowCol"); 
                    } 
                }
 
                if (SemanticResolver.IsNullExpression(colExpr))
                {
                    throw EntityUtil.EntitySqlError(aliasExpr.Expr.ErrCtx, System.Data.Entity.Strings.RowCtorElementCannotBeNull);
                } 

                rowColumns.Add(aliasName, colExpr.ResultType); 
 
                fieldExprs.Add(colExpr);
            } 

            return sr.CmdTree.CreateNewInstanceExpression(TypeHelpers.CreateRowTypeUsage(rowColumns, true /* readOnly */), fieldExprs);
        }
 

        ///  
        /// Converts Multiset type constructor expression 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpression ConvertMultisetConstructor( Expr expr, SemanticResolver sr )
        { 
            MultisetConstructorExpr msetCtor = (MultisetConstructorExpr)expr;
 
            if (null == msetCtor.ExprList) 
            {
                throw EntityUtil.EntitySqlError(expr.ErrCtx, System.Data.Entity.Strings.CannotCreateEmptyMultiset); 
            }

            PairOfLists mSetExprs = ProcessExprList(msetCtor.ExprList, sr);
 
            TypeUsage commonType = TypeHelpers.GetCommonTypeUsage(mSetExprs.Left);
 
            // 
            // ensure all elems have a common type
            // 
            if (null == commonType)
            {
                throw EntityUtil.EntitySqlError(expr.ErrCtx, System.Data.Entity.Strings.MultisetElemsAreNotTypeCompatible);
            } 

            // 
            // ensure common type is not an untyped null 
            //
            if (TypeSemantics.IsNullType(commonType)) 
            {
                throw EntityUtil.EntitySqlError(expr.ErrCtx, System.Data.Entity.Strings.CannotCreateMultisetofNulls);
            }
 
            commonType = TypeHelpers.GetReadOnlyType(commonType);
 
            // 
            // fixup untyped nulls
            // 
            for (int i = 0 ; i < mSetExprs.Count ; i++)
            {
                if (SemanticResolver.IsNullExpression(mSetExprs.Right[i]))
                { 
                    SemanticResolver.EnsureValidTypeForNullExpression(commonType, msetCtor.ExprList[i].ErrCtx);
 
                    mSetExprs.Right[i] = sr.CmdTree.CreateNullExpression(commonType); 
                }
            } 

            return sr.CmdTree.CreateNewInstanceExpression(TypeHelpers.CreateCollectionTypeUsage(commonType, true /* readOnly */), mSetExprs.Right);
        }
 

        ///  
        /// converts case-when-then expression 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpression ConvertCaseExpr( Expr expr, SemanticResolver sr )
        { 
            CaseExpr caseExpr = (CaseExpr)expr;
 
            List whenExprList = new List(caseExpr.WhenThenExprList.Count); 

            PairOfLists thenExprList = new PairOfLists(); 

            //
            // Resolve then expressions
            // 
            for (int i = 0 ; i < caseExpr.WhenThenExprList.Count ; i++)
            { 
                WhenThenExpr whenThenExpr = caseExpr.WhenThenExprList[i]; 

                DbExpression whenExpression = Convert(whenThenExpr.WhenExpr, sr); 

                if (!TypeResolver.IsBooleanType(whenExpression.ResultType))
                {
                    throw EntityUtil.EntitySqlError(whenThenExpr.WhenExpr.ErrCtx, System.Data.Entity.Strings.ExpressionTypeMustBeBoolean); 
                }
 
                whenExprList.Add(whenExpression); 

                DbExpression thenExpression = Convert(whenThenExpr.ThenExpr, sr); 

                thenExprList.Add(thenExpression, thenExpression.ResultType);
            }
 
            TypeUsage resultType = TypeHelpers.GetCommonTypeUsage(thenExprList.Right);
            if (null == resultType) 
            { 
                throw EntityUtil.EntitySqlError(caseExpr.WhenThenExprList.Expressions[0].ThenExpr.ErrCtx, System.Data.Entity.Strings.InvalidCaseThenTypes);
            } 

            if ((null == caseExpr.ElseExpr) && TypeSemantics.IsNullType(resultType))
            {
                throw EntityUtil.EntitySqlError(caseExpr.WhenThenExprList.Expressions[0].ThenExpr.ErrCtx, System.Data.Entity.Strings.InvalidCaseThenNullType); 
            }
 
            // 
            // Converts else if present
            // 
            DbExpression elseExpr = null;
            if (null != caseExpr.ElseExpr)
            {
                elseExpr = Convert(caseExpr.ElseExpr, sr); 

                resultType = TypeHelpers.GetCommonTypeUsage(resultType, elseExpr.ResultType); 
                if (null == resultType) 
                {
                    throw EntityUtil.EntitySqlError(caseExpr.ElseExpr.ErrCtx, System.Data.Entity.Strings.InvalidCaseElseType); 
                }

                if (TypeSemantics.IsNullType(resultType))
                { 
                    throw EntityUtil.EntitySqlError(caseExpr.ElseExpr.ErrCtx, System.Data.Entity.Strings.InvalidCaseWhenThenNullType);
                } 
 
                if (SemanticResolver.IsNullExpression(elseExpr))
                { 
                    SemanticResolver.EnsureValidTypeForNullExpression(resultType, caseExpr.ElseExpr.ErrCtx);
                    elseExpr = sr.CmdTree.CreateNullExpression(resultType);
                }
            } 
            else
            { 
                if (TypeSemantics.IsCollectionType(resultType)) 
                {
                    elseExpr = sr.CmdTree.CreateNewEmptyCollectionExpression(resultType); 
                }
                else
                {
                    SemanticResolver.EnsureValidTypeForNullExpression(resultType, caseExpr.ErrCtx); 
                    elseExpr = sr.CmdTree.CreateNullExpression(resultType);
                } 
            } 

            // 
            // fixup untyped nulls
            //
            for (int i = 0 ; i < thenExprList.Count ; i++)
            { 
                if (SemanticResolver.IsNullExpression(thenExprList.Left[i]))
                { 
                    SemanticResolver.EnsureValidTypeForNullExpression(resultType, caseExpr.WhenThenExprList[i].ThenExpr.ErrCtx); 

                    thenExprList[i] = new Pair(sr.CmdTree.CreateNullExpression(resultType), resultType); 
                }
            }

            return sr.CmdTree.CreateCaseExpression(whenExprList, thenExprList.Left, elseExpr); 
        }
 
 
        /// 
        /// Converts Query Expression 
        /// 
        /// 
        /// SemanticResolver instance relative to a especif typespace/system
        ///  
        private static DbExpression ConvertQuery( Expr expr, SemanticResolver sr )
        { 
            QueryExpr queryExpr = (QueryExpr)expr; 
            DbExpression converted = null;
            bool isRestrictedViewGenerationMode = (ParserOptions.CompilationMode.RestrictedViewGenerationMode == sr.ParserOptions.ParserCompilationMode); 

            //
            // Validate & Compensate Query
            // 
            ValidateAndCompensateQuery(queryExpr);
 
            // 
            // Create Source Scope Region
            // 
            using (sr.EnterScopeRegion())
            {
                //
                // Process From Clause 
                //
                DbExpressionBinding sourceExpr = ProcessFromClause(queryExpr.FromClause, sr); 
 
                //
                // Process Where Clause 
                //
                sourceExpr = ProcessWhereClause(sourceExpr, queryExpr.WhereClause, sr);

                Debug.Assert(isRestrictedViewGenerationMode ? null == queryExpr.GroupByClause : true, "GROUP BY clause must be null in RestrictedViewGenerationMode"); 
                Debug.Assert(isRestrictedViewGenerationMode ? null == queryExpr.HavingClause  : true, "HAVING clause must be null in RestrictedViewGenerationMode");
                Debug.Assert(isRestrictedViewGenerationMode ? null == queryExpr.OrderByClause : true, "ORDER BY clause must be null in RestrictedViewGenerationMode"); 
 
                if ( !isRestrictedViewGenerationMode )
                { 
                    //
                    // Process GroupBy Clause
                    //
                    sourceExpr = ProcessGroupByClause(sourceExpr, queryExpr, sr); 

                    // 
                    // Process Having Clause 
                    //
                    sourceExpr = ProcessHavingClause(sourceExpr, queryExpr.HavingClause, sr); 

                    //
                    // Process OrderBy Clause
                    // 
                    sourceExpr = ProcessOrderByClause(sourceExpr, queryExpr, sr);
                } 
 
                //
                // Process Projection Clause 
                //
                converted = ProcessSelectClause(sourceExpr, queryExpr, sr);

            } // end query scope region 

            return converted; 
        } 

 
        /// 
        /// Validates and Compensates query expression
        /// 
        ///  
        private static void ValidateAndCompensateQuery( QueryExpr queryExpr )
        { 
            if (null != queryExpr.HavingClause && null == queryExpr.GroupByClause) 
            {
                throw EntityUtil.EntitySqlError(queryExpr.ErrCtx, System.Data.Entity.Strings.HavingRequiresGroupClause); 
            }

            if (queryExpr.SelectClause.HasTopClause)
            { 
                if ((null != queryExpr.OrderByClause) && queryExpr.OrderByClause.HasLimitSubClause)
                { 
                    throw EntityUtil.EntitySqlError(queryExpr.SelectClause.TopExpr.ErrCtx, System.Data.Entity.Strings.TopAndLimitCannotCoexist); 
                }
 
                if ((null != queryExpr.OrderByClause) && queryExpr.OrderByClause.HasSkipSubClause)
                {
                    throw EntityUtil.EntitySqlError(queryExpr.SelectClause.TopExpr.ErrCtx, System.Data.Entity.Strings.TopAndSkipCannotCoexist);
                } 
            }
        } 
 

        ///  
        /// Process Select Clause
        /// 
        /// 
        ///  
        /// SemanticResolver instance relative to a especific typespace/system
        ///  
        private static DbExpression ProcessSelectClause( DbExpressionBinding source, QueryExpr queryExpr, SemanticResolver sr ) 
        {
            DbExpression projectExpression = null; 
            SelectClause selectClause = queryExpr.SelectClause;
            HashSet projectionAliases = new HashSet(sr.ScopeStringComparer);
            List> projFields = new List>(selectClause.Items.Count);
 
            //
            // if source is sort/skip expression, then skip projection conversion since it was already 
            // performed 
            //
            if (queryExpr.OrderByClause != null && selectClause.DistinctKind == DistinctKind.Distinct) 
            {
                projectExpression = source.Expression;
            }
            else 
            {
                // 
                // Converts projection list 
                //
                #region Process projection list 
                for (int i = 0; i < selectClause.Items.Count; i++)
                {
                    AliasExpr selectExprItem = selectClause.Items[i];
 
                    DbExpression converted = Convert(selectExprItem.Expr, sr);
 
                    // 
                    // ensure expression is typed
                    // 
                    SemanticResolver.EnsureIsNotUntypedNull(converted, selectExprItem.Expr.ErrCtx);

                    //
                    // infer projection expression alias 
                    //
                    string aliasName = sr.InferAliasName(selectExprItem, converted); 
 
                    //
                    // ensure the alias was not used already 
                    //
                    if (projectionAliases.Contains(aliasName))
                    {
                        if (selectExprItem.HasAlias) 
                        {
                            CqlErrorHelper.ReportAliasAlreadyUsedError(aliasName, selectExprItem.AliasIdentifier.ErrCtx, System.Data.Entity.Strings.InSelectProjectionList); 
                        } 
                        else
                        { 
                            aliasName = sr.GenerateInternalName("autoProject");
                        }
                    }
 
                    projectionAliases.Add(aliasName);
 
                    projFields.Add(new KeyValuePair(aliasName, converted)); 
                }
                #endregion 


                //
                // VALUE projection 
                //
                #region handles VALUE modifier 
                if (selectClause.SelectKind == SelectKind.SelectValue) 
                {
                    if (projFields.Count > 1) 
                    {
                        throw EntityUtil.EntitySqlError(selectClause.ErrCtx, System.Data.Entity.Strings.InvalidSelectItem);
                    }
 
                    projectExpression = sr.CmdTree.CreateProjectExpression(source, projFields[0].Value);
                } 
                else 
                {
                    projectExpression = sr.CmdTree.CreateProjectExpression(source, sr.CmdTree.CreateNewRowExpression(projFields)); 
                }
                #endregion

                // 
                // handle DISTINCT modifier
                // 
                #region DISTINCT 
                if (selectClause.DistinctKind == DistinctKind.Distinct)
                { 
                    //
                    // ensure element type is equal-comparable
                    //
                    SemanticResolver.ValidateDistinctProjection(selectClause, projectExpression.ResultType); 

                    // 
                    // create distinct expression 
                    //
                    projectExpression = sr.CmdTree.CreateDistinctExpression(projectExpression); 
                }
                #endregion
            }
 
            //
            // TOP sub-clause 
            // NOTE: WITH TIES is not supported in M3.2 
            //
            #region TOP/LIMIT sub-clause 
            if (selectClause.HasTopClause || ((null != queryExpr.OrderByClause) && queryExpr.OrderByClause.HasLimitSubClause))
            {
                ErrorContext errCtx = (selectClause.HasTopClause) ? selectClause.TopExpr.ErrCtx : queryExpr.OrderByClause.LimitSubClause.ErrCtx;
                // 
                // convert top argument
                // 
                DbExpression limitExpr = Convert((selectClause.HasTopClause) ? selectClause.TopExpr : queryExpr.OrderByClause.LimitSubClause, sr); 

                // 
                // ensure is not NULL expr
                //
                SemanticResolver.EnsureIsNotUntypedNull(limitExpr, errCtx);
 
                Debug.Assert(limitExpr is DbConstantExpression || limitExpr is DbParameterReferenceExpression, "TOP/LIMIT inner expression must be a parameter or numeric literal in this release");
 
                // 
                // ensure proper pre-conditions hold for TOP expression
                // 
                sr.EnsureValidLimitExpression(
                        errCtx,
                        limitExpr,
                        (selectClause.HasTopClause) ? "TOP" : "LIMIT"); 

                // create expression - WITH TIES is not supported in M3.2 
                projectExpression = sr.CmdTree.CreateLimitExpression(projectExpression, limitExpr); 
            }
            #endregion 

            Debug.Assert(null != projectExpression,"null != projectExpr");

            return projectExpression; 
        }
 
 
        /// 
        /// Process From Clause 
        /// 
        /// 
        /// SemanticResolver instance relative to a especif typespace/system
        ///  
        private static DbExpressionBinding ProcessFromClause( FromClause fromClause, SemanticResolver sr )
        { 
            DbExpressionBinding fromBinding = null; 
            DbExpressionBinding fromBindingAux = null;
 
            //
            // Process Each From Clause Item
            //
            for (int i = 0 ; i < fromClause.FromClauseItems.Count ; i++ ) 
            {
                // 
                // Set Scope Source Var Kind 
                //
                sr.SetCurrentScopeVarKind(fromClause.FromClauseItems[i].FromClauseItemKind); 

                //
                // Convert From Clause
                // 
                fromBindingAux = ProcessFromClauseItem(fromClause.FromClauseItems[i], sr);
 
                // 
                // Reset All Vars to SourceVar Kind
                // 
                sr.ResetCurrentScopeVarKind();

                if (null == fromBinding)
                { 
                    fromBinding = fromBindingAux;
                } 
                else 
                {
                    fromBinding = sr.CmdTree.CreateExpressionBinding( 
                                        sr.CmdTree.CreateCrossApplyExpression(fromBinding, fromBindingAux),
                                        sr.GenerateInternalName("lcapply"));

                    sr.FixupNamedSourceVarBindings(fromBinding.Variable); 
                }
 
            } 

            Debug.Assert(null != fromBinding,"null != fromBinding"); 

            return fromBinding;
        }
 

        ///  
        /// Process Generic From Clause Item 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpressionBinding ProcessFromClauseItem( FromClauseItem fromClauseItem, SemanticResolver sr )
        { 
            DbExpressionBinding fromItemBinding = null;
 
            AliasExpr aliasExpr = fromClauseItem.FromExpr as AliasExpr; 
            if (null != aliasExpr)
            { 
                fromItemBinding = ProcessAliasedFromClauseItem(aliasExpr, sr);
            }
            else
            { 
                JoinClauseItem joinClauseItem = fromClauseItem.FromExpr as JoinClauseItem;
                if (null != joinClauseItem) 
                { 
                    fromItemBinding = ProcessJoinClauseItem(joinClauseItem, sr);
                } 
                else
                {
                    fromItemBinding = ProcessApplyClauseItem((ApplyClauseItem)fromClauseItem.FromExpr, sr);
                } 
            }
 
            Debug.Assert(null != fromItemBinding,"null != fromItemBinding"); 

            return fromItemBinding; 
        }


        ///  
        /// Process 'Simple' From Clause Item
        ///  
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        ///  
        private static DbExpressionBinding ProcessAliasedFromClauseItem( AliasExpr aliasedExpr, SemanticResolver sr )
        {
            DbExpressionBinding aliasedBinding = null;
 
            //
            // converts from item expression 
            // 
            DbExpression converted = Convert(aliasedExpr.Expr, sr);
 
            //
            // ensure expression is typed
            //
            SemanticResolver.EnsureIsNotUntypedNull(converted, aliasedExpr.Expr.ErrCtx); 

            // 
            // validate it is of sequence type (Extent || ICollection) 
            //
            if (!TypeSemantics.IsCollectionType(converted.ResultType)) 
            {
                throw EntityUtil.EntitySqlError(aliasedExpr.Expr.ErrCtx, System.Data.Entity.Strings.ExpressionMustBeCollection);
            }
 
            //
            // infer source var alias name 
            // 
            string aliasName = sr.InferAliasName(aliasedExpr, converted);
 
            //
            // validate the name was not used yet.
            //
            if (sr.IsInCurrentScope(aliasName)) 
            {
                if (aliasedExpr.HasAlias) 
                { 
                    CqlErrorHelper.ReportAliasAlreadyUsedError(aliasName, aliasedExpr.AliasIdentifier.ErrCtx, System.Data.Entity.Strings.InFromClause);
                } 
                else
                {
                    aliasName = sr.GenerateInternalName("autoFrom");
                } 
            }
 
            // 
            // create cqt expression
            // 
            aliasedBinding = sr.CmdTree.CreateExpressionBinding(converted, aliasName);

            //
            // add source var to scope 
            //
            sr.AddSourceBinding(aliasedBinding); 
 
            Debug.Assert(null != aliasedBinding,"null != aliasedBinding");
 
            return aliasedBinding;
        }

 
        /// 
        /// process join clause item 
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static DbExpressionBinding ProcessJoinClauseItem( JoinClauseItem joinClause, SemanticResolver sr )
        {
            DbExpressionBinding joinBinding = null; 

            // 
            // make sure inner join have on predicate AND cross join has no ON predicate 
            //
            if (null == joinClause.OnExpr) 
            {
                if (JoinKind.Inner == joinClause.JoinKind)
                {
                    throw EntityUtil.EntitySqlError(joinClause.ErrCtx, System.Data.Entity.Strings.InnerJoinMustHaveOnPredicate); 
                }
            } 
            else 
            {
                if (JoinKind.Cross == joinClause.JoinKind) 
                {
                    throw EntityUtil.EntitySqlError(joinClause.OnExpr.ErrCtx, System.Data.Entity.Strings.InvalidPredicateForCrossJoin);
                }
            } 

            // 
            // Resolve Left Expression 
            //
            sr.CurrentScopeRegionFlags.PathTagger.VisitLeftNode(); 
            DbExpressionBinding leftBindingExpr = ProcessFromClauseItem(joinClause.LeftExpr, sr);
            sr.CurrentScopeRegionFlags.PathTagger.LeaveNode();

            // 
            // Resolve Right Expression
            // 
            sr.CurrentScopeRegionFlags.IsInsideJoinOnPredicate = false; 
            sr.CurrentScopeRegionFlags.PathTagger.VisitRightNode();
            DbExpressionBinding rightBindingExpr = ProcessFromClauseItem(joinClause.RightExpr, sr); 
            sr.CurrentScopeRegionFlags.PathTagger.LeaveNode();

            //
            // convert right outer to left outer 
            //
            if (joinClause.JoinKind == JoinKind.RightOuter) 
            { 
                joinClause.JoinKind = JoinKind.LeftOuter;
                DbExpressionBinding tmpExpr = leftBindingExpr; 
                leftBindingExpr = rightBindingExpr;
                rightBindingExpr = tmpExpr;
            }
 
            //
            // Resolve JoinType 
            // 
            DbExpressionKind joinKind = SemanticResolver.MapJoinKind(joinClause.JoinKind);
 
            //
            // Resolve ON
            //
            sr.CurrentScopeRegionFlags.IsInsideJoinOnPredicate = true; 
            DbExpression onExpr = null;
            if (null == joinClause.OnExpr) 
            { 
                if (DbExpressionKind.CrossJoin != joinKind)
                { 
                    onExpr = sr.CmdTree.CreateTrueExpression();
                }
            }
            else 
            {
                onExpr = Convert(joinClause.OnExpr, sr); 
 
                //
                // ensure expression is typed 
                //
                SemanticResolver.EnsureIsNotUntypedNull(onExpr, joinClause.OnExpr.ErrCtx);
            }
            sr.CurrentScopeRegionFlags.IsInsideJoinOnPredicate = false; 

            // 
            // Create New Join 
            //
            joinBinding = sr.CmdTree.CreateExpressionBinding( 
                                        sr.CmdTree.CreateJoinExpressionByKind(joinKind, onExpr, leftBindingExpr, rightBindingExpr),
                                        sr.GenerateInternalName("join"));

            // 
            // Fixup Join Source Vars in Scope
            // 
            sr.FixupNamedSourceVarBindings(joinBinding.Variable); 

            Debug.Assert(null != joinBinding,"null != joinBinding"); 

            return joinBinding;
        }
 

        ///  
        /// Process apply clause item 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpressionBinding ProcessApplyClauseItem( ApplyClauseItem applyClause, SemanticResolver sr )
        { 
            DbExpressionBinding applyBinding = null;
 
            // 
            // Resolve Left Expression
            // 
            sr.CurrentScopeRegionFlags.PathTagger.VisitLeftNode();
            DbExpressionBinding leftBindingExpr = ProcessFromClauseItem(applyClause.LeftExpr, sr);
            sr.CurrentScopeRegionFlags.PathTagger.LeaveNode();
 
            //
            // Resolve Right Expression 
            // 
            sr.CurrentScopeRegionFlags.PathTagger.VisitRightNode();
            DbExpressionBinding rightBindingExpr = ProcessFromClauseItem(applyClause.RightExpr, sr); 
            sr.CurrentScopeRegionFlags.PathTagger.LeaveNode();

            //
            // Create Apply 
            //
            applyBinding = sr.CmdTree.CreateExpressionBinding( 
                                sr.CmdTree.CreateApplyExpressionByKind(SemanticResolver.MapApplyKind(applyClause.ApplyKind), 
                                                 leftBindingExpr,
                                                 rightBindingExpr), 
                                sr.GenerateInternalName("apply"));

            //
            // Fixup Apply Source Vars in Scope 
            //
            sr.FixupNamedSourceVarBindings(applyBinding.Variable); 
 
            Debug.Assert(null != applyBinding,"null != applyBinding");
 
            return applyBinding;
        }

 

        ///  
        /// Process Where Expression 
        /// 
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpressionBinding ProcessWhereClause( DbExpressionBinding source, Expr whereClause, SemanticResolver sr ) 
        {
            if (null == whereClause) 
            { 
                return source;
            } 

            DbExpressionBinding whereBinding = null;

            // 
            // Convert Where Condition
            // 
            DbExpression filterConditionExpr = Convert(whereClause, sr); 

            // 
            // ensure expression is typed
            //
            SemanticResolver.EnsureIsNotUntypedNull(filterConditionExpr, whereClause.ErrCtx);
 
            //
            // ensure the predicate type is boolean 
            // 
            if (!TypeResolver.IsBooleanType(filterConditionExpr.ResultType))
            { 
                throw EntityUtil.EntitySqlError(whereClause.ErrCtx, System.Data.Entity.Strings.ExpressionTypeMustBeBoolean);
            }

            // 
            // Create New Filter Binding
            // 
            whereBinding = sr.CmdTree.CreateExpressionBinding( 
                                sr.CmdTree.CreateFilterExpression(source, filterConditionExpr),
                                sr.GenerateInternalName("where")); 

            //
            // Fixup Bindings
            // 
            sr.FixupSourceVarBindings(whereBinding.Variable);
 
            Debug.Assert(null != whereBinding,"null != whereBinding"); 

            return whereBinding; 
        }


        ///  
        /// Process Group By Clause
        ///  
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static DbExpressionBinding ProcessGroupByClause( DbExpressionBinding source, QueryExpr queryExpr, SemanticResolver sr )
        {
            SemanticResolver.ScopeViewKind saveScopeView = sr.GetScopeView(); 

            GroupByClause groupByClause = queryExpr.GroupByClause; 
 
            Debug.Assert((sr.ParserOptions.ParserCompilationMode == ParserOptions.CompilationMode.RestrictedViewGenerationMode) ? null == groupByClause : true, "GROUP BY clause must be null in RestrictedViewGenerationMode");
 
            //
            // if group expression is null, create a dummy and speculate that there are group aggregates in the remaining query expression
            // if no group aggregate if found after partial evaluation of Having, OrderBy and Select in the 1st pass, rollback what we did
            // and return source expression. 
            //
            #region Define Implicit Group if needed 
            if (null == queryExpr.GroupByClause) 
            {
                if (!queryExpr.HasMethodCall) 
                {
                    return source;
                }
 
                //
                // if group expression is null create a dummy and speculate that there are group aggregates in the remaining query expression 
                // if no group aggregate if found after partial evaluation of Having, OrderBy and Select in the 1st pass, rollback what we did 
                // and return source expression.
                // 
                sr.CurrentScopeRegionFlags.IsImplicitGroup = true;

            }
            else 
            {
                sr.CurrentScopeRegionFlags.IsImplicitGroup = false; 
            } 
            #endregion
 
            DbExpressionBinding groupBinding = null;

            //
            // Create Group Binding 
            //
            DbGroupExpressionBinding groupExprBinding = sr.CmdTree.CreateGroupExpressionBinding( 
                                                                        source.Expression, 
                                                                        sr.GenerateInternalName("geb"),
                                                                        sr.GenerateInternalName("group")); 
            //
            // Update source scope vars
            //
            sr.FixupGroupSourceVarBindings(groupExprBinding.Variable, groupExprBinding.GroupVariable); 

            // 
            // convert group elements 
            //
            #region Convert Group Key/Expressions 
            int groupKeysCount = (null != groupByClause ) ? groupByClause.GroupItems.Count : 0;
            List> groupKeys = new List>(groupKeysCount);
            HashSet groupKeyNames = new HashSet(sr.ScopeStringComparer);
            List groupKeysForAggregates = new List(8); 
            if (!sr.CurrentScopeRegionFlags.IsImplicitGroup)
            { 
                Debug.Assert(null != groupByClause, "groupByClause must not be null at this point"); 
                for (int i = 0 ; i < groupKeysCount ; i++)
                { 
                    AliasExpr aliasedExpr = groupByClause.GroupItems[i];

                    sr.ResetScopeRegionCorrelationFlag();
 
                    //
                    // convert key expression (relative to DbGroupExpressionBinding.Var) 
                    // 
                    DbExpression converted = Convert(aliasedExpr.Expr, sr);
 
                    //
                    // ensure expression is typed
                    //
                    SemanticResolver.EnsureIsNotUntypedNull(converted, aliasedExpr.Expr.ErrCtx); 

                    // 
                    // ensure group key expression is correlated 
                    //
                    if (!sr.CurrentScopeRegionFlags.WasResolutionCorrelated) 
                    {
                        throw EntityUtil.EntitySqlError(aliasedExpr.Expr.ErrCtx, System.Data.Entity.Strings.KeyMustBeCorrelated("GROUP BY"));
                    }
 
                    //
                    // convert key expression (relative to DbGroupExpressionBinding.GroupVar) 
                    // this is only needed because during the search for groupaggregates, group aggregates may 
                    // refer to group keys.
                    // 
                    sr.CurrentScopeRegionFlags.IsInsideGroupAggregate = true;

                    DbExpression groupKeyAggExpr = Convert(aliasedExpr.Expr, sr);
 
                    groupKeysForAggregates.Add(groupKeyAggExpr);
 
                    sr.CurrentScopeRegionFlags.IsInsideGroupAggregate = false; 

                    // 
                    // ensure keys are valid
                    //
                    if (!TypeHelpers.IsValidGroupKeyType(converted.ResultType))
                    { 
                        throw EntityUtil.EntitySqlError(aliasedExpr.Expr.ErrCtx, System.Data.Entity.Strings.GroupingKeysMustBeEqualComparable);
                    } 
 
                    //
                    // infer alias name 
                    //
                    string groupKeyAlias = sr.InferAliasName(aliasedExpr, converted);

                    // 
                    // check if alias was already used
                    // 
                    if (groupKeyNames.Contains(groupKeyAlias)) 
                    {
                        if (aliasedExpr.HasAlias) 
                        {
                            CqlErrorHelper.ReportAliasAlreadyUsedError(groupKeyAlias, aliasedExpr.AliasIdentifier.ErrCtx, System.Data.Entity.Strings.InGroupClause);
                        }
                        else 
                        {
                            groupKeyAlias = sr.GenerateInternalName("autoGroup"); 
                        } 
                    }
 
                    //
                    // add key name to alias dictionary
                    //
                    groupKeyNames.Add(groupKeyAlias); 

                    // 
                    // add key to keys collection 
                    //
                    groupKeys.Add(new KeyValuePair(groupKeyAlias, converted)); 

                    //
                    // group keys should visible by their 'original' key expression name. All forms should be allowed:
                    //   SELECT k FROM ... as p GROUP BY p.Price as k (explicit key alias) - handled above by InferAliasName() 
                    //   SELECT Price FROM ... as p GROUP BY p.Price (implicit alias - leading name) - handled above by InferAliasName()
                    //   SELECT p.Price FROM ... as p GROUP BY p.Price (original key expression) - case handled in the code bellow 
                    // 
                    if (!aliasedExpr.HasAlias)
                    { 
                        DotExpr dotExpr = aliasedExpr.Expr as DotExpr;
                        if (null != dotExpr && dotExpr.IsDottedIdentifier)
                        {
                            groupKeyAlias = dotExpr.FullName; 

                            if (groupKeyNames.Contains(groupKeyAlias)) 
                            { 
                                CqlErrorHelper.ReportAliasAlreadyUsedError(groupKeyAlias, dotExpr.ErrCtx, System.Data.Entity.Strings.InGroupClause);
                            } 

                            groupKeyNames.Add(groupKeyAlias);

                            groupKeys.Add(new KeyValuePair(groupKeyAlias, converted)); 

                            groupKeysForAggregates.Add(groupKeyAggExpr); 
                        } 
                    }
                } 
            }
            #endregion

            // 
            // save scope status
            // 
            SavePoint savePoint = sr.CreateSavePoint(); 

            // 
            // Push Group scope
            //
            sr.EnterScope();
 
            //
            // Add converted group variables/expressions to group scope 
            // 
            #region Add Converted Group Variables to Scope
            // 
            // add 'dummy' keys to scope.
            // this is needed since during the aggreagate search phase, keys may be referenced.
            //
            for (int i = 0 ; i < groupKeys.Count ; i++) 
            {
                sr.AddDummyGroupKeyToScope(groupKeys[i].Key, groupKeys[i].Value, groupKeysForAggregates[i]); 
            } 

            // 
            // flags that we are inside a group scope
            //
            sr.CurrentScopeRegionFlags.IsInGroupScope = true;
            #endregion 

            // 
            // Convert/Search Aggregates 
            // since aggregates can be defined in Having, OrderBy and/or Select clauses must be resolved as part of the group expression.
            // The resolution of these clauses result in potential collection of resolved group aggregates and the actual resulting 
            // expression is ignored. These clauses will be then resolved as usual on a second pass.
            //

            #region Search for group Aggregates 
            //
            // search for aggregates in HAVING clause 
            // 
            if (null != queryExpr.HavingClause && queryExpr.HavingClause.HasMethodCall)
            { 
                sr.CurrentScopeRegionFlags.ResetGroupAggregateNestingCount();

                DbExpression converted = Convert(queryExpr.HavingClause.HavingPredicate, sr);
 
                //
                // ensure expression is typed 
                // 
                SemanticResolver.EnsureIsNotUntypedNull(converted, queryExpr.HavingClause.ErrCtx);
            } 

            //
            // search for aggregates in SELECT clause
            // 
            Dictionary sortExpr = null;
            if ( null != queryExpr.OrderByClause || queryExpr.SelectClause.HasMethodCall ) 
            { 
                sortExpr = new Dictionary(queryExpr.SelectClause.Items.Count, sr.ScopeStringComparer);
                for ( int i = 0 ; i < queryExpr.SelectClause.Items.Count ; i++ ) 
                {
                    AliasExpr aliasedExpr = queryExpr.SelectClause.Items[i];

                    // 
                    // Reset Group aggregate nesting count
                    // 
                    sr.CurrentScopeRegionFlags.ResetGroupAggregateNestingCount(); 

                    // 
                    // convert projection item expression
                    //
                    DbExpression converted = Convert(aliasedExpr.Expr, sr);
 
                    //
                    // ensure expression is typed 
                    // 
                    SemanticResolver.EnsureIsNotUntypedNull(converted, aliasedExpr.Expr.ErrCtx);
 
                    //
                    // create Null Expression with actual type
                    //
                    converted = sr.CmdTree.CreateNullExpression(converted.ResultType); 

                    // 
                    // infer alias 
                    //
                    string aliasName = sr.InferAliasName(aliasedExpr, converted); 

                    if ( sortExpr.ContainsKey(aliasName) )
                    {
                        if ( aliasedExpr.HasAlias ) 
                        {
                            CqlErrorHelper.ReportAliasAlreadyUsedError(aliasName, 
                                                                       aliasedExpr.AliasIdentifier.ErrCtx, 
                                                                       System.Data.Entity.Strings.InSelectProjectionList);
                        } 
                        else
                        {
                            aliasName = sr.GenerateInternalName("autoProject");
                        } 
                    }
 
                    sortExpr.Add(aliasName, converted); 
                }
            } 

            //
            // search for aggregates in ORDER BY clause
            // 
            if (null != queryExpr.OrderByClause && queryExpr.OrderByClause.HasMethodCall)
            { 
                // 
                // push projection key scope
                // 
                sr.EnterScope();

                //
                // Add projection items to scope (it may be used in ORDER BY) 
                //
                foreach ( KeyValuePair kvp in sortExpr ) 
                { 
                    sr.AddToScope(kvp.Key, new ProjectionScopeEntry(kvp.Key, kvp.Value));
                } 

                //
                // search for aggregates in ORDER BY clause
                // 
                for (int i = 0 ; i < queryExpr.OrderByClause.OrderByClauseItem.Count ; i++)
                { 
                    OrderByClauseItem orderItem = queryExpr.OrderByClause.OrderByClauseItem[i]; 

                    sr.CurrentScopeRegionFlags.ResetGroupAggregateNestingCount(); 

                    sr.ResetScopeRegionCorrelationFlag();

                    DbExpression converted = Convert(orderItem.OrderExpr, sr); 

                    // 
                    // ensure expression is typed 
                    //
                    SemanticResolver.EnsureIsNotUntypedNull(converted, orderItem.OrderExpr.ErrCtx); 

                    //
                    // ensure key expression is correlated
                    // 
                    if (!sr.CurrentScopeRegionFlags.WasResolutionCorrelated)
                    { 
                        throw EntityUtil.EntitySqlError(orderItem.ErrCtx, System.Data.Entity.Strings.KeyMustBeCorrelated("ORDER BY")); 
                    }
                } 

                //
                // pop projection scope
                // 
                sr.LeaveScope();
            } 
            #endregion 

            // 
            // if we introduced a fake group but did not 'found' any group aggregate
            // on the first pass, then there is no need for creating an implicit group.
            // rollback to the status before entering ProcessGroupByClause().
            // if we did find group aggregates, make sure all non-group aggregate function 
            // expressions refer to group scope variables only
            // 
            #region Implicit Group Rollback 
            if (sr.CurrentScopeRegionFlags.IsImplicitGroup)
            { 
                if (0 == sr.CurrentScopeRegionFlags.GroupAggregatesInfo.Count)
                {
                    //
                    // rolls back scope status 
                    //
                    sr.RollbackToSavepoint(savePoint); 
 
                    //
                    // undo any group source fixups, re-applying the source var 
                    //
                    sr.UndoFixupGroupSourceVarBindings(source.Variable);

                    // 
                    // reset is inside group scope flag
                    // 
                    sr.CurrentScopeRegionFlags.IsInGroupScope = false; 

                    //// 
                    //// reset implict group flag
                    ////
                    sr.CurrentScopeRegionFlags.IsImplicitGroup = false;
 
                    //
                    // restore scope view kind 
                    // 
                    sr.SetScopeView(saveScopeView);
 
                    //
                    // return the original source var binding
                    //
                    return source; 
                }
 
                // 
                // now that we know that there are group aggregates in other expression, reset implict group flag to false
                // since it is now considered a legitimate group 
                //
                sr.CurrentScopeRegionFlags.IsImplicitGroup = false;
            }
            #endregion 

            // 
            // extract list of aggregates and names 
            //
            List> aggregates = new List>(sr.CurrentScopeRegionFlags.GroupAggregatesInfo.Count); 
            foreach(KeyValuePair kvp in sr.CurrentScopeRegionFlags.GroupAggregatesInfo)
            {
                aggregates.Add(new KeyValuePair(kvp.Value.AggregateName, kvp.Value.AggregateExpression));
                kvp.Key.ResetDummyExpression(); 
            }
 
            // 
            // Create Group Expression
            // 
            groupBinding = sr.CmdTree.CreateExpressionBinding(
                                                    sr.CmdTree.CreateGroupByExpression(
                                                                        groupExprBinding,
                                                                        groupKeys, 
                                                                        aggregates),
                                                    sr.GenerateInternalName("group")); 
 
            //
            // replace dummy keys with real keys 
            //
            for (int i = 0 ; i < groupKeys.Count ; i++)
            {
                sr.ReplaceGroupVarInScope(groupKeys[i].Key, groupBinding.Variable); 
            }
 
            // 
            // add aggregates to scope
            // 
            for (int i = 0 ; i < aggregates.Count ; i++ )
            {
                sr.CurrentScopeRegionFlags.AddGroupAggregateToScopeFlags(aggregates[i].Key);
 
                sr.AddGroupAggregateToScope(aggregates[i].Key, groupBinding.Variable);
            } 
 
            //
            // restrict group scope visibility 
            //
            sr.SetScopeView(SemanticResolver.ScopeViewKind.GroupScope);

            // 
            // fixup all source vars
            // 
            sr.FixupNamedSourceVarBindings(groupBinding.Variable); 

            // 
            // Mark source vars as group input vars
            //
            sr.MarkGroupInputVars();
 
            Debug.Assert(null != groupBinding,"null != groupBinding");
 
            return groupBinding; 
        }
 

        /// 
        /// Process Having Clause
        ///  
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static DbExpressionBinding ProcessHavingClause( DbExpressionBinding source, HavingClause havingClause, SemanticResolver sr ) 
        {
            Debug.Assert((sr.ParserOptions.ParserCompilationMode == ParserOptions.CompilationMode.RestrictedViewGenerationMode) ? null == havingClause : true, "HAVING clause must be null in RestrictedViewGenerationMode");

            if (null == havingClause) 
            {
                return source; 
            } 

            DbExpressionBinding havingBinding = null; 

            //
            // Convert Having Expression
            // 
            DbExpression filterConditionExpr = Convert(havingClause.HavingPredicate, sr);
 
            // 
            // ensure expression is typed
            // 
            SemanticResolver.EnsureIsNotUntypedNull(filterConditionExpr, havingClause.ErrCtx);

            //
            // ensure having predicate of boolean type 
            //
            if (!TypeResolver.IsBooleanType(filterConditionExpr.ResultType)) 
            { 
                throw EntityUtil.EntitySqlError(havingClause.ErrCtx, System.Data.Entity.Strings.ExpressionTypeMustBeBoolean);
            } 

            //
            // Create New Filter Binding
            // 
            havingBinding = sr.CmdTree.CreateExpressionBinding(
                                            sr.CmdTree.CreateFilterExpression(source, filterConditionExpr), 
                                            sr.GenerateInternalName("having")); 

            // 
            // Fixup Bindings
            //
            sr.FixupSourceVarBindings(havingBinding.Variable);
 
            Debug.Assert(null != havingBinding,"null != havingBinding");
 
            return havingBinding; 
        }
 

        /// 
        /// Process Order By Clause
        ///  
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static DbExpressionBinding ProcessOrderByClause( DbExpressionBinding source, QueryExpr queryExpr, SemanticResolver sr ) 
        {
            Debug.Assert((sr.ParserOptions.ParserCompilationMode == ParserOptions.CompilationMode.RestrictedViewGenerationMode) ? null == queryExpr.OrderByClause : true, "ORDER BY clause must be null in RestrictedViewGenerationMode");

            if (null == queryExpr.OrderByClause) 
            {
                return source; 
            } 

            DbExpressionBinding sortBinding = null; 
            OrderByClause orderByClause = queryExpr.OrderByClause;
            SelectClause selectClause = queryExpr.SelectClause;

            // 
            // Create a savepoint
            // 
            SavePoint savePoint = sr.CreateSavePoint(); 

            // 
            // perform partial conversion of SELECT statements
            //
            Dictionary projectionExpressions = new Dictionary(selectClause.Items.Count, sr.ScopeStringComparer);
            for (int i = 0 ; i < selectClause.Items.Count ; i++) 
            {
                AliasExpr aliasedExpr = selectClause.Items[i]; 
 
                DbExpression converted = Convert(aliasedExpr.Expr, sr);
 
                //
                // ensure expression is typed
                //
                SemanticResolver.EnsureIsNotUntypedNull(converted, aliasedExpr.Expr.ErrCtx); 

                // 
                // infer projection alias 
                //
                string aliasName = sr.InferAliasName(aliasedExpr, converted); 

                if (projectionExpressions.ContainsKey(aliasName))
                {
                    if (aliasedExpr.HasAlias) 
                    {
                        CqlErrorHelper.ReportAliasAlreadyUsedError(aliasName, aliasedExpr.AliasIdentifier.ErrCtx, System.Data.Entity.Strings.InSelectProjectionList); 
                    } 
                    else
                    { 
                        aliasName = sr.GenerateInternalName("autoProject");
                    }
                }
 
                projectionExpressions.Add(aliasName, converted);
            } 
 
            //
            // convert paging sub-clauses they if exists before adding projection list to scope 
            // NOTE: TOP, LIMIT and SKIP have nearly the same constraints in M3.2. in the future this is likely to change by allowing
            // these sub-clauses to have generic expressions.
            //
            #region Handles SKIP sub-clause 
            DbExpression skipExpr = null;
            if (orderByClause.HasSkipSubClause) 
            { 
                skipExpr = Convert(orderByClause.SkipSubClause, sr);
 
                //
                // ensure is not NULL expr
                //
                SemanticResolver.EnsureIsNotUntypedNull(skipExpr, orderByClause.SkipSubClause.ErrCtx); 

                DbConstantExpression constantExpr = skipExpr as DbConstantExpression; 
 
                Debug.Assert(constantExpr!=null || skipExpr is DbParameterReferenceExpression, "SKIP inner expression must be a parameter or numeric literal in this release");
 
                //
                // ensure SKIP expression have the right type
                //
                if (!TypeSemantics.IsPromotableTo(skipExpr.ResultType, sr.TypeResolver.Int64Type)) 
                {
                    throw EntityUtil.EntitySqlError(orderByClause.SkipSubClause.ErrCtx, System.Data.Entity.Strings.PlaceholderExpressionMustBeCompatibleWithEdm64("SKIP", skipExpr.ResultType.EdmType.FullName)); 
                } 

                // 
                // if it is a literal, make sure it has the correct value
                //
                if (null != constantExpr && System.Convert.ToInt64(constantExpr.Value, CultureInfo.InvariantCulture) < 0)
                { 
                    throw EntityUtil.EntitySqlError(orderByClause.SkipSubClause.ErrCtx, System.Data.Entity.Strings.PlaceholderExpressionMustBeGreaterThanOrEqualToZero("SKIP"));
                } 
 

            } 
            #endregion

            //
            // Push scope for projection items 
            //
            sr.EnterScope(); 
 
            //
            // Add projection items to scope 
            //
            foreach (KeyValuePair kvp in projectionExpressions)
            {
                // 
                // if the reference expression is a group aggregate, then there is no need to add to scope
                // 
                if (!sr.CurrentScopeRegionFlags.ContainsGroupAggregate(kvp.Key)) 
                {
                    sr.AddToScope(kvp.Key, new ProjectionScopeEntry(kvp.Key, kvp.Value)); 
                }
            }

            // 
            // save scope view
            // 
            SemanticResolver.ScopeViewKind saveScopeView = sr.GetScopeView(); 

            // 
            // If DISTICT was especified set visibility to current scope only
            // if DISTINCT modifier is present, push the projection and distinct expression down bellow
            // sort/skip expressions
            // 
            if (selectClause.DistinctKind == DistinctKind.Distinct)
            { 
                sr.SetScopeView(SemanticResolver.ScopeViewKind.CurrentScope); 

                List> projectionExpressionList = new List>(projectionExpressions); 

                //
                // Create projection
                // 
                DbExpression projectExpression;
                if (selectClause.SelectKind == SelectKind.SelectRow) 
                { 
                    projectExpression = sr.CmdTree.CreateNewRowExpression(projectionExpressionList);
                } 
                else
                {
                    Debug.Assert(selectClause.Items.Count == 1, "SELECT VALUE must have only one argument");
                    projectExpression = projectionExpressionList[0].Value; 
                }
                projectExpression = sr.CmdTree.CreateProjectExpression(source, projectExpression); 
 
                //
                // Ensure Projection is valid for DISTINCT modifier 
                //
                SemanticResolver.ValidateDistinctProjection(selectClause, projectExpression.ResultType);

                // 
                // create new source binding
                // 
                source = sr.CmdTree.CreateExpressionBinding(sr.CmdTree.CreateDistinctExpression(projectExpression), 
                                                            sr.GenerateInternalName("distinct"));
 
                //
                // replace Projection scope with new expression bindings
                //
                for (int i = 0; i < projectionExpressionList.Count; i++) 
                {
                    if (!sr.CurrentScopeRegionFlags.ContainsGroupAggregate(projectionExpressionList[i].Key)) 
                    { 
                        // remove old scope var
                        sr.RemoveFromScope(projectionExpressionList[i].Key); 

                        // create and add new source var to scope
                        SourceScopeEntry sce = new SourceScopeEntry(ScopeEntryKind.SourceVar, projectionExpressionList[i].Key, source.Variable);
                        if (selectClause.SelectKind == SelectKind.SelectRow) 
                        {
                            sce.AddBindingPrefix(projectionExpressionList[i].Key); 
                        } 
                        sr.AddToScope(projectionExpressionList[i].Key, sce);
                    } 
                }
            }

            // 
            // if is not DISTINCT, but is a group scope, then should be the group scope and the
            // projection list 
            // 
            else if (sr.CurrentScopeRegionFlags.IsInGroupScope)
            { 
                sr.SetScopeView(SemanticResolver.ScopeViewKind.CurrentAndPreviousScope);
            }

            // 
            // convert sort keys
            // 
            List sortKeys = new List(orderByClause.OrderByClauseItem.Expressions.Count); 
            for (int i = 0 ; i < orderByClause.OrderByClauseItem.Expressions.Count ; i++)
            { 
                OrderByClauseItem orderClauseItem = orderByClause.OrderByClauseItem.Expressions[i];

                sr.CurrentScopeRegionFlags.ResetGroupAggregateNestingCount();
 
                sr.ResetScopeRegionCorrelationFlag();
 
                // 
                // convert order key expression
                // 
                DbExpression keyExpr = Convert(orderClauseItem.OrderExpr, sr);

                //
                // ensure expression is typed 
                //
                SemanticResolver.EnsureIsNotUntypedNull(keyExpr, orderClauseItem.OrderExpr.ErrCtx); 
 
                //
                // ensure key expression is correlated. if group by is present, then the check was already performed 
                //
                if (!sr.CurrentScopeRegionFlags.WasResolutionCorrelated)
                {
                    throw EntityUtil.EntitySqlError(orderClauseItem.ErrCtx, System.Data.Entity.Strings.KeyMustBeCorrelated("ORDER BY")); 
                }
 
                // 
                // ensure key is order comparable
                // 
                if (!TypeHelpers.IsValidSortOpKeyType(keyExpr.ResultType))
                {
                    throw EntityUtil.EntitySqlError(orderClauseItem.OrderExpr.ErrCtx, System.Data.Entity.Strings.OrderByKeyIsNotOrderComparable);
                } 

                // 
                // define order 
                //
                bool ascSort = (orderClauseItem.OrderKind == OrderKind.None) || (orderClauseItem.OrderKind == OrderKind.Asc); 

                //
                // define collation
                // 
                string collation = null;
                if (orderClauseItem.IsCollated) 
                { 
                    if (!TypeResolver.IsKeyValidForCollation(keyExpr.ResultType))
                    { 
                        throw EntityUtil.EntitySqlError(orderClauseItem.OrderExpr.ErrCtx, System.Data.Entity.Strings.InvalidKeyTypeForCollation(keyExpr.ResultType.EdmType.FullName));
                    }

                    collation = orderClauseItem.CollateIdentifier.Name; 
                }
                // 
                // if orderby has no collation defined, check if a default was given through ParserOptions 
                //
                else if (sr.ParserOptions.DefaultOrderByCollation.Length > 0 && TypeResolver.IsKeyValidForCollation(keyExpr.ResultType)) 
                {
                    collation = sr.ParserOptions.DefaultOrderByCollation;
                }
 
                //
                // add keys to key collection 
                // 
                if (string.IsNullOrEmpty(collation))
                { 
                    sortKeys.Add(sr.CmdTree.CreateSortClause(keyExpr, ascSort));
                }
                else
                { 
                    sortKeys.Add(sr.CmdTree.CreateSortClause(keyExpr, ascSort, collation));
                } 
            } 
            DbExpression sortSourceExpr = null;
            if (orderByClause.HasSkipSubClause) 
            {
                sortSourceExpr = sr.CmdTree.CreateSkipExpression(source, sortKeys, skipExpr);
            }
            else 
            {
                sortSourceExpr = sr.CmdTree.CreateSortExpression(source, sortKeys); 
            } 

            // 
            // Create Sort Binding
            //
            sortBinding = sr.CmdTree.CreateExpressionBinding(
                                        sortSourceExpr, 
                                        sr.GenerateInternalName("sort"));
 
            // 
            // Fixup Bindings
            // 
            sr.FixupSourceVarBindings(sortBinding.Variable);

            //
            // pops projection keys from scope 
            //
            sr.RollbackToSavepoint(savePoint); 
 
            //
            // restore scope view 
            //
            sr.SetScopeView(saveScopeView);

            Debug.Assert(null != sortBinding,"null != sortBinding"); 

            return sortBinding; 
        } 

 
        /// 
        /// Converts a list of ast expression nodes
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        ///  
        private static PairOfLists ProcessExprList( ExprList astExprList, SemanticResolver sr ) 
        {
            List types = new List(astExprList.Count); 
            List convertedExprs = new List(astExprList.Count);

            for (int i = 0 ; i < astExprList.Count ; i++)
            { 
                DbExpression e = Convert(astExprList[i], sr);
                types.Add(e.ResultType); 
                convertedExprs.Add(e); 
            }
 
            return new PairOfLists(types, convertedExprs);
        }

 
        /// 
        /// [....]: Temporary workaround for 2/3 milestone. 
        /// Convert "x in multiset(y1, y2, ..., yn)" into 
        /// x = y1 or x = y2 or x = y3 ...
        ///  
        /// semantic resolver
        /// left-expression (the probe)
        /// right expression (the collection)
        /// Or chain of equality comparisons 
        private static DbExpression ConvertSimpleInExpression( SemanticResolver sr, DbExpression left, DbExpression right )
        { 
            // Only handle cases when the right-side is a new instance expression 
            Debug.Assert(right.ExpressionKind == DbExpressionKind.NewInstance,"right.ExpressionKind == DbExpressionKind.NewInstance");
            DbNewInstanceExpression rightColl = (DbNewInstanceExpression)right; 

            if (rightColl.Arguments.Count == 0)
            {
                return sr.CmdTree.CreateConstantExpression(false); 
            }
 
            DbExpression orExpr = null; 
            foreach (DbExpression e in rightColl.Arguments)
            { 
                DbExpression leftClone = (DbExpression)left.Clone();

                DbExpression eqExpr = sr.CmdTree.CreateEqualsExpression(leftClone, e);
 
                if (orExpr == null)
                { 
                    orExpr = eqExpr; 
                }
                else 
                {
                    orExpr = sr.CmdTree.CreateOrExpression(orExpr, eqExpr);
                }
            } 

            return orExpr; 
        } 

        #region Conversion Delegate Mappings 

        private delegate DbExpression AstExprConverter( Expr astExpr, SemanticResolver sr );
        private static readonly Dictionary _astExprConverters = CreateAstExprConverters();
        private delegate DbExpression BuiltInExprConverter( BuiltInExpr astBltInExpr, SemanticResolver sr ); 
        private static readonly Dictionary _builtInExprConverter = CreateBuiltInExprConverter();
 
        #region Define converter delegates 

        private static Dictionary CreateAstExprConverters() 
        {
            const int NumberOfElements = 15;  // number of elements initialized by the dictionary
            Dictionary astExprConverters = new Dictionary(NumberOfElements);
            astExprConverters.Add(typeof(Literal), new AstExprConverter(ConvertLiteral)); 
            astExprConverters.Add(typeof(Parameter), new AstExprConverter(ConvertParameter));
            astExprConverters.Add(typeof(Identifier), new AstExprConverter(ConvertIdentifier)); 
            astExprConverters.Add(typeof(DotExpr), new AstExprConverter(ConvertDotExpr)); 
            astExprConverters.Add(typeof(BuiltInExpr), new AstExprConverter(ConvertBuiltIn));
            astExprConverters.Add(typeof(QueryExpr), new AstExprConverter(ConvertQuery)); 
            astExprConverters.Add(typeof(RowConstructorExpr), new AstExprConverter(ConvertRowConstructor));
            astExprConverters.Add(typeof(MultisetConstructorExpr), new AstExprConverter(ConvertMultisetConstructor));
            astExprConverters.Add(typeof(CaseExpr), new AstExprConverter(ConvertCaseExpr));
            astExprConverters.Add(typeof(RelshipNavigationExpr), new AstExprConverter(ConvertRelshipNavigationExpr)); 
            astExprConverters.Add(typeof(RefExpr), new AstExprConverter(ConvertRefExpr));
            astExprConverters.Add(typeof(DerefExpr), new AstExprConverter(ConvertDeRefExpr)); 
            astExprConverters.Add(typeof(MethodExpr), new AstExprConverter(ConvertMethodExpr)); 
            astExprConverters.Add(typeof(CreateRefExpr), new AstExprConverter(ConvertCreateRefExpr));
            astExprConverters.Add(typeof(KeyExpr), new AstExprConverter(ConvertKeyExpr)); 
            Debug.Assert(NumberOfElements == astExprConverters.Count, "The number of elements and initial capacity don't match");
            return astExprConverters;
        }
 
        private static Dictionary CreateBuiltInExprConverter()
        { 
            Dictionary builtInExprConverter = new Dictionary(sizeof(BuiltInKind)); 

            //////////////////////////// 
            // Arithmetic Expressions
            ////////////////////////////

            // 
            // e1 + e2
            // 
            #region e1 + e2 
            builtInExprConverter.Add(BuiltInKind.Plus, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    Pair args = ConvertPlusOperands(bltInExpr, sr);

                    if (TypeSemantics.IsNumericType(args.Left.ResultType))
                    { 
                        return sr.CmdTree.CreatePlusExpression(args.Left, args.Right);
                    } 
                    else 
                    {
                        // 
                        // fold '+' operator into concat canonical function
                        //
                        IList functions;
                        if (!sr.TypeResolver.TryGetFunctionFromMetadata("Concat","Edm", true /* ignoreCase */, out functions)) 
                        {
                            throw EntityUtil.EntitySqlError(bltInExpr.ErrCtx, System.Data.Entity.Strings.ConcatBuiltinNotSupported); 
                        } 

                        List argTypes = new List(2); 
                        argTypes.Add(args.Left.ResultType);
                        argTypes.Add(args.Right.ResultType);

                        bool isAmbiguous = false; 
                        EdmFunction concatFunction = TypeResolver.ResolveFunctionOverloads(functions, argTypes, false /* isGroupAggregate */, out isAmbiguous);
                        if (null == concatFunction || isAmbiguous) 
                        { 
                            throw EntityUtil.EntitySqlError(bltInExpr.ErrCtx, System.Data.Entity.Strings.ConcatBuiltinNotSupported);
                        } 

                        return sr.CmdTree.CreateFunctionExpression(concatFunction,
                                                                   new DbExpression[] { args.Left, args.Right });
                    } 

                }); 
            #endregion 

            // 
            // e1 - e2
            //
            #region e1 - e2
            builtInExprConverter.Add(BuiltInKind.Minus, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    Pair args = ConvertArithmeticArgs(bltInExpr, sr); 
 
                    return sr.CmdTree.CreateMinusExpression(args.Left, args.Right);
                }); 
            #endregion

            //
            // e1 * e2 
            //
            #region e1 * e2 
            builtInExprConverter.Add(BuiltInKind.Multiply, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    Pair args = ConvertArithmeticArgs(bltInExpr, sr); 

                    return sr.CmdTree.CreateMultiplyExpression(args.Left, args.Right);
                });
            #endregion 

            // 
            // e1 / e2 
            //
            #region e1 / e2 
            builtInExprConverter.Add(BuiltInKind.Divide, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                {
                    Pair args = ConvertArithmeticArgs(bltInExpr, sr);
 
                    return sr.CmdTree.CreateDivideExpression(args.Left, args.Right);
                }); 
            #endregion 

            // 
            // e1 % e2
            //
            #region e1 % e2
            builtInExprConverter.Add(BuiltInKind.Modulus, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    Pair args = ConvertArithmeticArgs(bltInExpr, sr); 
 
                    return sr.CmdTree.CreateModuloExpression(args.Left, args.Right);
                }); 
            #endregion

            //
            // - e 
            //
            #region - e 
            builtInExprConverter.Add(BuiltInKind.UnaryMinus, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    DbExpression unaryExpr = sr.CmdTree.CreateUnaryMinusExpression(ConvertArithmeticArgs(bltInExpr, sr).Left); 
                    if (TypeSemantics.IsUnsignedNumericType(unaryExpr.ResultType))
                    {
                        TypeUsage closestPromotableType = null;
                        if (TypeHelpers.TryGetClosestPromotableType(unaryExpr.ResultType, out closestPromotableType)) 
                        {
                            unaryExpr = sr.CmdTree.CreateCastExpression(unaryExpr, closestPromotableType); 
                        } 
                        else
                        { 
                            throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.InvalidUnsignedTypeForUnaryMinusOperation(unaryExpr.ResultType.EdmType.FullName));
                        }
                    }
                    return unaryExpr; 
                });
            #endregion 
 
            //
            // + e 
            //
            #region + e
            builtInExprConverter.Add(BuiltInKind.UnaryPlus, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    return ConvertArithmeticArgs(bltInExpr, sr).Left;
                }); 
            #endregion 

            //////////////////////////// 
            // Logical Expressions
            ////////////////////////////

            // 
            // e1 AND e2
            // e1 && e2 
            // 
            #region e1 AND e2
            builtInExprConverter.Add(BuiltInKind.And, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    Pair args = SemanticAnalyzer.ConvertLogicalArgs(bltInExpr, sr);

                    return sr.CmdTree.CreateAndExpression(args.Left, args.Right); 
                });
            #endregion 
 
            //
            // e1 OR e2 
            // e1 || e2
            //
            #region e1 OR e2
            builtInExprConverter.Add(BuiltInKind.Or, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    Pair args = SemanticAnalyzer.ConvertLogicalArgs(bltInExpr, sr); 
 
                    return sr.CmdTree.CreateOrExpression(args.Left, args.Right);
                }); 
            #endregion

            //
            // NOT e 
            // ! e
            // 
            #region NOT e 
            builtInExprConverter.Add(BuiltInKind.Not, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    return sr.CmdTree.CreateNotExpression(ConvertLogicalArgs(bltInExpr, sr).Left);
                });
            #endregion
 
            ////////////////////////////
            // Comparison Expressions 
            //////////////////////////// 

            // 
            // e1 == e2 | e1 = e2
            //
            #region e1 == e2
            builtInExprConverter.Add(BuiltInKind.Equal, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    Pair args = ConvertEqualCompArgs(bltInExpr, sr); 
 
                    return sr.CmdTree.CreateEqualsExpression(args.Left, args.Right);
                }); 
            #endregion

            //
            // e1 != e2 | e1 <> e2 
            //
            #region e1 != e2 
            builtInExprConverter.Add(BuiltInKind.NotEqual, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    Pair args = ConvertEqualCompArgs(bltInExpr, sr); 

                    return sr.CmdTree.CreateNotExpression(
                                sr.CmdTree.CreateEqualsExpression(args.Left, args.Right));
                }); 
            #endregion
 
            // 
            // e1 >= e2
            // 
            #region e1 >= e2
            builtInExprConverter.Add(BuiltInKind.GreaterEqual, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                {
                    Pair args = ConvertOrderCompArgs(bltInExpr, sr); 

                    return sr.CmdTree.CreateGreaterThanOrEqualsExpression(args.Left, args.Right); 
                }); 
            #endregion
 
            //
            // e1 > e2
            //
            #region e1 > e2 
            builtInExprConverter.Add(BuiltInKind.GreaterThan, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    Pair args = ConvertOrderCompArgs(bltInExpr, sr); 

                    return sr.CmdTree.CreateGreaterThanExpression(args.Left, args.Right); 
                });
            #endregion

            // 
            // e1 <= e2
            // 
            #region e1 <= e2 
            builtInExprConverter.Add(BuiltInKind.LessEqual, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    Pair args = ConvertOrderCompArgs(bltInExpr, sr);

                    return sr.CmdTree.CreateLessThanOrEqualsExpression(args.Left, args.Right);
                }); 
            #endregion
 
            // 
            // e1 < e2
            // 
            #region e1 < e2
            builtInExprConverter.Add(BuiltInKind.LessThan, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                {
                    Pair args = ConvertOrderCompArgs(bltInExpr, sr); 

                    return sr.CmdTree.CreateLessThanExpression(args.Left, args.Right); 
                }); 
            #endregion
 

            ////////////////////////////
            //    SET EXPRESSIONS
            //////////////////////////// 

 
            // 
            // e1 UNION e2
            // 
            #region e1 UNION e2
            builtInExprConverter.Add(BuiltInKind.Union, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                {
                    Pair args = ConvertSetArgs(bltInExpr, sr); 

                    return sr.CmdTree.CreateDistinctExpression(sr.CmdTree.CreateUnionAllExpression(args.Left, args.Right)); 
                }); 
            #endregion
 
            //
            // e1 UNION ALL e2
            //
            #region e1 UNION ALL e2 
            builtInExprConverter.Add(BuiltInKind.UnionAll, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    Pair args = ConvertSetArgs(bltInExpr, sr); 

                    return sr.CmdTree.CreateUnionAllExpression(args.Left, args.Right); 
                });
            #endregion

            // 
            // e1 INTERSECT e2
            // 
            #region e1 INTERSECT e2 
            builtInExprConverter.Add(BuiltInKind.Intersect, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    Pair args = ConvertSetArgs(bltInExpr, sr);

                    return sr.CmdTree.CreateIntersectExpression(args.Left, args.Right);
                }); 
            #endregion
 
            // 
            // e1 OVERLAPS e2
            // 
            #region e1 OVERLAPS e1
            builtInExprConverter.Add(BuiltInKind.Overlaps, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                {
                    Pair args = ConvertSetArgs(bltInExpr, sr); 

                    return sr.CmdTree.CreateNotExpression( 
                                    sr.CmdTree.CreateIsEmptyExpression( 
                                        sr.CmdTree.CreateIntersectExpression(args.Left, args.Right)));
                }); 
            #endregion

            //
            // ANYELEMENT( e ) 
            //
            #region ANYELEMENT( e ) 
            builtInExprConverter.Add(BuiltInKind.AnyElement, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    return sr.CmdTree.CreateElementExpression(ConvertSetArgs(bltInExpr, sr).Left); 
                });
            #endregion

            // 
            // ELEMENT( e )
            // 
            #region ELEMENT( e ) - NOT SUPPORTED IN ORCAS TIMEFRAME 
            builtInExprConverter.Add(BuiltInKind.Element, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    throw EntityUtil.NotSupported(System.Data.Entity.Strings.ElementOperatorIsNotSupported);
                });
            #endregion
 
            //
            // e1 EXCEPT e2 
            // 
            #region e1 EXCEPT e2
            builtInExprConverter.Add(BuiltInKind.Except, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    Pair args = ConvertSetArgs(bltInExpr, sr);

                    return sr.CmdTree.CreateExceptExpression(args.Left, args.Right); 
                });
            #endregion 
 
            //
            // EXISTS( e ) 
            //
            #region EXISTS( e )
            builtInExprConverter.Add(BuiltInKind.Exists, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    return sr.CmdTree.CreateNotExpression(
                                    sr.CmdTree.CreateIsEmptyExpression(ConvertSetArgs(bltInExpr, sr).Left)); 
                }); 
            #endregion
 
            //
            // FLATTEN( e )
            //
            #region FLATTEN( e ) 
            builtInExprConverter.Add(BuiltInKind.Flatten, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    DbExpression elemExpr = Convert(bltInExpr.Arg1, sr); 

                    if (!TypeSemantics.IsCollectionType(elemExpr.ResultType)) 
                    {
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.InvalidFlattenArgument);
                    }
 
                    if (!TypeSemantics.IsCollectionType(TypeHelpers.GetElementTypeUsage(elemExpr.ResultType)))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.InvalidFlattenArgument); 
                    }
 
                    DbExpressionBinding leftExpr = sr.CmdTree.CreateExpressionBinding(elemExpr, sr.GenerateInternalName("l_flatten"));

                    DbExpressionBinding rightExpr = sr.CmdTree.CreateExpressionBinding(leftExpr.Variable, sr.GenerateInternalName("r_flatten"));
 
                    DbExpressionBinding applyBinding = sr.CmdTree.CreateExpressionBinding(
                                                                sr.CmdTree.CreateCrossApplyExpression(leftExpr, rightExpr), 
                                                                sr.GenerateInternalName("flatten")); 

                    return sr.CmdTree.CreateProjectExpression(applyBinding, sr.CmdTree.CreatePropertyExpression(rightExpr.VariableName, applyBinding.Variable)); 
                });
            #endregion

            // 
            // e1 IN e2
            // 
            #region e1 IN e2 
            builtInExprConverter.Add(BuiltInKind.In, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    Pair args = ConvertInExprArgs(bltInExpr, sr);

                    // [....]: Temporary workaround for 2/3 milestone.
                    // Convert "x in multiset(y1, y2, ..., yn)" into 
                    //    x = y1 or x = y2 or x = y3 ...
                    // 
                    if (args.Right.ExpressionKind == DbExpressionKind.NewInstance) 
                    {
                        return ConvertSimpleInExpression(sr, args.Left, args.Right); 
                    }
                    else
                    {
                        DbExpressionBinding rSet = sr.CmdTree.CreateExpressionBinding(args.Right, sr.GenerateInternalName("in-filter")); 

                        DbExpression leftIn = args.Left; 
                        DbExpression rightSet = rSet.Variable; 
                        DbExpression exists = sr.CmdTree.CreateNotExpression(
                                                    sr.CmdTree.CreateIsEmptyExpression( 
                                                            sr.CmdTree.CreateFilterExpression(
                                                                    rSet,
                                                                    sr.CmdTree.CreateEqualsExpression(leftIn, rightSet))));
 
                        List whenExpr = new List(1);
                        whenExpr.Add(sr.CmdTree.CreateIsNullExpression(leftIn)); 
                        List thenExpr = new List(1); 
                        thenExpr.Add(sr.CmdTree.CreateNullExpression(sr.TypeResolver.BooleanType));
 
                        DbExpression left = sr.CmdTree.CreateCaseExpression(
                                                                 whenExpr,
                                                                 thenExpr,
                                                                 sr.CmdTree.CreateFalseExpression()); 

                        DbExpression converted = sr.CmdTree.CreateOrExpression(left, exists); 
 
                        return converted;
                    } 
                });
            #endregion

            // 
            // e1 NOT IN e1
            // 
            #region e1 NOT IN e1 
            builtInExprConverter.Add(BuiltInKind.NotIn, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    Pair args = ConvertInExprArgs(bltInExpr, sr);

                    if (args.Right.ExpressionKind == DbExpressionKind.NewInstance)
                    { 
                        return sr.CmdTree.CreateNotExpression(
                            ConvertSimpleInExpression(sr, args.Left, args.Right)); 
                    } 
                    else
                    { 
                        DbExpressionBinding rSet = sr.CmdTree.CreateExpressionBinding(args.Right, sr.GenerateInternalName("in-filter"));

                        DbExpression leftIn = args.Left;
                        DbExpression rightSet = rSet.Variable; 
                        DbExpression exists = sr.CmdTree.CreateIsEmptyExpression(
                                                            sr.CmdTree.CreateFilterExpression( 
                                                                    rSet, 
                                                                    sr.CmdTree.CreateEqualsExpression(leftIn, rightSet)));
 
                        List whenExpr = new List(1);
                        whenExpr.Add(sr.CmdTree.CreateIsNullExpression(leftIn));
                        List thenExpr = new List(1);
                        thenExpr.Add(sr.CmdTree.CreateNullExpression(sr.TypeResolver.BooleanType)); 

                        DbExpression left = sr.CmdTree.CreateCaseExpression( 
                                                                 whenExpr, 
                                                                 thenExpr,
                                                                 sr.CmdTree.CreateTrueExpression()); 

                        DbExpression converted = sr.CmdTree.CreateAndExpression(left, exists);

                        return converted; 
                    }
                }); 
            #endregion 

            // 
            // SET( e ) - DISTINCT( e ) before
            //
            #region SET( e )
            builtInExprConverter.Add(BuiltInKind.Distinct, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    Pair args = ConvertSetArgs(bltInExpr, sr); 
 
                    return sr.CmdTree.CreateDistinctExpression(args.Left);
                }); 
            #endregion


            //////////////////////////// 
            // Nullabity Expressions
            //////////////////////////// 
 
            //
            // e IS NULL 
            //
            #region e IS NULL
            builtInExprConverter.Add(BuiltInKind.IsNull, delegate(BuiltInExpr bltInExpr, SemanticResolver sr)
            { 
                DbExpression isNullExpr = Convert(bltInExpr.Arg1, sr);
 
                // 
                // ensure expression type is valid for this operation
                // 
                if (!TypeHelpers.IsValidIsNullOpType(isNullExpr.ResultType))
                {
                    throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.IsNullInvalidType);
                } 

                return SemanticResolver.IsNullExpression(isNullExpr) ? sr.CmdTree.CreateTrueExpression() : (DbExpression)sr.CmdTree.CreateIsNullExpression(isNullExpr); 
            }); 
            #endregion
 
            //
            // e IS NOT NULL
            //
            #region e IS NOT NULL 
            builtInExprConverter.Add(BuiltInKind.IsNotNull, delegate(BuiltInExpr bltInExpr, SemanticResolver sr)
            { 
                DbExpression isNullExpr = Convert(bltInExpr.Arg1, sr); 

                // 
                // ensure expression type is valid for this operation
                //
                if (!TypeHelpers.IsValidIsNullOpType(isNullExpr.ResultType))
                { 
                    throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.IsNullInvalidType);
                } 
 
                isNullExpr = SemanticResolver.IsNullExpression(isNullExpr) ? sr.CmdTree.CreateTrueExpression() : (DbExpression)sr.CmdTree.CreateIsNullExpression(isNullExpr);
 
                return sr.CmdTree.CreateNotExpression(isNullExpr);
            });
            #endregion
 

            //////////////////////////// 
            //    Type Expressions 
            ////////////////////////////
 
            //
            // e IS OF ( [ONLY] T )
            //
            #region e IS OF ( [ONLY] T ) 
            builtInExprConverter.Add(BuiltInKind.IsOf, delegate(BuiltInExpr bltInExpr, SemanticResolver sr)
                { 
                    Pair args = ConvertTypeExprArgs(bltInExpr, sr); 

                    bool isOnly = (bool)((Literal)bltInExpr.ArgList[2]).Value; 
                    bool isNot = (bool)((Literal)bltInExpr.ArgList[3]).Value;
                    bool isNominalTypeAllowed = sr.ParserOptions.ParserCompilationMode == ParserOptions.CompilationMode.RestrictedViewGenerationMode;

                    if (TypeSemantics.IsNullType(args.Left.ResultType)) 
                    {
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, 
                                                    System.Data.Entity.Strings.ExpressionCannotBeNull); 
                    }
 
                    if (!isNominalTypeAllowed && !TypeSemantics.IsEntityType(args.Left.ResultType))
                    {
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx,
                                                    System.Data.Entity.Strings.ExpressionTypeMustBeEntityType(System.Data.Entity.Strings.CtxIsOf, 
                                                                                                              args.Left.ResultType.EdmType.BuiltInTypeKind.ToString(),
                                                                                                              args.Left.ResultType.EdmType.FullName)); 
                    } 
                    else if (isNominalTypeAllowed && !TypeSemantics.IsNominalType(args.Left.ResultType))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx,
                                                    System.Data.Entity.Strings.ExpressionTypeMustBeNominalType(System.Data.Entity.Strings.CtxIsOf,
                                                                                                              args.Left.ResultType.EdmType.BuiltInTypeKind.ToString(),
                                                                                                              args.Left.ResultType.EdmType.FullName)); 
                    }
 
                    if (!isNominalTypeAllowed && !TypeSemantics.IsEntityType(args.Right)) 
                    {
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.TypeMustBeEntityType(System.Data.Entity.Strings.CtxIsOf, 
                                                                                                                           args.Right.EdmType.BuiltInTypeKind.ToString(),
                                                                                                                           args.Right.EdmType.FullName));
                    }
                    else if (isNominalTypeAllowed && !TypeSemantics.IsNominalType(args.Right)) 
                    {
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.TypeMustBeNominalType(System.Data.Entity.Strings.CtxIsOf, 
                                                                                                                           args.Right.EdmType.BuiltInTypeKind.ToString(), 
                                                                                                                           args.Right.EdmType.FullName));
                    } 

                    if (!TypeSemantics.IsPolymorphicType(args.Left.ResultType))
                    {
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, 
                                                    System.Data.Entity.Strings.TypeMustBeInheritableType);
                    } 
 
                    if (!TypeSemantics.IsPolymorphicType(args.Right))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx,
                                                    System.Data.Entity.Strings.TypeMustBeInheritableType);
                    }
 
                    if (!TypeResolver.IsSubOrSuperType(args.Left.ResultType, args.Right))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.ErrCtx, 
                                                    System.Data.Entity.Strings.NotASuperOrSubType(args.Left.ResultType.EdmType.FullName,
                                                                                                  args.Right.EdmType.FullName)); 
                    }

                    args.Right = TypeHelpers.GetReadOnlyType(args.Right);
 
                    DbExpression retExpr = null;
                    if (isOnly) 
                    { 
                        retExpr = sr.CmdTree.CreateIsOfOnlyExpression(args.Left, args.Right);
                    } 
                    else
                    {
                        retExpr = sr.CmdTree.CreateIsOfExpression(args.Left, args.Right);
                    } 

                    if (isNot) 
                    { 
                        retExpr = sr.CmdTree.CreateNotExpression(retExpr);
                    } 

                    return retExpr;
                });
            #endregion 

            // 
            // TREAT( e as T ) 
            //
            #region TREAT( e as T ) 
            builtInExprConverter.Add(BuiltInKind.Treat, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                {
                    Pair args = ConvertTypeExprArgs(bltInExpr, sr);
 
                    bool isNominalTypeAllowed = sr.ParserOptions.ParserCompilationMode == ParserOptions.CompilationMode.RestrictedViewGenerationMode;
 
                    if (!isNominalTypeAllowed && !TypeSemantics.IsEntityType(args.Right)) 
                    {
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx, 
                                                    System.Data.Entity.Strings.TypeMustBeEntityType(System.Data.Entity.Strings.CtxTreat,
                                                                                                    args.Right.EdmType.BuiltInTypeKind.ToString(),
                                                                                                    args.Right.EdmType.FullName));
                    } 
                    else if (isNominalTypeAllowed && !TypeSemantics.IsNominalType(args.Right))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx, 
                                                    System.Data.Entity.Strings.TypeMustBeNominalType(System.Data.Entity.Strings.CtxTreat,
                                                                                                    args.Right.EdmType.BuiltInTypeKind.ToString(), 
                                                                                                    args.Right.EdmType.FullName));
                    }

                    if (TypeSemantics.IsNullType(args.Left.ResultType)) 
                    {
                        args.Left = sr.CmdTree.CreateNullExpression(args.Right); 
                    } 
                    else if (!isNominalTypeAllowed && !TypeSemantics.IsEntityType(args.Left.ResultType))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx,
                                                    System.Data.Entity.Strings.ExpressionTypeMustBeEntityType(System.Data.Entity.Strings.CtxTreat,
                                                                                                              args.Left.ResultType.EdmType.BuiltInTypeKind.ToString(),
                                                                                                              args.Left.ResultType.EdmType.FullName)); 
                    }
                    else if (isNominalTypeAllowed && !TypeSemantics.IsNominalType(args.Left.ResultType)) 
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx,
                                                    System.Data.Entity.Strings.ExpressionTypeMustBeNominalType(System.Data.Entity.Strings.CtxTreat, 
                                                                                                              args.Left.ResultType.EdmType.BuiltInTypeKind.ToString(),
                                                                                                              args.Left.ResultType.EdmType.FullName));
                    }
 
                    if (!TypeSemantics.IsPolymorphicType(args.Left.ResultType))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, 
                                                    System.Data.Entity.Strings.TypeMustBeInheritableType);
                    } 

                    if (!TypeSemantics.IsPolymorphicType(args.Right))
                    {
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx, 
                                                    System.Data.Entity.Strings.TypeMustBeInheritableType);
                    } 
 
                    if (!TypeResolver.IsSubOrSuperType(args.Left.ResultType, args.Right))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx,
                                                   System.Data.Entity.Strings.NotASuperOrSubType(args.Left.ResultType.EdmType.FullName,
                                                                                                 args.Right.EdmType.FullName));
                    } 

                    return sr.CmdTree.CreateTreatExpression(args.Left, TypeHelpers.GetReadOnlyType(args.Right)); 
                }); 
            #endregion
 
            //
            // CAST( e AS T )
            //
            #region CAST( e AS T ) 
            builtInExprConverter.Add(BuiltInKind.Cast, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    Pair args = ConvertTypeExprArgs(bltInExpr, sr); 

                    // 
                    // ensure CAST target type is Scalar
                    //
                    if (!TypeSemantics.IsPrimitiveType(args.Right))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.InvalidCastType);
                    } 
 
                    if (SemanticResolver.IsNullExpression(args.Left))
                    { 
                        return sr.CmdTree.CreateCastExpression(
                                                sr.CmdTree.CreateNullExpression(args.Right),
                                                args.Right);
                    } 

                    if (args.Left.ResultType.BuiltInTypeKind != BuiltInTypeKind.EnumType) 
                    { 
                        if (!TypeSemantics.IsPrimitiveType(args.Left.ResultType))
                        { 
                            throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.InvalidCastExpressionType);
                        }

                        if (!TypeSemantics.IsCastAllowed(args.Left.ResultType, args.Right)) 
                        {
                            throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, 
                                                        System.Data.Entity.Strings.InvalidCast( 
                                                                            args.Left.ResultType.EdmType,
                                                                            args.Right.EdmType.FullName)); 
                        }
                    }

                    return sr.CmdTree.CreateCastExpression(args.Left, TypeHelpers.GetReadOnlyType(args.Right)); 
                });
            #endregion 
 
            //
            // OFTYPE( [ONLY] e, T ) 
            //
            #region OFTYPE( [ONLY] e, T )
            builtInExprConverter.Add(BuiltInKind.OfType, delegate(BuiltInExpr bltInExpr, SemanticResolver sr)
            { 
                Pair args = ConvertTypeExprArgs(bltInExpr, sr);
 
                bool isOnly = (bool)((Literal)bltInExpr.ArgList[2]).Value; 

                bool isNominalTypeAllowed = sr.ParserOptions.ParserCompilationMode == ParserOptions.CompilationMode.RestrictedViewGenerationMode; 

                if (!TypeSemantics.IsCollectionType(args.Left.ResultType))
                {
                    throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, 
                                                System.Data.Entity.Strings.ExpressionMustBeCollection);
                } 
 
                TypeUsage elementType = TypeHelpers.GetElementTypeUsage(args.Left.ResultType);
                if (!isNominalTypeAllowed && !TypeSemantics.IsEntityType(elementType)) 
                {
                    throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx,
                                                System.Data.Entity.Strings.OfTypeExpressionElementTypeMustBeEntityType(elementType.EdmType.BuiltInTypeKind.ToString(),
                                                                                                                       elementType)); 
                }
                else if (isNominalTypeAllowed && !TypeSemantics.IsNominalType(elementType)) 
                { 
                    throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx,
                                                System.Data.Entity.Strings.OfTypeExpressionElementTypeMustBeNominalType(elementType.EdmType.BuiltInTypeKind.ToString(), 
                                                                                                                       elementType));
                }

                if (!isNominalTypeAllowed && !TypeSemantics.IsEntityType(args.Right)) 
                {
                    throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx, 
                                                System.Data.Entity.Strings.TypeMustBeEntityType(System.Data.Entity.Strings.CtxOfType, 
                                                                                                args.Right.EdmType.BuiltInTypeKind.ToString(),
                                                                                                args.Right.EdmType.FullName)); 
                }
                else if (isNominalTypeAllowed && !TypeSemantics.IsNominalType(args.Right))
                {
                    throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx, 
                                                System.Data.Entity.Strings.TypeMustBeNominalType(System.Data.Entity.Strings.CtxOfType,
                                                                                                args.Right.EdmType.BuiltInTypeKind.ToString(), 
                                                                                                args.Right.EdmType.FullName)); 
                }
 
                if (isOnly && args.Right.EdmType.Abstract)
                {
                    throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx,
                                                System.Data.Entity.Strings.OfTypeOnlyTypeArgumentCannotBeAbstract(args.Right.EdmType.FullName)); 
                }
 
                if (!TypeResolver.IsSubOrSuperType(elementType, args.Right)) 
                {
                    throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, 
                                                System.Data.Entity.Strings.NotASuperOrSubType(elementType.EdmType.FullName,
                                                                                              args.Right.EdmType.FullName));
                }
 
                DbExpression ofTypeExpression = null;
                if (isOnly) 
                { 
                    ofTypeExpression = sr.CmdTree.CreateOfTypeOnlyExpression(args.Left, TypeHelpers.GetReadOnlyType(args.Right));
                } 
                else
                {
                    ofTypeExpression = sr.CmdTree.CreateOfTypeExpression(args.Left, TypeHelpers.GetReadOnlyType(args.Right));
                } 

                return ofTypeExpression; 
            }); 
            #endregion
 
            //
            // e LIKE pattern [ESCAPE escape]
            //
            #region e LIKE pattern [ESCAPE escape] 
            builtInExprConverter.Add(BuiltInKind.Like, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    DbExpression likeExpr = null; 

                    DbExpression matchExpr = Convert(bltInExpr.Arg1, sr); 

                    if (TypeSemantics.IsNullType(matchExpr.ResultType))
                    {
                        matchExpr = sr.CmdTree.CreateNullExpression(sr.TypeResolver.StringType); 
                    }
                    else if (!TypeResolver.IsStringType(matchExpr.ResultType)) 
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.LikeArgMustBeStringType);
                    } 

                    DbExpression patternExpr = Convert(bltInExpr.Arg2, sr);

                    if (patternExpr is UntypedNullExpression) 
                    {
                        patternExpr = sr.CmdTree.CreateNullExpression(sr.TypeResolver.StringType); 
                    } 
                    else if (!TypeResolver.IsStringType(patternExpr.ResultType))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.LikeArgMustBeStringType);
                    }

                    if (3 == bltInExpr.ArgCount) 
                    {
                        DbExpression escapeExpr = Convert(bltInExpr.ArgList[2], sr); 
 
                        if (escapeExpr is UntypedNullExpression)
                        { 
                            escapeExpr = sr.CmdTree.CreateNullExpression(sr.TypeResolver.StringType);
                        }
                        else if (!TypeResolver.IsStringType(escapeExpr.ResultType))
                        { 
                            throw EntityUtil.EntitySqlError(bltInExpr.ArgList[2].ErrCtx, System.Data.Entity.Strings.LikeArgMustBeStringType);
                        } 
 
                        likeExpr = sr.CmdTree.CreateLikeExpression(matchExpr, patternExpr, escapeExpr);
                    } 
                    else
                    {
                        likeExpr = sr.CmdTree.CreateLikeExpression(matchExpr, patternExpr);
                    } 

                    return likeExpr; 
                }); 
            #endregion
 
            //
            // e BETWEEN e1 AND e2
            //
            #region e BETWEEN e1 AND e2 
            builtInExprConverter.Add(BuiltInKind.Between, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    Debug.Assert(bltInExpr.ArgCount == 3); 

                    // 
                    // convert lower and upper limits
                    //
                    Pair limitsExpr = sr.EnsureTypedNulls(
                                                                        Convert(bltInExpr.ArgList[1], sr), 
                                                                        Convert(bltInExpr.ArgList[2], sr),
                                                                        bltInExpr.ArgList[0].ErrCtx, 
                                                                        () => Strings.BetweenLimitsCannotBeUntypedNulls); 

                    // 
                    // Get and check common type for limits
                    //
                    TypeUsage rangeCommonType = TypeHelpers.GetCommonTypeUsage(limitsExpr.Left.ResultType, limitsExpr.Right.ResultType);
                    if (null == rangeCommonType) 
                    {
                        throw EntityUtil.EntitySqlError(bltInExpr.ArgList[0].ErrCtx, System.Data.Entity.Strings.BetweenLimitsTypesAreNotCompatible(limitsExpr.Left.ResultType.EdmType.FullName, limitsExpr.Right.ResultType.EdmType.FullName)); 
                    } 

                    // 
                    // check if limit types are order-comp
                    //
                    if (!TypeSemantics.IsOrderComparableTo(limitsExpr.Left.ResultType, limitsExpr.Right.ResultType))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.ArgList[0].ErrCtx, System.Data.Entity.Strings.BetweenLimitsTypesAreNotOrderComparable(limitsExpr.Left.ResultType.EdmType.FullName, limitsExpr.Right.ResultType.EdmType.FullName));
                    } 
 
                    //
                    // convert value expression 
                    //
                    DbExpression valueExpr = Convert(bltInExpr.ArgList[0], sr);

                    // 
                    // Fixup value type if untyped
                    // 
                    if (TypeSemantics.IsNullType(valueExpr.ResultType)) 
                    {
                        valueExpr = sr.CmdTree.CreateNullExpression(rangeCommonType); 
                    }

                    //
                    // check if valueExpr is order-comparable to limits 
                    //
                    if (!TypeSemantics.IsOrderComparableTo(valueExpr.ResultType, rangeCommonType)) 
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.ArgList[0].ErrCtx, System.Data.Entity.Strings.BetweenValueIsNotOrderComparable(valueExpr.ResultType.EdmType.FullName, rangeCommonType.EdmType.FullName));
                    } 

                    return sr.CmdTree.CreateAndExpression(
                                            sr.CmdTree.CreateGreaterThanOrEqualsExpression(valueExpr, limitsExpr.Left),
                                            sr.CmdTree.CreateLessThanOrEqualsExpression(valueExpr, limitsExpr.Right)); 
                });
            #endregion 
 
            //
            // e NOT BETWEEN e1 AND e2 
            //
            #region e NOT BETWEEN e1 AND e2
            builtInExprConverter.Add(BuiltInKind.NotBetween, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    bltInExpr.Kind = BuiltInKind.Between;
 
                    DbExpression converted = sr.CmdTree.CreateNotExpression(ConvertBuiltIn(bltInExpr, sr)); 

                    bltInExpr.Kind = BuiltInKind.NotBetween; 

                    return converted;
                });
            #endregion 

            return builtInExprConverter; 
        } 

        #endregion 

        #endregion
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....]
// @backup [....] 
//--------------------------------------------------------------------- 

namespace System.Data.Common.EntitySql 
{
    using System;
    using System.Globalization;
    using System.Collections.Generic; 
    using System.Diagnostics;
 
    using System.Data.Common.CommandTrees; 
    using System.Data.Metadata.Edm;
    using System.Data.Entity; 

    /// 
    /// Implements Semantic Analysis and Conversion
    /// Provides the translation service between an abstract syntax tree to a canonical command tree 
    /// For complete documentation of the language syntax and semantics, refer to http://sqlweb/default.asp?specDirId=764
    /// The class was designed to be type system agnostic by delegating to a given SemanticResolver instance all type related services as well as to TypeHelper class, however 
    /// we rely on the assumption that metadata was pre-loaded and is relevant to the query. 
    /// 
    internal sealed class SemanticAnalyzer 
    {
        private SemanticResolver _sr;

        ///  
        /// Initializes semantic analyzer
        ///  
        /// initialized SemanticResolver instance for a given typespace/type system 
        internal SemanticAnalyzer( SemanticResolver sr )
        { 
            EntityUtil.CheckArgumentNull(sr, "sr");
            _sr = sr;
        }
 
        /// 
        /// Entry point to semantic analysis. Converts astTree into DbExpression. 
        ///  
        /// ast tree
        /// command tree to build the expression 
        /// 
        /// Thrown when Syntatic or Semantic rules are violated and the query cannot be accepted
        /// Thrown when metadata related service requests fail
        /// Thrown when mapping related service requests fail 
        /// 
        /// DbExpression 
        internal DbExpression Analyze(Expr astExpr, DbCommandTree commandTree) 
        {
            CommandExpr command = Initialize(astExpr, commandTree); 
            DbExpression converted = ConvertRootExpression(command.QueryExpr, _sr);
            return converted;
        }
 
        /// 
        /// Entry point to semantic analysis. Converts astTree into command tree. 
        ///  
        /// ast tree
        ///  
        /// Thrown when Syntatic or Semantic rules are violated and the query cannot be accepted
        /// Thrown when metadata related service requests fail
        /// Thrown when mapping related service requests fail
        ///  
        /// DbCommandTree
        internal DbCommandTree Analyze( Expr astExpr ) 
        { 
            CommandExpr astCommandExpr = Initialize(astExpr, null);
 
            //
            // Convert query Expression
            //
            DbCommandTree commandTree = ConvertCommand(astCommandExpr, _sr); 

            Debug.Assert(null != commandTree,"null != commandTree"); 
 
            return commandTree;
        } 

        /// 
        /// Common initialization required whether the semantic analysis process
        /// is producing a command tree or only an expression. Validates that the 
        /// parse phase did in fact produce a command AST.
        ///  
        /// The root of the abstract syntax tree produced by the parse phase 
        /// 
        ///     An optional command tree to use, only provided when constructing an expression. 
        ///     When constructing a command tree, an instance of the appropriate command tree
        ///     class will be created and returned by semantic analysis.
        /// 
        /// The  that is the root of the AST specified by  
        private CommandExpr Initialize(Expr astExpr, DbCommandTree tree)
        { 
            CommandExpr astCommandExpr = astExpr as CommandExpr; 
            if (null == astCommandExpr)
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.UnknownAstCommandExpression);
            }

            // 
            // Sets DbCommandTree Factory
            // 
            if (tree == null) 
            {
                _sr.SetCommandTreeFactory(astCommandExpr); 
            }
            else
            {
                _sr.SetCommandTreeFactory(astCommandExpr, tree); 
            }
 
            // 
            // Declare Canonical Namespace
            // 
            _sr.DeclareCanonicalNamespace();

            //
            // Declare Namespaces 
            //
            _sr.DeclareNamespaces(astCommandExpr.NamespaceDeclList); 
 
            return astCommandExpr;
        } 

        #region command converter delegates
        delegate DbCommandTree CommandConverter( Expr astExpr, SemanticResolver sr );
        static CommandConverter[] commandConverters = 
        {
            /* ExprKind.Generic */ ConvertGeneralExpression, 
            /* ExprKind.Query   */ ConvertGeneralExpression, 
        };
        #endregion 


        /// 
        /// Dispatches/Converts top command expressions. 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static DbCommandTree ConvertCommand( CommandExpr astCommandExpr, SemanticResolver sr ) 
        {
            EntityUtil.CheckArgumentNull(astCommandExpr, "astCommandExpr");

            Expr queryExpr = astCommandExpr.QueryExpr; 

            return commandConverters[(int)queryExpr.ExprKind](queryExpr, sr); 
        } 

 
        /// 
        /// Converts {Query|General} Expression
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        ///  
        private static DbCommandTree ConvertGeneralExpression( Expr astExpr, SemanticResolver sr ) 
        {
            DbExpression converted = ConvertRootExpression(astExpr, sr); 

            DbQueryCommandTree qryCmdTree = (DbQueryCommandTree)sr.CmdTree;

            qryCmdTree.Query = converted; 

            Debug.Assert(null != qryCmdTree,"null != qryCmdTree"); 
 
            return qryCmdTree;
        } 

        /// 
        /// Converts the expression that is the 'root' of a query AST to a
        /// normalized and validated . This entry 
        /// point to the semantic analysis phase is used when producing a
        /// query command tree (from a Query or General AST expression) or 
        /// producing only a . 
        /// 
        /// The root AST node for this query 
        /// The  instance to use
        /// 
        ///     An instance of , adjusted to handle 'inline' projections
        ///     and validated to produce a result type appropriate for the root of a query command tree. 
        /// 
        private static DbExpression ConvertRootExpression(Expr astExpr, SemanticResolver sr) 
        { 
            DbExpression converted = Convert(astExpr, sr);
 
            //
            // ensure converted expression is not untyped-null
            //
            if (TypeSemantics.IsNullType(converted.ResultType)) 
            {
                throw EntityUtil.EntitySqlError(astExpr.ErrCtx, System.Data.Entity.Strings.ResultingExpressionTypeCannotBeNull); 
            } 

            // 
            // Handles the "inline" projection case
            //
            if (converted is DbScanExpression)
            { 
                DbExpressionBinding source = sr.CmdTree.CreateExpressionBinding(converted, sr.GenerateInternalName("extent"));
 
                converted = sr.CmdTree.CreateProjectExpression(source, source.Variable); 
            }
 
            //
            // ensure return type is valid for query. for V1, association types are the only
            // type that cannot be at 'top' level result. Note that this is only applicable in
            // general queries and association types are valid in view gen mode queries 
            //
            if (sr.ParserOptions.ParserCompilationMode == ParserOptions.CompilationMode.NormalMode) 
            { 
                SemanticResolver.ValidateQueryResultType(converted.ResultType, astExpr.ErrCtx);
            } 

            return converted;
        }
 
        /// 
        /// Dispatches/Converts general expressions 
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static DbExpression Convert( Expr astExpr, SemanticResolver sr )
        {
            if (null == astExpr) 
            {
                return null; 
            } 

            AstExprConverter converter = _astExprConverters[astExpr.GetType()]; 

            if (null == converter)
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.UnknownAstExpressionType); 
            }
 
            DbExpression converted = converter(astExpr, sr); 

            Debug.Assert(null != converted,"null != converted"); 

            return converted;
        }
 

        ///  
        /// Converts Literal Expression 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpression ConvertLiteral( Expr expr, SemanticResolver sr )
        { 
            Literal literal = (Literal)expr;
 
            if (literal.IsNullLiteral) 
            {
                // 
                // if it is literal null, return untyped null
                // untyped nulls will later have their type inferred depending on the
                // especific expression in which it participates
                // 
                return new UntypedNullExpression(sr.CmdTree);
            } 
            else 
            {
                return sr.CmdTree.CreateConstantExpression(literal.Value, 
                                                           sr.TypeResolver.GetLiteralTypeUsage(literal));
            }
        }
 

        ///  
        /// Converts Simple Identifier 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpression ConvertIdentifier( Expr expr, SemanticResolver sr )
        { 
            Identifier idExpr = (Identifier)expr;
 
            DbExpression converted = sr.ResolveIdentifier(new string[] { idExpr.Name }, expr.ErrCtx); 

            if (null == converted) 
            {
                CqlErrorHelper.ReportIdentifierError(expr, sr);
            }
 
            return converted;
        } 
 

        ///  
        /// Converts DotExpression
        /// 
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static DbExpression ConvertDotExpr( Expr expr, SemanticResolver sr ) 
        { 
            DotExpr dotExpr = (DotExpr)expr;
 
            DbExpression converted = null;

            if (dotExpr.IsDottedIdentifier)
            { 
                converted = sr.ResolveIdentifier(dotExpr.Names, dotExpr.ErrCtx);
 
                if (null == converted) 
                {
                    CqlErrorHelper.ReportIdentifierError(expr, sr); 
                }
            }
            else
            { 
                converted = ConvertDotExpressionProcess(dotExpr, sr);
            } 
 
            Debug.Assert(null != converted,"null != converted");
 
            return converted;
        }

 
        /// 
        /// converts dot expression. dotted id case is handled by resolveId 
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        /// 
        /// 
        ///  
        /// 
        static private DbExpression ConvertDotExpressionProcess( DotExpr dotExpr, SemanticResolver sr ) 
        { 
            Debug.Assert(!dotExpr.IsDottedIdentifier,"!dotExpr.IsDottedIdentifier");
 
            return sr.ResolveIdentifierChain(dotExpr.Names, 0, Convert(dotExpr.LeftMostExpression, sr), dotExpr.ErrCtx);
        }

 
        /// 
        /// Converts methods, functions and type constructors 
        /// methods (instance or static) can be in the form: (expr).chain.of.names(args) or chain.of.names(args) 
        /// Functions are chain.of.names(args)
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpression ConvertMethodExpr( Expr expr, SemanticResolver sr ) 
        {
            MethodExpr methodExpr = (MethodExpr)expr; 
 
            DbExpression converted = null;
 
            DotExpr dotExpr = methodExpr.MethodPrefixExpr;

            //
            // resolve base expression if one exists 
            //
            DbExpression baseExpr = (null != dotExpr.LeftMostExpression) ? Convert(dotExpr.LeftMostExpression, sr) : null; 
 
            //
            // If base expression is still unresolved, check if leftmost name element is in in scope 
            //
            int prefixIndex = 0;
            KeyValuePair varInfo;
            if (null == baseExpr && dotExpr.IsDottedIdentifier && dotExpr.Names.Length > 0) 
            {
                ScopeEntry scopeEntry; 
 
                if (sr.TryScopeLookup(dotExpr.Names[0], out scopeEntry))
                { 
                    //
                    // make sure is a valid type for method call
                    //
                    if (TypeResolver.IsValidTypeForMethodCall(scopeEntry.Expression.ResultType)) 
                    {
                        baseExpr = scopeEntry.Expression; 
                        prefixIndex = 1; 
                    }
                    else 
                    {
                        throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.DefiningTypeDoesNotSupportMethodCalls);
                    }
                } 
                else if (sr.Variables.TryGetValue(dotExpr.Names[0], out varInfo))
                { 
                    baseExpr = sr.CmdTree.CreateVariableReferenceExpression(varInfo.Key, varInfo.Value); 
                    prefixIndex = 1;
                } 
            }

            //
            // check if base expression if is untyped null 
            //
            if (baseExpr is UntypedNullExpression) 
            { 
                throw EntityUtil.EntitySqlError(dotExpr.LeftMostExpression.ErrCtx, System.Data.Entity.Strings.ExpressionCannotBeNull);
            } 

            //
            // dispatches methodExpr to static or instance kind of method conversion
            // 
            if (null == baseExpr)
            { 
                // 
                // if base expression is still unresolved, it should be a function(aggregates included), static method or type constructor
                // 
                converted = ConvertStaticMethodOrFunction(methodExpr, sr);
            }
            else
            { 
                //
                // otherwise, should be an instance method invocation 
                // 
                converted = ConvertMethodInstance(baseExpr, methodExpr, prefixIndex, sr);
            } 

            Debug.Assert(null != converted,"null != converted");

            return converted; 
        }
 
 
        /// 
        /// Converts a method expr into a Static Method, Type Constructor or EdmFunction call (including aggregates) 
        /// 
        /// 
        /// 
        ///  
        private static DbExpression ConvertStaticMethodOrFunction( MethodExpr methodExpr, SemanticResolver sr )
        { 
            DbExpression converted = null; 

            // 
            // Find out if given name path is a Static Method, Type Constructor or EdmFunction call (including aggregates)
            //
            TypeUsage constructorType;
            TypeUsage staticMethodType; 
            IList functionType;
 
            // 
            // Resolve methodExpr
            // 
            sr.ResolveNameAsStaticMethodOrFunction(methodExpr, out constructorType, out staticMethodType, out functionType);

            //
            // at this point, only one of the three must be not null 
            // that is ensured by ResolveNameAsStaticMethodOrFunction()
            // 
            Debug.Assert(constructorType != null || staticMethodType != null || functionType != null,"constructorType != null || staticMethodType != null || functionType != null"); 

            // 
            // if it is a constructorType, create an instance of it
            //
            if (null != constructorType)
            { 
                List relshipExprList = null;
 
                // 
                // convert relationships if present
                // 
                if (methodExpr.HasRelationships)
                {
                    if (ParserOptions.CompilationMode.NormalMode == sr.ParserOptions.ParserCompilationMode)
                    { 
                        throw EntityUtil.EntitySqlError(methodExpr.Relationships.ErrCtx, System.Data.Entity.Strings.InvalidModeForWithRelationshipClause);
                    } 
 
                    HashSet targetEnds = new HashSet();
                    relshipExprList = new List(methodExpr.Relationships.Count); 
                    for (int i = 0; i < methodExpr.Relationships.Count; i++)
                    {
                        RelshipNavigationExpr relshipExpr = methodExpr.Relationships[i];
 
                        DbRelatedEntityRef relshipTarget = ConvertRelatedEntityRef(relshipExpr, sr);
 
                        string targetEndId = String.Join(":", new String[] { relshipTarget.TargetEnd.DeclaringType.Identity, relshipTarget.TargetEnd.Identity }); 
                        if (targetEnds.Contains(targetEndId))
                        { 
                            throw EntityUtil.EntitySqlError(relshipExpr.ErrCtx,
                                                        System.Data.Entity.Strings.RelationshipTargetMustBeUnique(relshipTarget.TargetEntityReference.ResultType.EdmType.Identity));
                        }
 
                        targetEnds.Add(targetEndId);
 
                        relshipExprList.Add(relshipTarget); 
                    }
                } 

                converted = sr.CreateInstanceOfType(constructorType,
                                                    ConvertFunctionArguments(methodExpr.Args, sr),
                                                    relshipExprList, 
                                                    methodExpr);
            } 
            // 
            // if it is staticMethodType, create method call expression
            // 
            else if (null != staticMethodType)
            {
                converted = SemanticResolver.CreateStaticMethod(staticMethodType, ConvertFunctionArguments(methodExpr.Args, sr), methodExpr);
            } 
            //
            // if it is functionType 
            // 
            else if (null != functionType && 0 < functionType.Count)
            { 
                //
                // decide if it is an ordinary function or group aggreagate
                //
                if (TypeSemantics.IsAggregateFunction(functionType[0]) && sr.IsInAnyGroupScope()) 
                {
                    // 
                    // if it is an aggreagate function inside a group scope, dispatch to ConvertGroupAggregate() 
                    //
                    converted = ConvertAggregateFunctionInGroupScope(methodExpr, functionType, sr); 
                }
                else
                {
                    // 
                    // else, is just an ordinary function call (including collection aggregates)
                    // 
                    converted = sr.CreateFunction(functionType, ConvertFunctionArguments(methodExpr.Args, sr), methodExpr); 
                }
 
            }
            else
            {
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.CannotResolveNameToFunction(methodExpr.MethodPrefixExpr.FullName)); 
            }
 
            Debug.Assert(null != converted,"null != converted"); 

            return converted; 
        }


        ///  
        /// Converts Group Aggregates
        ///  
        ///  
        /// 
        ///  
        /// 
        /// 
        /// This method convert group aggregates in two phases:
        /// Phase 1 - it will resolve the actual inner (argument) expression and then anotate the ast node and add the resolved aggregate 
        /// to the scope
        /// Phase 2 - if ast node was annotated, just extract the precomputed expression from the scope. 
        ///  
        private static DbExpression ConvertAggregateFunctionInGroupScope( MethodExpr methodExpr, IList functionTypes, SemanticResolver sr )
        { 
            DbExpression converted = null;

            //
            // first, try if aggregate was already pre resolved 
            //
            if (TryConvertAsResolvedGroupAggregate(methodExpr, sr, out converted)) 
            { 
                return converted;
            } 

            //
            // then, try to resolve as Ordinary function (collection aggregate)
            // 
            if (TryConvertAsOrdinaryFunctionInGroup(methodExpr, functionTypes, sr, out converted))
            { 
                return converted; 
            }
 
            //
            // finally, try to convert as group aggregate
            //
            if (TryConvertAsGroupAggregateFunction(methodExpr, functionTypes, sr, out converted)) 
            {
                return converted; 
            } 

            // 
            // if we reach this point, means the resolution failed
            //
            throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.FailedToResolveAggregateFunction(methodExpr.MethodPrefixExpr.FullName));
        } 

 
        ///  
        /// try to convert as pre resolved aggregate function
        ///  
        /// 
        /// 
        /// 
        ///  
        private static bool TryConvertAsResolvedGroupAggregate( MethodExpr methodExpr, SemanticResolver sr, out DbExpression converted )
        { 
            converted = null; 

            // 
            // if ast node was annotated in a previous pass, means it was already resolved and should be in scope
            //
            if (methodExpr.WasResolved)
            { 
                sr.CurrentScopeRegionFlags.DecrementGroupAggregateNestingCount();
 
                ScopeEntry scopeEntry; 

                SemanticResolver.ScopeViewKind saveScopeView = sr.GetScopeView(); 

                sr.SetScopeView(SemanticResolver.ScopeViewKind.All);

                int scopeIndex; 
                if (!sr.TryScopeLookup(methodExpr.InternalAggregateName, out scopeEntry, out scopeIndex))
                { 
                    Debug.Assert(methodExpr.DummyExpression != null, "resolved aggregate dummy expression must not be null"); 

                    converted = methodExpr.DummyExpression; 

                    return true;
                }
                else 
                {
                    // 
                    // Sets correlation flag 
                    //
                    sr.SetScopeRegionCorrelationFlag(scopeIndex); 
                }

                sr.SetScopeView(saveScopeView);
 
                converted = scopeEntry.Expression;
 
                return true; 
            }
 
            return false;
        }

 
        /// 
        /// Try convert method expr in a group scope as an ordinary function (collection aggregate) 
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        private static bool TryConvertAsOrdinaryFunctionInGroup( MethodExpr methodExpr          , 
                                                                 IList functionTypes   ,
                                                                 SemanticResolver sr            , 
                                                                 out DbExpression converted       ) 
        {
            converted = null; 

            //
            // save scope view
            // 
            SemanticResolver.ScopeViewKind saveScopeView = sr.GetScopeView();
 
            // 
            // convert aggregate arguments
            // 
            List args = ConvertFunctionArguments(methodExpr.Args, sr);

            //
            // collect argument types 
            //
            List argTypes = new List(args.Count); 
            for (int i = 0 ; i < args.Count ; i++) 
            {
                argTypes.Add(args[i].ResultType); 
            }

            //
            // try to see if there is a overload match 
            //
            bool isAmbiguous = false; 
            EdmFunction functionType = TypeResolver.ResolveFunctionOverloads( functionTypes, 
                                                                              argTypes,
                                                                              false /* isGroupAggregateFunction */, 
                                                                              out isAmbiguous);

            //
            // if there is more then one overload that matches given arguments, throw 
            //
            if (isAmbiguous) 
            { 
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.AmbiguousFunctionArguments);
            } 

            //
            // if not null, means a match was found as an ordinary function
            // 
            if (null != functionType)
            { 
                // 
                // make sure all referenced vars are from group scope only
                // 
                if (!sr.CurrentScopeRegionFlags.IsImplicitGroup)
                {
                    sr.SetScopeView(SemanticResolver.ScopeViewKind.CurrentScope);
                } 

                // 
                // convert aggregate arguments 
                //
                args = ConvertFunctionArguments(methodExpr.Args, sr); 

                //
                // restore previous scope view
                // 
                sr.SetScopeView(saveScopeView);
 
                // 
                // return function
                // 
                converted = sr.CmdTree.CreateFunctionExpression(functionType, args);

            }
 
            return (null != functionType);
        } 
 

        ///  
        ///
        /// 
        /// 
        ///  
        /// 
        ///  
        ///  
        private static bool TryConvertAsGroupAggregateFunction( MethodExpr methodExpr,
                                                                IList functionTypeList, 
                                                                SemanticResolver sr,
                                                                out DbExpression converted )
        {
            converted = null; 

            // 
            // save scope view 
            //
            SemanticResolver.ScopeViewKind saveScopeView = sr.GetScopeView(); 

            //
            // Aggregates in groups can refer to all scopes
            // 
            sr.SetScopeView(SemanticResolver.ScopeViewKind.All);
 
            // 
            // flag that it is inside a group aggregate
            // 
            sr.CurrentScopeRegionFlags.IsInsideGroupAggregate = true;

            //
            // reset nested references flag 
            //
            sr.CurrentScopeRegionFlags.WasNestedGroupAggregateReferredByInnerExpressions = false; 
 
            //
            // pushes candidate aggregate ast node 
            //
            sr.PushAggregateAstNode(methodExpr);

 
            sr.CurrentScopeRegionFlags.DecrementGroupAggregateNestingCount();
 
            // 
            // convert aggregate arguments
            // 
            List args = ConvertFunctionArguments(methodExpr.Args, sr);

            //
            // clear inside group aggregate flag 
            //
            sr.CurrentScopeRegionFlags.IsInsideGroupAggregate = false; 
 
            //
            // collect argument types 
            //
            List argTypes = new List(args.Count);
            for (int i = 0 ; i < args.Count ; i++)
            { 
                argTypes.Add(args[i].ResultType);
            } 
 
            //
            // try to find an overload match as group aggregate 
            //
            bool isAmbiguous = false;
            EdmFunction functionType = TypeResolver.ResolveFunctionOverloads(functionTypeList,
                                                                             argTypes, 
                                                                             true /* isGroupAggregateFunction */,
                                                                             out isAmbiguous); 
 
            //
            // if there is more then one overload that matches given arguments, throw 
            //
            if (isAmbiguous)
            {
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.AmbiguousFunctionArguments); 
            }
 
            // 
            // if it still null, then there is no overload as an ordinary function or group aggregate function
            // 
            if (null == functionType)
            {
                CqlErrorHelper.ReportFunctionOverloadError(methodExpr, functionTypeList[0], argTypes);
            } 

            // 
            // ensure that group aggregate was not referenced by inner sub-expression 
            //
            if (sr.CurrentScopeRegionFlags.WasNestedGroupAggregateReferredByInnerExpressions) 
            {
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.NestedAggregatesCannotBeUsedInAggregateFunctions);
            }
 
            //
            // ensure it is not a nested group aggregate call 
            // 
            if (sr.CurrentScopeRegionFlags.GroupAggregateNestingCount < -1)
            { 
                throw EntityUtil.EntitySqlError(methodExpr.MethodIdentifier.ErrCtx, System.Data.Entity.Strings.InvalidNestedGroupAggregateCall);
            }

            // 
            // aggregate functions in the current release can have only one argument and must of of collectio type
            // 
            Debug.Assert((1 == functionType.Parameters.Count), "(1 == functionType.Parameters.Count)"); // we only support monadic aggregate functions 
            Debug.Assert(TypeSemantics.IsCollectionType(functionType.Parameters[0].TypeUsage), "functionType.Parameters[0].Type is CollectionType");
            TypeUsage argumentType = TypeHelpers.GetElementTypeUsage(functionType.Parameters[0].TypeUsage); 
            if (TypeSemantics.IsNullType(args[0].ResultType))
            {
                args[0] = sr.CmdTree.CreateNullExpression(argumentType);
            } 

            // 
            // create function aggregate expression 
            //
            DbFunctionAggregate functionAggregate; 

            // create distinct expression if espeficied
            if (methodExpr.DistinctKind == DistinctKind.Distinct)
            { 
                functionAggregate = sr.CmdTree.CreateDistinctFunctionAggregate(functionType, args[0]);
            } 
            else 
            {
                functionAggregate = sr.CmdTree.CreateFunctionAggregate(functionType, args[0]); 
            }

            //
            // generate name for the aggregate 'property'. this name will the internal name of the pre-computed expression in the scope and 
            // annotated ast node in the ast tree
            // 
            string internalAggregateName = sr.GenerateInternalName("groupAgg" + functionType.Name); 

            // 
            // add aggreate to aggreate list
            //
            AggregateAstNodeInfo aggrAstInfo = sr.PopAggregateAstNode();
            aggrAstInfo.AssertMethodExprEquivalent(methodExpr); 
            sr.AddGroupAggregateInfoToScopeRegion(methodExpr, internalAggregateName, functionAggregate, aggrAstInfo.ScopeIndex);
 
            // 
            // return 'dummy' expression with same type as aggregate function
            // 
            converted = sr.CmdTree.CreateNullExpression(functionType.ReturnParameter.TypeUsage);

            //
            // anotate method expression node as aggregate 
            //
            methodExpr.SetAggregateInfo(internalAggregateName, converted); 
 
            //
            // restore visibility to group scope only 
            //
            sr.SetScopeView(saveScopeView);

            // 
            // increment nesting count
            // 
            sr.CurrentScopeRegionFlags.IncrementGroupAggregateNestingCount(); 

            return true; 
        }


 
        /// 
        /// Converted a instance method. 
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        private static DbExpression ConvertMethodInstance( DbExpression baseExpr, MethodExpr methodExpr, int prefixIndex, SemanticResolver sr ) 
        {
            DbExpression converted = null; 
 
            Debug.Assert(null != baseExpr,"null != baseExpr");
 
            DotExpr dotExpr = methodExpr.MethodPrefixExpr;

            //
            // ensure methods are not called on Scalar type instances 
            //
            if (TypeSemantics.IsPrimitiveType(baseExpr.ResultType)) 
            { 
                throw EntityUtil.EntitySqlError(dotExpr.LeftMostExpression.ErrCtx, System.Data.Entity.Strings.MethodNotAllowedOnScalars);
            } 

            //
            // build the instance property references chain up to the method name
            // 
            DbExpression innerExpression = baseExpr;
            for (int i = prefixIndex ; i < dotExpr.Length - 1 ; i++) 
            { 

                innerExpression = sr.ResolveIdentifierElement(innerExpression.ResultType, innerExpression, dotExpr.Names[i], dotExpr.ErrCtx); 

                //
                // if this point is reached, means that an element in the path name is not a valid property
                // such as name[ i + 1 ] is not a valid property/member of defining type resolved previosly for name[ i ] 
                //
                if (null == innerExpression) 
                { 
                    throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.InvalidMethodPathElement(dotExpr.Names[i], innerExpression.ResultType.EdmType.FullName));
                } 
            }

            //
            // convert method arguments 
            //
            List args = ConvertFunctionArguments(methodExpr.Args, sr); 
 
            //
            // Resolve/Validate overloads and create method expression 
            //
            converted = SemanticResolver.CreateInstanceMethod(innerExpression, args, methodExpr);

            Debug.Assert(null != converted,"null != converted"); 

            return converted; 
        } 

 
        /// 
        /// Converts EdmFunction Arguments representes a list of astExpr nodes
        /// 
        ///  
        /// 
        ///  
        private static List ConvertFunctionArguments( ExprList astExprList, SemanticResolver sr ) 
        {
            List convertedArgs = new List(); 

            if (null != astExprList)
            {
                for (int i = 0 ; i < astExprList.Count ; i++) 
                {
                    convertedArgs.Add(Convert(astExprList[i], sr)); 
                } 
            }
 
            return convertedArgs;
        }

 
        /// 
        /// Convert Paramerters 
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static DbExpression ConvertParameter( Expr expr, SemanticResolver sr )
        {
            Parameter parameter = (Parameter)expr; 
            TypeUsage paramType = null;
            KeyValuePair varInfo; 
 
            if (sr.Variables != null && sr.Variables.TryGetValue(parameter.Name, out varInfo))
            { 
                return sr.CmdTree.CreateVariableReferenceExpression(varInfo.Key, varInfo.Value);
            }

            if (null == sr.Parameters || !sr.Parameters.TryGetValue(parameter.Name, out paramType)) 
            {
                throw EntityUtil.EntitySqlError(parameter.ErrCtx, System.Data.Entity.Strings.ParameterWasNotDefined(parameter.Name)); 
            } 

            sr.CmdTree.AddParameter(parameter.Name, TypeHelpers.GetReadOnlyType(paramType)); 

            return sr.CmdTree.CreateParameterReferenceExpression(parameter.Name);
        }
 
        /// 
        /// Validate a relationship-traversal - used for both Navigate expressions 
        /// and for entity construction with related entity refs. 
        ///
        /// For "related entity refs", "isTargetEnd" is true - for Navigate expressions, 
        /// this parameter is "false".
        ///
        /// 
        /// the relationshipExpr AST 
        /// 
        /// resolver context 
        /// the source/target expression 
        /// the relationship type
        /// from end of the relationship 
        /// to-end of the relationship
        private static void ValidateRelationshipTraversal(RelshipNavigationExpr relshipExpr,
                                                          bool isTargetEnd,
                                                          SemanticResolver sr, 
                                                          out DbExpression refExpr,
                                                          out RelationshipType relationshipType, 
                                                          out RelationshipEndMember refEnd, 
                                                          out RelationshipEndMember otherEnd)
        { 
            relationshipType = null;
            refEnd = null;
            otherEnd = null;
            refExpr = null; 

            // 
            // resolve relationship type 
            //
            relationshipType = sr.ResolveNameAsType(relshipExpr.RelationTypeNames, relshipExpr.RelationTypeNameIdentifier).EdmType as RelationshipType; 
            if (null == relationshipType)
            {
                throw EntityUtil.EntitySqlError(relshipExpr.RelationTypeNameIdentifier.ErrCtx, System.Data.Entity.Strings.InvalidRelationshipTypeName(relshipExpr.RelationTypeFullName));
            } 

            // 
            // convert relationship 'instance' expression 
            //
            refExpr = Convert(relshipExpr.RelationshipSource, sr); 

            //
            // if is entity, create entity ref out if it
            // 
            if (!isTargetEnd && TypeSemantics.IsEntityType(refExpr.ResultType))
            { 
                refExpr = sr.CmdTree.CreateEntityRefExpression(refExpr); 
            }
 
            //
            // make sure is ref type
            //
            if (!TypeSemantics.IsReferenceType(refExpr.ResultType)) 
            {
                throw EntityUtil.EntitySqlError(relshipExpr.RelationshipSource.ErrCtx, System.Data.Entity.Strings.InvalidRelationshipSourceType); 
            } 

            // 
            // ensure entity 'participates' in the given relationship type
            //
            if (!TypeSemantics.IsTypeValidForRelationship(TypeHelpers.GetElementTypeUsage(refExpr.ResultType), relationshipType))
            { 
                throw EntityUtil.EntitySqlError(relshipExpr.RelationTypeNameIdentifier.ErrCtx, System.Data.Entity.Strings.RelationshipTypeIsNotCompatibleWithEntity(
                    TypeHelpers.GetFullName(TypeHelpers.GetElementTypeUsage(refExpr.ResultType)), 
                    TypeHelpers.GetFullName(relationshipType))); 
            }
 
            //
            // ensure relationship ends are valid
            // metadata ensures that there will never happen to have two equal end names
            // 
            TypeUsage fromEndType = null;
            int fromEndMatchCount = 0; 
            TypeUsage elementType = TypeHelpers.GetElementTypeUsage(refExpr.ResultType); 
            for (int i = 0; i < relationshipType.Members.Count; i++)
            { 
                //
                // check 'to' end
                //
                if (relationshipType.Members[i].Name.Equals(relshipExpr.ToEndIdentifierName, StringComparison.OrdinalIgnoreCase)) 
                {
                    otherEnd = (RelationshipEndMember)relationshipType.Members[i]; 
                    continue; 
                }
 
                //
                // check 'from' end
                //
                if ( 
                    (null != relshipExpr.FromEndIdentifier && relationshipType.Members[i].Name.Equals(relshipExpr.FromEndIdentifierName, StringComparison.OrdinalIgnoreCase)) ||
                    (null == relshipExpr.FromEndIdentifier && TypeSemantics.IsEquivalentOrPromotableTo(elementType, TypeHelpers.GetElementTypeUsage(relationshipType.Members[i].TypeUsage))) 
                   ) 
                {
                    fromEndMatchCount++; 

                    if (fromEndMatchCount > 1)
                    {
                        ErrorContext errCtx = (null == relshipExpr.FromEndIdentifier) ? relshipExpr.ErrCtx : relshipExpr.FromEndIdentifier.ErrCtx; 

                        throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.RelationshipFromEndIsAmbiguos); 
                    } 

                    refEnd = (RelationshipEndMember)relationshipType.Members[i]; 
                    fromEndType = relationshipType.Members[i].TypeUsage;
                }
            }
 
            //
            // ensure relationship 'To' end contains given property 
            // 
            if (null == otherEnd)
            { 
                if (null != relshipExpr.ToEndIdentifier)
                {
                    throw EntityUtil.EntitySqlError(relshipExpr.ToEndIdentifier.ErrCtx, System.Data.Entity.Strings.InvalidRelationshipMember(relshipExpr.ToEndIdentifierName, relshipExpr.RelationTypeFullName));
                } 

                if (2 != relationshipType.Members.Count) 
                { 
                    throw EntityUtil.EntitySqlError(relshipExpr.ErrCtx, System.Data.Entity.Strings.InvalidImplicitRelationshipToEnd(relshipExpr.RelationTypeFullName));
                } 

                Debug.Assert(null != refEnd, "null!=fromEnd");

                otherEnd = (RelationshipEndMember)(refEnd.Name.Equals(relationshipType.Members[0].Name, StringComparison.OrdinalIgnoreCase) ? relationshipType.Members[1] : relationshipType.Members[0]); 
            }
 
            // 
            // ensure relationship 'From' end contains given entity
            // 
            if (null == refEnd || null == fromEndType)
            {
                ErrorContext errCtx = (null == relshipExpr.FromEndIdentifier) ? relshipExpr.ErrCtx : relshipExpr.FromEndIdentifier.ErrCtx;
 
                if (null == relshipExpr.FromEndIdentifier)
                { 
                    throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.InvalidImplicitRelationshipFromEnd(relshipExpr.RelationTypeFullName)); 
                }
                else 
                {
                    throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.InvalidRelationshipMember(relshipExpr.FromEndIdentifierName, relshipExpr.RelationTypeFullName));
                }
            } 

            // 
            // check if source is promotable to from end type 
            //
            if (!TypeSemantics.IsValidPolymorphicCast(TypeHelpers.GetElementTypeUsage(refExpr.ResultType), 
                                                      TypeHelpers.GetElementTypeUsage(refEnd.TypeUsage)))
            {
                ErrorContext errCtx = (null == relshipExpr.FromEndIdentifier) ? relshipExpr.ErrCtx : relshipExpr.FromEndIdentifier.ErrCtx;
 
                throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.SourceTypeMustBePromotoableToFromEndRelationType(TypeHelpers.GetElementTypeUsage(refExpr.ResultType).EdmType.FullName, TypeHelpers.GetElementTypeUsage(fromEndType).EdmType.FullName));
            } 
 
            return;
        } 

        /// 
        /// Build out a RelatedEntityRef
        ///  
        /// the ast expression
        /// the Semantic Resolver context 
        /// a DbRelatedEntityRef instance 
        private static DbRelatedEntityRef ConvertRelatedEntityRef(RelshipNavigationExpr relshipExpr, SemanticResolver sr)
        { 
            //
            // Validate the relationship traversal
            //
            DbExpression targetRef; 
            RelationshipEndMember targetRefEnd;
            RelationshipEndMember otherEnd; 
            RelationshipType relationshipType; 

            ValidateRelationshipTraversal(relshipExpr, 
                                          true /* targetEnd */ ,
                                          sr,
                                          out targetRef,
                                          out relationshipType, 
                                          out targetRefEnd,
                                          out otherEnd); 
 
            //
            // ensure is *..{0|1} 
            //
            if (RelationshipMultiplicity.One != targetRefEnd.RelationshipMultiplicity &&
                RelationshipMultiplicity.ZeroOrOne != targetRefEnd.RelationshipMultiplicity)
            { 
                throw EntityUtil.EntitySqlError(relshipExpr.ErrCtx,
                                            System.Data.Entity.Strings.InvalidWithRelationshipTargetEndMultiplicity(targetRefEnd.Identity, 
                                                                                                                    targetRefEnd.RelationshipMultiplicity.ToString())); 
            }
 
            DbRelatedEntityRef relatedEntityRef = sr.CmdTree.CreateRelatedEntityRef(otherEnd, targetRefEnd, targetRef);

            return relatedEntityRef;
        } 

        ///  
        /// converts Relationship Navigation operator 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpression ConvertRelshipNavigationExpr( Expr astExpr, SemanticResolver sr )
        { 
            RelshipNavigationExpr relshipExpr = (RelshipNavigationExpr)astExpr;
 
            // 
            // Validate the relationship traversal
            // 
            DbExpression relationshipSource;
            RelationshipEndMember fromEnd;
            RelationshipEndMember toEnd;
            RelationshipType relationshipType; 

            ValidateRelationshipTraversal(relshipExpr, 
                                          false /* !targetEnd */, 
                                          sr,
                                          out relationshipSource, 
                                          out relationshipType,
                                          out fromEnd,
                                          out toEnd);
 
            //
            // create cqt expression 
            // 
            DbExpression converted = sr.CmdTree.CreateRelationshipNavigationExpression(fromEnd, toEnd, relationshipSource);
 
            Debug.Assert(null != converted,"null != converted");

            return converted;
        } 

 
        ///  
        /// converts REF operator
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpression ConvertRefExpr( Expr astExpr, SemanticResolver sr ) 
        {
            RefExpr refExpr = (RefExpr)astExpr; 
 
            DbExpression converted = Convert(refExpr.RefArgExpr, sr);
 
            //
            // check if is entity type
            //
            if (!TypeSemantics.IsEntityType(converted.ResultType)) 
            {
                throw EntityUtil.EntitySqlError(refExpr.RefArgExpr.ErrCtx, System.Data.Entity.Strings.RefArgIsNotOfEntityType(converted.ResultType.EdmType.FullName)); 
            } 

            // 
            // create ref expression
            //
            converted = sr.CmdTree.CreateEntityRefExpression(converted);
 
            Debug.Assert(null != converted,"null != converted");
 
            return converted; 
        }
 

        /// 
        /// converts DEREF operator
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        ///  
        private static DbExpression ConvertDeRefExpr( Expr astExpr, SemanticResolver sr )
        { 
            DerefExpr deRefExpr = (DerefExpr)astExpr;

            DbExpression converted = null;
 
            converted = Convert(deRefExpr.RefExpr, sr);
 
            // 
            // check if return type is RefType
            // 
            if (!TypeSemantics.IsReferenceType(converted.ResultType))
            {
                throw EntityUtil.EntitySqlError(deRefExpr.RefExpr.ErrCtx, System.Data.Entity.Strings.DeRefArgIsNotOfRefType(converted.ResultType.EdmType.FullName));
            } 

            // 
            // create DeRef expression 
            //
            converted = sr.CmdTree.CreateDerefExpression(converted); 

            Debug.Assert(null != converted,"null != converted");

            return converted; 
        }
 
 
        /// 
        /// converts CREATEREF operator 
        /// 
        /// 
        /// SemanticResolver instance relative to a especif typespace/system
        ///  
        private static DbExpression ConvertCreateRefExpr( Expr astExpr, SemanticResolver sr )
        { 
            CreateRefExpr createRefExpr = (CreateRefExpr)astExpr; 

            DbExpression converted = null; 

            //
            // Convert the entity set, also, ensure that we get back an extent expression
            // 
            DbScanExpression entitySetExpr = Convert(createRefExpr.EntitySet, sr) as DbScanExpression;
            if (entitySetExpr == null) 
            { 
                throw EntityUtil.EntitySqlError(createRefExpr.EntitySet.ErrCtx, System.Data.Entity.Strings.ExprIsNotValidEntitySetForCreateRef);
            } 

            //
            // Ensure that the extent is an entity set
            // 
            EntitySet entitySet = entitySetExpr.Target as EntitySet;
            if (entitySet == null) 
            { 
                throw EntityUtil.EntitySqlError(createRefExpr.EntitySet.ErrCtx, System.Data.Entity.Strings.ExprIsNotValidEntitySetForCreateRef);
            } 

            DbExpression keyRowExpression = Convert(createRefExpr.Keys, sr);

            SemanticResolver.EnsureIsNotUntypedNull(keyRowExpression, createRefExpr.Keys.ErrCtx); 

            RowType inputKeyRowType = keyRowExpression.ResultType.EdmType as RowType; 
            if (null == inputKeyRowType) 
            {
                throw EntityUtil.EntitySqlError(createRefExpr.Keys.ErrCtx,System.Data.Entity.Strings.InvalidCreateRefKeyType); 
            }

            RowType entityKeyRowType = TypeHelpers.CreateKeyRowType(entitySet.ElementType, sr.CmdTree.MetadataWorkspace);
 
            if (entityKeyRowType.Members.Count != inputKeyRowType.Members.Count)
            { 
                throw EntityUtil.EntitySqlError(createRefExpr.Keys.ErrCtx, System.Data.Entity.Strings.ImcompatibleCreateRefKeyType); 
            }
 
            if (!TypeSemantics.IsEquivalentOrPromotableTo(keyRowExpression.ResultType, TypeUsage.Create(entityKeyRowType)))
            {
                throw EntityUtil.EntitySqlError(createRefExpr.Keys.ErrCtx, System.Data.Entity.Strings.ImcompatibleCreateRefKeyElementType);
            } 

            // 
            // if CREATEREF specifies a type, resolve and validate the type 
            //
            if (null != createRefExpr.TypeIdentifier) 
            {
                TypeUsage targetTypeUsage = ConvertTypeIdentifier(createRefExpr.TypeIdentifier, sr);

                // 
                // ensure type is entity
                // 
                if (!TypeSemantics.IsEntityType(targetTypeUsage)) 
                {
 
                    throw EntityUtil.EntitySqlError(createRefExpr.TypeIdentifier.ErrCtx,
                                                System.Data.Entity.Strings.CreateRefTypeIdentifierMustSpecifyAnEntityType(
                                                                    targetTypeUsage.EdmType.Identity,
                                                                    targetTypeUsage.EdmType.BuiltInTypeKind.ToString())); 
                }
 
                if (!TypeSemantics.IsValidPolymorphicCast(entitySet.ElementType, targetTypeUsage.EdmType)) 
                {
                    throw EntityUtil.EntitySqlError(createRefExpr.TypeIdentifier.ErrCtx, 
                                                System.Data.Entity.Strings.CreateRefTypeIdentifierMustBeASubOrSuperType(
                                                                    entitySet.ElementType.Identity,
                                                                    targetTypeUsage.EdmType.FullName));
                } 

                converted = sr.CmdTree.CreateRefExpression(entitySet, 
                                                           keyRowExpression, 
                                                           (EntityType)targetTypeUsage.EdmType);
            } 
            else
            {
                //
                // finally creates the expression 
                //
                converted = sr.CmdTree.CreateRefExpression(entitySet, keyRowExpression); 
            } 

            Debug.Assert(null != converted,"null != converted"); 

            return converted;
        }
 

        ///  
        /// converts KEY operator 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpression ConvertKeyExpr( Expr astExpr, SemanticResolver sr )
        { 
            KeyExpr keyExpr = (KeyExpr)astExpr;
 
            DbExpression converted = Convert(keyExpr.RefExpr, sr); 

            SemanticResolver.EnsureIsNotUntypedNull(converted, keyExpr.RefExpr.ErrCtx); 

            if (TypeSemantics.IsEntityType(converted.ResultType))
            {
                converted = sr.CmdTree.CreateEntityRefExpression(converted); 
            }
            else if (!TypeSemantics.IsReferenceType(converted.ResultType)) 
            { 
                throw EntityUtil.EntitySqlError(keyExpr.RefExpr.ErrCtx,System.Data.Entity.Strings.InvalidKeyArgument(TypeHelpers.GetFullName(converted.ResultType)));
            } 

            converted = sr.CmdTree.CreateRefKeyExpression(converted);

            Debug.Assert(null != converted, "null != converted"); 

            return converted; 
        } 

 
        /// 
        /// Dispatches/Converts BuiltIn Expressions
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        ///  
        private static DbExpression ConvertBuiltIn( Expr astExpr, SemanticResolver sr ) 
        {
            if (null == astExpr) 
            {
                return null;
            }
 
            BuiltInExpr bltInExpr = (BuiltInExpr)astExpr;
 
            BuiltInExprConverter builtInConverter = _builtInExprConverter[bltInExpr.Kind]; 

            if (null == builtInConverter) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.UnknownBuiltInAstExpressionType);
            }
 
            DbExpression converted = builtInConverter(bltInExpr, sr);
 
            Debug.Assert(null != converted,"null != converted"); 

            return converted; 
        }


        ///  
        /// Converts Arithmetic Expressions Args
        ///  
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        ///  
        private static Pair ConvertArithmeticArgs( BuiltInExpr astBuiltInExpr, SemanticResolver sr )
        {
            DbExpression leftExpr = Convert(astBuiltInExpr.Arg1, sr);
            if (!(TypeSemantics.IsNumericType(leftExpr.ResultType) || SemanticResolver.IsNullExpression(leftExpr))) 
            {
                throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.ExpressionMustBeNumericType); 
            } 

            DbExpression rightExpr = null; 
            if (null != astBuiltInExpr.Arg2)
            {
                rightExpr = Convert(astBuiltInExpr.Arg2, sr);
 
                if (!(TypeSemantics.IsNumericType(rightExpr.ResultType) || SemanticResolver.IsNullExpression(rightExpr)))
                { 
                    throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.ExpressionMustBeNumericType); 
                }
 
                if (null == TypeHelpers.GetCommonTypeUsage(leftExpr.ResultType, rightExpr.ResultType))
                {
                    throw EntityUtil.EntitySqlError(astBuiltInExpr.ErrCtx, System.Data.Entity.Strings.ArgumentTypesAreIncompatible(leftExpr.ResultType.EdmType.FullName, rightExpr.ResultType.EdmType.FullName));
                } 
            }
 
            return sr.EnsureTypedNulls(leftExpr, rightExpr, astBuiltInExpr.ErrCtx, () => Strings.InvalidNullArithmetic); 
        }
 
        /// 
        /// Converts Plus Args - specific case since string type is an allowed type for '+'
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        ///  
        private static Pair ConvertPlusOperands( BuiltInExpr astBuiltInExpr, SemanticResolver sr ) 
        {
            DbExpression leftExpr = Convert(astBuiltInExpr.Arg1, sr); 
            if (!(TypeSemantics.IsNumericType(leftExpr.ResultType) ||
                  TypeSemantics.IsPrimitiveType(leftExpr.ResultType,PrimitiveTypeKind.String) ||
                  SemanticResolver.IsNullExpression(leftExpr)))
            { 
                throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.PlusLeftExpressionInvalidType);
            } 
 
            DbExpression rightExpr = Convert(astBuiltInExpr.Arg2, sr);
            if (!(TypeSemantics.IsNumericType(rightExpr.ResultType) || 
                  TypeSemantics.IsPrimitiveType(rightExpr.ResultType, PrimitiveTypeKind.String) ||
                  SemanticResolver.IsNullExpression(rightExpr)))
            {
                throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.PlusRightExpressionInvalidType); 
            }
 
            if (null == TypeHelpers.GetCommonTypeUsage(leftExpr.ResultType, rightExpr.ResultType)) 
            {
                throw EntityUtil.EntitySqlError(astBuiltInExpr.ErrCtx, System.Data.Entity.Strings.ArgumentTypesAreIncompatible(leftExpr.ResultType.EdmType.FullName, rightExpr.ResultType.EdmType.FullName)); 
            }

            return sr.EnsureTypedNulls(leftExpr, rightExpr, astBuiltInExpr.ErrCtx, () => Strings.InvalidNullArithmetic);
        } 

 
        ///  
        /// Converts Logical Expression Args
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static Pair ConvertLogicalArgs( BuiltInExpr astBuiltInExpr, SemanticResolver sr ) 
        {
            DbExpression leftExpr = Convert(astBuiltInExpr.Arg1, sr); 
            if (leftExpr is UntypedNullExpression) 
            {
                leftExpr = sr.CmdTree.CreateNullExpression(sr.TypeResolver.BooleanType); 
            }

            DbExpression rightExpr = Convert(astBuiltInExpr.Arg2, sr);
            if (rightExpr is UntypedNullExpression) 
            {
                rightExpr = sr.CmdTree.CreateNullExpression(sr.TypeResolver.BooleanType); 
            } 

            // 
            // ensure left expression type is boolean
            //
            if (!TypeResolver.IsBooleanType(leftExpr.ResultType))
            { 
                throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.ExpressionTypeMustBeBoolean);
            } 
 
            //
            // ensure right expression type is boolean 
            //
            if (null != rightExpr && !TypeResolver.IsBooleanType(rightExpr.ResultType))
            {
                throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.ExpressionTypeMustBeBoolean); 
            }
 
            return new Pair(leftExpr, rightExpr); 
        }
 

        /// 
        /// Converts Equal Comparison Expression Args
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        ///  
        private static Pair ConvertEqualCompArgs( BuiltInExpr astBuiltInExpr, SemanticResolver sr )
        { 
            //
            // convert left and right types and infer null types
            //
            Pair compArgs = sr.EnsureTypedNulls( Convert(astBuiltInExpr.Arg1, sr), 
                                                                         Convert(astBuiltInExpr.Arg2, sr),
                                                                         astBuiltInExpr.ErrCtx, 
                                                                         () => Strings.InvalidNullComparison); 

            // 
            // ensure both operand types are equal-comparable
            //
            if (!TypeSemantics.IsEqualComparableTo(compArgs.Left.ResultType, compArgs.Right.ResultType))
            { 
                throw EntityUtil.EntitySqlError(astBuiltInExpr.ErrCtx, System.Data.Entity.Strings.ArgumentTypesAreIncompatible(compArgs.Left.ResultType.EdmType.FullName, compArgs.Right.ResultType.EdmType.FullName));
            } 
 
            return compArgs;
        } 


        /// 
        /// Converts Order Comparison Expression Args 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static Pair ConvertOrderCompArgs( BuiltInExpr astBuiltInExpr, SemanticResolver sr ) 
        {
            Pair compArgs = sr.EnsureTypedNulls(
                                                            Convert(astBuiltInExpr.Arg1, sr),
                                                            Convert(astBuiltInExpr.Arg2, sr), 
                                                            astBuiltInExpr.ErrCtx,
                                                            () => Strings.InvalidNullComparison); 
 
            //
            // ensure both operand types are order-comparable 
            //
            if (!TypeSemantics.IsOrderComparableTo(compArgs.Left.ResultType, compArgs.Right.ResultType))
            {
                throw EntityUtil.EntitySqlError(astBuiltInExpr.ErrCtx, System.Data.Entity.Strings.ArgumentTypesAreIncompatible(compArgs.Left.ResultType.EdmType.FullName, compArgs.Right.ResultType.EdmType.FullName)); 
            }
 
            return compArgs; 
        }
 

        /// 
        /// Converts Set Expression Args
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        ///  
        private static Pair ConvertSetArgs( BuiltInExpr astBuiltInExpr, SemanticResolver sr )
        { 
            //
            // convert left expression
            //
            DbExpression leftExpr = Convert(astBuiltInExpr.Arg1, sr); 

            // 
            // convert right expression if binary set op kind 
            //
            DbExpression rightExpr = null; 
            if (null != astBuiltInExpr.Arg2)
            {
                //
                // binary set op 
                //
 
                // 
                // make sure left expression type is of sequence type (ICollection or Extent)
                // 
                if (!TypeSemantics.IsCollectionType(leftExpr.ResultType))
                {
                    throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.LeftSetExpressionArgsMustBeCollection);
                } 

                // 
                // convert right expression 
                //
                rightExpr = Convert(astBuiltInExpr.Arg2, sr); 

                //
                // make sure right expression type is of sequence type (ICollection or Extent)
                // 
                if (!TypeSemantics.IsCollectionType(rightExpr.ResultType))
                { 
                    throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.RightSetExpressionArgsMustBeCollection); 
                }
 
                TypeUsage commonType;
                TypeUsage leftElemType = TypeHelpers.GetElementTypeUsage(leftExpr.ResultType);
                TypeUsage rightElemType = TypeHelpers.GetElementTypeUsage(rightExpr.ResultType);
                if (!TypeSemantics.TryGetCommonType(leftElemType, rightElemType, out commonType)) 
                {
                    CqlErrorHelper.ReportIncompatibleCommonType(astBuiltInExpr.ErrCtx, leftElemType, rightElemType); 
                } 

                if (astBuiltInExpr.Kind != BuiltInKind.UnionAll) 
                {
                    //
                    // ensure left argument is set op comparable
                    // 
                    if (!TypeHelpers.IsSetComparableOpType(TypeHelpers.GetElementTypeUsage(leftExpr.ResultType)))
                    { 
                        throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg1.ErrCtx, 
                                             System.Data.Entity.Strings.PlaceholderSetArgTypeIsNotEqualComparable(
                                                           astBuiltInExpr.Kind.ToString().ToUpperInvariant(), 
                                                           System.Data.Entity.Strings.LocalizedLeft,
                                                           TypeHelpers.GetElementTypeUsage(leftExpr.ResultType).EdmType.FullName));
                    }
 
                    //
                    // ensure right argument is set op comparable 
                    // 
                    if (!TypeHelpers.IsSetComparableOpType(TypeHelpers.GetElementTypeUsage(rightExpr.ResultType)))
                    { 
                        throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg2.ErrCtx,
                                             System.Data.Entity.Strings.PlaceholderSetArgTypeIsNotEqualComparable(
                                                           astBuiltInExpr.Kind.ToString().ToUpperInvariant(),
                                                           System.Data.Entity.Strings.LocalizedRight, 
                                                           TypeHelpers.GetElementTypeUsage(rightExpr.ResultType).EdmType.FullName));
                    } 
                } 
                else
                { 
                    if (Helper.IsAssociationType(leftElemType.EdmType))
                    {
                        throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.InvalidAssociationTypeForUnion(leftElemType.Identity));
                    } 

                    if (Helper.IsAssociationType(rightElemType.EdmType)) 
                    { 
                        throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.InvalidAssociationTypeForUnion(rightElemType.Identity));
                    } 
                }
            }
            else
            { 
                //
                // unary set op 
                // 

                // 
                // make sure expression type is of sequence type (ICollection or Extent)
                //
                if (!TypeSemantics.IsCollectionType(leftExpr.ResultType))
                { 
                    throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.InvalidUnarySetOpArgument(astBuiltInExpr.Name));
                } 
 
                //
                // make sure that if is distinct unary operator, arg element type must be equal-comparable 
                //
                if (astBuiltInExpr.Kind == BuiltInKind.Distinct && !TypeHelpers.IsValidDistinctOpType(TypeHelpers.GetElementTypeUsage(leftExpr.ResultType)))
                {
                    throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.ExpressionTypeMustBeEqualComparable); 
                }
            } 
 
            return new Pair(leftExpr, rightExpr);
        } 


        /// 
        /// Converts Set 'IN' expression args 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static Pair ConvertInExprArgs( BuiltInExpr astBuiltInExpr, SemanticResolver sr ) 
        {
            DbExpression leftExpr = Convert(astBuiltInExpr.Arg1, sr);
            if (TypeSemantics.IsCollectionType(leftExpr.ResultType))
            { 
                throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.ExpressionTypeMustNotBeCollection);
            } 
 
            DbExpression rightExpr = Convert(astBuiltInExpr.Arg2, sr);
            if (!TypeSemantics.IsCollectionType(rightExpr.ResultType)) 
            {
                throw EntityUtil.EntitySqlError(astBuiltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.RightSetExpressionArgsMustBeCollection);
            }
 
            //
            // if left expression type is null, infer its type from the collection element type 
            // 
            if (SemanticResolver.IsNullExpression(leftExpr))
            { 
                TypeUsage elementType = TypeHelpers.GetElementTypeUsage(rightExpr.ResultType);

                SemanticResolver.EnsureValidTypeForNullExpression(elementType, astBuiltInExpr.Arg1.ErrCtx);
 
                leftExpr = sr.CmdTree.CreateNullExpression(elementType);
            } 
            else 
            {
                // 
                // ensure that if left and right are typed expressions then their types must be comparable for IN op
                //
                TypeUsage commonElemType = TypeHelpers.GetCommonTypeUsage(leftExpr.ResultType, TypeHelpers.GetElementTypeUsage(rightExpr.ResultType));
                if (null == commonElemType || !TypeHelpers.IsValidInOpType(commonElemType)) 
                {
                    throw EntityUtil.EntitySqlError(astBuiltInExpr.ErrCtx, System.Data.Entity.Strings.InvalidInExprArgs(leftExpr.ResultType.EdmType.FullName, rightExpr.ResultType.EdmType.FullName)); 
                } 
            }
 
            return new Pair(leftExpr, rightExpr);
        }

 
        /// 
        /// Converts Type Expression Args 
        ///  
        /// 
        /// SemanticResolver instance relative to a specific typespace/system 
        /// 
        private static Pair ConvertTypeExprArgs( BuiltInExpr astBuiltInExpr, SemanticResolver sr )
        {
            return new Pair(Convert(astBuiltInExpr.Arg1, sr), 
                                                     ConvertTypeIdentifier(astBuiltInExpr.Arg2, sr));
        } 
 

        ///  
        /// Converts TypeIdentifier
        /// TypeIdentifier can have the 'shape' of a simple identifier (product), a dotted identifier (namespace.bar) or a methodExpr ( edm.decimal(10,4) )
        /// 
        ///  
        /// 
        ///  
        private static TypeUsage ConvertTypeIdentifier(Expr typeIdentifierExpr, SemanticResolver sr) 
        {
            MethodExpr methodExpr = null; 
            string[] typeNames;

            //
            // if it is dot id get full id name 
            //
            DotExpr dotExpr = typeIdentifierExpr as DotExpr; 
            if (null != dotExpr && dotExpr.IsDottedIdentifier) 
            {
                typeNames = dotExpr.Names; 
            }
            else
            {
                // 
                // method expression, type with parameters
                // 
                methodExpr = typeIdentifierExpr as MethodExpr; 
                if (null != methodExpr)
                { 
                    typeNames = methodExpr.MethodPrefixExpr.Names;
                    Debug.Assert(methodExpr.Args.Count == 1 || methodExpr.Args.Count == 2, "decimal type must have one or two arguments");
                    Debug.Assert(methodExpr.Args[0] is Literal, "type expression must have literal arg");
                    Debug.Assert((methodExpr.Args.Count == 2) ? methodExpr.Args[1] is Literal : true, "type expression must have literal arg"); 
                }
                else 
                { 
                    //
                    // if it is single id, get it is name 
                    //
                    Identifier id = typeIdentifierExpr as Identifier;
                    if (null != id)
                    { 
                        typeNames = new string[] { id.Name };
                    } 
                    else 
                    {
                        throw EntityUtil.EntitySqlError(typeIdentifierExpr.ErrCtx, System.Data.Entity.Strings.InvalidTypeNameExpression); 
                    }
                }
            }
 
            //
            // Resolve type 
            // 
            TypeUsage typeUsage = sr.ResolveNameAsType(typeNames, typeIdentifierExpr);
 
            return typeUsage;
        }

 
        /// 
        /// Converts Row type constructor expression 
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static DbExpression ConvertRowConstructor( Expr expr, SemanticResolver sr )
        {
            RowConstructorExpr rowExpr = (RowConstructorExpr)expr; 
            Dictionary rowColumns = new Dictionary(sr.ScopeStringComparer);
            List fieldExprs = new List(rowExpr.AliasExprList.Count); 
 
            for (int i = 0 ; i < rowExpr.AliasExprList.Count ; i++)
            { 
                AliasExpr aliasExpr = rowExpr.AliasExprList[i];

                DbExpression colExpr = Convert(aliasExpr.Expr, sr);
 
                string aliasName = sr.InferAliasName(aliasExpr, colExpr);
 
                if (rowColumns.ContainsKey(aliasName)) 
                {
                    if (aliasExpr.HasAlias) 
                    {
                        CqlErrorHelper.ReportAliasAlreadyUsedError(aliasName, aliasExpr.AliasIdentifier.ErrCtx, System.Data.Entity.Strings.InRowConstructor);
                    }
                    else 
                    {
                        aliasName = sr.GenerateInternalName("autoRowCol"); 
                    } 
                }
 
                if (SemanticResolver.IsNullExpression(colExpr))
                {
                    throw EntityUtil.EntitySqlError(aliasExpr.Expr.ErrCtx, System.Data.Entity.Strings.RowCtorElementCannotBeNull);
                } 

                rowColumns.Add(aliasName, colExpr.ResultType); 
 
                fieldExprs.Add(colExpr);
            } 

            return sr.CmdTree.CreateNewInstanceExpression(TypeHelpers.CreateRowTypeUsage(rowColumns, true /* readOnly */), fieldExprs);
        }
 

        ///  
        /// Converts Multiset type constructor expression 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpression ConvertMultisetConstructor( Expr expr, SemanticResolver sr )
        { 
            MultisetConstructorExpr msetCtor = (MultisetConstructorExpr)expr;
 
            if (null == msetCtor.ExprList) 
            {
                throw EntityUtil.EntitySqlError(expr.ErrCtx, System.Data.Entity.Strings.CannotCreateEmptyMultiset); 
            }

            PairOfLists mSetExprs = ProcessExprList(msetCtor.ExprList, sr);
 
            TypeUsage commonType = TypeHelpers.GetCommonTypeUsage(mSetExprs.Left);
 
            // 
            // ensure all elems have a common type
            // 
            if (null == commonType)
            {
                throw EntityUtil.EntitySqlError(expr.ErrCtx, System.Data.Entity.Strings.MultisetElemsAreNotTypeCompatible);
            } 

            // 
            // ensure common type is not an untyped null 
            //
            if (TypeSemantics.IsNullType(commonType)) 
            {
                throw EntityUtil.EntitySqlError(expr.ErrCtx, System.Data.Entity.Strings.CannotCreateMultisetofNulls);
            }
 
            commonType = TypeHelpers.GetReadOnlyType(commonType);
 
            // 
            // fixup untyped nulls
            // 
            for (int i = 0 ; i < mSetExprs.Count ; i++)
            {
                if (SemanticResolver.IsNullExpression(mSetExprs.Right[i]))
                { 
                    SemanticResolver.EnsureValidTypeForNullExpression(commonType, msetCtor.ExprList[i].ErrCtx);
 
                    mSetExprs.Right[i] = sr.CmdTree.CreateNullExpression(commonType); 
                }
            } 

            return sr.CmdTree.CreateNewInstanceExpression(TypeHelpers.CreateCollectionTypeUsage(commonType, true /* readOnly */), mSetExprs.Right);
        }
 

        ///  
        /// converts case-when-then expression 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpression ConvertCaseExpr( Expr expr, SemanticResolver sr )
        { 
            CaseExpr caseExpr = (CaseExpr)expr;
 
            List whenExprList = new List(caseExpr.WhenThenExprList.Count); 

            PairOfLists thenExprList = new PairOfLists(); 

            //
            // Resolve then expressions
            // 
            for (int i = 0 ; i < caseExpr.WhenThenExprList.Count ; i++)
            { 
                WhenThenExpr whenThenExpr = caseExpr.WhenThenExprList[i]; 

                DbExpression whenExpression = Convert(whenThenExpr.WhenExpr, sr); 

                if (!TypeResolver.IsBooleanType(whenExpression.ResultType))
                {
                    throw EntityUtil.EntitySqlError(whenThenExpr.WhenExpr.ErrCtx, System.Data.Entity.Strings.ExpressionTypeMustBeBoolean); 
                }
 
                whenExprList.Add(whenExpression); 

                DbExpression thenExpression = Convert(whenThenExpr.ThenExpr, sr); 

                thenExprList.Add(thenExpression, thenExpression.ResultType);
            }
 
            TypeUsage resultType = TypeHelpers.GetCommonTypeUsage(thenExprList.Right);
            if (null == resultType) 
            { 
                throw EntityUtil.EntitySqlError(caseExpr.WhenThenExprList.Expressions[0].ThenExpr.ErrCtx, System.Data.Entity.Strings.InvalidCaseThenTypes);
            } 

            if ((null == caseExpr.ElseExpr) && TypeSemantics.IsNullType(resultType))
            {
                throw EntityUtil.EntitySqlError(caseExpr.WhenThenExprList.Expressions[0].ThenExpr.ErrCtx, System.Data.Entity.Strings.InvalidCaseThenNullType); 
            }
 
            // 
            // Converts else if present
            // 
            DbExpression elseExpr = null;
            if (null != caseExpr.ElseExpr)
            {
                elseExpr = Convert(caseExpr.ElseExpr, sr); 

                resultType = TypeHelpers.GetCommonTypeUsage(resultType, elseExpr.ResultType); 
                if (null == resultType) 
                {
                    throw EntityUtil.EntitySqlError(caseExpr.ElseExpr.ErrCtx, System.Data.Entity.Strings.InvalidCaseElseType); 
                }

                if (TypeSemantics.IsNullType(resultType))
                { 
                    throw EntityUtil.EntitySqlError(caseExpr.ElseExpr.ErrCtx, System.Data.Entity.Strings.InvalidCaseWhenThenNullType);
                } 
 
                if (SemanticResolver.IsNullExpression(elseExpr))
                { 
                    SemanticResolver.EnsureValidTypeForNullExpression(resultType, caseExpr.ElseExpr.ErrCtx);
                    elseExpr = sr.CmdTree.CreateNullExpression(resultType);
                }
            } 
            else
            { 
                if (TypeSemantics.IsCollectionType(resultType)) 
                {
                    elseExpr = sr.CmdTree.CreateNewEmptyCollectionExpression(resultType); 
                }
                else
                {
                    SemanticResolver.EnsureValidTypeForNullExpression(resultType, caseExpr.ErrCtx); 
                    elseExpr = sr.CmdTree.CreateNullExpression(resultType);
                } 
            } 

            // 
            // fixup untyped nulls
            //
            for (int i = 0 ; i < thenExprList.Count ; i++)
            { 
                if (SemanticResolver.IsNullExpression(thenExprList.Left[i]))
                { 
                    SemanticResolver.EnsureValidTypeForNullExpression(resultType, caseExpr.WhenThenExprList[i].ThenExpr.ErrCtx); 

                    thenExprList[i] = new Pair(sr.CmdTree.CreateNullExpression(resultType), resultType); 
                }
            }

            return sr.CmdTree.CreateCaseExpression(whenExprList, thenExprList.Left, elseExpr); 
        }
 
 
        /// 
        /// Converts Query Expression 
        /// 
        /// 
        /// SemanticResolver instance relative to a especif typespace/system
        ///  
        private static DbExpression ConvertQuery( Expr expr, SemanticResolver sr )
        { 
            QueryExpr queryExpr = (QueryExpr)expr; 
            DbExpression converted = null;
            bool isRestrictedViewGenerationMode = (ParserOptions.CompilationMode.RestrictedViewGenerationMode == sr.ParserOptions.ParserCompilationMode); 

            //
            // Validate & Compensate Query
            // 
            ValidateAndCompensateQuery(queryExpr);
 
            // 
            // Create Source Scope Region
            // 
            using (sr.EnterScopeRegion())
            {
                //
                // Process From Clause 
                //
                DbExpressionBinding sourceExpr = ProcessFromClause(queryExpr.FromClause, sr); 
 
                //
                // Process Where Clause 
                //
                sourceExpr = ProcessWhereClause(sourceExpr, queryExpr.WhereClause, sr);

                Debug.Assert(isRestrictedViewGenerationMode ? null == queryExpr.GroupByClause : true, "GROUP BY clause must be null in RestrictedViewGenerationMode"); 
                Debug.Assert(isRestrictedViewGenerationMode ? null == queryExpr.HavingClause  : true, "HAVING clause must be null in RestrictedViewGenerationMode");
                Debug.Assert(isRestrictedViewGenerationMode ? null == queryExpr.OrderByClause : true, "ORDER BY clause must be null in RestrictedViewGenerationMode"); 
 
                if ( !isRestrictedViewGenerationMode )
                { 
                    //
                    // Process GroupBy Clause
                    //
                    sourceExpr = ProcessGroupByClause(sourceExpr, queryExpr, sr); 

                    // 
                    // Process Having Clause 
                    //
                    sourceExpr = ProcessHavingClause(sourceExpr, queryExpr.HavingClause, sr); 

                    //
                    // Process OrderBy Clause
                    // 
                    sourceExpr = ProcessOrderByClause(sourceExpr, queryExpr, sr);
                } 
 
                //
                // Process Projection Clause 
                //
                converted = ProcessSelectClause(sourceExpr, queryExpr, sr);

            } // end query scope region 

            return converted; 
        } 

 
        /// 
        /// Validates and Compensates query expression
        /// 
        ///  
        private static void ValidateAndCompensateQuery( QueryExpr queryExpr )
        { 
            if (null != queryExpr.HavingClause && null == queryExpr.GroupByClause) 
            {
                throw EntityUtil.EntitySqlError(queryExpr.ErrCtx, System.Data.Entity.Strings.HavingRequiresGroupClause); 
            }

            if (queryExpr.SelectClause.HasTopClause)
            { 
                if ((null != queryExpr.OrderByClause) && queryExpr.OrderByClause.HasLimitSubClause)
                { 
                    throw EntityUtil.EntitySqlError(queryExpr.SelectClause.TopExpr.ErrCtx, System.Data.Entity.Strings.TopAndLimitCannotCoexist); 
                }
 
                if ((null != queryExpr.OrderByClause) && queryExpr.OrderByClause.HasSkipSubClause)
                {
                    throw EntityUtil.EntitySqlError(queryExpr.SelectClause.TopExpr.ErrCtx, System.Data.Entity.Strings.TopAndSkipCannotCoexist);
                } 
            }
        } 
 

        ///  
        /// Process Select Clause
        /// 
        /// 
        ///  
        /// SemanticResolver instance relative to a especific typespace/system
        ///  
        private static DbExpression ProcessSelectClause( DbExpressionBinding source, QueryExpr queryExpr, SemanticResolver sr ) 
        {
            DbExpression projectExpression = null; 
            SelectClause selectClause = queryExpr.SelectClause;
            HashSet projectionAliases = new HashSet(sr.ScopeStringComparer);
            List> projFields = new List>(selectClause.Items.Count);
 
            //
            // if source is sort/skip expression, then skip projection conversion since it was already 
            // performed 
            //
            if (queryExpr.OrderByClause != null && selectClause.DistinctKind == DistinctKind.Distinct) 
            {
                projectExpression = source.Expression;
            }
            else 
            {
                // 
                // Converts projection list 
                //
                #region Process projection list 
                for (int i = 0; i < selectClause.Items.Count; i++)
                {
                    AliasExpr selectExprItem = selectClause.Items[i];
 
                    DbExpression converted = Convert(selectExprItem.Expr, sr);
 
                    // 
                    // ensure expression is typed
                    // 
                    SemanticResolver.EnsureIsNotUntypedNull(converted, selectExprItem.Expr.ErrCtx);

                    //
                    // infer projection expression alias 
                    //
                    string aliasName = sr.InferAliasName(selectExprItem, converted); 
 
                    //
                    // ensure the alias was not used already 
                    //
                    if (projectionAliases.Contains(aliasName))
                    {
                        if (selectExprItem.HasAlias) 
                        {
                            CqlErrorHelper.ReportAliasAlreadyUsedError(aliasName, selectExprItem.AliasIdentifier.ErrCtx, System.Data.Entity.Strings.InSelectProjectionList); 
                        } 
                        else
                        { 
                            aliasName = sr.GenerateInternalName("autoProject");
                        }
                    }
 
                    projectionAliases.Add(aliasName);
 
                    projFields.Add(new KeyValuePair(aliasName, converted)); 
                }
                #endregion 


                //
                // VALUE projection 
                //
                #region handles VALUE modifier 
                if (selectClause.SelectKind == SelectKind.SelectValue) 
                {
                    if (projFields.Count > 1) 
                    {
                        throw EntityUtil.EntitySqlError(selectClause.ErrCtx, System.Data.Entity.Strings.InvalidSelectItem);
                    }
 
                    projectExpression = sr.CmdTree.CreateProjectExpression(source, projFields[0].Value);
                } 
                else 
                {
                    projectExpression = sr.CmdTree.CreateProjectExpression(source, sr.CmdTree.CreateNewRowExpression(projFields)); 
                }
                #endregion

                // 
                // handle DISTINCT modifier
                // 
                #region DISTINCT 
                if (selectClause.DistinctKind == DistinctKind.Distinct)
                { 
                    //
                    // ensure element type is equal-comparable
                    //
                    SemanticResolver.ValidateDistinctProjection(selectClause, projectExpression.ResultType); 

                    // 
                    // create distinct expression 
                    //
                    projectExpression = sr.CmdTree.CreateDistinctExpression(projectExpression); 
                }
                #endregion
            }
 
            //
            // TOP sub-clause 
            // NOTE: WITH TIES is not supported in M3.2 
            //
            #region TOP/LIMIT sub-clause 
            if (selectClause.HasTopClause || ((null != queryExpr.OrderByClause) && queryExpr.OrderByClause.HasLimitSubClause))
            {
                ErrorContext errCtx = (selectClause.HasTopClause) ? selectClause.TopExpr.ErrCtx : queryExpr.OrderByClause.LimitSubClause.ErrCtx;
                // 
                // convert top argument
                // 
                DbExpression limitExpr = Convert((selectClause.HasTopClause) ? selectClause.TopExpr : queryExpr.OrderByClause.LimitSubClause, sr); 

                // 
                // ensure is not NULL expr
                //
                SemanticResolver.EnsureIsNotUntypedNull(limitExpr, errCtx);
 
                Debug.Assert(limitExpr is DbConstantExpression || limitExpr is DbParameterReferenceExpression, "TOP/LIMIT inner expression must be a parameter or numeric literal in this release");
 
                // 
                // ensure proper pre-conditions hold for TOP expression
                // 
                sr.EnsureValidLimitExpression(
                        errCtx,
                        limitExpr,
                        (selectClause.HasTopClause) ? "TOP" : "LIMIT"); 

                // create expression - WITH TIES is not supported in M3.2 
                projectExpression = sr.CmdTree.CreateLimitExpression(projectExpression, limitExpr); 
            }
            #endregion 

            Debug.Assert(null != projectExpression,"null != projectExpr");

            return projectExpression; 
        }
 
 
        /// 
        /// Process From Clause 
        /// 
        /// 
        /// SemanticResolver instance relative to a especif typespace/system
        ///  
        private static DbExpressionBinding ProcessFromClause( FromClause fromClause, SemanticResolver sr )
        { 
            DbExpressionBinding fromBinding = null; 
            DbExpressionBinding fromBindingAux = null;
 
            //
            // Process Each From Clause Item
            //
            for (int i = 0 ; i < fromClause.FromClauseItems.Count ; i++ ) 
            {
                // 
                // Set Scope Source Var Kind 
                //
                sr.SetCurrentScopeVarKind(fromClause.FromClauseItems[i].FromClauseItemKind); 

                //
                // Convert From Clause
                // 
                fromBindingAux = ProcessFromClauseItem(fromClause.FromClauseItems[i], sr);
 
                // 
                // Reset All Vars to SourceVar Kind
                // 
                sr.ResetCurrentScopeVarKind();

                if (null == fromBinding)
                { 
                    fromBinding = fromBindingAux;
                } 
                else 
                {
                    fromBinding = sr.CmdTree.CreateExpressionBinding( 
                                        sr.CmdTree.CreateCrossApplyExpression(fromBinding, fromBindingAux),
                                        sr.GenerateInternalName("lcapply"));

                    sr.FixupNamedSourceVarBindings(fromBinding.Variable); 
                }
 
            } 

            Debug.Assert(null != fromBinding,"null != fromBinding"); 

            return fromBinding;
        }
 

        ///  
        /// Process Generic From Clause Item 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpressionBinding ProcessFromClauseItem( FromClauseItem fromClauseItem, SemanticResolver sr )
        { 
            DbExpressionBinding fromItemBinding = null;
 
            AliasExpr aliasExpr = fromClauseItem.FromExpr as AliasExpr; 
            if (null != aliasExpr)
            { 
                fromItemBinding = ProcessAliasedFromClauseItem(aliasExpr, sr);
            }
            else
            { 
                JoinClauseItem joinClauseItem = fromClauseItem.FromExpr as JoinClauseItem;
                if (null != joinClauseItem) 
                { 
                    fromItemBinding = ProcessJoinClauseItem(joinClauseItem, sr);
                } 
                else
                {
                    fromItemBinding = ProcessApplyClauseItem((ApplyClauseItem)fromClauseItem.FromExpr, sr);
                } 
            }
 
            Debug.Assert(null != fromItemBinding,"null != fromItemBinding"); 

            return fromItemBinding; 
        }


        ///  
        /// Process 'Simple' From Clause Item
        ///  
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        ///  
        private static DbExpressionBinding ProcessAliasedFromClauseItem( AliasExpr aliasedExpr, SemanticResolver sr )
        {
            DbExpressionBinding aliasedBinding = null;
 
            //
            // converts from item expression 
            // 
            DbExpression converted = Convert(aliasedExpr.Expr, sr);
 
            //
            // ensure expression is typed
            //
            SemanticResolver.EnsureIsNotUntypedNull(converted, aliasedExpr.Expr.ErrCtx); 

            // 
            // validate it is of sequence type (Extent || ICollection) 
            //
            if (!TypeSemantics.IsCollectionType(converted.ResultType)) 
            {
                throw EntityUtil.EntitySqlError(aliasedExpr.Expr.ErrCtx, System.Data.Entity.Strings.ExpressionMustBeCollection);
            }
 
            //
            // infer source var alias name 
            // 
            string aliasName = sr.InferAliasName(aliasedExpr, converted);
 
            //
            // validate the name was not used yet.
            //
            if (sr.IsInCurrentScope(aliasName)) 
            {
                if (aliasedExpr.HasAlias) 
                { 
                    CqlErrorHelper.ReportAliasAlreadyUsedError(aliasName, aliasedExpr.AliasIdentifier.ErrCtx, System.Data.Entity.Strings.InFromClause);
                } 
                else
                {
                    aliasName = sr.GenerateInternalName("autoFrom");
                } 
            }
 
            // 
            // create cqt expression
            // 
            aliasedBinding = sr.CmdTree.CreateExpressionBinding(converted, aliasName);

            //
            // add source var to scope 
            //
            sr.AddSourceBinding(aliasedBinding); 
 
            Debug.Assert(null != aliasedBinding,"null != aliasedBinding");
 
            return aliasedBinding;
        }

 
        /// 
        /// process join clause item 
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static DbExpressionBinding ProcessJoinClauseItem( JoinClauseItem joinClause, SemanticResolver sr )
        {
            DbExpressionBinding joinBinding = null; 

            // 
            // make sure inner join have on predicate AND cross join has no ON predicate 
            //
            if (null == joinClause.OnExpr) 
            {
                if (JoinKind.Inner == joinClause.JoinKind)
                {
                    throw EntityUtil.EntitySqlError(joinClause.ErrCtx, System.Data.Entity.Strings.InnerJoinMustHaveOnPredicate); 
                }
            } 
            else 
            {
                if (JoinKind.Cross == joinClause.JoinKind) 
                {
                    throw EntityUtil.EntitySqlError(joinClause.OnExpr.ErrCtx, System.Data.Entity.Strings.InvalidPredicateForCrossJoin);
                }
            } 

            // 
            // Resolve Left Expression 
            //
            sr.CurrentScopeRegionFlags.PathTagger.VisitLeftNode(); 
            DbExpressionBinding leftBindingExpr = ProcessFromClauseItem(joinClause.LeftExpr, sr);
            sr.CurrentScopeRegionFlags.PathTagger.LeaveNode();

            // 
            // Resolve Right Expression
            // 
            sr.CurrentScopeRegionFlags.IsInsideJoinOnPredicate = false; 
            sr.CurrentScopeRegionFlags.PathTagger.VisitRightNode();
            DbExpressionBinding rightBindingExpr = ProcessFromClauseItem(joinClause.RightExpr, sr); 
            sr.CurrentScopeRegionFlags.PathTagger.LeaveNode();

            //
            // convert right outer to left outer 
            //
            if (joinClause.JoinKind == JoinKind.RightOuter) 
            { 
                joinClause.JoinKind = JoinKind.LeftOuter;
                DbExpressionBinding tmpExpr = leftBindingExpr; 
                leftBindingExpr = rightBindingExpr;
                rightBindingExpr = tmpExpr;
            }
 
            //
            // Resolve JoinType 
            // 
            DbExpressionKind joinKind = SemanticResolver.MapJoinKind(joinClause.JoinKind);
 
            //
            // Resolve ON
            //
            sr.CurrentScopeRegionFlags.IsInsideJoinOnPredicate = true; 
            DbExpression onExpr = null;
            if (null == joinClause.OnExpr) 
            { 
                if (DbExpressionKind.CrossJoin != joinKind)
                { 
                    onExpr = sr.CmdTree.CreateTrueExpression();
                }
            }
            else 
            {
                onExpr = Convert(joinClause.OnExpr, sr); 
 
                //
                // ensure expression is typed 
                //
                SemanticResolver.EnsureIsNotUntypedNull(onExpr, joinClause.OnExpr.ErrCtx);
            }
            sr.CurrentScopeRegionFlags.IsInsideJoinOnPredicate = false; 

            // 
            // Create New Join 
            //
            joinBinding = sr.CmdTree.CreateExpressionBinding( 
                                        sr.CmdTree.CreateJoinExpressionByKind(joinKind, onExpr, leftBindingExpr, rightBindingExpr),
                                        sr.GenerateInternalName("join"));

            // 
            // Fixup Join Source Vars in Scope
            // 
            sr.FixupNamedSourceVarBindings(joinBinding.Variable); 

            Debug.Assert(null != joinBinding,"null != joinBinding"); 

            return joinBinding;
        }
 

        ///  
        /// Process apply clause item 
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpressionBinding ProcessApplyClauseItem( ApplyClauseItem applyClause, SemanticResolver sr )
        { 
            DbExpressionBinding applyBinding = null;
 
            // 
            // Resolve Left Expression
            // 
            sr.CurrentScopeRegionFlags.PathTagger.VisitLeftNode();
            DbExpressionBinding leftBindingExpr = ProcessFromClauseItem(applyClause.LeftExpr, sr);
            sr.CurrentScopeRegionFlags.PathTagger.LeaveNode();
 
            //
            // Resolve Right Expression 
            // 
            sr.CurrentScopeRegionFlags.PathTagger.VisitRightNode();
            DbExpressionBinding rightBindingExpr = ProcessFromClauseItem(applyClause.RightExpr, sr); 
            sr.CurrentScopeRegionFlags.PathTagger.LeaveNode();

            //
            // Create Apply 
            //
            applyBinding = sr.CmdTree.CreateExpressionBinding( 
                                sr.CmdTree.CreateApplyExpressionByKind(SemanticResolver.MapApplyKind(applyClause.ApplyKind), 
                                                 leftBindingExpr,
                                                 rightBindingExpr), 
                                sr.GenerateInternalName("apply"));

            //
            // Fixup Apply Source Vars in Scope 
            //
            sr.FixupNamedSourceVarBindings(applyBinding.Variable); 
 
            Debug.Assert(null != applyBinding,"null != applyBinding");
 
            return applyBinding;
        }

 

        ///  
        /// Process Where Expression 
        /// 
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system
        /// 
        private static DbExpressionBinding ProcessWhereClause( DbExpressionBinding source, Expr whereClause, SemanticResolver sr ) 
        {
            if (null == whereClause) 
            { 
                return source;
            } 

            DbExpressionBinding whereBinding = null;

            // 
            // Convert Where Condition
            // 
            DbExpression filterConditionExpr = Convert(whereClause, sr); 

            // 
            // ensure expression is typed
            //
            SemanticResolver.EnsureIsNotUntypedNull(filterConditionExpr, whereClause.ErrCtx);
 
            //
            // ensure the predicate type is boolean 
            // 
            if (!TypeResolver.IsBooleanType(filterConditionExpr.ResultType))
            { 
                throw EntityUtil.EntitySqlError(whereClause.ErrCtx, System.Data.Entity.Strings.ExpressionTypeMustBeBoolean);
            }

            // 
            // Create New Filter Binding
            // 
            whereBinding = sr.CmdTree.CreateExpressionBinding( 
                                sr.CmdTree.CreateFilterExpression(source, filterConditionExpr),
                                sr.GenerateInternalName("where")); 

            //
            // Fixup Bindings
            // 
            sr.FixupSourceVarBindings(whereBinding.Variable);
 
            Debug.Assert(null != whereBinding,"null != whereBinding"); 

            return whereBinding; 
        }


        ///  
        /// Process Group By Clause
        ///  
        ///  
        /// 
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static DbExpressionBinding ProcessGroupByClause( DbExpressionBinding source, QueryExpr queryExpr, SemanticResolver sr )
        {
            SemanticResolver.ScopeViewKind saveScopeView = sr.GetScopeView(); 

            GroupByClause groupByClause = queryExpr.GroupByClause; 
 
            Debug.Assert((sr.ParserOptions.ParserCompilationMode == ParserOptions.CompilationMode.RestrictedViewGenerationMode) ? null == groupByClause : true, "GROUP BY clause must be null in RestrictedViewGenerationMode");
 
            //
            // if group expression is null, create a dummy and speculate that there are group aggregates in the remaining query expression
            // if no group aggregate if found after partial evaluation of Having, OrderBy and Select in the 1st pass, rollback what we did
            // and return source expression. 
            //
            #region Define Implicit Group if needed 
            if (null == queryExpr.GroupByClause) 
            {
                if (!queryExpr.HasMethodCall) 
                {
                    return source;
                }
 
                //
                // if group expression is null create a dummy and speculate that there are group aggregates in the remaining query expression 
                // if no group aggregate if found after partial evaluation of Having, OrderBy and Select in the 1st pass, rollback what we did 
                // and return source expression.
                // 
                sr.CurrentScopeRegionFlags.IsImplicitGroup = true;

            }
            else 
            {
                sr.CurrentScopeRegionFlags.IsImplicitGroup = false; 
            } 
            #endregion
 
            DbExpressionBinding groupBinding = null;

            //
            // Create Group Binding 
            //
            DbGroupExpressionBinding groupExprBinding = sr.CmdTree.CreateGroupExpressionBinding( 
                                                                        source.Expression, 
                                                                        sr.GenerateInternalName("geb"),
                                                                        sr.GenerateInternalName("group")); 
            //
            // Update source scope vars
            //
            sr.FixupGroupSourceVarBindings(groupExprBinding.Variable, groupExprBinding.GroupVariable); 

            // 
            // convert group elements 
            //
            #region Convert Group Key/Expressions 
            int groupKeysCount = (null != groupByClause ) ? groupByClause.GroupItems.Count : 0;
            List> groupKeys = new List>(groupKeysCount);
            HashSet groupKeyNames = new HashSet(sr.ScopeStringComparer);
            List groupKeysForAggregates = new List(8); 
            if (!sr.CurrentScopeRegionFlags.IsImplicitGroup)
            { 
                Debug.Assert(null != groupByClause, "groupByClause must not be null at this point"); 
                for (int i = 0 ; i < groupKeysCount ; i++)
                { 
                    AliasExpr aliasedExpr = groupByClause.GroupItems[i];

                    sr.ResetScopeRegionCorrelationFlag();
 
                    //
                    // convert key expression (relative to DbGroupExpressionBinding.Var) 
                    // 
                    DbExpression converted = Convert(aliasedExpr.Expr, sr);
 
                    //
                    // ensure expression is typed
                    //
                    SemanticResolver.EnsureIsNotUntypedNull(converted, aliasedExpr.Expr.ErrCtx); 

                    // 
                    // ensure group key expression is correlated 
                    //
                    if (!sr.CurrentScopeRegionFlags.WasResolutionCorrelated) 
                    {
                        throw EntityUtil.EntitySqlError(aliasedExpr.Expr.ErrCtx, System.Data.Entity.Strings.KeyMustBeCorrelated("GROUP BY"));
                    }
 
                    //
                    // convert key expression (relative to DbGroupExpressionBinding.GroupVar) 
                    // this is only needed because during the search for groupaggregates, group aggregates may 
                    // refer to group keys.
                    // 
                    sr.CurrentScopeRegionFlags.IsInsideGroupAggregate = true;

                    DbExpression groupKeyAggExpr = Convert(aliasedExpr.Expr, sr);
 
                    groupKeysForAggregates.Add(groupKeyAggExpr);
 
                    sr.CurrentScopeRegionFlags.IsInsideGroupAggregate = false; 

                    // 
                    // ensure keys are valid
                    //
                    if (!TypeHelpers.IsValidGroupKeyType(converted.ResultType))
                    { 
                        throw EntityUtil.EntitySqlError(aliasedExpr.Expr.ErrCtx, System.Data.Entity.Strings.GroupingKeysMustBeEqualComparable);
                    } 
 
                    //
                    // infer alias name 
                    //
                    string groupKeyAlias = sr.InferAliasName(aliasedExpr, converted);

                    // 
                    // check if alias was already used
                    // 
                    if (groupKeyNames.Contains(groupKeyAlias)) 
                    {
                        if (aliasedExpr.HasAlias) 
                        {
                            CqlErrorHelper.ReportAliasAlreadyUsedError(groupKeyAlias, aliasedExpr.AliasIdentifier.ErrCtx, System.Data.Entity.Strings.InGroupClause);
                        }
                        else 
                        {
                            groupKeyAlias = sr.GenerateInternalName("autoGroup"); 
                        } 
                    }
 
                    //
                    // add key name to alias dictionary
                    //
                    groupKeyNames.Add(groupKeyAlias); 

                    // 
                    // add key to keys collection 
                    //
                    groupKeys.Add(new KeyValuePair(groupKeyAlias, converted)); 

                    //
                    // group keys should visible by their 'original' key expression name. All forms should be allowed:
                    //   SELECT k FROM ... as p GROUP BY p.Price as k (explicit key alias) - handled above by InferAliasName() 
                    //   SELECT Price FROM ... as p GROUP BY p.Price (implicit alias - leading name) - handled above by InferAliasName()
                    //   SELECT p.Price FROM ... as p GROUP BY p.Price (original key expression) - case handled in the code bellow 
                    // 
                    if (!aliasedExpr.HasAlias)
                    { 
                        DotExpr dotExpr = aliasedExpr.Expr as DotExpr;
                        if (null != dotExpr && dotExpr.IsDottedIdentifier)
                        {
                            groupKeyAlias = dotExpr.FullName; 

                            if (groupKeyNames.Contains(groupKeyAlias)) 
                            { 
                                CqlErrorHelper.ReportAliasAlreadyUsedError(groupKeyAlias, dotExpr.ErrCtx, System.Data.Entity.Strings.InGroupClause);
                            } 

                            groupKeyNames.Add(groupKeyAlias);

                            groupKeys.Add(new KeyValuePair(groupKeyAlias, converted)); 

                            groupKeysForAggregates.Add(groupKeyAggExpr); 
                        } 
                    }
                } 
            }
            #endregion

            // 
            // save scope status
            // 
            SavePoint savePoint = sr.CreateSavePoint(); 

            // 
            // Push Group scope
            //
            sr.EnterScope();
 
            //
            // Add converted group variables/expressions to group scope 
            // 
            #region Add Converted Group Variables to Scope
            // 
            // add 'dummy' keys to scope.
            // this is needed since during the aggreagate search phase, keys may be referenced.
            //
            for (int i = 0 ; i < groupKeys.Count ; i++) 
            {
                sr.AddDummyGroupKeyToScope(groupKeys[i].Key, groupKeys[i].Value, groupKeysForAggregates[i]); 
            } 

            // 
            // flags that we are inside a group scope
            //
            sr.CurrentScopeRegionFlags.IsInGroupScope = true;
            #endregion 

            // 
            // Convert/Search Aggregates 
            // since aggregates can be defined in Having, OrderBy and/or Select clauses must be resolved as part of the group expression.
            // The resolution of these clauses result in potential collection of resolved group aggregates and the actual resulting 
            // expression is ignored. These clauses will be then resolved as usual on a second pass.
            //

            #region Search for group Aggregates 
            //
            // search for aggregates in HAVING clause 
            // 
            if (null != queryExpr.HavingClause && queryExpr.HavingClause.HasMethodCall)
            { 
                sr.CurrentScopeRegionFlags.ResetGroupAggregateNestingCount();

                DbExpression converted = Convert(queryExpr.HavingClause.HavingPredicate, sr);
 
                //
                // ensure expression is typed 
                // 
                SemanticResolver.EnsureIsNotUntypedNull(converted, queryExpr.HavingClause.ErrCtx);
            } 

            //
            // search for aggregates in SELECT clause
            // 
            Dictionary sortExpr = null;
            if ( null != queryExpr.OrderByClause || queryExpr.SelectClause.HasMethodCall ) 
            { 
                sortExpr = new Dictionary(queryExpr.SelectClause.Items.Count, sr.ScopeStringComparer);
                for ( int i = 0 ; i < queryExpr.SelectClause.Items.Count ; i++ ) 
                {
                    AliasExpr aliasedExpr = queryExpr.SelectClause.Items[i];

                    // 
                    // Reset Group aggregate nesting count
                    // 
                    sr.CurrentScopeRegionFlags.ResetGroupAggregateNestingCount(); 

                    // 
                    // convert projection item expression
                    //
                    DbExpression converted = Convert(aliasedExpr.Expr, sr);
 
                    //
                    // ensure expression is typed 
                    // 
                    SemanticResolver.EnsureIsNotUntypedNull(converted, aliasedExpr.Expr.ErrCtx);
 
                    //
                    // create Null Expression with actual type
                    //
                    converted = sr.CmdTree.CreateNullExpression(converted.ResultType); 

                    // 
                    // infer alias 
                    //
                    string aliasName = sr.InferAliasName(aliasedExpr, converted); 

                    if ( sortExpr.ContainsKey(aliasName) )
                    {
                        if ( aliasedExpr.HasAlias ) 
                        {
                            CqlErrorHelper.ReportAliasAlreadyUsedError(aliasName, 
                                                                       aliasedExpr.AliasIdentifier.ErrCtx, 
                                                                       System.Data.Entity.Strings.InSelectProjectionList);
                        } 
                        else
                        {
                            aliasName = sr.GenerateInternalName("autoProject");
                        } 
                    }
 
                    sortExpr.Add(aliasName, converted); 
                }
            } 

            //
            // search for aggregates in ORDER BY clause
            // 
            if (null != queryExpr.OrderByClause && queryExpr.OrderByClause.HasMethodCall)
            { 
                // 
                // push projection key scope
                // 
                sr.EnterScope();

                //
                // Add projection items to scope (it may be used in ORDER BY) 
                //
                foreach ( KeyValuePair kvp in sortExpr ) 
                { 
                    sr.AddToScope(kvp.Key, new ProjectionScopeEntry(kvp.Key, kvp.Value));
                } 

                //
                // search for aggregates in ORDER BY clause
                // 
                for (int i = 0 ; i < queryExpr.OrderByClause.OrderByClauseItem.Count ; i++)
                { 
                    OrderByClauseItem orderItem = queryExpr.OrderByClause.OrderByClauseItem[i]; 

                    sr.CurrentScopeRegionFlags.ResetGroupAggregateNestingCount(); 

                    sr.ResetScopeRegionCorrelationFlag();

                    DbExpression converted = Convert(orderItem.OrderExpr, sr); 

                    // 
                    // ensure expression is typed 
                    //
                    SemanticResolver.EnsureIsNotUntypedNull(converted, orderItem.OrderExpr.ErrCtx); 

                    //
                    // ensure key expression is correlated
                    // 
                    if (!sr.CurrentScopeRegionFlags.WasResolutionCorrelated)
                    { 
                        throw EntityUtil.EntitySqlError(orderItem.ErrCtx, System.Data.Entity.Strings.KeyMustBeCorrelated("ORDER BY")); 
                    }
                } 

                //
                // pop projection scope
                // 
                sr.LeaveScope();
            } 
            #endregion 

            // 
            // if we introduced a fake group but did not 'found' any group aggregate
            // on the first pass, then there is no need for creating an implicit group.
            // rollback to the status before entering ProcessGroupByClause().
            // if we did find group aggregates, make sure all non-group aggregate function 
            // expressions refer to group scope variables only
            // 
            #region Implicit Group Rollback 
            if (sr.CurrentScopeRegionFlags.IsImplicitGroup)
            { 
                if (0 == sr.CurrentScopeRegionFlags.GroupAggregatesInfo.Count)
                {
                    //
                    // rolls back scope status 
                    //
                    sr.RollbackToSavepoint(savePoint); 
 
                    //
                    // undo any group source fixups, re-applying the source var 
                    //
                    sr.UndoFixupGroupSourceVarBindings(source.Variable);

                    // 
                    // reset is inside group scope flag
                    // 
                    sr.CurrentScopeRegionFlags.IsInGroupScope = false; 

                    //// 
                    //// reset implict group flag
                    ////
                    sr.CurrentScopeRegionFlags.IsImplicitGroup = false;
 
                    //
                    // restore scope view kind 
                    // 
                    sr.SetScopeView(saveScopeView);
 
                    //
                    // return the original source var binding
                    //
                    return source; 
                }
 
                // 
                // now that we know that there are group aggregates in other expression, reset implict group flag to false
                // since it is now considered a legitimate group 
                //
                sr.CurrentScopeRegionFlags.IsImplicitGroup = false;
            }
            #endregion 

            // 
            // extract list of aggregates and names 
            //
            List> aggregates = new List>(sr.CurrentScopeRegionFlags.GroupAggregatesInfo.Count); 
            foreach(KeyValuePair kvp in sr.CurrentScopeRegionFlags.GroupAggregatesInfo)
            {
                aggregates.Add(new KeyValuePair(kvp.Value.AggregateName, kvp.Value.AggregateExpression));
                kvp.Key.ResetDummyExpression(); 
            }
 
            // 
            // Create Group Expression
            // 
            groupBinding = sr.CmdTree.CreateExpressionBinding(
                                                    sr.CmdTree.CreateGroupByExpression(
                                                                        groupExprBinding,
                                                                        groupKeys, 
                                                                        aggregates),
                                                    sr.GenerateInternalName("group")); 
 
            //
            // replace dummy keys with real keys 
            //
            for (int i = 0 ; i < groupKeys.Count ; i++)
            {
                sr.ReplaceGroupVarInScope(groupKeys[i].Key, groupBinding.Variable); 
            }
 
            // 
            // add aggregates to scope
            // 
            for (int i = 0 ; i < aggregates.Count ; i++ )
            {
                sr.CurrentScopeRegionFlags.AddGroupAggregateToScopeFlags(aggregates[i].Key);
 
                sr.AddGroupAggregateToScope(aggregates[i].Key, groupBinding.Variable);
            } 
 
            //
            // restrict group scope visibility 
            //
            sr.SetScopeView(SemanticResolver.ScopeViewKind.GroupScope);

            // 
            // fixup all source vars
            // 
            sr.FixupNamedSourceVarBindings(groupBinding.Variable); 

            // 
            // Mark source vars as group input vars
            //
            sr.MarkGroupInputVars();
 
            Debug.Assert(null != groupBinding,"null != groupBinding");
 
            return groupBinding; 
        }
 

        /// 
        /// Process Having Clause
        ///  
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static DbExpressionBinding ProcessHavingClause( DbExpressionBinding source, HavingClause havingClause, SemanticResolver sr ) 
        {
            Debug.Assert((sr.ParserOptions.ParserCompilationMode == ParserOptions.CompilationMode.RestrictedViewGenerationMode) ? null == havingClause : true, "HAVING clause must be null in RestrictedViewGenerationMode");

            if (null == havingClause) 
            {
                return source; 
            } 

            DbExpressionBinding havingBinding = null; 

            //
            // Convert Having Expression
            // 
            DbExpression filterConditionExpr = Convert(havingClause.HavingPredicate, sr);
 
            // 
            // ensure expression is typed
            // 
            SemanticResolver.EnsureIsNotUntypedNull(filterConditionExpr, havingClause.ErrCtx);

            //
            // ensure having predicate of boolean type 
            //
            if (!TypeResolver.IsBooleanType(filterConditionExpr.ResultType)) 
            { 
                throw EntityUtil.EntitySqlError(havingClause.ErrCtx, System.Data.Entity.Strings.ExpressionTypeMustBeBoolean);
            } 

            //
            // Create New Filter Binding
            // 
            havingBinding = sr.CmdTree.CreateExpressionBinding(
                                            sr.CmdTree.CreateFilterExpression(source, filterConditionExpr), 
                                            sr.GenerateInternalName("having")); 

            // 
            // Fixup Bindings
            //
            sr.FixupSourceVarBindings(havingBinding.Variable);
 
            Debug.Assert(null != havingBinding,"null != havingBinding");
 
            return havingBinding; 
        }
 

        /// 
        /// Process Order By Clause
        ///  
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system 
        /// 
        private static DbExpressionBinding ProcessOrderByClause( DbExpressionBinding source, QueryExpr queryExpr, SemanticResolver sr ) 
        {
            Debug.Assert((sr.ParserOptions.ParserCompilationMode == ParserOptions.CompilationMode.RestrictedViewGenerationMode) ? null == queryExpr.OrderByClause : true, "ORDER BY clause must be null in RestrictedViewGenerationMode");

            if (null == queryExpr.OrderByClause) 
            {
                return source; 
            } 

            DbExpressionBinding sortBinding = null; 
            OrderByClause orderByClause = queryExpr.OrderByClause;
            SelectClause selectClause = queryExpr.SelectClause;

            // 
            // Create a savepoint
            // 
            SavePoint savePoint = sr.CreateSavePoint(); 

            // 
            // perform partial conversion of SELECT statements
            //
            Dictionary projectionExpressions = new Dictionary(selectClause.Items.Count, sr.ScopeStringComparer);
            for (int i = 0 ; i < selectClause.Items.Count ; i++) 
            {
                AliasExpr aliasedExpr = selectClause.Items[i]; 
 
                DbExpression converted = Convert(aliasedExpr.Expr, sr);
 
                //
                // ensure expression is typed
                //
                SemanticResolver.EnsureIsNotUntypedNull(converted, aliasedExpr.Expr.ErrCtx); 

                // 
                // infer projection alias 
                //
                string aliasName = sr.InferAliasName(aliasedExpr, converted); 

                if (projectionExpressions.ContainsKey(aliasName))
                {
                    if (aliasedExpr.HasAlias) 
                    {
                        CqlErrorHelper.ReportAliasAlreadyUsedError(aliasName, aliasedExpr.AliasIdentifier.ErrCtx, System.Data.Entity.Strings.InSelectProjectionList); 
                    } 
                    else
                    { 
                        aliasName = sr.GenerateInternalName("autoProject");
                    }
                }
 
                projectionExpressions.Add(aliasName, converted);
            } 
 
            //
            // convert paging sub-clauses they if exists before adding projection list to scope 
            // NOTE: TOP, LIMIT and SKIP have nearly the same constraints in M3.2. in the future this is likely to change by allowing
            // these sub-clauses to have generic expressions.
            //
            #region Handles SKIP sub-clause 
            DbExpression skipExpr = null;
            if (orderByClause.HasSkipSubClause) 
            { 
                skipExpr = Convert(orderByClause.SkipSubClause, sr);
 
                //
                // ensure is not NULL expr
                //
                SemanticResolver.EnsureIsNotUntypedNull(skipExpr, orderByClause.SkipSubClause.ErrCtx); 

                DbConstantExpression constantExpr = skipExpr as DbConstantExpression; 
 
                Debug.Assert(constantExpr!=null || skipExpr is DbParameterReferenceExpression, "SKIP inner expression must be a parameter or numeric literal in this release");
 
                //
                // ensure SKIP expression have the right type
                //
                if (!TypeSemantics.IsPromotableTo(skipExpr.ResultType, sr.TypeResolver.Int64Type)) 
                {
                    throw EntityUtil.EntitySqlError(orderByClause.SkipSubClause.ErrCtx, System.Data.Entity.Strings.PlaceholderExpressionMustBeCompatibleWithEdm64("SKIP", skipExpr.ResultType.EdmType.FullName)); 
                } 

                // 
                // if it is a literal, make sure it has the correct value
                //
                if (null != constantExpr && System.Convert.ToInt64(constantExpr.Value, CultureInfo.InvariantCulture) < 0)
                { 
                    throw EntityUtil.EntitySqlError(orderByClause.SkipSubClause.ErrCtx, System.Data.Entity.Strings.PlaceholderExpressionMustBeGreaterThanOrEqualToZero("SKIP"));
                } 
 

            } 
            #endregion

            //
            // Push scope for projection items 
            //
            sr.EnterScope(); 
 
            //
            // Add projection items to scope 
            //
            foreach (KeyValuePair kvp in projectionExpressions)
            {
                // 
                // if the reference expression is a group aggregate, then there is no need to add to scope
                // 
                if (!sr.CurrentScopeRegionFlags.ContainsGroupAggregate(kvp.Key)) 
                {
                    sr.AddToScope(kvp.Key, new ProjectionScopeEntry(kvp.Key, kvp.Value)); 
                }
            }

            // 
            // save scope view
            // 
            SemanticResolver.ScopeViewKind saveScopeView = sr.GetScopeView(); 

            // 
            // If DISTICT was especified set visibility to current scope only
            // if DISTINCT modifier is present, push the projection and distinct expression down bellow
            // sort/skip expressions
            // 
            if (selectClause.DistinctKind == DistinctKind.Distinct)
            { 
                sr.SetScopeView(SemanticResolver.ScopeViewKind.CurrentScope); 

                List> projectionExpressionList = new List>(projectionExpressions); 

                //
                // Create projection
                // 
                DbExpression projectExpression;
                if (selectClause.SelectKind == SelectKind.SelectRow) 
                { 
                    projectExpression = sr.CmdTree.CreateNewRowExpression(projectionExpressionList);
                } 
                else
                {
                    Debug.Assert(selectClause.Items.Count == 1, "SELECT VALUE must have only one argument");
                    projectExpression = projectionExpressionList[0].Value; 
                }
                projectExpression = sr.CmdTree.CreateProjectExpression(source, projectExpression); 
 
                //
                // Ensure Projection is valid for DISTINCT modifier 
                //
                SemanticResolver.ValidateDistinctProjection(selectClause, projectExpression.ResultType);

                // 
                // create new source binding
                // 
                source = sr.CmdTree.CreateExpressionBinding(sr.CmdTree.CreateDistinctExpression(projectExpression), 
                                                            sr.GenerateInternalName("distinct"));
 
                //
                // replace Projection scope with new expression bindings
                //
                for (int i = 0; i < projectionExpressionList.Count; i++) 
                {
                    if (!sr.CurrentScopeRegionFlags.ContainsGroupAggregate(projectionExpressionList[i].Key)) 
                    { 
                        // remove old scope var
                        sr.RemoveFromScope(projectionExpressionList[i].Key); 

                        // create and add new source var to scope
                        SourceScopeEntry sce = new SourceScopeEntry(ScopeEntryKind.SourceVar, projectionExpressionList[i].Key, source.Variable);
                        if (selectClause.SelectKind == SelectKind.SelectRow) 
                        {
                            sce.AddBindingPrefix(projectionExpressionList[i].Key); 
                        } 
                        sr.AddToScope(projectionExpressionList[i].Key, sce);
                    } 
                }
            }

            // 
            // if is not DISTINCT, but is a group scope, then should be the group scope and the
            // projection list 
            // 
            else if (sr.CurrentScopeRegionFlags.IsInGroupScope)
            { 
                sr.SetScopeView(SemanticResolver.ScopeViewKind.CurrentAndPreviousScope);
            }

            // 
            // convert sort keys
            // 
            List sortKeys = new List(orderByClause.OrderByClauseItem.Expressions.Count); 
            for (int i = 0 ; i < orderByClause.OrderByClauseItem.Expressions.Count ; i++)
            { 
                OrderByClauseItem orderClauseItem = orderByClause.OrderByClauseItem.Expressions[i];

                sr.CurrentScopeRegionFlags.ResetGroupAggregateNestingCount();
 
                sr.ResetScopeRegionCorrelationFlag();
 
                // 
                // convert order key expression
                // 
                DbExpression keyExpr = Convert(orderClauseItem.OrderExpr, sr);

                //
                // ensure expression is typed 
                //
                SemanticResolver.EnsureIsNotUntypedNull(keyExpr, orderClauseItem.OrderExpr.ErrCtx); 
 
                //
                // ensure key expression is correlated. if group by is present, then the check was already performed 
                //
                if (!sr.CurrentScopeRegionFlags.WasResolutionCorrelated)
                {
                    throw EntityUtil.EntitySqlError(orderClauseItem.ErrCtx, System.Data.Entity.Strings.KeyMustBeCorrelated("ORDER BY")); 
                }
 
                // 
                // ensure key is order comparable
                // 
                if (!TypeHelpers.IsValidSortOpKeyType(keyExpr.ResultType))
                {
                    throw EntityUtil.EntitySqlError(orderClauseItem.OrderExpr.ErrCtx, System.Data.Entity.Strings.OrderByKeyIsNotOrderComparable);
                } 

                // 
                // define order 
                //
                bool ascSort = (orderClauseItem.OrderKind == OrderKind.None) || (orderClauseItem.OrderKind == OrderKind.Asc); 

                //
                // define collation
                // 
                string collation = null;
                if (orderClauseItem.IsCollated) 
                { 
                    if (!TypeResolver.IsKeyValidForCollation(keyExpr.ResultType))
                    { 
                        throw EntityUtil.EntitySqlError(orderClauseItem.OrderExpr.ErrCtx, System.Data.Entity.Strings.InvalidKeyTypeForCollation(keyExpr.ResultType.EdmType.FullName));
                    }

                    collation = orderClauseItem.CollateIdentifier.Name; 
                }
                // 
                // if orderby has no collation defined, check if a default was given through ParserOptions 
                //
                else if (sr.ParserOptions.DefaultOrderByCollation.Length > 0 && TypeResolver.IsKeyValidForCollation(keyExpr.ResultType)) 
                {
                    collation = sr.ParserOptions.DefaultOrderByCollation;
                }
 
                //
                // add keys to key collection 
                // 
                if (string.IsNullOrEmpty(collation))
                { 
                    sortKeys.Add(sr.CmdTree.CreateSortClause(keyExpr, ascSort));
                }
                else
                { 
                    sortKeys.Add(sr.CmdTree.CreateSortClause(keyExpr, ascSort, collation));
                } 
            } 
            DbExpression sortSourceExpr = null;
            if (orderByClause.HasSkipSubClause) 
            {
                sortSourceExpr = sr.CmdTree.CreateSkipExpression(source, sortKeys, skipExpr);
            }
            else 
            {
                sortSourceExpr = sr.CmdTree.CreateSortExpression(source, sortKeys); 
            } 

            // 
            // Create Sort Binding
            //
            sortBinding = sr.CmdTree.CreateExpressionBinding(
                                        sortSourceExpr, 
                                        sr.GenerateInternalName("sort"));
 
            // 
            // Fixup Bindings
            // 
            sr.FixupSourceVarBindings(sortBinding.Variable);

            //
            // pops projection keys from scope 
            //
            sr.RollbackToSavepoint(savePoint); 
 
            //
            // restore scope view 
            //
            sr.SetScopeView(saveScopeView);

            Debug.Assert(null != sortBinding,"null != sortBinding"); 

            return sortBinding; 
        } 

 
        /// 
        /// Converts a list of ast expression nodes
        /// 
        ///  
        /// SemanticResolver instance relative to a especif typespace/system
        ///  
        private static PairOfLists ProcessExprList( ExprList astExprList, SemanticResolver sr ) 
        {
            List types = new List(astExprList.Count); 
            List convertedExprs = new List(astExprList.Count);

            for (int i = 0 ; i < astExprList.Count ; i++)
            { 
                DbExpression e = Convert(astExprList[i], sr);
                types.Add(e.ResultType); 
                convertedExprs.Add(e); 
            }
 
            return new PairOfLists(types, convertedExprs);
        }

 
        /// 
        /// [....]: Temporary workaround for 2/3 milestone. 
        /// Convert "x in multiset(y1, y2, ..., yn)" into 
        /// x = y1 or x = y2 or x = y3 ...
        ///  
        /// semantic resolver
        /// left-expression (the probe)
        /// right expression (the collection)
        /// Or chain of equality comparisons 
        private static DbExpression ConvertSimpleInExpression( SemanticResolver sr, DbExpression left, DbExpression right )
        { 
            // Only handle cases when the right-side is a new instance expression 
            Debug.Assert(right.ExpressionKind == DbExpressionKind.NewInstance,"right.ExpressionKind == DbExpressionKind.NewInstance");
            DbNewInstanceExpression rightColl = (DbNewInstanceExpression)right; 

            if (rightColl.Arguments.Count == 0)
            {
                return sr.CmdTree.CreateConstantExpression(false); 
            }
 
            DbExpression orExpr = null; 
            foreach (DbExpression e in rightColl.Arguments)
            { 
                DbExpression leftClone = (DbExpression)left.Clone();

                DbExpression eqExpr = sr.CmdTree.CreateEqualsExpression(leftClone, e);
 
                if (orExpr == null)
                { 
                    orExpr = eqExpr; 
                }
                else 
                {
                    orExpr = sr.CmdTree.CreateOrExpression(orExpr, eqExpr);
                }
            } 

            return orExpr; 
        } 

        #region Conversion Delegate Mappings 

        private delegate DbExpression AstExprConverter( Expr astExpr, SemanticResolver sr );
        private static readonly Dictionary _astExprConverters = CreateAstExprConverters();
        private delegate DbExpression BuiltInExprConverter( BuiltInExpr astBltInExpr, SemanticResolver sr ); 
        private static readonly Dictionary _builtInExprConverter = CreateBuiltInExprConverter();
 
        #region Define converter delegates 

        private static Dictionary CreateAstExprConverters() 
        {
            const int NumberOfElements = 15;  // number of elements initialized by the dictionary
            Dictionary astExprConverters = new Dictionary(NumberOfElements);
            astExprConverters.Add(typeof(Literal), new AstExprConverter(ConvertLiteral)); 
            astExprConverters.Add(typeof(Parameter), new AstExprConverter(ConvertParameter));
            astExprConverters.Add(typeof(Identifier), new AstExprConverter(ConvertIdentifier)); 
            astExprConverters.Add(typeof(DotExpr), new AstExprConverter(ConvertDotExpr)); 
            astExprConverters.Add(typeof(BuiltInExpr), new AstExprConverter(ConvertBuiltIn));
            astExprConverters.Add(typeof(QueryExpr), new AstExprConverter(ConvertQuery)); 
            astExprConverters.Add(typeof(RowConstructorExpr), new AstExprConverter(ConvertRowConstructor));
            astExprConverters.Add(typeof(MultisetConstructorExpr), new AstExprConverter(ConvertMultisetConstructor));
            astExprConverters.Add(typeof(CaseExpr), new AstExprConverter(ConvertCaseExpr));
            astExprConverters.Add(typeof(RelshipNavigationExpr), new AstExprConverter(ConvertRelshipNavigationExpr)); 
            astExprConverters.Add(typeof(RefExpr), new AstExprConverter(ConvertRefExpr));
            astExprConverters.Add(typeof(DerefExpr), new AstExprConverter(ConvertDeRefExpr)); 
            astExprConverters.Add(typeof(MethodExpr), new AstExprConverter(ConvertMethodExpr)); 
            astExprConverters.Add(typeof(CreateRefExpr), new AstExprConverter(ConvertCreateRefExpr));
            astExprConverters.Add(typeof(KeyExpr), new AstExprConverter(ConvertKeyExpr)); 
            Debug.Assert(NumberOfElements == astExprConverters.Count, "The number of elements and initial capacity don't match");
            return astExprConverters;
        }
 
        private static Dictionary CreateBuiltInExprConverter()
        { 
            Dictionary builtInExprConverter = new Dictionary(sizeof(BuiltInKind)); 

            //////////////////////////// 
            // Arithmetic Expressions
            ////////////////////////////

            // 
            // e1 + e2
            // 
            #region e1 + e2 
            builtInExprConverter.Add(BuiltInKind.Plus, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    Pair args = ConvertPlusOperands(bltInExpr, sr);

                    if (TypeSemantics.IsNumericType(args.Left.ResultType))
                    { 
                        return sr.CmdTree.CreatePlusExpression(args.Left, args.Right);
                    } 
                    else 
                    {
                        // 
                        // fold '+' operator into concat canonical function
                        //
                        IList functions;
                        if (!sr.TypeResolver.TryGetFunctionFromMetadata("Concat","Edm", true /* ignoreCase */, out functions)) 
                        {
                            throw EntityUtil.EntitySqlError(bltInExpr.ErrCtx, System.Data.Entity.Strings.ConcatBuiltinNotSupported); 
                        } 

                        List argTypes = new List(2); 
                        argTypes.Add(args.Left.ResultType);
                        argTypes.Add(args.Right.ResultType);

                        bool isAmbiguous = false; 
                        EdmFunction concatFunction = TypeResolver.ResolveFunctionOverloads(functions, argTypes, false /* isGroupAggregate */, out isAmbiguous);
                        if (null == concatFunction || isAmbiguous) 
                        { 
                            throw EntityUtil.EntitySqlError(bltInExpr.ErrCtx, System.Data.Entity.Strings.ConcatBuiltinNotSupported);
                        } 

                        return sr.CmdTree.CreateFunctionExpression(concatFunction,
                                                                   new DbExpression[] { args.Left, args.Right });
                    } 

                }); 
            #endregion 

            // 
            // e1 - e2
            //
            #region e1 - e2
            builtInExprConverter.Add(BuiltInKind.Minus, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    Pair args = ConvertArithmeticArgs(bltInExpr, sr); 
 
                    return sr.CmdTree.CreateMinusExpression(args.Left, args.Right);
                }); 
            #endregion

            //
            // e1 * e2 
            //
            #region e1 * e2 
            builtInExprConverter.Add(BuiltInKind.Multiply, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    Pair args = ConvertArithmeticArgs(bltInExpr, sr); 

                    return sr.CmdTree.CreateMultiplyExpression(args.Left, args.Right);
                });
            #endregion 

            // 
            // e1 / e2 
            //
            #region e1 / e2 
            builtInExprConverter.Add(BuiltInKind.Divide, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                {
                    Pair args = ConvertArithmeticArgs(bltInExpr, sr);
 
                    return sr.CmdTree.CreateDivideExpression(args.Left, args.Right);
                }); 
            #endregion 

            // 
            // e1 % e2
            //
            #region e1 % e2
            builtInExprConverter.Add(BuiltInKind.Modulus, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    Pair args = ConvertArithmeticArgs(bltInExpr, sr); 
 
                    return sr.CmdTree.CreateModuloExpression(args.Left, args.Right);
                }); 
            #endregion

            //
            // - e 
            //
            #region - e 
            builtInExprConverter.Add(BuiltInKind.UnaryMinus, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    DbExpression unaryExpr = sr.CmdTree.CreateUnaryMinusExpression(ConvertArithmeticArgs(bltInExpr, sr).Left); 
                    if (TypeSemantics.IsUnsignedNumericType(unaryExpr.ResultType))
                    {
                        TypeUsage closestPromotableType = null;
                        if (TypeHelpers.TryGetClosestPromotableType(unaryExpr.ResultType, out closestPromotableType)) 
                        {
                            unaryExpr = sr.CmdTree.CreateCastExpression(unaryExpr, closestPromotableType); 
                        } 
                        else
                        { 
                            throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.InvalidUnsignedTypeForUnaryMinusOperation(unaryExpr.ResultType.EdmType.FullName));
                        }
                    }
                    return unaryExpr; 
                });
            #endregion 
 
            //
            // + e 
            //
            #region + e
            builtInExprConverter.Add(BuiltInKind.UnaryPlus, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    return ConvertArithmeticArgs(bltInExpr, sr).Left;
                }); 
            #endregion 

            //////////////////////////// 
            // Logical Expressions
            ////////////////////////////

            // 
            // e1 AND e2
            // e1 && e2 
            // 
            #region e1 AND e2
            builtInExprConverter.Add(BuiltInKind.And, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    Pair args = SemanticAnalyzer.ConvertLogicalArgs(bltInExpr, sr);

                    return sr.CmdTree.CreateAndExpression(args.Left, args.Right); 
                });
            #endregion 
 
            //
            // e1 OR e2 
            // e1 || e2
            //
            #region e1 OR e2
            builtInExprConverter.Add(BuiltInKind.Or, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    Pair args = SemanticAnalyzer.ConvertLogicalArgs(bltInExpr, sr); 
 
                    return sr.CmdTree.CreateOrExpression(args.Left, args.Right);
                }); 
            #endregion

            //
            // NOT e 
            // ! e
            // 
            #region NOT e 
            builtInExprConverter.Add(BuiltInKind.Not, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    return sr.CmdTree.CreateNotExpression(ConvertLogicalArgs(bltInExpr, sr).Left);
                });
            #endregion
 
            ////////////////////////////
            // Comparison Expressions 
            //////////////////////////// 

            // 
            // e1 == e2 | e1 = e2
            //
            #region e1 == e2
            builtInExprConverter.Add(BuiltInKind.Equal, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    Pair args = ConvertEqualCompArgs(bltInExpr, sr); 
 
                    return sr.CmdTree.CreateEqualsExpression(args.Left, args.Right);
                }); 
            #endregion

            //
            // e1 != e2 | e1 <> e2 
            //
            #region e1 != e2 
            builtInExprConverter.Add(BuiltInKind.NotEqual, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    Pair args = ConvertEqualCompArgs(bltInExpr, sr); 

                    return sr.CmdTree.CreateNotExpression(
                                sr.CmdTree.CreateEqualsExpression(args.Left, args.Right));
                }); 
            #endregion
 
            // 
            // e1 >= e2
            // 
            #region e1 >= e2
            builtInExprConverter.Add(BuiltInKind.GreaterEqual, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                {
                    Pair args = ConvertOrderCompArgs(bltInExpr, sr); 

                    return sr.CmdTree.CreateGreaterThanOrEqualsExpression(args.Left, args.Right); 
                }); 
            #endregion
 
            //
            // e1 > e2
            //
            #region e1 > e2 
            builtInExprConverter.Add(BuiltInKind.GreaterThan, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    Pair args = ConvertOrderCompArgs(bltInExpr, sr); 

                    return sr.CmdTree.CreateGreaterThanExpression(args.Left, args.Right); 
                });
            #endregion

            // 
            // e1 <= e2
            // 
            #region e1 <= e2 
            builtInExprConverter.Add(BuiltInKind.LessEqual, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    Pair args = ConvertOrderCompArgs(bltInExpr, sr);

                    return sr.CmdTree.CreateLessThanOrEqualsExpression(args.Left, args.Right);
                }); 
            #endregion
 
            // 
            // e1 < e2
            // 
            #region e1 < e2
            builtInExprConverter.Add(BuiltInKind.LessThan, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                {
                    Pair args = ConvertOrderCompArgs(bltInExpr, sr); 

                    return sr.CmdTree.CreateLessThanExpression(args.Left, args.Right); 
                }); 
            #endregion
 

            ////////////////////////////
            //    SET EXPRESSIONS
            //////////////////////////// 

 
            // 
            // e1 UNION e2
            // 
            #region e1 UNION e2
            builtInExprConverter.Add(BuiltInKind.Union, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                {
                    Pair args = ConvertSetArgs(bltInExpr, sr); 

                    return sr.CmdTree.CreateDistinctExpression(sr.CmdTree.CreateUnionAllExpression(args.Left, args.Right)); 
                }); 
            #endregion
 
            //
            // e1 UNION ALL e2
            //
            #region e1 UNION ALL e2 
            builtInExprConverter.Add(BuiltInKind.UnionAll, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    Pair args = ConvertSetArgs(bltInExpr, sr); 

                    return sr.CmdTree.CreateUnionAllExpression(args.Left, args.Right); 
                });
            #endregion

            // 
            // e1 INTERSECT e2
            // 
            #region e1 INTERSECT e2 
            builtInExprConverter.Add(BuiltInKind.Intersect, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    Pair args = ConvertSetArgs(bltInExpr, sr);

                    return sr.CmdTree.CreateIntersectExpression(args.Left, args.Right);
                }); 
            #endregion
 
            // 
            // e1 OVERLAPS e2
            // 
            #region e1 OVERLAPS e1
            builtInExprConverter.Add(BuiltInKind.Overlaps, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                {
                    Pair args = ConvertSetArgs(bltInExpr, sr); 

                    return sr.CmdTree.CreateNotExpression( 
                                    sr.CmdTree.CreateIsEmptyExpression( 
                                        sr.CmdTree.CreateIntersectExpression(args.Left, args.Right)));
                }); 
            #endregion

            //
            // ANYELEMENT( e ) 
            //
            #region ANYELEMENT( e ) 
            builtInExprConverter.Add(BuiltInKind.AnyElement, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    return sr.CmdTree.CreateElementExpression(ConvertSetArgs(bltInExpr, sr).Left); 
                });
            #endregion

            // 
            // ELEMENT( e )
            // 
            #region ELEMENT( e ) - NOT SUPPORTED IN ORCAS TIMEFRAME 
            builtInExprConverter.Add(BuiltInKind.Element, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    throw EntityUtil.NotSupported(System.Data.Entity.Strings.ElementOperatorIsNotSupported);
                });
            #endregion
 
            //
            // e1 EXCEPT e2 
            // 
            #region e1 EXCEPT e2
            builtInExprConverter.Add(BuiltInKind.Except, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    Pair args = ConvertSetArgs(bltInExpr, sr);

                    return sr.CmdTree.CreateExceptExpression(args.Left, args.Right); 
                });
            #endregion 
 
            //
            // EXISTS( e ) 
            //
            #region EXISTS( e )
            builtInExprConverter.Add(BuiltInKind.Exists, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    return sr.CmdTree.CreateNotExpression(
                                    sr.CmdTree.CreateIsEmptyExpression(ConvertSetArgs(bltInExpr, sr).Left)); 
                }); 
            #endregion
 
            //
            // FLATTEN( e )
            //
            #region FLATTEN( e ) 
            builtInExprConverter.Add(BuiltInKind.Flatten, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    DbExpression elemExpr = Convert(bltInExpr.Arg1, sr); 

                    if (!TypeSemantics.IsCollectionType(elemExpr.ResultType)) 
                    {
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.InvalidFlattenArgument);
                    }
 
                    if (!TypeSemantics.IsCollectionType(TypeHelpers.GetElementTypeUsage(elemExpr.ResultType)))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.InvalidFlattenArgument); 
                    }
 
                    DbExpressionBinding leftExpr = sr.CmdTree.CreateExpressionBinding(elemExpr, sr.GenerateInternalName("l_flatten"));

                    DbExpressionBinding rightExpr = sr.CmdTree.CreateExpressionBinding(leftExpr.Variable, sr.GenerateInternalName("r_flatten"));
 
                    DbExpressionBinding applyBinding = sr.CmdTree.CreateExpressionBinding(
                                                                sr.CmdTree.CreateCrossApplyExpression(leftExpr, rightExpr), 
                                                                sr.GenerateInternalName("flatten")); 

                    return sr.CmdTree.CreateProjectExpression(applyBinding, sr.CmdTree.CreatePropertyExpression(rightExpr.VariableName, applyBinding.Variable)); 
                });
            #endregion

            // 
            // e1 IN e2
            // 
            #region e1 IN e2 
            builtInExprConverter.Add(BuiltInKind.In, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    Pair args = ConvertInExprArgs(bltInExpr, sr);

                    // [....]: Temporary workaround for 2/3 milestone.
                    // Convert "x in multiset(y1, y2, ..., yn)" into 
                    //    x = y1 or x = y2 or x = y3 ...
                    // 
                    if (args.Right.ExpressionKind == DbExpressionKind.NewInstance) 
                    {
                        return ConvertSimpleInExpression(sr, args.Left, args.Right); 
                    }
                    else
                    {
                        DbExpressionBinding rSet = sr.CmdTree.CreateExpressionBinding(args.Right, sr.GenerateInternalName("in-filter")); 

                        DbExpression leftIn = args.Left; 
                        DbExpression rightSet = rSet.Variable; 
                        DbExpression exists = sr.CmdTree.CreateNotExpression(
                                                    sr.CmdTree.CreateIsEmptyExpression( 
                                                            sr.CmdTree.CreateFilterExpression(
                                                                    rSet,
                                                                    sr.CmdTree.CreateEqualsExpression(leftIn, rightSet))));
 
                        List whenExpr = new List(1);
                        whenExpr.Add(sr.CmdTree.CreateIsNullExpression(leftIn)); 
                        List thenExpr = new List(1); 
                        thenExpr.Add(sr.CmdTree.CreateNullExpression(sr.TypeResolver.BooleanType));
 
                        DbExpression left = sr.CmdTree.CreateCaseExpression(
                                                                 whenExpr,
                                                                 thenExpr,
                                                                 sr.CmdTree.CreateFalseExpression()); 

                        DbExpression converted = sr.CmdTree.CreateOrExpression(left, exists); 
 
                        return converted;
                    } 
                });
            #endregion

            // 
            // e1 NOT IN e1
            // 
            #region e1 NOT IN e1 
            builtInExprConverter.Add(BuiltInKind.NotIn, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    Pair args = ConvertInExprArgs(bltInExpr, sr);

                    if (args.Right.ExpressionKind == DbExpressionKind.NewInstance)
                    { 
                        return sr.CmdTree.CreateNotExpression(
                            ConvertSimpleInExpression(sr, args.Left, args.Right)); 
                    } 
                    else
                    { 
                        DbExpressionBinding rSet = sr.CmdTree.CreateExpressionBinding(args.Right, sr.GenerateInternalName("in-filter"));

                        DbExpression leftIn = args.Left;
                        DbExpression rightSet = rSet.Variable; 
                        DbExpression exists = sr.CmdTree.CreateIsEmptyExpression(
                                                            sr.CmdTree.CreateFilterExpression( 
                                                                    rSet, 
                                                                    sr.CmdTree.CreateEqualsExpression(leftIn, rightSet)));
 
                        List whenExpr = new List(1);
                        whenExpr.Add(sr.CmdTree.CreateIsNullExpression(leftIn));
                        List thenExpr = new List(1);
                        thenExpr.Add(sr.CmdTree.CreateNullExpression(sr.TypeResolver.BooleanType)); 

                        DbExpression left = sr.CmdTree.CreateCaseExpression( 
                                                                 whenExpr, 
                                                                 thenExpr,
                                                                 sr.CmdTree.CreateTrueExpression()); 

                        DbExpression converted = sr.CmdTree.CreateAndExpression(left, exists);

                        return converted; 
                    }
                }); 
            #endregion 

            // 
            // SET( e ) - DISTINCT( e ) before
            //
            #region SET( e )
            builtInExprConverter.Add(BuiltInKind.Distinct, delegate( BuiltInExpr bltInExpr, SemanticResolver sr ) 
                {
                    Pair args = ConvertSetArgs(bltInExpr, sr); 
 
                    return sr.CmdTree.CreateDistinctExpression(args.Left);
                }); 
            #endregion


            //////////////////////////// 
            // Nullabity Expressions
            //////////////////////////// 
 
            //
            // e IS NULL 
            //
            #region e IS NULL
            builtInExprConverter.Add(BuiltInKind.IsNull, delegate(BuiltInExpr bltInExpr, SemanticResolver sr)
            { 
                DbExpression isNullExpr = Convert(bltInExpr.Arg1, sr);
 
                // 
                // ensure expression type is valid for this operation
                // 
                if (!TypeHelpers.IsValidIsNullOpType(isNullExpr.ResultType))
                {
                    throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.IsNullInvalidType);
                } 

                return SemanticResolver.IsNullExpression(isNullExpr) ? sr.CmdTree.CreateTrueExpression() : (DbExpression)sr.CmdTree.CreateIsNullExpression(isNullExpr); 
            }); 
            #endregion
 
            //
            // e IS NOT NULL
            //
            #region e IS NOT NULL 
            builtInExprConverter.Add(BuiltInKind.IsNotNull, delegate(BuiltInExpr bltInExpr, SemanticResolver sr)
            { 
                DbExpression isNullExpr = Convert(bltInExpr.Arg1, sr); 

                // 
                // ensure expression type is valid for this operation
                //
                if (!TypeHelpers.IsValidIsNullOpType(isNullExpr.ResultType))
                { 
                    throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.IsNullInvalidType);
                } 
 
                isNullExpr = SemanticResolver.IsNullExpression(isNullExpr) ? sr.CmdTree.CreateTrueExpression() : (DbExpression)sr.CmdTree.CreateIsNullExpression(isNullExpr);
 
                return sr.CmdTree.CreateNotExpression(isNullExpr);
            });
            #endregion
 

            //////////////////////////// 
            //    Type Expressions 
            ////////////////////////////
 
            //
            // e IS OF ( [ONLY] T )
            //
            #region e IS OF ( [ONLY] T ) 
            builtInExprConverter.Add(BuiltInKind.IsOf, delegate(BuiltInExpr bltInExpr, SemanticResolver sr)
                { 
                    Pair args = ConvertTypeExprArgs(bltInExpr, sr); 

                    bool isOnly = (bool)((Literal)bltInExpr.ArgList[2]).Value; 
                    bool isNot = (bool)((Literal)bltInExpr.ArgList[3]).Value;
                    bool isNominalTypeAllowed = sr.ParserOptions.ParserCompilationMode == ParserOptions.CompilationMode.RestrictedViewGenerationMode;

                    if (TypeSemantics.IsNullType(args.Left.ResultType)) 
                    {
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, 
                                                    System.Data.Entity.Strings.ExpressionCannotBeNull); 
                    }
 
                    if (!isNominalTypeAllowed && !TypeSemantics.IsEntityType(args.Left.ResultType))
                    {
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx,
                                                    System.Data.Entity.Strings.ExpressionTypeMustBeEntityType(System.Data.Entity.Strings.CtxIsOf, 
                                                                                                              args.Left.ResultType.EdmType.BuiltInTypeKind.ToString(),
                                                                                                              args.Left.ResultType.EdmType.FullName)); 
                    } 
                    else if (isNominalTypeAllowed && !TypeSemantics.IsNominalType(args.Left.ResultType))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx,
                                                    System.Data.Entity.Strings.ExpressionTypeMustBeNominalType(System.Data.Entity.Strings.CtxIsOf,
                                                                                                              args.Left.ResultType.EdmType.BuiltInTypeKind.ToString(),
                                                                                                              args.Left.ResultType.EdmType.FullName)); 
                    }
 
                    if (!isNominalTypeAllowed && !TypeSemantics.IsEntityType(args.Right)) 
                    {
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.TypeMustBeEntityType(System.Data.Entity.Strings.CtxIsOf, 
                                                                                                                           args.Right.EdmType.BuiltInTypeKind.ToString(),
                                                                                                                           args.Right.EdmType.FullName));
                    }
                    else if (isNominalTypeAllowed && !TypeSemantics.IsNominalType(args.Right)) 
                    {
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.TypeMustBeNominalType(System.Data.Entity.Strings.CtxIsOf, 
                                                                                                                           args.Right.EdmType.BuiltInTypeKind.ToString(), 
                                                                                                                           args.Right.EdmType.FullName));
                    } 

                    if (!TypeSemantics.IsPolymorphicType(args.Left.ResultType))
                    {
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, 
                                                    System.Data.Entity.Strings.TypeMustBeInheritableType);
                    } 
 
                    if (!TypeSemantics.IsPolymorphicType(args.Right))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx,
                                                    System.Data.Entity.Strings.TypeMustBeInheritableType);
                    }
 
                    if (!TypeResolver.IsSubOrSuperType(args.Left.ResultType, args.Right))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.ErrCtx, 
                                                    System.Data.Entity.Strings.NotASuperOrSubType(args.Left.ResultType.EdmType.FullName,
                                                                                                  args.Right.EdmType.FullName)); 
                    }

                    args.Right = TypeHelpers.GetReadOnlyType(args.Right);
 
                    DbExpression retExpr = null;
                    if (isOnly) 
                    { 
                        retExpr = sr.CmdTree.CreateIsOfOnlyExpression(args.Left, args.Right);
                    } 
                    else
                    {
                        retExpr = sr.CmdTree.CreateIsOfExpression(args.Left, args.Right);
                    } 

                    if (isNot) 
                    { 
                        retExpr = sr.CmdTree.CreateNotExpression(retExpr);
                    } 

                    return retExpr;
                });
            #endregion 

            // 
            // TREAT( e as T ) 
            //
            #region TREAT( e as T ) 
            builtInExprConverter.Add(BuiltInKind.Treat, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                {
                    Pair args = ConvertTypeExprArgs(bltInExpr, sr);
 
                    bool isNominalTypeAllowed = sr.ParserOptions.ParserCompilationMode == ParserOptions.CompilationMode.RestrictedViewGenerationMode;
 
                    if (!isNominalTypeAllowed && !TypeSemantics.IsEntityType(args.Right)) 
                    {
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx, 
                                                    System.Data.Entity.Strings.TypeMustBeEntityType(System.Data.Entity.Strings.CtxTreat,
                                                                                                    args.Right.EdmType.BuiltInTypeKind.ToString(),
                                                                                                    args.Right.EdmType.FullName));
                    } 
                    else if (isNominalTypeAllowed && !TypeSemantics.IsNominalType(args.Right))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx, 
                                                    System.Data.Entity.Strings.TypeMustBeNominalType(System.Data.Entity.Strings.CtxTreat,
                                                                                                    args.Right.EdmType.BuiltInTypeKind.ToString(), 
                                                                                                    args.Right.EdmType.FullName));
                    }

                    if (TypeSemantics.IsNullType(args.Left.ResultType)) 
                    {
                        args.Left = sr.CmdTree.CreateNullExpression(args.Right); 
                    } 
                    else if (!isNominalTypeAllowed && !TypeSemantics.IsEntityType(args.Left.ResultType))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx,
                                                    System.Data.Entity.Strings.ExpressionTypeMustBeEntityType(System.Data.Entity.Strings.CtxTreat,
                                                                                                              args.Left.ResultType.EdmType.BuiltInTypeKind.ToString(),
                                                                                                              args.Left.ResultType.EdmType.FullName)); 
                    }
                    else if (isNominalTypeAllowed && !TypeSemantics.IsNominalType(args.Left.ResultType)) 
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx,
                                                    System.Data.Entity.Strings.ExpressionTypeMustBeNominalType(System.Data.Entity.Strings.CtxTreat, 
                                                                                                              args.Left.ResultType.EdmType.BuiltInTypeKind.ToString(),
                                                                                                              args.Left.ResultType.EdmType.FullName));
                    }
 
                    if (!TypeSemantics.IsPolymorphicType(args.Left.ResultType))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, 
                                                    System.Data.Entity.Strings.TypeMustBeInheritableType);
                    } 

                    if (!TypeSemantics.IsPolymorphicType(args.Right))
                    {
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx, 
                                                    System.Data.Entity.Strings.TypeMustBeInheritableType);
                    } 
 
                    if (!TypeResolver.IsSubOrSuperType(args.Left.ResultType, args.Right))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx,
                                                   System.Data.Entity.Strings.NotASuperOrSubType(args.Left.ResultType.EdmType.FullName,
                                                                                                 args.Right.EdmType.FullName));
                    } 

                    return sr.CmdTree.CreateTreatExpression(args.Left, TypeHelpers.GetReadOnlyType(args.Right)); 
                }); 
            #endregion
 
            //
            // CAST( e AS T )
            //
            #region CAST( e AS T ) 
            builtInExprConverter.Add(BuiltInKind.Cast, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    Pair args = ConvertTypeExprArgs(bltInExpr, sr); 

                    // 
                    // ensure CAST target type is Scalar
                    //
                    if (!TypeSemantics.IsPrimitiveType(args.Right))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.InvalidCastType);
                    } 
 
                    if (SemanticResolver.IsNullExpression(args.Left))
                    { 
                        return sr.CmdTree.CreateCastExpression(
                                                sr.CmdTree.CreateNullExpression(args.Right),
                                                args.Right);
                    } 

                    if (args.Left.ResultType.BuiltInTypeKind != BuiltInTypeKind.EnumType) 
                    { 
                        if (!TypeSemantics.IsPrimitiveType(args.Left.ResultType))
                        { 
                            throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.InvalidCastExpressionType);
                        }

                        if (!TypeSemantics.IsCastAllowed(args.Left.ResultType, args.Right)) 
                        {
                            throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, 
                                                        System.Data.Entity.Strings.InvalidCast( 
                                                                            args.Left.ResultType.EdmType,
                                                                            args.Right.EdmType.FullName)); 
                        }
                    }

                    return sr.CmdTree.CreateCastExpression(args.Left, TypeHelpers.GetReadOnlyType(args.Right)); 
                });
            #endregion 
 
            //
            // OFTYPE( [ONLY] e, T ) 
            //
            #region OFTYPE( [ONLY] e, T )
            builtInExprConverter.Add(BuiltInKind.OfType, delegate(BuiltInExpr bltInExpr, SemanticResolver sr)
            { 
                Pair args = ConvertTypeExprArgs(bltInExpr, sr);
 
                bool isOnly = (bool)((Literal)bltInExpr.ArgList[2]).Value; 

                bool isNominalTypeAllowed = sr.ParserOptions.ParserCompilationMode == ParserOptions.CompilationMode.RestrictedViewGenerationMode; 

                if (!TypeSemantics.IsCollectionType(args.Left.ResultType))
                {
                    throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, 
                                                System.Data.Entity.Strings.ExpressionMustBeCollection);
                } 
 
                TypeUsage elementType = TypeHelpers.GetElementTypeUsage(args.Left.ResultType);
                if (!isNominalTypeAllowed && !TypeSemantics.IsEntityType(elementType)) 
                {
                    throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx,
                                                System.Data.Entity.Strings.OfTypeExpressionElementTypeMustBeEntityType(elementType.EdmType.BuiltInTypeKind.ToString(),
                                                                                                                       elementType)); 
                }
                else if (isNominalTypeAllowed && !TypeSemantics.IsNominalType(elementType)) 
                { 
                    throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx,
                                                System.Data.Entity.Strings.OfTypeExpressionElementTypeMustBeNominalType(elementType.EdmType.BuiltInTypeKind.ToString(), 
                                                                                                                       elementType));
                }

                if (!isNominalTypeAllowed && !TypeSemantics.IsEntityType(args.Right)) 
                {
                    throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx, 
                                                System.Data.Entity.Strings.TypeMustBeEntityType(System.Data.Entity.Strings.CtxOfType, 
                                                                                                args.Right.EdmType.BuiltInTypeKind.ToString(),
                                                                                                args.Right.EdmType.FullName)); 
                }
                else if (isNominalTypeAllowed && !TypeSemantics.IsNominalType(args.Right))
                {
                    throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx, 
                                                System.Data.Entity.Strings.TypeMustBeNominalType(System.Data.Entity.Strings.CtxOfType,
                                                                                                args.Right.EdmType.BuiltInTypeKind.ToString(), 
                                                                                                args.Right.EdmType.FullName)); 
                }
 
                if (isOnly && args.Right.EdmType.Abstract)
                {
                    throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx,
                                                System.Data.Entity.Strings.OfTypeOnlyTypeArgumentCannotBeAbstract(args.Right.EdmType.FullName)); 
                }
 
                if (!TypeResolver.IsSubOrSuperType(elementType, args.Right)) 
                {
                    throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, 
                                                System.Data.Entity.Strings.NotASuperOrSubType(elementType.EdmType.FullName,
                                                                                              args.Right.EdmType.FullName));
                }
 
                DbExpression ofTypeExpression = null;
                if (isOnly) 
                { 
                    ofTypeExpression = sr.CmdTree.CreateOfTypeOnlyExpression(args.Left, TypeHelpers.GetReadOnlyType(args.Right));
                } 
                else
                {
                    ofTypeExpression = sr.CmdTree.CreateOfTypeExpression(args.Left, TypeHelpers.GetReadOnlyType(args.Right));
                } 

                return ofTypeExpression; 
            }); 
            #endregion
 
            //
            // e LIKE pattern [ESCAPE escape]
            //
            #region e LIKE pattern [ESCAPE escape] 
            builtInExprConverter.Add(BuiltInKind.Like, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    DbExpression likeExpr = null; 

                    DbExpression matchExpr = Convert(bltInExpr.Arg1, sr); 

                    if (TypeSemantics.IsNullType(matchExpr.ResultType))
                    {
                        matchExpr = sr.CmdTree.CreateNullExpression(sr.TypeResolver.StringType); 
                    }
                    else if (!TypeResolver.IsStringType(matchExpr.ResultType)) 
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg1.ErrCtx, System.Data.Entity.Strings.LikeArgMustBeStringType);
                    } 

                    DbExpression patternExpr = Convert(bltInExpr.Arg2, sr);

                    if (patternExpr is UntypedNullExpression) 
                    {
                        patternExpr = sr.CmdTree.CreateNullExpression(sr.TypeResolver.StringType); 
                    } 
                    else if (!TypeResolver.IsStringType(patternExpr.ResultType))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.Arg2.ErrCtx, System.Data.Entity.Strings.LikeArgMustBeStringType);
                    }

                    if (3 == bltInExpr.ArgCount) 
                    {
                        DbExpression escapeExpr = Convert(bltInExpr.ArgList[2], sr); 
 
                        if (escapeExpr is UntypedNullExpression)
                        { 
                            escapeExpr = sr.CmdTree.CreateNullExpression(sr.TypeResolver.StringType);
                        }
                        else if (!TypeResolver.IsStringType(escapeExpr.ResultType))
                        { 
                            throw EntityUtil.EntitySqlError(bltInExpr.ArgList[2].ErrCtx, System.Data.Entity.Strings.LikeArgMustBeStringType);
                        } 
 
                        likeExpr = sr.CmdTree.CreateLikeExpression(matchExpr, patternExpr, escapeExpr);
                    } 
                    else
                    {
                        likeExpr = sr.CmdTree.CreateLikeExpression(matchExpr, patternExpr);
                    } 

                    return likeExpr; 
                }); 
            #endregion
 
            //
            // e BETWEEN e1 AND e2
            //
            #region e BETWEEN e1 AND e2 
            builtInExprConverter.Add(BuiltInKind.Between, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    Debug.Assert(bltInExpr.ArgCount == 3); 

                    // 
                    // convert lower and upper limits
                    //
                    Pair limitsExpr = sr.EnsureTypedNulls(
                                                                        Convert(bltInExpr.ArgList[1], sr), 
                                                                        Convert(bltInExpr.ArgList[2], sr),
                                                                        bltInExpr.ArgList[0].ErrCtx, 
                                                                        () => Strings.BetweenLimitsCannotBeUntypedNulls); 

                    // 
                    // Get and check common type for limits
                    //
                    TypeUsage rangeCommonType = TypeHelpers.GetCommonTypeUsage(limitsExpr.Left.ResultType, limitsExpr.Right.ResultType);
                    if (null == rangeCommonType) 
                    {
                        throw EntityUtil.EntitySqlError(bltInExpr.ArgList[0].ErrCtx, System.Data.Entity.Strings.BetweenLimitsTypesAreNotCompatible(limitsExpr.Left.ResultType.EdmType.FullName, limitsExpr.Right.ResultType.EdmType.FullName)); 
                    } 

                    // 
                    // check if limit types are order-comp
                    //
                    if (!TypeSemantics.IsOrderComparableTo(limitsExpr.Left.ResultType, limitsExpr.Right.ResultType))
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.ArgList[0].ErrCtx, System.Data.Entity.Strings.BetweenLimitsTypesAreNotOrderComparable(limitsExpr.Left.ResultType.EdmType.FullName, limitsExpr.Right.ResultType.EdmType.FullName));
                    } 
 
                    //
                    // convert value expression 
                    //
                    DbExpression valueExpr = Convert(bltInExpr.ArgList[0], sr);

                    // 
                    // Fixup value type if untyped
                    // 
                    if (TypeSemantics.IsNullType(valueExpr.ResultType)) 
                    {
                        valueExpr = sr.CmdTree.CreateNullExpression(rangeCommonType); 
                    }

                    //
                    // check if valueExpr is order-comparable to limits 
                    //
                    if (!TypeSemantics.IsOrderComparableTo(valueExpr.ResultType, rangeCommonType)) 
                    { 
                        throw EntityUtil.EntitySqlError(bltInExpr.ArgList[0].ErrCtx, System.Data.Entity.Strings.BetweenValueIsNotOrderComparable(valueExpr.ResultType.EdmType.FullName, rangeCommonType.EdmType.FullName));
                    } 

                    return sr.CmdTree.CreateAndExpression(
                                            sr.CmdTree.CreateGreaterThanOrEqualsExpression(valueExpr, limitsExpr.Left),
                                            sr.CmdTree.CreateLessThanOrEqualsExpression(valueExpr, limitsExpr.Right)); 
                });
            #endregion 
 
            //
            // e NOT BETWEEN e1 AND e2 
            //
            #region e NOT BETWEEN e1 AND e2
            builtInExprConverter.Add(BuiltInKind.NotBetween, delegate( BuiltInExpr bltInExpr, SemanticResolver sr )
                { 
                    bltInExpr.Kind = BuiltInKind.Between;
 
                    DbExpression converted = sr.CmdTree.CreateNotExpression(ConvertBuiltIn(bltInExpr, sr)); 

                    bltInExpr.Kind = BuiltInKind.NotBetween; 

                    return converted;
                });
            #endregion 

            return builtInExprConverter; 
        } 

        #endregion 

        #endregion
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK