SemanticResolver.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Common / EntitySql / SemanticResolver.cs / 4 / SemanticResolver.cs

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

 
namespace System.Data.Common.EntitySql
{
    using System;
    using System.IO; 
    using System.Globalization;
    using System.Collections.Generic; 
    using System.Diagnostics; 

    using System.Data.Mapping; 
    using System.Data.Common.CommandTrees;
    using System.Data.Common;
    using System.Data.Metadata.Edm;
    using System.Data.Entity; 

    ///  
    /// implements the semantic resolver in the context of a metadata workspace and typespace 
    /// 
    /// not thread safe 
    internal sealed class SemanticResolver
    {
        private StaticContext _staticContext;
        private DbCommandTree _commandTree; 
        private ParserOptions _parserOptions;
        private Dictionary _parameters; 
        private Dictionary> _variables; 
        private uint _namegenCounter = 0;
        private TypeResolver _typeResolver; 
        private int _scopeIndexHighMark;
        private List _scopeRegionSavepoints = new List();
        private List _scopeRegionFlags = new List();
        private StringComparer _stringComparer; 
        private List _aggregateAstNodes = new List();
 
 
        /// 
        /// Initializes semantic resolver 
        /// 
        /// 
        /// options
        /// ordinary parameters 
        /// variable parameters
        ///  
        ///  
        /// 
        internal SemanticResolver(Perspective perspective, 
                                    ParserOptions parserOptions,
                                    Dictionary eSqlParameters,
                                    Dictionary variableParameters)
        { 
            EntityUtil.CheckArgumentNull(perspective, "perspective");
            EntityUtil.CheckArgumentNull(parserOptions, "parserOptions"); 
 
            //
            // set parser options 
            //
            _parserOptions = parserOptions;

            // 
            // Initialize string comparer based on parser configuration
            // 
            if (ParserOptions.CaseSensitiveness.CaseSensitive == _parserOptions.IdentifierCaseSensitiveness) 
            {
                _stringComparer = StringComparer.Ordinal; 
            }
            else
            {
                _stringComparer = StringComparer.OrdinalIgnoreCase; 
            }
 
            // 
            // Initialize Type Resolver
            // 
            _typeResolver = new TypeResolver(perspective, _stringComparer);

            //
            // Creates Scope manager 
            //
            _staticContext = new StaticContext(_stringComparer); 
 
            //
            // Validate eSql parameters 
            //
            _parameters = ValidateParameters(eSqlParameters);

            // 
            // validate variable-representing
            // 
            _variables = ValidateVariables(variableParameters); 

            // 
            // push a 'global' scope region
            //
            EnterScopeRegion();
 
            //
            // set default scope visibility to All scopes 
            // 
            CurrentScopeRegionFlags.ScopeViewKind = ScopeViewKind.All;
        } 


        /// 
        /// returns command tree 
        /// 
        internal DbCommandTree CmdTree 
        { 
            get { return _commandTree; }
        } 


        /// 
        /// returns parameters 
        /// 
        internal Dictionary Parameters 
        { 
            get { return _parameters; }
        } 


        /// 
        /// returns variables 
        /// 
        internal Dictionary> Variables 
        { 
            get { return _variables; }
        } 


        /// 
        /// TypeSpace/Metadata/Perspective Dependent Type Resolver 
        /// 
        internal TypeResolver TypeResolver 
        { 
            get { return _typeResolver; }
        } 


        /// 
        /// Returns current Parser Options 
        /// 
        internal ParserOptions ParserOptions 
        { 
            get { return _parserOptions; }
        } 


        /// 
        /// returns the current string comparer 
        /// 
        internal StringComparer ScopeStringComparer 
        { 
            get { return _stringComparer; }
        } 


        /// 
        /// sets the command tree factory 
        /// 
        ///  
        ///  
        /// 
        ///  
        internal void SetCommandTreeFactory(CommandExpr astCommandExpr)
        {
            EntityUtil.CheckArgumentNull(astCommandExpr, "astCommandExpr");
 
            if (null != _commandTree)
            { 
                throw EntityUtil.EntitySqlError(Strings.CommandTreeCanOnlyBeSetOnce); 
            }
 
            switch (astCommandExpr.QueryExpr.ExprKind)
            {
                case AstExprKind.Query:
                case AstExprKind.Generic: 
                    _commandTree = new DbQueryCommandTree(TypeResolver.Perspective.MetadataWorkspace, TypeResolver.Perspective.TargetDataspace);
                    break; 
 
                default:
                    throw EntityUtil.Argument(Strings.UnknownAstExpressionType); 
            }
        }

        ///  
        /// Sets the command tree factory using the specified command tree.
        /// When specifying a command tree, the AST command expression may 
        /// only be a query/generic expression, since these are the only 
        /// AST command expression that can be used to create a stand-alone .
        ///  
        /// The command expression that is the root of the AST
        /// The command tree to use when converting the AST into a 
        internal void SetCommandTreeFactory(CommandExpr astCommandExpr, DbCommandTree commandTree)
        { 
            EntityUtil.CheckArgumentNull(astCommandExpr, "astCommandExpr");
            EntityUtil.CheckArgumentNull(commandTree, "commandTree"); 
 
            if (null != _commandTree)
            { 
                throw EntityUtil.EntitySqlError(Strings.CommandTreeCanOnlyBeSetOnce);
            }

            DbQueryCommandTree queryTree = commandTree as DbQueryCommandTree; 
            if (null == queryTree ||
                (astCommandExpr.ExprKind != AstExprKind.Query && 
                 astCommandExpr.ExprKind != AstExprKind.Generic)) 
            {
                throw EntityUtil.Argument(Strings.UnknownAstExpressionType); 
            }

            _commandTree = commandTree;
        } 

        ///  
        /// declares and validates namespaces 
        /// 
        /// namespace expression list 
        /// 
        /// 
        /// 
        internal void DeclareNamespaces(ExprList nsExprList) 
        {
            if (null == nsExprList) 
            { 
                return;
            } 

            for (int i = 0; i < nsExprList.Count; i++)
            {
                NamespaceExpr nsExpr = nsExprList[i]; 

                string namespaceName = nsExpr.NamespaceName.FullName; 
 
                if (namespaceName.Equals(EdmConstants.CanonicalFunctionNamespace, StringComparison.OrdinalIgnoreCase))
                { 
                    throw EntityUtil.EntitySqlError(nsExpr.NamespaceName.ErrCtx, System.Data.Entity.Strings.CannotUseCanonicalNamespace(namespaceName));
                }

                if (nsExpr.IsAliased) 
                {
                    string aliasName = nsExpr.AliasIdentifier.Name; 
 
                    if (!TypeResolver.TryAddAliasedNamespace(aliasName, namespaceName))
                    { 
                        throw EntityUtil.EntitySqlError(nsExpr.AliasIdentifier.ErrCtx, System.Data.Entity.Strings.NamespaceAliasAlreadyUsed(aliasName));
                    }
                }
                else 
                {
                    if (!TypeResolver.TryAddNamespace(namespaceName)) 
                    { 
                        throw EntityUtil.EntitySqlError(nsExpr.NamespaceName.ErrCtx, System.Data.Entity.Strings.NamespaceNameAlreadyDeclared(namespaceName));
                    } 
                }
            }
        }
 
        /// 
        /// Declares Canonical namespace in query scope 
        ///  
        internal void DeclareCanonicalNamespace()
        { 
            if (!TypeResolver.TryAddNamespace(EdmConstants.CanonicalFunctionNamespace))
            {
                throw EntityUtil.EntitySqlError(Strings.FailedToDeclareCanonicalNamespace);
            } 
        }
 
        ///  
        /// defines scope visibility mode
        ///  
        internal enum ScopeViewKind
        {
            All,                        /* default - all scopes plus types/extents */
            CurrentContext,             /* entire context - all stacked scopes */ 
            CurrentScopeRegion,         /* current scope region */
            CurrentAndPreviousScope,    /* top 2 scopes */ 
            CurrentScope,                /* current scope only   */ 
            GroupScope
        } 


        /// 
        /// sets the current scope visibility 
        /// 
        ///  
        internal void SetScopeView(ScopeViewKind viewKind) 
        {
            CurrentScopeRegionFlags.ScopeViewKind = viewKind; 

            switch (CurrentScopeRegionFlags.ScopeViewKind)
            {
                case ScopeViewKind.All: 
                case ScopeViewKind.CurrentContext:
                case ScopeViewKind.GroupScope: 
                    _scopeIndexHighMark = 0; 
                    break;
 
                case ScopeViewKind.CurrentAndPreviousScope:
                    _scopeIndexHighMark = CurrentScopeIndex - 1;
                    break;
 
                case ScopeViewKind.CurrentScopeRegion:
                    _scopeIndexHighMark = CurrentScopeRegionSavePoint.ScopeIndex; 
                    break; 

                case ScopeViewKind.CurrentScope: 
                    _scopeIndexHighMark = CurrentScopeIndex;
                    break;
            }
 
            Debug.Assert(_scopeIndexHighMark <= CurrentScopeIndex, "_scopeIndexHighMark <= CurrentScopeIndex");
        } 
 
        /// 
        /// returns current scope view kind 
        /// 
        /// 
        internal ScopeViewKind GetScopeView()
        { 
            return CurrentScopeRegionFlags.ScopeViewKind;
        } 
 
        /// 
        /// returns current scope index 
        /// 
        internal int CurrentScopeIndex
        {
            get { return _staticContext.CurrentScopeIndex; } 
        }
 
        ///  
        /// Performs scope lookup returning the scope index entry
        ///  
        /// 
        /// 
        /// 
        internal bool TryScopeLookup(string key, out ScopeEntry scopeEntry) 
        {
            int dummyVar; 
            return TryScopeLookup(key, out scopeEntry, out dummyVar); 
        }
 
        /// 
        /// Performs scope lookup returning the scope index entry
        /// 
        ///  
        /// 
        ///  
        ///  
        internal bool TryScopeLookup(string key, out ScopeEntry scopeEntry, out int scopeIndex)
        { 
            return TryScopeLookup(key, false /* ignoreGroupScope */, out scopeEntry, out scopeIndex);
        }

        ///  
        /// Performs scope lookup returning the scope index entry
        ///  
        ///  
        /// 
        ///  
        /// 
        /// 
        internal bool TryScopeLookup(string key, bool ignoreGroupScope, out ScopeEntry scopeEntry, out int scopeIndex)
        { 
            scopeEntry = null;
            scopeIndex = -1; 
 
            // assert that scope index is always greater or equal to current scope index
            // scopes grow top -> bottom with high mark always 'higher or equal' then the bottom 
            // of the stack of scopes
            Debug.Assert(_scopeIndexHighMark <= CurrentScopeIndex, "_scopeIndexHighMark <= CurrentScopeIndex");

            int i = 0; 
            for (i = CurrentScopeIndex; i >= _scopeIndexHighMark; i--)
            { 
                if (_staticContext.GetScopeByIndex(i).TryLookup(key, out scopeEntry)) 
                {
                    if (!ignoreGroupScope && CurrentScopeRegionFlags.IsInGroupScope && scopeEntry.VarKind == SourceVarKind.GroupInput) 
                    {
                        return false;
                    }
                    scopeIndex = i; 
                    return true;
                } 
            } 
            return false;
        } 


        /// 
        /// returns the appropriate expression from a given scope entry. 
        /// 
        ///  
        ///  
        /// 
        private DbExpression GetExpressionFromScopeEntry(ScopeEntry scopeEntry, int scopeIndex) 
        {
            DbExpression innerExpr = null;

            innerExpr = scopeEntry.Expression; 

            // 
            // if it inside a group aggregate function, the 'base' expression is relative to 
            // the groupVar, represented in the scope entry as AggregateExpression
            // 
            if (CurrentScopeRegionFlags.IsInsideGroupAggregate)
            {
                if (_aggregateAstNodes.Count > 0)
                { 
                    _aggregateAstNodes[0].ScopeIndex = Math.Max(_aggregateAstNodes[0].ScopeIndex, scopeIndex);
                } 
 
                SourceScopeEntry sse = scopeEntry as SourceScopeEntry;
                if (null != sse) 
                {
                    if (sse.GroupVarExpression != null)
                    {
                        return sse.AggregateExpression; 
                    }
                    else 
                    { 
                        return innerExpr;
                    } 
                }

                DummyGroupVarScopeEntry dgv = scopeEntry as DummyGroupVarScopeEntry;
                if (null != dgv) 
                {
                    return dgv.AggregateExpression; 
                } 

            } 

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

            return innerExpr; 
        }
 
        ///  
        /// resolve identifier or dotidentifier ast expression
        ///  
        /// 
        /// 
        /// 
        ///  
        /// 
        ///  
        ///  
        /// DbExpression
        internal DbExpression ResolveIdentifier(string[] names, ErrorContext errCtx) 
        {
            Debug.Assert(CurrentScopeIndex >= _scopeIndexHighMark, "CurrentScopeIndex >= _scopeIndexHighMark FAILED");
            Debug.Assert(_scopeRegionFlags.Count == _scopeRegionSavepoints.Count, "_scopeRegionFlags.Count == _scopeRegionSavepoints.Count FAILED");
 
            TypeUsage definingType = null;
            DbExpression innerExpr = null; 
            ScopeEntry scopeEntry; 
            KeyValuePair varInfo;
            int scopeIndex = -1; 
            int suffixIndex = 0;

            //
            // try base type in scope first 
            //
            if (names.Length > 1 && TryScopeLookup(TypeResolver.GetFullName(names), out scopeEntry, out scopeIndex)) 
            { 
                //
                // Sets correlation flag 
                //
                SetScopeRegionCorrelationFlag(scopeIndex);

                return GetExpressionFromScopeEntry(scopeEntry, scopeIndex); 
            }
            else if (TryScopeLookup(names[0], out scopeEntry, out scopeIndex)) 
            { 
                //
                // check for invalid left correlation 
                //
                if (scopeEntry.Kind == ScopeEntryKind.JoinSourceVar && !CurrentScopeRegionFlags.IsInsideJoinOnPredicate)
                {
                    throw EntityUtil.EntitySqlError(errCtx, Strings.InvalidJoinLeftCorrelation); 
                }
 
                // 
                // Sets correlation flag
                // 
                SetScopeRegionCorrelationFlag(scopeIndex);

                //
                // trim resolved prefix 
                //
                names = TypeResolver.TrimNamesPrefix(names, 1); 
 
                //
                // get inner expression from the scope entry 
                // also verifies if a nested group aggregate is being referenced inside
                //
                innerExpr = GetExpressionFromScopeEntry(scopeEntry, scopeIndex);
 
                //
                // assume defining type as the expression type 
                // 
                definingType = innerExpr.ResultType;
 
            }
            //
            //
 
            else if (_variables.TryGetValue(names[0], out varInfo))
            { 
                // 
                // Can the identifier be resolved as a variable?
                // 
                names = TypeResolver.TrimNamesPrefix(names, 1);

                innerExpr = CmdTree.CreateVariableReferenceExpression(varInfo.Key, varInfo.Value);
 
                definingType = innerExpr.ResultType;
            } 
            else 
            {
                // 
                // Try resolve as entity container/entity set
                //
                if (TryResolveAsEntitySet(names, errCtx, out suffixIndex, out innerExpr))
                { 
                    //return innerExpr;
                    definingType = innerExpr.ResultType; 
                } 
                else
                { 
                    //
                    // try base type from metadata
                    //
                    int matchCount = 0; 

                    definingType = TypeResolver.ResolveBaseType(names, out suffixIndex, out matchCount); 
 
                    if (matchCount > 1)
                    { 
                        throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.AmbiguousName(TypeResolver.GetFullName(names)));
                    }
                }
            } 

            if (null != definingType) 
            { 
                return ResolveIdentifierChain(names, suffixIndex, definingType, innerExpr, errCtx);
            } 

            return null;
        }
 

        ///  
        /// Resolves Identifier name chain relative to a base expression 
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  
        /// 
        ///  
        ///  
        /// 
        ///  
        internal DbExpression ResolveIdentifierChain(string[] names, int suffixIndex, DbExpression innerExpr, ErrorContext errCtx)
        {
            return ResolveIdentifierChain(names, suffixIndex, innerExpr.ResultType, innerExpr, errCtx);
        } 

 
        ///  
        /// Resolve identifier chain of names
        ///  
        /// 
        /// 
        /// 
        ///  
        /// 
        ///  
        private DbExpression ResolveIdentifierChain(string[] names, 
                                                        int suffixIndex,
                                                        TypeUsage definingType, 
                                                        DbExpression innerExpr,
                                                        ErrorContext errCtx)
        {
            Debug.Assert(null != names, "null != names"); 
            Debug.Assert(null != definingType, "null != definingType");
 
            DbExpression convertedExpr = innerExpr; 

            if (names.Length > 0) 
            {
                TypeUsage baseType = definingType;
                for (int i = suffixIndex; i < names.Length; i++)
                { 
                    convertedExpr = ResolveIdentifierElement(baseType, convertedExpr, names[i], errCtx);
 
                    baseType = convertedExpr.ResultType; 
                }
            } 

            return convertedExpr;
        }
 

        ///  
        /// resolve part of identifier 
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  
        /// 
        ///  
        ///  
        /// 
        ///  
        internal DbExpression ResolveIdentifierElement(TypeUsage definingType, DbExpression innerExpr, string name, ErrorContext errCtx)
        {
            DbExpression converted = null;
 
            if (TryResolveAsProperty(name, (null == innerExpr ? definingType : innerExpr.ResultType), innerExpr, errCtx, out converted))
            { 
                return converted; 
            }
 
            if (TryResolveAsRef(name, (null == innerExpr ? definingType : innerExpr.ResultType), innerExpr, errCtx, out converted))
            {
                return converted;
            } 

            throw CqlErrorHelper.ReportIdentifierElementError(errCtx, name, definingType); 
        } 

 
        /// 
        /// Try resolve as EntitySet
        /// 
        ///  
        /// 
        ///  
        ///  
        private bool TryResolveAsEntitySet(string[] names, ErrorContext errCtx, out int suffixIndex, out DbExpression convExpr)
        { 
            Debug.Assert(names.Length > 0, "(names.Length > 0) assertion failed");
            convExpr = null;
            suffixIndex = 0;
            EntityContainer entityContainer = null; 

            // first see if there a default EC 
            if (names.Length == 1) 
            {
                entityContainer = TypeResolver.Perspective.GetDefaultContainer(); 
                suffixIndex = 0;
            }
            else
            { 
                if (TypeResolver.Perspective.TryGetEntityContainer(names[0], true /*ignoreCase*/, out entityContainer))
                { 
                    suffixIndex = 1; 
                }
                else 
                {
                    return false;
                }
            } 

            if (null != entityContainer) 
            { 
                EntitySetBase entitySet = null;
                if (TypeResolver.Perspective.TryGetExtent(entityContainer, names[suffixIndex], true /*ignoreCase*/, out entitySet)) 
                {
                    convExpr = CmdTree.CreateScanExpression(entitySet);
                    suffixIndex++;
                    return true; 
                }
                else if (names.Length > 1) 
                { 
                    throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.EntitySetIsDoesNotBelongToEntityContainer(names[1], names[0]));
                } 
            }

            if (names.Length == 1 && TypeResolver.Perspective.TryGetEntityContainer(names[0], true /*ignoreCase*/, out entityContainer))
            { 
                throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.MissingEntitySetName(names[0]));
            } 
 
            return false;
        } 

        /// 
        /// Try resolve name as property
        ///  
        /// 
        ///  
        ///  
        /// 
        ///  
        /// 
        private bool TryResolveAsProperty(string name, TypeUsage definingType, DbExpression innerExpr, ErrorContext errCtx, out DbExpression convExpr)
        {
            convExpr = null; 

            if (Helper.IsStructuralType(definingType.EdmType)) 
            { 
                EdmMember member = null;
                if (TypeResolver.Perspective.TryGetMember((StructuralType)definingType.EdmType, name, true, out member)) 
                {
                    if (null != member)
                    {
                        Debug.Assert(name.Equals(member.Name, StringComparison.OrdinalIgnoreCase), "name.Equals(member.Name,StringComparison.OrdinalIgnoreCase)"); 

                        if (null == innerExpr) 
                        { 
                            //
                            // if we dont have an instance, then it means it is a static member that is not supported in EDM 
                            //
                            throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.StaticMembersAreNotSupported(TypeHelpers.GetFullName(definingType.EdmType), name));
                        }
 
                        convExpr = CmdTree.CreatePropertyExpression(name, true /* case insenstive */, innerExpr);
 
                        return true; 
                    }
                } 
            }

            return false;
        } 

 
        ///  
        /// try resolve name as ref
        ///  
        /// 
        /// 
        /// 
        ///  
        /// 
        ///  
        private bool TryResolveAsRef(string name, TypeUsage definingType, DbExpression innerExpr, ErrorContext errCtx, out DbExpression convExpr) 
        {
            convExpr = null; 

            if (TypeSemantics.IsReferenceType(definingType))
            {
                convExpr = CmdTree.CreateDerefExpression(innerExpr); 

                TypeUsage dereferencedType = convExpr.ResultType; 
 
                if (TryResolveAsProperty(name, convExpr.ResultType, convExpr, errCtx, out convExpr))
                { 
                    return true;
                }

                throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.InvalidDeRefProperty(name, TypeHelpers.GetFullName(dereferencedType), TypeHelpers.GetFullName(definingType))); 
            }
 
            return false; 
        }
 
        /// 
        /// Resolve given name as Type
        /// 
        ///  
        /// 
        ///  
        ///  
        /// 
        ///  
        /// 
        /// TypeUsage
        internal TypeUsage ResolveNameAsType(string[] names, Expr astTypeExpression)
        { 
            int matchCount = 0;
            ErrorContext errCtx = astTypeExpression.ErrCtx; 
            TypeUsage typeUsage = TypeResolver.ResolveNameAsType(names, names.Length, out matchCount); 

            // 
            // if null, means there is no type with given name in the current typespace
            //
            if (null == typeUsage)
            { 
                CqlErrorHelper.ReportTypeResolutionError(names, astTypeExpression, this);
            } 
 
            //
            // if match count is greater then 1, means there are more then one match and is therefore ambiguous 
            //
            if (matchCount > 1)
            {
                throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.AmbiguousTypeName(TypeResolver.GetFullName(names))); 
            }
 
            // 
            // check for parametrized types
            // 
            MethodExpr methodExpr = astTypeExpression as MethodExpr;
            if (null != methodExpr)
            {
                typeUsage = HandleParametrizedType(typeUsage, methodExpr); 
            }
 
            return typeUsage; 
        }
 

        /// 
        /// Handles parametrized types such as Decimal, Decimal(p) and Decimal(p,s)
        ///  
        /// typeusage of the resolved type name
        /// ast node with representing additional type parameters to be validated 
        ///  
        private TypeUsage HandleParametrizedType(TypeUsage typeUsage, MethodExpr methodExpr)
        { 
            //
            // The only type in EDM that we support arguments is EDM.Decimal as of Sep 2007.
            //
            PrimitiveType primitiveType = typeUsage.EdmType as PrimitiveType; 
            if (null == primitiveType || primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.Decimal)
            { 
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.TypeDoesNotSupportParameters(primitiveType.FullName)); 
            }
 
            Debug.Assert(methodExpr.Args[0] is Literal, "first type argument must be a literal node");
            Debug.Assert((methodExpr.Args.Count == 2) ? methodExpr.Args[1] is Literal : true, "second type argument must be a literal node");

            // 
            // Get valid Precision for given type from provider
            // 
            byte precision = GetValidDecimalFacetValue(primitiveType, 
                                                      (Literal)methodExpr.Args[0],
                                                      DbProviderManifest.PrecisionFacetName); 

            //
            // Get valid Scale for given type from provider
            // 
            byte scale = 0;
            if (2 == methodExpr.Args.Count) 
            { 
                scale = GetValidDecimalFacetValue(primitiveType,
                                                  (Literal)methodExpr.Args[1], 
                                                  DbProviderManifest.ScaleFacetName);
            }

            // 
            // Ensure P >= S
            // 
            if (precision < scale) 
            {
                Debug.Assert(2 == methodExpr.Args.Count, "decimal with precision and scale must have 2 arguments"); 
                throw EntityUtil.EntitySqlError(methodExpr.Args[1].ErrCtx, System.Data.Entity.Strings.DecimalPrecisionMustBeGreaterThanScale(primitiveType.FullName));
            }

            // 
            // finally create TypeUsage with given precision and scale
            // 
            return TypeUsage.CreateDecimalTypeUsage(primitiveType, precision, scale); 
        }
 

        /// 
        /// validates and returns the appropriate facet for decimal type
        ///  
        /// 
        ///  
        ///  
        /// 
        private byte GetValidDecimalFacetValue(PrimitiveType primitiveType, Literal typeArg, string FacetName) 
        {
            FacetDescription facetDescription = Helper.GetFacet(primitiveType.ProviderManifest.GetFacetDescriptions(primitiveType), FacetName);
            if (null == facetDescription)
            { 
                throw EntityUtil.EntitySqlError(typeArg.ErrCtx, System.Data.Entity.Strings.TypeDoesNotSupportPrecisionOrScale(primitiveType.FullName, FacetName));
            } 
 
            byte typeArgValue = 0;
            if (Byte.TryParse(typeArg.OriginalValue, out typeArgValue)) 
            {
                if (typeArgValue > facetDescription.MaxValue)
                {
                    throw EntityUtil.EntitySqlError(typeArg.ErrCtx, System.Data.Entity.Strings.TypeSpecExceedsMax(FacetName)); 
                }
 
                if (typeArgValue < facetDescription.MinValue) 
                {
                    throw EntityUtil.EntitySqlError(typeArg.ErrCtx, System.Data.Entity.Strings.TypeSpecBellowMin(FacetName)); 
                }
            }
            else
            { 
                throw EntityUtil.EntitySqlError(typeArg.ErrCtx, System.Data.Entity.Strings.TypeSpecIsNotValid);
            } 
 
            return (byte)typeArgValue;
        } 


        /// 
        /// Handles expressions dotted id( List{e} ) that can be resolved to Static Methods, Type Constructors, Ordinary Functions and Aggregate Functions. 
        /// this function ensures that one of the 3 posibilities must be resolved, otherwise an exception will be raised.
        /// Also, it ensures that the name is not ambiguous. 
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        internal void ResolveNameAsStaticMethodOrFunction(MethodExpr methodExpr, 
                                                            out TypeUsage constructorType,
                                                            out TypeUsage staticMethodType, 
                                                            out IList functionType) 
        {
            DotExpr dotExpr = methodExpr.MethodPrefixExpr; 
            int matchCount = 0;
            int typeMatches = 0;

            constructorType = null; 
            staticMethodType = null;
            functionType = null; 
 
            //
            // Try Resolving as Type Constructor 
            //
            constructorType = TypeResolver.ResolveNameAsType(dotExpr.Names, dotExpr.Names.Length, out matchCount);
            if (0 < matchCount)
            { 
                typeMatches++;
 
                // 
                // ensure type has contructor. one of: Entity, ComplexType or RelationType
                // 
                if (!TypeSemantics.IsStructuralType(constructorType))
                {
                    throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.InvalidCtorUseOnType(TypeHelpers.GetFullName(constructorType)));
                } 

                if (1 < matchCount) 
                { 
                    dotExpr.ErrCtx.ErrorContextInfo = EntityRes.CtxGenericTypeCtor;
                    throw EntityUtil.EntitySqlError(dotExpr.ErrCtx, 
                                         System.Data.Entity.Strings.MultipleMatchesForName(
                                                       System.Data.Entity.Strings.LocalizedType,
                                                       dotExpr.FullName));
                } 
            }
 
            // 
            // Try Resolving as EdmFunction
            // 
            List foundNamespaces = null;
            functionType = TypeResolver.ResolveNameAsFunction(dotExpr.Names, true /* ignore case */, out matchCount, out foundNamespaces);

            if (0 < matchCount) 
            {
                typeMatches++; 
 
                if (1 < matchCount)
                { 
                    methodExpr.ErrCtx.ErrorContextInfo = EntityRes.CtxGenericFunctionCall;
                    CqlErrorHelper.ReportAmbiguousFunctionError(methodExpr, foundNamespaces);
                }
            } 

#if SUPPORT_STATIC_METHODS 
            // 
            // Try Resolving as Static Method
            // 
            staticMethodType = null;
            if (dotExpr.Names.Length > 1)
            {
                staticMethodType = TypeResolver.ResolveNameAsType(dotExpr.Names, dotExpr.Names.Length - 1, out matchCount); 
                if (0 < matchCount)
                { 
                    typeMatches++; 

                    if (1 < matchCount) 
                    {
                        dotExpr.ErrCtx.ErrorContextInfo = EntityRes.CtxMethod;
                        throw EntityUtil.QueryError(dotExpr.ErrCtx,
                                             System.Data.Entity.Strings.MultipleMatchesForName( 
                                                           System.Data.Entity.Strings.LocalizedType,
                                                           dotExpr.FullName)); 
                    } 
                }
            } 
#endif
            //
            // check if it is ambiguous. if the given method prefix name can be found as multiple types, then throw
            // 
            if (1 < typeMatches)
            { 
                throw EntityUtil.EntitySqlError(dotExpr.Identifier.ErrCtx, System.Data.Entity.Strings.AmbiguousFunctionMethodCtorName(dotExpr.FullName)); 
            }
 
            //
            // Check if lookup was a miss
            //
            if (0 == typeMatches) 
            {
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.CannotResolveNameToFunction(dotExpr.FullName)); 
            } 
        }
 


        /// 
        /// Creates new instance of a given Type (IEntity, ComplexType or RelationType) 
        /// Validates and infer argument types
        ///  
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  
        /// 
        ///  
        internal DbExpression CreateInstanceOfType(TypeUsage type, List args, List relshipExprList, MethodExpr methodExpr) 
        {
            DbExpression newInstance = null; 
            int idx = 0;
            int argCount = args.Count;

            methodExpr.ErrCtx.ErrorContextInfo = EntityRes.CtxGenericTypeCtor; 

            // 
            // abstract types cannot be instanciated 
            //
            if (type.EdmType.Abstract) 
            {
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx,
                                            System.Data.Entity.Strings.CannotInstantiateAbstractType(type.EdmType.FullName));
            } 

            // 
            // ensure DISTINCT/ALL was not used on type constructors 
            //
            if (methodExpr.DistinctKind != DistinctKind.None) 
            {
                methodExpr.ErrCtx.ErrorContextInfo = System.Data.Entity.Strings.CtxTypeCtorWithType(TypeHelpers.GetFullName(type));
                methodExpr.ErrCtx.UseContextInfoAsResourceIdentifier = false;
 
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx,
                                            Strings.InvalidDistinctArgumentInCtor); 
            } 

            // 
            // find overloads by searching members in order of its definition
            // each member will be considered as a formal argument type in the order of its definition
            //
            if (TypeSemantics.IsComplexType(type) || TypeSemantics.IsEntityType(type) || TypeSemantics.IsRelationshipType(type)) 
            {
                StructuralType stype = (StructuralType)type.EdmType; 
                foreach (EdmMember member in TypeHelpers.GetAllStructuralMembers(stype)) 
                {
                    TypeUsage memberModelTypeUsage = Helper.GetModelTypeUsage(member); 

                    Debug.Assert(memberModelTypeUsage.EdmType.DataSpace == DataSpace.CSpace, "member space must be CSpace");

                    // 
                    // ensure given arguments are not less than 'formal' constructor arguments
                    // 
                    if (argCount <= idx) 
                    {
                        methodExpr.ErrCtx.ErrorContextInfo = System.Data.Entity.Strings.CtxTypeCtorWithType(TypeHelpers.GetFullName(type)); 
                        methodExpr.ErrCtx.UseContextInfoAsResourceIdentifier = false;

                        throw EntityUtil.EntitySqlError(methodExpr.ErrCtx,
                                             System.Data.Entity.Strings.NumberOfTypeCtorIsLessThenFormalSpec(member.Name)); 
                    }
 
                    // 
                    // if given argument is an untyped null, infer type the ctor formal argument list type
                    // 
                    if (TypeSemantics.IsNullType(args[idx].ResultType))
                    {
                        if (Helper.IsEdmProperty(member) && !((EdmProperty)member).Nullable)
                        { 
                            throw EntityUtil.EntitySqlError(methodExpr.Args[idx].ErrCtx,
                                                 System.Data.Entity.Strings.InvalidNullLiteralForNonNullableMember( 
                                                               member.Name, 
                                                               TypeHelpers.GetFullName(stype)));
                        } 
                        args[idx] = CmdTree.CreateNullExpression(memberModelTypeUsage);
                    }

                    // 
                    // if not, given argument is already typed, then ensure it is promotable to formal ctor argument type
                    // 
                    bool isPromotable = TypeSemantics.IsPromotableTo(args[idx].ResultType, memberModelTypeUsage); 
                    if (ParserOptions.CompilationMode.RestrictedViewGenerationMode == _parserOptions.ParserCompilationMode ||
                        ParserOptions.CompilationMode.UserViewGenerationMode == _parserOptions.ParserCompilationMode        ) 
                    {
                        if (!isPromotable && !TypeSemantics.IsPromotableTo(memberModelTypeUsage, args[idx].ResultType))
                        {
                            throw EntityUtil.EntitySqlError(methodExpr.Args[idx].ErrCtx, 
                                                           System.Data.Entity.Strings.InvalidCtorArgumentType(
                                                           args[idx].ResultType.Identity, 
                                                           member.Name, 
                                                           memberModelTypeUsage.Identity));
                        } 

                        if (Helper.IsPrimitiveType(memberModelTypeUsage.EdmType) &&
                            !TypeSemantics.IsSubTypeOf(args[idx].ResultType, memberModelTypeUsage))
                        { 
                            args[idx] = _commandTree.CreateCastExpression(args[idx], memberModelTypeUsage);
                        } 
                    } 
                    else
                    { 
                        if (!isPromotable)
                        {
                            throw EntityUtil.EntitySqlError(methodExpr.Args[idx].ErrCtx,
                                                           System.Data.Entity.Strings.InvalidCtorArgumentType( 
                                                           args[idx].ResultType.Identity,
                                                           member.Name, 
                                                           memberModelTypeUsage.Identity)); 
                        }
                    } 

                    idx++;
                }
            } 
            //
            // the type does not support type constructors 
            // 
            else
            { 
                methodExpr.ErrCtx.ErrorContextInfo = System.Data.Entity.Strings.CtxTypeCtorWithType(TypeHelpers.GetFullName(type));
                methodExpr.ErrCtx.UseContextInfoAsResourceIdentifier = false;

                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, 
                                     System.Data.Entity.Strings.InvalidCtorUseOnType(
                                                   TypeHelpers.GetFullName(type))); 
            } 

            // 
            // ensure all given arguments and all 'formal' ctor arguments were considered and properly checked
            //
            if (idx != argCount)
            { 
                methodExpr.ErrCtx.ErrorContextInfo = System.Data.Entity.Strings.CtxTypeCtorWithType(TypeHelpers.GetFullName(type));
                methodExpr.ErrCtx.UseContextInfoAsResourceIdentifier = false; 
 
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx,
                                     System.Data.Entity.Strings.NumberOfTypeCtorIsMoreThenFormalSpec( 
                                                   TypeHelpers.GetFullName(type)));
            }

            // 
            // finally, create expression
            // 
            if (relshipExprList != null && relshipExprList.Count > 0) 
            {
                EntityType entityType = (EntityType)type.EdmType; 
                newInstance = CmdTree.CreateNewEntityWithRelationshipsExpression(entityType, args, relshipExprList);
            }
            else
            { 
                newInstance = CmdTree.CreateNewInstanceExpression(TypeHelpers.GetReadOnlyType(type), args);
            } 
            Debug.Assert(null != newInstance, "null != newInstance"); 

            return newInstance; 
        }


        ///  
        /// Creates DbFunctionExpression from metadata and arg list. validates overloads
        ///  
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  
        /// DbFunctionExpression
        internal DbExpression CreateFunction(IList functionTypeList, 
                                            List args, 
                                            MethodExpr methodExpr)
        { 
            Debug.Assert(functionTypeList.Count > 0, "functionList.Count > 0");

            DbExpression functionExpression = null;
            methodExpr.ErrCtx.ErrorContextInfo = EntityRes.CtxGenericFunctionCall; 
            bool isAmbiguous = false;
 
            // 
            // if DISTINCT was used, ensure function type and argument types are valid
            // 
            if (methodExpr.DistinctKind != DistinctKind.None)
            {
                methodExpr.ErrCtx.ErrorContextInfo = System.Data.Entity.Strings.CtxFunction(functionTypeList[0].Name);
                methodExpr.ErrCtx.UseContextInfoAsResourceIdentifier = false; 

                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, 
                                     Strings.InvalidDistinctArgumentInNonAggFunction); 
            }
 
            //
            // collect argument types from argument expression list
            //
            List argTypes = new List(args.Count); 
            for (int i = 0; i < args.Count; i++)
            { 
                argTypes.Add(args[i].ResultType); 
            }
 
            //
            // Find function overload match for given argument types
            //
            EdmFunction functionType = TypeResolver.ResolveFunctionOverloads(functionTypeList, 
                                                                              argTypes,
                                                                              false /* isGroupAggregateFunction */, 
                                                                              out isAmbiguous); 
            //
            // if there is more then one overload that matches given arguments, throw 
            //
            if (isAmbiguous)
            {
                methodExpr.ErrCtx.ErrorContextInfo = System.Data.Entity.Strings.CtxFunction(functionTypeList[0].Name); 
                methodExpr.ErrCtx.UseContextInfoAsResourceIdentifier = false;
 
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, 
                                            Strings.AmbiguousFunctionArguments);
            } 

            //
            // if null, means no overload matched
            // 
            if (null == functionType)
            { 
                CqlErrorHelper.ReportFunctionOverloadError(methodExpr, functionTypeList[0], argTypes); 
            }
 
            //
            // fixup untyped nulls in given arguments from formal method argument types
            //
            for (int i = 0; i < args.Count; i++) 
            {
                if (TypeSemantics.IsNullType(args[i].ResultType)) 
                { 
                    args[i] = CmdTree.CreateNullExpression(functionType.Parameters[i].TypeUsage);
                } 
            }

            //
            // Finally, create expression 
            //
            functionExpression = CmdTree.CreateFunctionExpression(functionType, args); 
 
            Debug.Assert(null != functionExpression, "null != functionExpression");
 
            return functionExpression;
        }

        ///  
        /// Creates a static method expression
        ///  
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  
        /// MethodExpression
        internal static DbExpression CreateStaticMethod(TypeUsage definingType, List args, MethodExpr methodExpr) 
        { 
            return CreateMethod(definingType, args, methodExpr, null, true);
        } 


        /// 
        /// creates instance method expression 
        /// 
        ///  
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        /// InstanceMethodExpression or StaticMethodExpression 
        internal static DbExpression CreateInstanceMethod(DbExpression instance, List args, MethodExpr methodExpr)
        { 
            return CreateMethod(instance.ResultType, args, methodExpr, instance, false); 
        }
 

        /// 
        /// Creates a method expression.
        ///  
        /// 
        ///  
        ///  
        /// 
        ///  
        /// 
        private static DbExpression CreateMethod(TypeUsage definingType,
                                            List args,
                                            MethodExpr methodExpr, 
                                            DbExpression instance,
                                            bool isStatic) 
        { 
#if METHOD_EXPRESSION
            Expression methodExpression = null; 

            methodExpr.ErrCtx.ContextInfo = System.Data.Entity.Strings.CtxMethodTerm(methodExpr.MethodName);

            // 
            // ensure definiting type is allowed for method calls
            // 
            if (!TypeResolver.IsValidTypeForMethodCall(definingType)) 
            {
                throw EntityUtil.QueryError(methodExpr.ErrCtx, System.Data.Entity.Strings.DefiningTypeDoesNotSupportMethodCalls); 
            }

            //
            // check if distinct/ALL was incorrectly used on methods 
            //
            if (methodExpr.DistinctKind != DistinctKind.None) 
            { 
                throw EntityUtil.QueryError(methodExpr.ErrCtx, System.Data.Entity.Strings.InvalidDistinctArgumentInMethod);
            } 

            //
            // create list of arg types
            // 
            List argTypes = new List();
            foreach (Expression argExpr in args) 
            { 
                argTypes.Add(argExpr.ResultType);
            } 

            //
            // Find function overload match for given args
            // 
            bool isAmbiguous = false;
            MethodMetadata methodMetadata = TypeResolver.ResolveMethodOverloads(definingType, 
                                                                                       methodExpr.MethodName, 
                                                                                       argTypes,
                                                                                       isStatic, 
                                                                                       out isAmbiguous);

            //
            // check if more than one overload match was found 
            //
            if (isAmbiguous) 
            { 
                throw EntityUtil.QueryError(methodExpr.ErrCtx, System.Data.Entity.Strings.AmbiguousFunctionArguments);
            } 

            //
            // check if there is a match
            // 
            if (null == methodMetadata)
            { 
                throw EntityUtil.QueryError(methodExpr.ErrCtx, System.Data.Entity.Strings.NoMethodOverloadMatch(methodExpr.MethodName, definingType.FullName)); 
            }
 
            //
            // fixup untyped nulls in given arguments from formal method argument types
            //
            for (int i = 0 ; i < args.Count ; i++) 
            {
                if (TypeResolver.IsNull(args[i].ResultType)) 
                { 
                    args[i] = CmdTree.CreateNullExpression(methodMetadata.Parameters[i].Type);
                } 
            }

            //
            // Finally, create expression 
            //
#if CALCULATED_MEMBERS 
            ClrCalculatedMethod clrCalculatedMethod = methodMetadata as ClrCalculatedMethod; 
            if (null != clrCalculatedMethod)
            { 
                if (!isStatic)
                {
                    args.Insert(0, instance);
                } 

                methodExpression = clrCalculatedMethod.GetExpression(CmdTree, args); 
 
            }
            else 
            {
#endif
                if (isStatic)
                { 
                    methodExpression = CmdTree.CreateStaticMethodExpression(methodMetadata, args);
                } 
                else 
                {
                    methodExpression = CmdTree.CreateInstanceMethodExpression(methodMetadata, instance, args); 
                }
#if CALCULATED_MEMBERS
            }
#endif 

            Debug.Assert(null != methodExpression); 
 
            return methodExpression;
#endif 
            throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.MethodInvocationNotSupported);
        }

        ///  
        /// Ensure and typifies nulls if present
        ///  
        ///  
        /// 
        ///  
        /// Pair of Expressions with NullTypes inferred to the proper type
        internal Pair EnsureTypedNulls(DbExpression leftExpr,
                                                                DbExpression rightExpr,
                                                                ErrorContext errCtx, 
                                                                Func formatMessage)
        { 
            DbExpression newLeftExpr = leftExpr; 
            DbExpression newRightExpr = rightExpr;
            UntypedNullExpression untypedLeftExpr = leftExpr as UntypedNullExpression; 
            UntypedNullExpression untypedRightExpr = rightExpr as UntypedNullExpression;

            if (null != untypedLeftExpr)
            { 
                if (null != untypedRightExpr || null == rightExpr)
                { 
                    throw EntityUtil.EntitySqlError(errCtx, formatMessage()); 
                }
                else 
                {
                    newLeftExpr = CmdTree.CreateNullExpression(rightExpr.ResultType);
                }
            } 
            else if (null != untypedRightExpr)
            { 
                newRightExpr = CmdTree.CreateNullExpression(leftExpr.ResultType); 
            }
 
            return new Pair(newLeftExpr, newRightExpr);
        }

 
        /// 
        /// returns if an expresison is an untyped null expression 
        ///  
        /// 
        ///  
        internal static bool IsNullExpression(DbExpression expression)
        {
            return expression is UntypedNullExpression;
        } 

 
        ///  
        /// Set current source scope kind
        ///  
        /// 
        internal void SetCurrentScopeKind(ScopeEntryKind scopeKind)
        {
            CurrentScopeRegionFlags.ScopeEntryKind = scopeKind; 
        }
 
        ///  
        /// Get current source scope kind
        ///  
        internal ScopeEntryKind CurrentScopeKind
        {
            get { return CurrentScopeRegionFlags.ScopeEntryKind; }
        } 

 
        ///  
        /// Generates internal name to be used in cqt
        ///  
        /// 
        /// 
        internal string GenerateInternalName(string hint)
        { 
            // string concat is faster than String.Join and much faster than String.Format
            return "_##" + hint + unchecked(_namegenCounter++).ToString(CultureInfo.InvariantCulture); 
        } 

        private static DbExpressionKind[] joinMap = { DbExpressionKind.CrossJoin, DbExpressionKind.InnerJoin, DbExpressionKind.LeftOuterJoin, DbExpressionKind.FullOuterJoin }; 

        /// 
        /// maps ast jointype to cqt join type
        ///  
        /// 
        ///  
        internal static DbExpressionKind MapJoinKind(JoinKind joinKind) 
        {
            Debug.Assert(joinKind != JoinKind.RightOuter, "joinKind != JoinKind.RightOuter"); 
            return joinMap[(int)joinKind];
        }

 
        private static DbExpressionKind[] applyMap = { DbExpressionKind.CrossApply, DbExpressionKind.OuterApply };
 
        ///  
        /// maps ast applytype to cqt apply type
        ///  
        /// 
        /// 
        internal static DbExpressionKind MapApplyKind(ApplyKind applyKind)
        { 
            return applyMap[(int)applyKind];
        } 
 

        ///  
        /// returns current scope region savepoint
        /// 
        internal SavePoint CurrentScopeRegionSavePoint
        { 
            get
            { 
                Debug.Assert(_scopeRegionSavepoints.Count > 0, "_scopeRegionSavepoints.Count > 0"); 

                return _scopeRegionSavepoints[0]; 
            }
        }

        ///  
        /// propagates new ebinding up the tree for the vars in scope
        ///  
        ///  
        internal void FixupSourceVarBindings(DbVariableReferenceExpression newSourceVar)
        { 
            Debug.Assert(CurrentScopeRegionSavePoint.ScopeIndex + 1 <= CurrentScopeIndex, "CurrentScopeRegionSavePoint.ScopeIndex + 1 <= CurrentScopeIndex");

            for (int i = CurrentScopeRegionSavePoint.ScopeIndex + 1; i <= CurrentScopeIndex; i++)
            { 
                foreach (KeyValuePair scope in _staticContext.GetScopeByIndex(i))
                { 
                    SourceScopeEntry scopeEntry = scope.Value as SourceScopeEntry; 
                    if (null != scopeEntry)
                    { 
                        scopeEntry.SetNewSourceBinding(newSourceVar);
                    }
                }
            } 
        }
 
 
        /// 
        /// fixup new eb 
        /// 
        /// 
        internal void FixupNamedSourceVarBindings(DbVariableReferenceExpression newSourceVar)
        { 
            Debug.Assert(CurrentScopeRegionSavePoint.ScopeIndex + 1 <= CurrentScopeIndex, "CurrentScopeRegionSavePoint.ScopeIndex + 1 <= CurrentScopeIndex");
 
            for (int i = CurrentScopeRegionSavePoint.ScopeIndex + 1; i <= CurrentScopeIndex; i++) 
            {
                foreach (KeyValuePair scope in _staticContext.GetScopeByIndex(i)) 
                {
                    if (scope.Value.Kind == CurrentScopeKind && !scope.Value.IsHidden)
                    {
                        SourceScopeEntry scopeEntry = scope.Value as SourceScopeEntry; 
                        if (null != scopeEntry && TreePathTagger.IsChildNode(CurrentScopeRegionFlags.PathTagger.Tag, scopeEntry.VarTag))
                        { 
                            scopeEntry.AddBindingPrefix(newSourceVar.VariableName); 
                            scopeEntry.SetNewSourceBinding(newSourceVar);
                        } 
                    }
                }
            }
        } 

        internal void MarkGroupInputVars() 
        { 
            for (int i = CurrentScopeRegionSavePoint.ScopeIndex + 1; i <= CurrentScopeIndex; i++)
            { 
                foreach (KeyValuePair scope in _staticContext.GetScopeByIndex(i))
                {
                    if (scope.Value.VarKind != SourceVarKind.GroupAggregate && scope.Value.VarKind != SourceVarKind.GroupKey)
                    { 
                        scope.Value.VarKind = SourceVarKind.GroupInput;
                    } 
                } 
            }
        } 

        /// 
        /// Fixes up source vars and adds groupvar in case the var is referenced in an group aggregate fucntion
        ///  
        /// 
        ///  
        internal void FixupGroupSourceVarBindings(DbVariableReferenceExpression newSourceVar, DbVariableReferenceExpression newGroupVar) 
        {
            InternalFixupGroupSourceVarBindings(newSourceVar, newGroupVar); 
        }


        ///  
        /// undo group var
        ///  
        ///  
        internal void UndoFixupGroupSourceVarBindings(DbVariableReferenceExpression originalSourceVar)
        { 
            InternalFixupGroupSourceVarBindings(originalSourceVar, null);
        }

 
        private void InternalFixupGroupSourceVarBindings(DbVariableReferenceExpression newSourceVar, DbVariableReferenceExpression newGroupVar)
        { 
            Debug.Assert(CurrentScopeRegionSavePoint.ScopeIndex + 1 <= CurrentScopeIndex, "CurrentScopeRegionSavePoint.ScopeIndex + 1 <= CurrentScopeIndex"); 

            for (int i = CurrentScopeRegionSavePoint.ScopeIndex + 1; i <= CurrentScopeIndex; i++) 
            {
                foreach (KeyValuePair scope in _staticContext.GetScopeByIndex(i))
                {
                    if (scope.Value.Kind == CurrentScopeKind && !scope.Value.IsHidden) 
                    {
                        SourceScopeEntry scopeEntry = scope.Value as SourceScopeEntry; 
                        if (null != scopeEntry) 
                        {
                            scopeEntry.SetNewSourceBinding(newSourceVar); 
                            scopeEntry.GroupVarExpression = newGroupVar;
                        }
                    }
                } 
            }
        } 
 

        ///  
        /// Sets Current Scope Source Var Kind
        /// 
        /// 
        internal void SetCurrentScopeVarKind(FromClauseItemKind fromClauseItemKind) 
        {
            if (fromClauseItemKind == FromClauseItemKind.JoinFromClause) 
            { 
                SetCurrentScopeKind(ScopeEntryKind.JoinSourceVar);
            } 
            else if (fromClauseItemKind == FromClauseItemKind.ApplyFromClause)
            {
                SetCurrentScopeKind(ScopeEntryKind.ApplySourceVar);
            } 
            else
            { 
                SetCurrentScopeKind(ScopeEntryKind.SourceVar); 
            }
        } 


        /// 
        /// resets all source vars to default SourceVar Kind 
        /// 
        internal void ResetCurrentScopeVarKind() 
        { 
            for (int i = CurrentScopeRegionSavePoint.ScopeIndex + 1; i <= CurrentScopeIndex; i++)
            { 
                foreach (KeyValuePair scope in _staticContext.GetScopeByIndex(i))
                {
                    scope.Value.Kind = ScopeEntryKind.SourceVar;
                } 
            }
 
            SetCurrentScopeKind(ScopeEntryKind.SourceVar); 
        }
 

        /// 
        /// Infers and Creates a new Alias name based on expr information
        ///  
        /// 
        ///  
        private string CreateNewAlias(DbExpression expr) 
        {
            DbScanExpression extent = expr as DbScanExpression; 
            if (null != extent)
            {
                return extent.Target.Name;
            } 

            DbPropertyExpression property = expr as DbPropertyExpression; 
            if (null != property) 
            {
                return property.Property.Name; 
            }

            DbVariableReferenceExpression varRef = expr as DbVariableReferenceExpression;
            if (null != varRef) 
            {
                return varRef.VariableName; 
            } 

            return GenerateInternalName(String.Empty); 
        }


        ///  
        /// infers alias name from astNode information and converted expression.
        ///  
        ///  
        /// 
        ///  
        internal string InferAliasName(AliasExpr aliasExpr, DbExpression convertedExpression)
        {
            if (aliasExpr.HasAlias)
            { 
                return aliasExpr.AliasIdentifier.Name;
            } 
 
            Identifier id = aliasExpr.Expr as Identifier;
            if (null != id) 
            {
                return id.Name;
            }
 
            DotExpr dotExpr = aliasExpr.Expr as DotExpr;
            if (null != dotExpr && dotExpr.IsDottedIdentifier) 
            { 
                return dotExpr.Names[dotExpr.Length - 1];
            } 

            return CreateNewAlias(convertedExpression);
        }
 

        ///  
        /// represents scope region disposer helper 
        /// 
        internal sealed class ScopeRegionDisposer : IDisposable 
        {
            private SemanticResolver _semanticResolver;

            internal ScopeRegionDisposer(SemanticResolver semanticResolver) 
            {
                _semanticResolver = semanticResolver; 
            } 

            public void Dispose() 
            {
                _semanticResolver.LeaveScopeRegion();
            }
        } 

 
        ///  
        /// adds a scope entry to the scope
        ///  
        /// 
        /// 
        internal void AddToScope(string key, ScopeEntry scopeEntry)
        { 
            _staticContext.Add(key, scopeEntry);
        } 
 

        ///  
        /// Removes an entry from scope
        /// 
        /// 
        internal void RemoveFromScope(string key) 
        {
            _staticContext.RemoveFromScope(key); 
        } 

 
        /// 
        /// enters a scope region
        /// 
        ///  
        internal ScopeRegionDisposer EnterScopeRegion()
        { 
            Debug.Assert(_scopeRegionSavepoints.Count == _scopeRegionFlags.Count, "_scopeRegionSavepoints.Count == _scopeRegionFlags.Count"); 

            // 
            // push new savepoint
            //
            _scopeRegionSavepoints.Insert(0, CreateSavePoint());
 
            //
            // push new scope 
            // 
            _staticContext.EnterScope();
 
            //
            // push new scoperegion flags
            //
            _scopeRegionFlags.Insert(0, new ScopeRegionFlags()); 

            Debug.Assert(_scopeRegionSavepoints.Count == _scopeRegionFlags.Count, "_scopeRegionSavepoints.Count == _scopeRegionFlags.Count"); 
 
            //
            // return disposer 
            //
            return new ScopeRegionDisposer(this);
        }
 

        ///  
        /// Leaves a scope region 
        /// 
        internal void LeaveScopeRegion() 
        {
            Debug.Assert(_scopeRegionSavepoints.Count > 0, "_scopeRegionSavepoints.Count > 0");
            Debug.Assert(_scopeRegionFlags.Count > 0, "_scopeRegionFlags.Count > 0");
            Debug.Assert(_scopeRegionSavepoints.Count == _scopeRegionFlags.Count, "_scopeRegionSavepoints.Count == _scopeRegionFlags.Count"); 

            // 
            // roll back scopes to the ScopeRegion savepoint 
            //
            RollbackToSavepoint(CurrentScopeRegionSavePoint); 

            //
            // pop top ScopeRegion savepoint
            // 
            _scopeRegionSavepoints.RemoveAt(0);
 
            // 
            // cleanup all aggregates related to this scope region
            // 
            foreach (MethodExpr me in CurrentScopeRegionFlags.GroupAggregatesInfo.Keys)
            {
                me.ResetAggregateInfo();
            } 

            // 
            // pop top ScopeRegion flags 
            //
            _scopeRegionFlags.RemoveAt(0); 

            //
            // restore scope view to the previously save view
            // 
            SetScopeView(CurrentScopeRegionFlags.ScopeViewKind);
 
            Debug.Assert(_scopeRegionSavepoints.Count == _scopeRegionFlags.Count, "_scopeRegionSavepoints.Count == _scopeRegionFlags.Count"); 
        }
 
        /// 
        /// Creates a scope save point
        /// 
        ///  
        internal SavePoint CreateSavePoint()
        { 
            return new SavePoint(CurrentScopeIndex); 
        }
 
        /// 
        /// rolls back the scope to a give savepoint
        /// 
        ///  
        internal void RollbackToSavepoint(SavePoint sp)
        { 
            _staticContext.RollbackToSavepoint(sp); 
        }
 
        /// 
        /// returns current scope region flags
        /// 
        internal ScopeRegionFlags CurrentScopeRegionFlags 
        {
            get { return _scopeRegionFlags[0]; } 
        } 

        ///  
        /// scope disposer
        /// 
        internal sealed class ScopeDisposer : IDisposable
        { 
            private SemanticResolver _semanticResolver;
 
            internal ScopeDisposer(SemanticResolver semanticResolver) 
            {
                _semanticResolver = semanticResolver; 
            }

            public void Dispose()
            { 
                _semanticResolver.LeaveScope();
            } 
        } 

 
        /// 
        /// entry scope
        /// 
        ///  
        internal ScopeDisposer EnterScope()
        { 
            _staticContext.EnterScope(); 

            return new ScopeDisposer(this); 
        }


        ///  
        /// leave scope
        ///  
        internal void LeaveScope() 
        {
            _staticContext.LeaveScope(); 
        }

        /// 
        /// ensures the expression is typed 
        /// 
        ///  
        ///  
        /// 
        ///  
        /// 
        internal static void EnsureIsNotUntypedNull(DbExpression expression, ErrorContext errCtx)
        {
            if (expression is UntypedNullExpression) 
            {
                throw EntityUtil.EntitySqlError(errCtx, Strings.ExpressionCannotBeNull); 
            } 
        }
 
        /// 
        /// checks if a name is in the current scope
        /// 
        ///  
        /// 
        internal bool IsInCurrentScope(string key) 
        { 
            return _staticContext.IsInCurrentScope(key);
        } 


        /// 
        /// adds a source binding 
        /// 
        ///  
        internal void AddSourceBinding(DbExpressionBinding sourceBinding) 
        {
            _staticContext.AddSourceBinding(sourceBinding, this.CurrentScopeRegionFlags.ScopeEntryKind, this.CurrentScopeRegionFlags.PathTagger.Tag); 
        }

        /// 
        /// adds dummy group key to be consumed during aggregate search pahse 
        /// 
        ///  
        ///  
        /// 
        internal void AddDummyGroupKeyToScope(string groupKey, DbExpression varBasedExpression, DbExpression groupVarBasedExpression) 
        {
            _staticContext.AddGroupDummyVar(groupKey, varBasedExpression, groupVarBasedExpression);
        }
 
        /// 
        /// Replaces dummy key added during the aggregate search phase by the real group key 
        ///  
        /// 
        ///  
        internal void ReplaceGroupVarInScope(string groupVarName, DbVariableReferenceExpression groupSourceBinding)
        {
            _staticContext.ReplaceGroupVarInScope(groupVarName, groupSourceBinding);
        } 

        ///  
        /// Adds group aggregate vars to scope, including nested aggregate 
        /// 
        ///  
        /// 
        internal void AddGroupAggregateToScope(string aggregateName, DbVariableReferenceExpression sourceVar)
        {
            _staticContext.AddAggregateToScope(aggregateName, sourceVar); 
        }
 
        ///  
        /// Validates that the specified parameters have valid, non-duplicated names
        ///  
        /// The set of input parameter names and types
        /// A valid dictionary that maps parameter names to types using the current StringComparer
        private Dictionary ValidateParameters(Dictionary paramDefs)
        { 
            Dictionary retParams = new Dictionary(_stringComparer);
 
            if (paramDefs != null) 
            {
                foreach (KeyValuePair paramDef in paramDefs) 
                {
                    if (retParams.ContainsKey(paramDef.Key))
                    {
                        throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.MultipleDefinitionsOfParameter(paramDef.Key)); 
                    }
 
                    if (!ValidateParameterType(paramDef.Value)) 
                    {
                        throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.InvalidParameterType(paramDef.Key)); 
                    }

                    retParams.Add(paramDef.Key, paramDef.Value);
                } 
            }
 
            return retParams; 
        }
 

        /// 
        /// Validates that the specified variables have valid, non-duplicated names
        ///  
        /// The set of input parameter names and types
        /// A valid dictionary that maps variable names to types using the current StringComparer 
        private Dictionary> ValidateVariables(Dictionary varDefs) 
        {
            Dictionary> retVars = 
                new Dictionary>(_stringComparer);

            if (varDefs != null)
            { 
                foreach (KeyValuePair varDef in varDefs)
                { 
                    if (retVars.ContainsKey(varDef.Key)) 
                    {
                        throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.MultipleDefinitionsOfVariable(varDef.Key)); 
                    }

                    retVars.Add(varDef.Key, new KeyValuePair(varDef.Key, varDef.Value));
                } 
            }
 
            return retVars; 
        }
 
        private static bool ValidateParameterType(TypeUsage paramType)
        {
            return (paramType != null && paramType.EdmType != null &&
                (TypeSemantics.IsPrimitiveType(paramType) || paramType.EdmType is EnumType)); 
        }
 
        internal static void EnsureValidTypeForNullExpression(TypeUsage type, ErrorContext errCtx) 
        {
            if (TypeSemantics.IsCollectionType(type)) 
            {
                throw EntityUtil.EntitySqlError(errCtx, Strings.NullLiteralCannotBePromotedToCollectionOfNulls);
            }
        } 

        ///  
        /// Adds the group aggregate information to the innermost correlated scope. if the expression is not correlated 
        /// then add to the innermost scope.
        ///  
        /// 
        /// 
        /// 
        ///  
        internal void AddGroupAggregateInfoToScopeRegion(MethodExpr astNode, string aggregateName, DbAggregate aggregateExpression, int groupVarScopeIndex)
        { 
            int scopeRegionIndex = 0; 
            bool bFound = false;
 
            // if scope index is NonCorrelatedScope, it means the inner aggregate expression is not correlated and it is
            // just as constant expression
            if (groupVarScopeIndex == AggregateAstNodeInfo.NonCorrelatedScope)
            { 
                bFound = true;
                scopeRegionIndex = 0; 
            } 
            else
            { 
                // inner expression is correlated and we need to find the exact group var scope
                for (scopeRegionIndex = 0; scopeRegionIndex < _scopeRegionSavepoints.Count; scopeRegionIndex++)
                {
                    if (_scopeRegionSavepoints[scopeRegionIndex].ContainsScope(groupVarScopeIndex)) 
                    {
                        bFound = true; 
                        break; 
                    }
                } 
            }

            if (bFound)
            { 
                Debug.Assert(_scopeRegionFlags.Count > 0, "must have a scope region (_scopeRegionFlags.Count > 0)");
                _scopeRegionFlags[scopeRegionIndex].AddGroupAggregateInfo(astNode, new GroupAggregateInfo(aggregateName, aggregateExpression)); 
            } 
            else
            { 
                throw EntityUtil.EntitySqlError(Strings.GroupVarNotFoundInScope);
            }
        }
 
        /// 
        /// pushes aggregate ast node 
        ///  
        /// 
        internal void PushAggregateAstNode(MethodExpr astNode) 
        {
            _aggregateAstNodes.Insert(0, new AggregateAstNodeInfo(astNode));
        }
 
        /// 
        /// removes aggregate ast node from the top of the stack 
        ///  
        /// 
        internal AggregateAstNodeInfo PopAggregateAstNode() 
        {
            Debug.Assert(_aggregateAstNodes.Count > 0, "_aggregateAstNodeInfo.Count must be greater than zero to pop");
            AggregateAstNodeInfo result = _aggregateAstNodes[0];
            _aggregateAstNodes.RemoveAt(0); 
            return result;
        } 
 

        ///  
        /// returns true if any of the ScopeRegions from the closest to the outermost has a group scope
        /// 
        /// 
        internal bool IsInAnyGroupScope() 
        {
            for (int i = 0; i < _scopeRegionFlags.Count; i++) 
            { 
                if (_scopeRegionFlags[i].IsInGroupScope)
                { 
                    return true;
                }
            }
            return false; 
        }
 
        ///  
        /// resets correlation flag in current scope region
        ///  
        internal void ResetScopeRegionCorrelationFlag()
        {
            CurrentScopeRegionFlags.WasResolutionCorrelated = false;
        } 

        ///  
        /// sets the correlation flag based on the input var scope index 
        /// 
        ///  
        internal void SetScopeRegionCorrelationFlag(int scopeIndex)
        {
            Debug.Assert(_scopeRegionFlags.Count == _scopeRegionSavepoints.Count, "_scopeRegionFlags.Count == _scopeRegionSavepoints.Count pre-condition FAILED");
            for (int i = 0; i < _scopeRegionFlags.Count; i++) 
            {
                if (scopeIndex > _scopeRegionSavepoints[i].ScopeIndex) 
                { 
                    _scopeRegionFlags[i].WasResolutionCorrelated = true;
                    return; 
                }
            }
        }
 
        /// 
        /// ensures limit expression (used in TOP and LIMIT) have valid pre-conditions 
        /// NOTE that in M3.2 these preconditions are exactly the same for TOP and LIMIT. 
        /// 
        ///  
        /// 
        /// 
        internal void EnsureValidLimitExpression(ErrorContext errCtx, DbExpression expr, string subclauseName)
        { 
            //
            // ensure resolved expression have the right type 
            // 
            if (!TypeSemantics.IsPromotableTo(expr.ResultType, TypeResolver.Int64Type))
            { 
                throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.PlaceholderExpressionMustBeCompatibleWithEdm64(subclauseName, expr.ResultType.EdmType.FullName));
            }

            // 
            // if it is a literal, make sure it has the correct value
            // 
            DbConstantExpression constantExpr = expr as DbConstantExpression; 
            if (null != constantExpr && System.Convert.ToInt64(constantExpr.Value, CultureInfo.InvariantCulture) < 0)
            { 
                throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.PlaceholderExpressionMustBeGreaterThanOrEqualToZero(subclauseName));
            }
        }
 

        ///  
        /// Ensures Projection is valid for Distinct modifier 
        /// 
        ///  
        /// 
        internal static void ValidateDistinctProjection(SelectClause selectClause, TypeUsage projectionType)
        {
            TypeUsage elemType = TypeHelpers.GetElementTypeUsage(projectionType); 
            if (!TypeHelpers.IsValidDistinctOpType(elemType))
            { 
                ErrorContext errCtx = selectClause.Items[0].Expr.ErrCtx; 
                if (TypeSemantics.IsRowType(elemType))
                { 
                    RowType rowType = elemType.EdmType as RowType;
                    Debug.Assert(selectClause.Items.Count == rowType.Members.Count);
                    for (int i = 0; i < rowType.Members.Count; i++)
                    { 
                        if (!TypeSemantics.IsEqualComparable(rowType.Members[i].TypeUsage))
                        { 
                            errCtx = selectClause.Items[i].Expr.ErrCtx; 
                            break;
                        } 
                    }
                }
                throw EntityUtil.EntitySqlError(errCtx, Strings.SelectDistinctMustBeEqualComparable);
            } 
        }
 
        ///  
        /// Ensures that the result of a query expression is valid.
        ///  
        /// 
        /// 
        internal static void ValidateQueryResultType(TypeUsage resultType, ErrorContext errCtx)
        { 
            if (Helper.IsCollectionType(resultType.EdmType))
            { 
                ValidateQueryResultType(((CollectionType)resultType.EdmType).TypeUsage, errCtx); 
            }
            else if (Helper.IsRowType(resultType.EdmType)) 
            {
                foreach (EdmProperty property in ((RowType)resultType.EdmType).Properties)
                {
                    ValidateQueryResultType(property.TypeUsage, errCtx); 
                }
            } 
            else if (Helper.IsAssociationType(resultType.EdmType)) 
            {
                throw EntityUtil.EntitySqlError(errCtx, Strings.InvalidQueryResultType(resultType.Identity)); 
            }
        }
    }
 

    ///  
    /// represents a method ast node during aggregate resolution 
    /// 
    internal sealed class AggregateAstNodeInfo 
    {
        internal const int NonCorrelatedScope = Int32.MinValue;
        private MethodExpr _methodExpr;
        private int _scopeIndex; 

        internal AggregateAstNodeInfo( MethodExpr methodAstNode ) 
        { 
            _methodExpr = methodAstNode;
            _scopeIndex = NonCorrelatedScope; 
        }

        internal void AssertMethodExprEquivalent(MethodExpr other)
        { 
            Debug.Assert(_methodExpr == other, "method ast node from the top of the stack must be the same");
        } 
 
        internal int ScopeIndex
        { 
            get { return _scopeIndex; }
            set
            {
                Debug.Assert(value >= 0); 
                _scopeIndex = value;
            } 
        } 
    }
 
    /// 
    /// represents resolved group aggregate information
    /// 
    internal sealed class GroupAggregateInfo 
    {
        private DbAggregate _aggregateExpression = null; 
        private string _aggregateName = null; 

        internal GroupAggregateInfo( string aggregateName, DbAggregate aggregateExpression ) 
        {
            _aggregateName = aggregateName;
            _aggregateExpression = aggregateExpression;
        } 

        internal DbAggregate AggregateExpression 
        { 
            get { return _aggregateExpression; }
        } 

        internal string AggregateName
        {
            get { return _aggregateName; } 
        }
    } 
 
    ///
    /// represents set of flags for a ScopeRegion 
    ///
    internal sealed class ScopeRegionFlags
    {
        /// 
        /// used to indicate when JoinSourceVars are visible within the scope of join sub-expresion tree resolution.
        /// Join right sub-expressions must not refer to join left sub-expressions (recursively). Of course, by definition 
        /// ON predicate is allowed to refer to any previously defined join sources. General left correlation 
        /// is allowed though. for instance:
        ///     Select ... From A JOIN B JOIN A.x -> invalid 
        ///     Select ... From A JOIN B JOIN C ON A.x == C.x -> valid
        ///     Select ... From A JOIN B, C JOIN A.x ... -> valid
        ///
        private bool _isInsideJoinOnPredicate = false; 
        internal bool IsInsideJoinOnPredicate
        { 
            get { return _isInsideJoinOnPredicate; } 
            set { _isInsideJoinOnPredicate = value; }
        } 

        ///
        /// indicates if input scope has group scope semantics
        /// 
        private bool _isInGroupScope = false;
        internal bool IsInGroupScope 
        { 
            get { return _isInGroupScope; }
            set { _isInGroupScope = value; } 
        }

        /// 
        /// indicates expression being resolved is a candidate for group aggregate and 
        /// should reference groupVar instead of the sourceVar
        ///  
        private bool _isInsideGroupAggregate = false; 
        internal bool IsInsideGroupAggregate
        { 
            get { return _isInsideGroupAggregate; }
            set { _isInsideGroupAggregate = value; }
        }
 
        /// 
        /// tracks group aggregate nesting calls 
        ///  
        private int _groupAggregateNestingCount = 0;
        internal int GroupAggregateNestingCount 
        {
            get { return _groupAggregateNestingCount; }
        }
 
        /// 
        /// resets group aggregate function nesting call 
        ///  
        internal void ResetGroupAggregateNestingCount()
        { 
            _groupAggregateNestingCount = 0;
        }

        internal void IncrementGroupAggregateNestingCount() 
        {
            _groupAggregateNestingCount++; 
        } 

        internal void DecrementGroupAggregateNestingCount() 
        {
            _groupAggregateNestingCount--;
        }
 

        private Dictionary _groupAggregatesInfo = new Dictionary(); 
        internal void AddGroupAggregateInfo( MethodExpr astMethodNode, GroupAggregateInfo groupAggrInfo ) 
        {
            _groupAggregatesInfo.Add(astMethodNode, groupAggrInfo); 
        }

        internal Dictionary GroupAggregatesInfo
        { 
            get { return _groupAggregatesInfo; }
        } 
 
        /// 
        /// keep group aggregates names 
        /// 
        private HashSet _groupAggregateNames = new HashSet();
        internal bool ContainsGroupAggregate( string groupAggregateName )
        { 
            return _groupAggregateNames.Contains(groupAggregateName);
        } 
 
        /// 
        /// adds group aggregate name to scope region flags 
        /// 
        /// 
        internal void AddGroupAggregateToScopeFlags( string groupAggregateName )
        { 
            Debug.Assert(!_groupAggregateNames.Contains(groupAggregateName),"!_groupAggregateNames.ContainsKey(groupAggregateName)");
            _groupAggregateNames.Add(groupAggregateName); 
        } 

        ///  
        /// indicates if a nested group aggregate was referred by any sub-expression within
        /// a give group scope
        /// 
        private bool _wasNestedGroupAggregateReferredByInnerExpressions = false; 
        internal bool WasNestedGroupAggregateReferredByInnerExpressions
        { 
            get { return _wasNestedGroupAggregateReferredByInnerExpressions; } 
            set { _wasNestedGroupAggregateReferredByInnerExpressions = value; }
        } 

        private SemanticResolver.ScopeViewKind _scopeViewKind = SemanticResolver.ScopeViewKind.All;
        internal SemanticResolver.ScopeViewKind ScopeViewKind
        { 
            get { return _scopeViewKind; }
            set { _scopeViewKind = value; } 
        } 

        ///  
        /// indicates if current scope region holds an implicit group
        /// 
        internal bool IsImplicitGroup
        { 
            get { return _isImplicitGroup; }
            set { _isImplicitGroup = value; } 
        } 
        private bool _isImplicitGroup = false;
 
        /// 
        /// indicates the kind of the current scope entries
        /// 
        internal ScopeEntryKind ScopeEntryKind 
        {
            get { return _scopeEntryKind; } 
            set { _scopeEntryKind = value; } 
        }
        private ScopeEntryKind _scopeEntryKind = ScopeEntryKind.SourceVar; 

        /// 
        /// defines if a given expression resolution is correlated
        ///  
        internal bool WasResolutionCorrelated
        { 
            get { return _wasResolutionCorrelated; } 
            set { _wasResolutionCorrelated = value; }
        } 
        private bool _wasResolutionCorrelated = false;

        /// 
        /// Represents the path tagger in the current input scope 
        /// 
        private TreePathTagger _treePathTagger = new TreePathTagger(); 
        internal TreePathTagger PathTagger 
        {
            get { return _treePathTagger; } 
        }

    }
 

    ///  
    /// represents a pair of types to avoid uncessary enumerations to split kvp elements 
    /// 
    ///  
    /// 
    internal sealed class Pair
    {
        internal Pair( L left, R right ) 
        {
            Left = left; 
            Right = right; 
        }
        internal L Left; 
        internal R Right;
    }

 
    /// 
    /// represents a pair of types to avoid uncessary enumerations to split kvp lists 
    ///  
    /// 
    ///  
    internal sealed class PairOfLists /* : IEnumerable> */
    {
        private List _leftValues;
        internal List Left 
        {
            get { return _leftValues; } 
        } 

        private List _rightValues; 
        internal List Right
        {
            get { return _rightValues; }
        } 

        internal PairOfLists() 
        { 
            _leftValues = new List();
            _rightValues = new List(); 
        }

        internal PairOfLists( List leftValues, List rightValues )
        { 
            _leftValues = leftValues;
            _rightValues = rightValues; 
        } 

        internal int Count 
        {
            get { return _leftValues.Count; }
        }
 
        internal void Add( L left, R right )
        { 
            _leftValues.Add(left); 
            _rightValues.Add(right);
        } 

        internal Pair this[int index]
        {
            set 
            {
                Left[index] = value.Left; 
                Right[index] = value.Right; 
            }
        } 

#if EXTRA_ENTITYSQL_PARSER_DEBUGGING
        #region GetEnumerator()
        public IEnumerator> GetEnumerator() 
        {
            return new PairEnumerator(this); 
        } 

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
        {
            return GetEnumerator();
        }
        #endregion 

 
        #region Enumerator 
        internal struct PairEnumerator : IEnumerator>
        { 
            PairOfLists _pair;
            int _pos;

            internal PairEnumerator( PairOfLists pair ) 
            {
                _pair = pair; 
                _pos = -1; 
            }
 
            public Pair Current
            {
                get
                { 
                    return new Pair(_pair._leftValues[_pos], _pair._rightValues[_pos]);
                } 
            } 

            public bool MoveNext() 
            {
                _pos++;
                if (_pos >= _pair.Count)
                { 
                    return false;
                } 
                return true; 
            }
 
            public void Dispose()
            {
            }
 
            public void Reset()
            { 
            } 

            object System.Collections.IEnumerator.Current 
            {
                get { return null; }
            }
        } 
        #endregion
#endif 
 
    }
 
    /// 
    /// Helper class to enable tree path tagging in complex join/apply expressions
    /// Consider Moving to a bitmap or dictionary if needed.
    ///  
    internal class TreePathTagger
    { 
        private System.Text.StringBuilder _sb; 

        ///  
        /// defauls constructor
        /// 
        internal TreePathTagger()
        { 
            _sb = new System.Text.StringBuilder(8);
        } 
 
        /// 
        /// Marks a left visit in the path 
        /// 
        internal void VisitLeftNode() { _sb.Append('-'); }

        ///  
        /// Marks a right visit in the path
        ///  
        internal void VisitRightNode() { _sb.Append('+'); } 

        ///  
        /// leaves a path
        /// 
        internal void LeaveNode() { _sb.Remove(_sb.Length - 1, 1); }
 
        /// 
        /// returns the current path tag 
        ///  
        internal string Tag { get { return _sb.ToString(); } }
 
        /// 
        /// Validates if a given path tag is a child of another path tag.
        /// 
        /// ch 
        /// 
        ///  
        static internal bool IsChildNode( string parentNodePrefix, string childNodePrefix ) 
        {
            if (String.IsNullOrEmpty(childNodePrefix)) 
            {
                return true;
            }
 
            return (childNodePrefix.Length > parentNodePrefix.Length && childNodePrefix.StartsWith(parentNodePrefix, StringComparison.Ordinal));
        } 
    } 

} 

// 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.IO; 
    using System.Globalization;
    using System.Collections.Generic; 
    using System.Diagnostics; 

    using System.Data.Mapping; 
    using System.Data.Common.CommandTrees;
    using System.Data.Common;
    using System.Data.Metadata.Edm;
    using System.Data.Entity; 

    ///  
    /// implements the semantic resolver in the context of a metadata workspace and typespace 
    /// 
    /// not thread safe 
    internal sealed class SemanticResolver
    {
        private StaticContext _staticContext;
        private DbCommandTree _commandTree; 
        private ParserOptions _parserOptions;
        private Dictionary _parameters; 
        private Dictionary> _variables; 
        private uint _namegenCounter = 0;
        private TypeResolver _typeResolver; 
        private int _scopeIndexHighMark;
        private List _scopeRegionSavepoints = new List();
        private List _scopeRegionFlags = new List();
        private StringComparer _stringComparer; 
        private List _aggregateAstNodes = new List();
 
 
        /// 
        /// Initializes semantic resolver 
        /// 
        /// 
        /// options
        /// ordinary parameters 
        /// variable parameters
        ///  
        ///  
        /// 
        internal SemanticResolver(Perspective perspective, 
                                    ParserOptions parserOptions,
                                    Dictionary eSqlParameters,
                                    Dictionary variableParameters)
        { 
            EntityUtil.CheckArgumentNull(perspective, "perspective");
            EntityUtil.CheckArgumentNull(parserOptions, "parserOptions"); 
 
            //
            // set parser options 
            //
            _parserOptions = parserOptions;

            // 
            // Initialize string comparer based on parser configuration
            // 
            if (ParserOptions.CaseSensitiveness.CaseSensitive == _parserOptions.IdentifierCaseSensitiveness) 
            {
                _stringComparer = StringComparer.Ordinal; 
            }
            else
            {
                _stringComparer = StringComparer.OrdinalIgnoreCase; 
            }
 
            // 
            // Initialize Type Resolver
            // 
            _typeResolver = new TypeResolver(perspective, _stringComparer);

            //
            // Creates Scope manager 
            //
            _staticContext = new StaticContext(_stringComparer); 
 
            //
            // Validate eSql parameters 
            //
            _parameters = ValidateParameters(eSqlParameters);

            // 
            // validate variable-representing
            // 
            _variables = ValidateVariables(variableParameters); 

            // 
            // push a 'global' scope region
            //
            EnterScopeRegion();
 
            //
            // set default scope visibility to All scopes 
            // 
            CurrentScopeRegionFlags.ScopeViewKind = ScopeViewKind.All;
        } 


        /// 
        /// returns command tree 
        /// 
        internal DbCommandTree CmdTree 
        { 
            get { return _commandTree; }
        } 


        /// 
        /// returns parameters 
        /// 
        internal Dictionary Parameters 
        { 
            get { return _parameters; }
        } 


        /// 
        /// returns variables 
        /// 
        internal Dictionary> Variables 
        { 
            get { return _variables; }
        } 


        /// 
        /// TypeSpace/Metadata/Perspective Dependent Type Resolver 
        /// 
        internal TypeResolver TypeResolver 
        { 
            get { return _typeResolver; }
        } 


        /// 
        /// Returns current Parser Options 
        /// 
        internal ParserOptions ParserOptions 
        { 
            get { return _parserOptions; }
        } 


        /// 
        /// returns the current string comparer 
        /// 
        internal StringComparer ScopeStringComparer 
        { 
            get { return _stringComparer; }
        } 


        /// 
        /// sets the command tree factory 
        /// 
        ///  
        ///  
        /// 
        ///  
        internal void SetCommandTreeFactory(CommandExpr astCommandExpr)
        {
            EntityUtil.CheckArgumentNull(astCommandExpr, "astCommandExpr");
 
            if (null != _commandTree)
            { 
                throw EntityUtil.EntitySqlError(Strings.CommandTreeCanOnlyBeSetOnce); 
            }
 
            switch (astCommandExpr.QueryExpr.ExprKind)
            {
                case AstExprKind.Query:
                case AstExprKind.Generic: 
                    _commandTree = new DbQueryCommandTree(TypeResolver.Perspective.MetadataWorkspace, TypeResolver.Perspective.TargetDataspace);
                    break; 
 
                default:
                    throw EntityUtil.Argument(Strings.UnknownAstExpressionType); 
            }
        }

        ///  
        /// Sets the command tree factory using the specified command tree.
        /// When specifying a command tree, the AST command expression may 
        /// only be a query/generic expression, since these are the only 
        /// AST command expression that can be used to create a stand-alone .
        ///  
        /// The command expression that is the root of the AST
        /// The command tree to use when converting the AST into a 
        internal void SetCommandTreeFactory(CommandExpr astCommandExpr, DbCommandTree commandTree)
        { 
            EntityUtil.CheckArgumentNull(astCommandExpr, "astCommandExpr");
            EntityUtil.CheckArgumentNull(commandTree, "commandTree"); 
 
            if (null != _commandTree)
            { 
                throw EntityUtil.EntitySqlError(Strings.CommandTreeCanOnlyBeSetOnce);
            }

            DbQueryCommandTree queryTree = commandTree as DbQueryCommandTree; 
            if (null == queryTree ||
                (astCommandExpr.ExprKind != AstExprKind.Query && 
                 astCommandExpr.ExprKind != AstExprKind.Generic)) 
            {
                throw EntityUtil.Argument(Strings.UnknownAstExpressionType); 
            }

            _commandTree = commandTree;
        } 

        ///  
        /// declares and validates namespaces 
        /// 
        /// namespace expression list 
        /// 
        /// 
        /// 
        internal void DeclareNamespaces(ExprList nsExprList) 
        {
            if (null == nsExprList) 
            { 
                return;
            } 

            for (int i = 0; i < nsExprList.Count; i++)
            {
                NamespaceExpr nsExpr = nsExprList[i]; 

                string namespaceName = nsExpr.NamespaceName.FullName; 
 
                if (namespaceName.Equals(EdmConstants.CanonicalFunctionNamespace, StringComparison.OrdinalIgnoreCase))
                { 
                    throw EntityUtil.EntitySqlError(nsExpr.NamespaceName.ErrCtx, System.Data.Entity.Strings.CannotUseCanonicalNamespace(namespaceName));
                }

                if (nsExpr.IsAliased) 
                {
                    string aliasName = nsExpr.AliasIdentifier.Name; 
 
                    if (!TypeResolver.TryAddAliasedNamespace(aliasName, namespaceName))
                    { 
                        throw EntityUtil.EntitySqlError(nsExpr.AliasIdentifier.ErrCtx, System.Data.Entity.Strings.NamespaceAliasAlreadyUsed(aliasName));
                    }
                }
                else 
                {
                    if (!TypeResolver.TryAddNamespace(namespaceName)) 
                    { 
                        throw EntityUtil.EntitySqlError(nsExpr.NamespaceName.ErrCtx, System.Data.Entity.Strings.NamespaceNameAlreadyDeclared(namespaceName));
                    } 
                }
            }
        }
 
        /// 
        /// Declares Canonical namespace in query scope 
        ///  
        internal void DeclareCanonicalNamespace()
        { 
            if (!TypeResolver.TryAddNamespace(EdmConstants.CanonicalFunctionNamespace))
            {
                throw EntityUtil.EntitySqlError(Strings.FailedToDeclareCanonicalNamespace);
            } 
        }
 
        ///  
        /// defines scope visibility mode
        ///  
        internal enum ScopeViewKind
        {
            All,                        /* default - all scopes plus types/extents */
            CurrentContext,             /* entire context - all stacked scopes */ 
            CurrentScopeRegion,         /* current scope region */
            CurrentAndPreviousScope,    /* top 2 scopes */ 
            CurrentScope,                /* current scope only   */ 
            GroupScope
        } 


        /// 
        /// sets the current scope visibility 
        /// 
        ///  
        internal void SetScopeView(ScopeViewKind viewKind) 
        {
            CurrentScopeRegionFlags.ScopeViewKind = viewKind; 

            switch (CurrentScopeRegionFlags.ScopeViewKind)
            {
                case ScopeViewKind.All: 
                case ScopeViewKind.CurrentContext:
                case ScopeViewKind.GroupScope: 
                    _scopeIndexHighMark = 0; 
                    break;
 
                case ScopeViewKind.CurrentAndPreviousScope:
                    _scopeIndexHighMark = CurrentScopeIndex - 1;
                    break;
 
                case ScopeViewKind.CurrentScopeRegion:
                    _scopeIndexHighMark = CurrentScopeRegionSavePoint.ScopeIndex; 
                    break; 

                case ScopeViewKind.CurrentScope: 
                    _scopeIndexHighMark = CurrentScopeIndex;
                    break;
            }
 
            Debug.Assert(_scopeIndexHighMark <= CurrentScopeIndex, "_scopeIndexHighMark <= CurrentScopeIndex");
        } 
 
        /// 
        /// returns current scope view kind 
        /// 
        /// 
        internal ScopeViewKind GetScopeView()
        { 
            return CurrentScopeRegionFlags.ScopeViewKind;
        } 
 
        /// 
        /// returns current scope index 
        /// 
        internal int CurrentScopeIndex
        {
            get { return _staticContext.CurrentScopeIndex; } 
        }
 
        ///  
        /// Performs scope lookup returning the scope index entry
        ///  
        /// 
        /// 
        /// 
        internal bool TryScopeLookup(string key, out ScopeEntry scopeEntry) 
        {
            int dummyVar; 
            return TryScopeLookup(key, out scopeEntry, out dummyVar); 
        }
 
        /// 
        /// Performs scope lookup returning the scope index entry
        /// 
        ///  
        /// 
        ///  
        ///  
        internal bool TryScopeLookup(string key, out ScopeEntry scopeEntry, out int scopeIndex)
        { 
            return TryScopeLookup(key, false /* ignoreGroupScope */, out scopeEntry, out scopeIndex);
        }

        ///  
        /// Performs scope lookup returning the scope index entry
        ///  
        ///  
        /// 
        ///  
        /// 
        /// 
        internal bool TryScopeLookup(string key, bool ignoreGroupScope, out ScopeEntry scopeEntry, out int scopeIndex)
        { 
            scopeEntry = null;
            scopeIndex = -1; 
 
            // assert that scope index is always greater or equal to current scope index
            // scopes grow top -> bottom with high mark always 'higher or equal' then the bottom 
            // of the stack of scopes
            Debug.Assert(_scopeIndexHighMark <= CurrentScopeIndex, "_scopeIndexHighMark <= CurrentScopeIndex");

            int i = 0; 
            for (i = CurrentScopeIndex; i >= _scopeIndexHighMark; i--)
            { 
                if (_staticContext.GetScopeByIndex(i).TryLookup(key, out scopeEntry)) 
                {
                    if (!ignoreGroupScope && CurrentScopeRegionFlags.IsInGroupScope && scopeEntry.VarKind == SourceVarKind.GroupInput) 
                    {
                        return false;
                    }
                    scopeIndex = i; 
                    return true;
                } 
            } 
            return false;
        } 


        /// 
        /// returns the appropriate expression from a given scope entry. 
        /// 
        ///  
        ///  
        /// 
        private DbExpression GetExpressionFromScopeEntry(ScopeEntry scopeEntry, int scopeIndex) 
        {
            DbExpression innerExpr = null;

            innerExpr = scopeEntry.Expression; 

            // 
            // if it inside a group aggregate function, the 'base' expression is relative to 
            // the groupVar, represented in the scope entry as AggregateExpression
            // 
            if (CurrentScopeRegionFlags.IsInsideGroupAggregate)
            {
                if (_aggregateAstNodes.Count > 0)
                { 
                    _aggregateAstNodes[0].ScopeIndex = Math.Max(_aggregateAstNodes[0].ScopeIndex, scopeIndex);
                } 
 
                SourceScopeEntry sse = scopeEntry as SourceScopeEntry;
                if (null != sse) 
                {
                    if (sse.GroupVarExpression != null)
                    {
                        return sse.AggregateExpression; 
                    }
                    else 
                    { 
                        return innerExpr;
                    } 
                }

                DummyGroupVarScopeEntry dgv = scopeEntry as DummyGroupVarScopeEntry;
                if (null != dgv) 
                {
                    return dgv.AggregateExpression; 
                } 

            } 

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

            return innerExpr; 
        }
 
        ///  
        /// resolve identifier or dotidentifier ast expression
        ///  
        /// 
        /// 
        /// 
        ///  
        /// 
        ///  
        ///  
        /// DbExpression
        internal DbExpression ResolveIdentifier(string[] names, ErrorContext errCtx) 
        {
            Debug.Assert(CurrentScopeIndex >= _scopeIndexHighMark, "CurrentScopeIndex >= _scopeIndexHighMark FAILED");
            Debug.Assert(_scopeRegionFlags.Count == _scopeRegionSavepoints.Count, "_scopeRegionFlags.Count == _scopeRegionSavepoints.Count FAILED");
 
            TypeUsage definingType = null;
            DbExpression innerExpr = null; 
            ScopeEntry scopeEntry; 
            KeyValuePair varInfo;
            int scopeIndex = -1; 
            int suffixIndex = 0;

            //
            // try base type in scope first 
            //
            if (names.Length > 1 && TryScopeLookup(TypeResolver.GetFullName(names), out scopeEntry, out scopeIndex)) 
            { 
                //
                // Sets correlation flag 
                //
                SetScopeRegionCorrelationFlag(scopeIndex);

                return GetExpressionFromScopeEntry(scopeEntry, scopeIndex); 
            }
            else if (TryScopeLookup(names[0], out scopeEntry, out scopeIndex)) 
            { 
                //
                // check for invalid left correlation 
                //
                if (scopeEntry.Kind == ScopeEntryKind.JoinSourceVar && !CurrentScopeRegionFlags.IsInsideJoinOnPredicate)
                {
                    throw EntityUtil.EntitySqlError(errCtx, Strings.InvalidJoinLeftCorrelation); 
                }
 
                // 
                // Sets correlation flag
                // 
                SetScopeRegionCorrelationFlag(scopeIndex);

                //
                // trim resolved prefix 
                //
                names = TypeResolver.TrimNamesPrefix(names, 1); 
 
                //
                // get inner expression from the scope entry 
                // also verifies if a nested group aggregate is being referenced inside
                //
                innerExpr = GetExpressionFromScopeEntry(scopeEntry, scopeIndex);
 
                //
                // assume defining type as the expression type 
                // 
                definingType = innerExpr.ResultType;
 
            }
            //
            //
 
            else if (_variables.TryGetValue(names[0], out varInfo))
            { 
                // 
                // Can the identifier be resolved as a variable?
                // 
                names = TypeResolver.TrimNamesPrefix(names, 1);

                innerExpr = CmdTree.CreateVariableReferenceExpression(varInfo.Key, varInfo.Value);
 
                definingType = innerExpr.ResultType;
            } 
            else 
            {
                // 
                // Try resolve as entity container/entity set
                //
                if (TryResolveAsEntitySet(names, errCtx, out suffixIndex, out innerExpr))
                { 
                    //return innerExpr;
                    definingType = innerExpr.ResultType; 
                } 
                else
                { 
                    //
                    // try base type from metadata
                    //
                    int matchCount = 0; 

                    definingType = TypeResolver.ResolveBaseType(names, out suffixIndex, out matchCount); 
 
                    if (matchCount > 1)
                    { 
                        throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.AmbiguousName(TypeResolver.GetFullName(names)));
                    }
                }
            } 

            if (null != definingType) 
            { 
                return ResolveIdentifierChain(names, suffixIndex, definingType, innerExpr, errCtx);
            } 

            return null;
        }
 

        ///  
        /// Resolves Identifier name chain relative to a base expression 
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  
        /// 
        ///  
        ///  
        /// 
        ///  
        internal DbExpression ResolveIdentifierChain(string[] names, int suffixIndex, DbExpression innerExpr, ErrorContext errCtx)
        {
            return ResolveIdentifierChain(names, suffixIndex, innerExpr.ResultType, innerExpr, errCtx);
        } 

 
        ///  
        /// Resolve identifier chain of names
        ///  
        /// 
        /// 
        /// 
        ///  
        /// 
        ///  
        private DbExpression ResolveIdentifierChain(string[] names, 
                                                        int suffixIndex,
                                                        TypeUsage definingType, 
                                                        DbExpression innerExpr,
                                                        ErrorContext errCtx)
        {
            Debug.Assert(null != names, "null != names"); 
            Debug.Assert(null != definingType, "null != definingType");
 
            DbExpression convertedExpr = innerExpr; 

            if (names.Length > 0) 
            {
                TypeUsage baseType = definingType;
                for (int i = suffixIndex; i < names.Length; i++)
                { 
                    convertedExpr = ResolveIdentifierElement(baseType, convertedExpr, names[i], errCtx);
 
                    baseType = convertedExpr.ResultType; 
                }
            } 

            return convertedExpr;
        }
 

        ///  
        /// resolve part of identifier 
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  
        /// 
        ///  
        ///  
        /// 
        ///  
        internal DbExpression ResolveIdentifierElement(TypeUsage definingType, DbExpression innerExpr, string name, ErrorContext errCtx)
        {
            DbExpression converted = null;
 
            if (TryResolveAsProperty(name, (null == innerExpr ? definingType : innerExpr.ResultType), innerExpr, errCtx, out converted))
            { 
                return converted; 
            }
 
            if (TryResolveAsRef(name, (null == innerExpr ? definingType : innerExpr.ResultType), innerExpr, errCtx, out converted))
            {
                return converted;
            } 

            throw CqlErrorHelper.ReportIdentifierElementError(errCtx, name, definingType); 
        } 

 
        /// 
        /// Try resolve as EntitySet
        /// 
        ///  
        /// 
        ///  
        ///  
        private bool TryResolveAsEntitySet(string[] names, ErrorContext errCtx, out int suffixIndex, out DbExpression convExpr)
        { 
            Debug.Assert(names.Length > 0, "(names.Length > 0) assertion failed");
            convExpr = null;
            suffixIndex = 0;
            EntityContainer entityContainer = null; 

            // first see if there a default EC 
            if (names.Length == 1) 
            {
                entityContainer = TypeResolver.Perspective.GetDefaultContainer(); 
                suffixIndex = 0;
            }
            else
            { 
                if (TypeResolver.Perspective.TryGetEntityContainer(names[0], true /*ignoreCase*/, out entityContainer))
                { 
                    suffixIndex = 1; 
                }
                else 
                {
                    return false;
                }
            } 

            if (null != entityContainer) 
            { 
                EntitySetBase entitySet = null;
                if (TypeResolver.Perspective.TryGetExtent(entityContainer, names[suffixIndex], true /*ignoreCase*/, out entitySet)) 
                {
                    convExpr = CmdTree.CreateScanExpression(entitySet);
                    suffixIndex++;
                    return true; 
                }
                else if (names.Length > 1) 
                { 
                    throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.EntitySetIsDoesNotBelongToEntityContainer(names[1], names[0]));
                } 
            }

            if (names.Length == 1 && TypeResolver.Perspective.TryGetEntityContainer(names[0], true /*ignoreCase*/, out entityContainer))
            { 
                throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.MissingEntitySetName(names[0]));
            } 
 
            return false;
        } 

        /// 
        /// Try resolve name as property
        ///  
        /// 
        ///  
        ///  
        /// 
        ///  
        /// 
        private bool TryResolveAsProperty(string name, TypeUsage definingType, DbExpression innerExpr, ErrorContext errCtx, out DbExpression convExpr)
        {
            convExpr = null; 

            if (Helper.IsStructuralType(definingType.EdmType)) 
            { 
                EdmMember member = null;
                if (TypeResolver.Perspective.TryGetMember((StructuralType)definingType.EdmType, name, true, out member)) 
                {
                    if (null != member)
                    {
                        Debug.Assert(name.Equals(member.Name, StringComparison.OrdinalIgnoreCase), "name.Equals(member.Name,StringComparison.OrdinalIgnoreCase)"); 

                        if (null == innerExpr) 
                        { 
                            //
                            // if we dont have an instance, then it means it is a static member that is not supported in EDM 
                            //
                            throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.StaticMembersAreNotSupported(TypeHelpers.GetFullName(definingType.EdmType), name));
                        }
 
                        convExpr = CmdTree.CreatePropertyExpression(name, true /* case insenstive */, innerExpr);
 
                        return true; 
                    }
                } 
            }

            return false;
        } 

 
        ///  
        /// try resolve name as ref
        ///  
        /// 
        /// 
        /// 
        ///  
        /// 
        ///  
        private bool TryResolveAsRef(string name, TypeUsage definingType, DbExpression innerExpr, ErrorContext errCtx, out DbExpression convExpr) 
        {
            convExpr = null; 

            if (TypeSemantics.IsReferenceType(definingType))
            {
                convExpr = CmdTree.CreateDerefExpression(innerExpr); 

                TypeUsage dereferencedType = convExpr.ResultType; 
 
                if (TryResolveAsProperty(name, convExpr.ResultType, convExpr, errCtx, out convExpr))
                { 
                    return true;
                }

                throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.InvalidDeRefProperty(name, TypeHelpers.GetFullName(dereferencedType), TypeHelpers.GetFullName(definingType))); 
            }
 
            return false; 
        }
 
        /// 
        /// Resolve given name as Type
        /// 
        ///  
        /// 
        ///  
        ///  
        /// 
        ///  
        /// 
        /// TypeUsage
        internal TypeUsage ResolveNameAsType(string[] names, Expr astTypeExpression)
        { 
            int matchCount = 0;
            ErrorContext errCtx = astTypeExpression.ErrCtx; 
            TypeUsage typeUsage = TypeResolver.ResolveNameAsType(names, names.Length, out matchCount); 

            // 
            // if null, means there is no type with given name in the current typespace
            //
            if (null == typeUsage)
            { 
                CqlErrorHelper.ReportTypeResolutionError(names, astTypeExpression, this);
            } 
 
            //
            // if match count is greater then 1, means there are more then one match and is therefore ambiguous 
            //
            if (matchCount > 1)
            {
                throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.AmbiguousTypeName(TypeResolver.GetFullName(names))); 
            }
 
            // 
            // check for parametrized types
            // 
            MethodExpr methodExpr = astTypeExpression as MethodExpr;
            if (null != methodExpr)
            {
                typeUsage = HandleParametrizedType(typeUsage, methodExpr); 
            }
 
            return typeUsage; 
        }
 

        /// 
        /// Handles parametrized types such as Decimal, Decimal(p) and Decimal(p,s)
        ///  
        /// typeusage of the resolved type name
        /// ast node with representing additional type parameters to be validated 
        ///  
        private TypeUsage HandleParametrizedType(TypeUsage typeUsage, MethodExpr methodExpr)
        { 
            //
            // The only type in EDM that we support arguments is EDM.Decimal as of Sep 2007.
            //
            PrimitiveType primitiveType = typeUsage.EdmType as PrimitiveType; 
            if (null == primitiveType || primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.Decimal)
            { 
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.TypeDoesNotSupportParameters(primitiveType.FullName)); 
            }
 
            Debug.Assert(methodExpr.Args[0] is Literal, "first type argument must be a literal node");
            Debug.Assert((methodExpr.Args.Count == 2) ? methodExpr.Args[1] is Literal : true, "second type argument must be a literal node");

            // 
            // Get valid Precision for given type from provider
            // 
            byte precision = GetValidDecimalFacetValue(primitiveType, 
                                                      (Literal)methodExpr.Args[0],
                                                      DbProviderManifest.PrecisionFacetName); 

            //
            // Get valid Scale for given type from provider
            // 
            byte scale = 0;
            if (2 == methodExpr.Args.Count) 
            { 
                scale = GetValidDecimalFacetValue(primitiveType,
                                                  (Literal)methodExpr.Args[1], 
                                                  DbProviderManifest.ScaleFacetName);
            }

            // 
            // Ensure P >= S
            // 
            if (precision < scale) 
            {
                Debug.Assert(2 == methodExpr.Args.Count, "decimal with precision and scale must have 2 arguments"); 
                throw EntityUtil.EntitySqlError(methodExpr.Args[1].ErrCtx, System.Data.Entity.Strings.DecimalPrecisionMustBeGreaterThanScale(primitiveType.FullName));
            }

            // 
            // finally create TypeUsage with given precision and scale
            // 
            return TypeUsage.CreateDecimalTypeUsage(primitiveType, precision, scale); 
        }
 

        /// 
        /// validates and returns the appropriate facet for decimal type
        ///  
        /// 
        ///  
        ///  
        /// 
        private byte GetValidDecimalFacetValue(PrimitiveType primitiveType, Literal typeArg, string FacetName) 
        {
            FacetDescription facetDescription = Helper.GetFacet(primitiveType.ProviderManifest.GetFacetDescriptions(primitiveType), FacetName);
            if (null == facetDescription)
            { 
                throw EntityUtil.EntitySqlError(typeArg.ErrCtx, System.Data.Entity.Strings.TypeDoesNotSupportPrecisionOrScale(primitiveType.FullName, FacetName));
            } 
 
            byte typeArgValue = 0;
            if (Byte.TryParse(typeArg.OriginalValue, out typeArgValue)) 
            {
                if (typeArgValue > facetDescription.MaxValue)
                {
                    throw EntityUtil.EntitySqlError(typeArg.ErrCtx, System.Data.Entity.Strings.TypeSpecExceedsMax(FacetName)); 
                }
 
                if (typeArgValue < facetDescription.MinValue) 
                {
                    throw EntityUtil.EntitySqlError(typeArg.ErrCtx, System.Data.Entity.Strings.TypeSpecBellowMin(FacetName)); 
                }
            }
            else
            { 
                throw EntityUtil.EntitySqlError(typeArg.ErrCtx, System.Data.Entity.Strings.TypeSpecIsNotValid);
            } 
 
            return (byte)typeArgValue;
        } 


        /// 
        /// Handles expressions dotted id( List{e} ) that can be resolved to Static Methods, Type Constructors, Ordinary Functions and Aggregate Functions. 
        /// this function ensures that one of the 3 posibilities must be resolved, otherwise an exception will be raised.
        /// Also, it ensures that the name is not ambiguous. 
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        internal void ResolveNameAsStaticMethodOrFunction(MethodExpr methodExpr, 
                                                            out TypeUsage constructorType,
                                                            out TypeUsage staticMethodType, 
                                                            out IList functionType) 
        {
            DotExpr dotExpr = methodExpr.MethodPrefixExpr; 
            int matchCount = 0;
            int typeMatches = 0;

            constructorType = null; 
            staticMethodType = null;
            functionType = null; 
 
            //
            // Try Resolving as Type Constructor 
            //
            constructorType = TypeResolver.ResolveNameAsType(dotExpr.Names, dotExpr.Names.Length, out matchCount);
            if (0 < matchCount)
            { 
                typeMatches++;
 
                // 
                // ensure type has contructor. one of: Entity, ComplexType or RelationType
                // 
                if (!TypeSemantics.IsStructuralType(constructorType))
                {
                    throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.InvalidCtorUseOnType(TypeHelpers.GetFullName(constructorType)));
                } 

                if (1 < matchCount) 
                { 
                    dotExpr.ErrCtx.ErrorContextInfo = EntityRes.CtxGenericTypeCtor;
                    throw EntityUtil.EntitySqlError(dotExpr.ErrCtx, 
                                         System.Data.Entity.Strings.MultipleMatchesForName(
                                                       System.Data.Entity.Strings.LocalizedType,
                                                       dotExpr.FullName));
                } 
            }
 
            // 
            // Try Resolving as EdmFunction
            // 
            List foundNamespaces = null;
            functionType = TypeResolver.ResolveNameAsFunction(dotExpr.Names, true /* ignore case */, out matchCount, out foundNamespaces);

            if (0 < matchCount) 
            {
                typeMatches++; 
 
                if (1 < matchCount)
                { 
                    methodExpr.ErrCtx.ErrorContextInfo = EntityRes.CtxGenericFunctionCall;
                    CqlErrorHelper.ReportAmbiguousFunctionError(methodExpr, foundNamespaces);
                }
            } 

#if SUPPORT_STATIC_METHODS 
            // 
            // Try Resolving as Static Method
            // 
            staticMethodType = null;
            if (dotExpr.Names.Length > 1)
            {
                staticMethodType = TypeResolver.ResolveNameAsType(dotExpr.Names, dotExpr.Names.Length - 1, out matchCount); 
                if (0 < matchCount)
                { 
                    typeMatches++; 

                    if (1 < matchCount) 
                    {
                        dotExpr.ErrCtx.ErrorContextInfo = EntityRes.CtxMethod;
                        throw EntityUtil.QueryError(dotExpr.ErrCtx,
                                             System.Data.Entity.Strings.MultipleMatchesForName( 
                                                           System.Data.Entity.Strings.LocalizedType,
                                                           dotExpr.FullName)); 
                    } 
                }
            } 
#endif
            //
            // check if it is ambiguous. if the given method prefix name can be found as multiple types, then throw
            // 
            if (1 < typeMatches)
            { 
                throw EntityUtil.EntitySqlError(dotExpr.Identifier.ErrCtx, System.Data.Entity.Strings.AmbiguousFunctionMethodCtorName(dotExpr.FullName)); 
            }
 
            //
            // Check if lookup was a miss
            //
            if (0 == typeMatches) 
            {
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.CannotResolveNameToFunction(dotExpr.FullName)); 
            } 
        }
 


        /// 
        /// Creates new instance of a given Type (IEntity, ComplexType or RelationType) 
        /// Validates and infer argument types
        ///  
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  
        /// 
        ///  
        internal DbExpression CreateInstanceOfType(TypeUsage type, List args, List relshipExprList, MethodExpr methodExpr) 
        {
            DbExpression newInstance = null; 
            int idx = 0;
            int argCount = args.Count;

            methodExpr.ErrCtx.ErrorContextInfo = EntityRes.CtxGenericTypeCtor; 

            // 
            // abstract types cannot be instanciated 
            //
            if (type.EdmType.Abstract) 
            {
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx,
                                            System.Data.Entity.Strings.CannotInstantiateAbstractType(type.EdmType.FullName));
            } 

            // 
            // ensure DISTINCT/ALL was not used on type constructors 
            //
            if (methodExpr.DistinctKind != DistinctKind.None) 
            {
                methodExpr.ErrCtx.ErrorContextInfo = System.Data.Entity.Strings.CtxTypeCtorWithType(TypeHelpers.GetFullName(type));
                methodExpr.ErrCtx.UseContextInfoAsResourceIdentifier = false;
 
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx,
                                            Strings.InvalidDistinctArgumentInCtor); 
            } 

            // 
            // find overloads by searching members in order of its definition
            // each member will be considered as a formal argument type in the order of its definition
            //
            if (TypeSemantics.IsComplexType(type) || TypeSemantics.IsEntityType(type) || TypeSemantics.IsRelationshipType(type)) 
            {
                StructuralType stype = (StructuralType)type.EdmType; 
                foreach (EdmMember member in TypeHelpers.GetAllStructuralMembers(stype)) 
                {
                    TypeUsage memberModelTypeUsage = Helper.GetModelTypeUsage(member); 

                    Debug.Assert(memberModelTypeUsage.EdmType.DataSpace == DataSpace.CSpace, "member space must be CSpace");

                    // 
                    // ensure given arguments are not less than 'formal' constructor arguments
                    // 
                    if (argCount <= idx) 
                    {
                        methodExpr.ErrCtx.ErrorContextInfo = System.Data.Entity.Strings.CtxTypeCtorWithType(TypeHelpers.GetFullName(type)); 
                        methodExpr.ErrCtx.UseContextInfoAsResourceIdentifier = false;

                        throw EntityUtil.EntitySqlError(methodExpr.ErrCtx,
                                             System.Data.Entity.Strings.NumberOfTypeCtorIsLessThenFormalSpec(member.Name)); 
                    }
 
                    // 
                    // if given argument is an untyped null, infer type the ctor formal argument list type
                    // 
                    if (TypeSemantics.IsNullType(args[idx].ResultType))
                    {
                        if (Helper.IsEdmProperty(member) && !((EdmProperty)member).Nullable)
                        { 
                            throw EntityUtil.EntitySqlError(methodExpr.Args[idx].ErrCtx,
                                                 System.Data.Entity.Strings.InvalidNullLiteralForNonNullableMember( 
                                                               member.Name, 
                                                               TypeHelpers.GetFullName(stype)));
                        } 
                        args[idx] = CmdTree.CreateNullExpression(memberModelTypeUsage);
                    }

                    // 
                    // if not, given argument is already typed, then ensure it is promotable to formal ctor argument type
                    // 
                    bool isPromotable = TypeSemantics.IsPromotableTo(args[idx].ResultType, memberModelTypeUsage); 
                    if (ParserOptions.CompilationMode.RestrictedViewGenerationMode == _parserOptions.ParserCompilationMode ||
                        ParserOptions.CompilationMode.UserViewGenerationMode == _parserOptions.ParserCompilationMode        ) 
                    {
                        if (!isPromotable && !TypeSemantics.IsPromotableTo(memberModelTypeUsage, args[idx].ResultType))
                        {
                            throw EntityUtil.EntitySqlError(methodExpr.Args[idx].ErrCtx, 
                                                           System.Data.Entity.Strings.InvalidCtorArgumentType(
                                                           args[idx].ResultType.Identity, 
                                                           member.Name, 
                                                           memberModelTypeUsage.Identity));
                        } 

                        if (Helper.IsPrimitiveType(memberModelTypeUsage.EdmType) &&
                            !TypeSemantics.IsSubTypeOf(args[idx].ResultType, memberModelTypeUsage))
                        { 
                            args[idx] = _commandTree.CreateCastExpression(args[idx], memberModelTypeUsage);
                        } 
                    } 
                    else
                    { 
                        if (!isPromotable)
                        {
                            throw EntityUtil.EntitySqlError(methodExpr.Args[idx].ErrCtx,
                                                           System.Data.Entity.Strings.InvalidCtorArgumentType( 
                                                           args[idx].ResultType.Identity,
                                                           member.Name, 
                                                           memberModelTypeUsage.Identity)); 
                        }
                    } 

                    idx++;
                }
            } 
            //
            // the type does not support type constructors 
            // 
            else
            { 
                methodExpr.ErrCtx.ErrorContextInfo = System.Data.Entity.Strings.CtxTypeCtorWithType(TypeHelpers.GetFullName(type));
                methodExpr.ErrCtx.UseContextInfoAsResourceIdentifier = false;

                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, 
                                     System.Data.Entity.Strings.InvalidCtorUseOnType(
                                                   TypeHelpers.GetFullName(type))); 
            } 

            // 
            // ensure all given arguments and all 'formal' ctor arguments were considered and properly checked
            //
            if (idx != argCount)
            { 
                methodExpr.ErrCtx.ErrorContextInfo = System.Data.Entity.Strings.CtxTypeCtorWithType(TypeHelpers.GetFullName(type));
                methodExpr.ErrCtx.UseContextInfoAsResourceIdentifier = false; 
 
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx,
                                     System.Data.Entity.Strings.NumberOfTypeCtorIsMoreThenFormalSpec( 
                                                   TypeHelpers.GetFullName(type)));
            }

            // 
            // finally, create expression
            // 
            if (relshipExprList != null && relshipExprList.Count > 0) 
            {
                EntityType entityType = (EntityType)type.EdmType; 
                newInstance = CmdTree.CreateNewEntityWithRelationshipsExpression(entityType, args, relshipExprList);
            }
            else
            { 
                newInstance = CmdTree.CreateNewInstanceExpression(TypeHelpers.GetReadOnlyType(type), args);
            } 
            Debug.Assert(null != newInstance, "null != newInstance"); 

            return newInstance; 
        }


        ///  
        /// Creates DbFunctionExpression from metadata and arg list. validates overloads
        ///  
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  
        /// DbFunctionExpression
        internal DbExpression CreateFunction(IList functionTypeList, 
                                            List args, 
                                            MethodExpr methodExpr)
        { 
            Debug.Assert(functionTypeList.Count > 0, "functionList.Count > 0");

            DbExpression functionExpression = null;
            methodExpr.ErrCtx.ErrorContextInfo = EntityRes.CtxGenericFunctionCall; 
            bool isAmbiguous = false;
 
            // 
            // if DISTINCT was used, ensure function type and argument types are valid
            // 
            if (methodExpr.DistinctKind != DistinctKind.None)
            {
                methodExpr.ErrCtx.ErrorContextInfo = System.Data.Entity.Strings.CtxFunction(functionTypeList[0].Name);
                methodExpr.ErrCtx.UseContextInfoAsResourceIdentifier = false; 

                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, 
                                     Strings.InvalidDistinctArgumentInNonAggFunction); 
            }
 
            //
            // collect argument types from argument expression list
            //
            List argTypes = new List(args.Count); 
            for (int i = 0; i < args.Count; i++)
            { 
                argTypes.Add(args[i].ResultType); 
            }
 
            //
            // Find function overload match for given argument types
            //
            EdmFunction functionType = TypeResolver.ResolveFunctionOverloads(functionTypeList, 
                                                                              argTypes,
                                                                              false /* isGroupAggregateFunction */, 
                                                                              out isAmbiguous); 
            //
            // if there is more then one overload that matches given arguments, throw 
            //
            if (isAmbiguous)
            {
                methodExpr.ErrCtx.ErrorContextInfo = System.Data.Entity.Strings.CtxFunction(functionTypeList[0].Name); 
                methodExpr.ErrCtx.UseContextInfoAsResourceIdentifier = false;
 
                throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, 
                                            Strings.AmbiguousFunctionArguments);
            } 

            //
            // if null, means no overload matched
            // 
            if (null == functionType)
            { 
                CqlErrorHelper.ReportFunctionOverloadError(methodExpr, functionTypeList[0], argTypes); 
            }
 
            //
            // fixup untyped nulls in given arguments from formal method argument types
            //
            for (int i = 0; i < args.Count; i++) 
            {
                if (TypeSemantics.IsNullType(args[i].ResultType)) 
                { 
                    args[i] = CmdTree.CreateNullExpression(functionType.Parameters[i].TypeUsage);
                } 
            }

            //
            // Finally, create expression 
            //
            functionExpression = CmdTree.CreateFunctionExpression(functionType, args); 
 
            Debug.Assert(null != functionExpression, "null != functionExpression");
 
            return functionExpression;
        }

        ///  
        /// Creates a static method expression
        ///  
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  
        /// MethodExpression
        internal static DbExpression CreateStaticMethod(TypeUsage definingType, List args, MethodExpr methodExpr) 
        { 
            return CreateMethod(definingType, args, methodExpr, null, true);
        } 


        /// 
        /// creates instance method expression 
        /// 
        ///  
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        /// InstanceMethodExpression or StaticMethodExpression 
        internal static DbExpression CreateInstanceMethod(DbExpression instance, List args, MethodExpr methodExpr)
        { 
            return CreateMethod(instance.ResultType, args, methodExpr, instance, false); 
        }
 

        /// 
        /// Creates a method expression.
        ///  
        /// 
        ///  
        ///  
        /// 
        ///  
        /// 
        private static DbExpression CreateMethod(TypeUsage definingType,
                                            List args,
                                            MethodExpr methodExpr, 
                                            DbExpression instance,
                                            bool isStatic) 
        { 
#if METHOD_EXPRESSION
            Expression methodExpression = null; 

            methodExpr.ErrCtx.ContextInfo = System.Data.Entity.Strings.CtxMethodTerm(methodExpr.MethodName);

            // 
            // ensure definiting type is allowed for method calls
            // 
            if (!TypeResolver.IsValidTypeForMethodCall(definingType)) 
            {
                throw EntityUtil.QueryError(methodExpr.ErrCtx, System.Data.Entity.Strings.DefiningTypeDoesNotSupportMethodCalls); 
            }

            //
            // check if distinct/ALL was incorrectly used on methods 
            //
            if (methodExpr.DistinctKind != DistinctKind.None) 
            { 
                throw EntityUtil.QueryError(methodExpr.ErrCtx, System.Data.Entity.Strings.InvalidDistinctArgumentInMethod);
            } 

            //
            // create list of arg types
            // 
            List argTypes = new List();
            foreach (Expression argExpr in args) 
            { 
                argTypes.Add(argExpr.ResultType);
            } 

            //
            // Find function overload match for given args
            // 
            bool isAmbiguous = false;
            MethodMetadata methodMetadata = TypeResolver.ResolveMethodOverloads(definingType, 
                                                                                       methodExpr.MethodName, 
                                                                                       argTypes,
                                                                                       isStatic, 
                                                                                       out isAmbiguous);

            //
            // check if more than one overload match was found 
            //
            if (isAmbiguous) 
            { 
                throw EntityUtil.QueryError(methodExpr.ErrCtx, System.Data.Entity.Strings.AmbiguousFunctionArguments);
            } 

            //
            // check if there is a match
            // 
            if (null == methodMetadata)
            { 
                throw EntityUtil.QueryError(methodExpr.ErrCtx, System.Data.Entity.Strings.NoMethodOverloadMatch(methodExpr.MethodName, definingType.FullName)); 
            }
 
            //
            // fixup untyped nulls in given arguments from formal method argument types
            //
            for (int i = 0 ; i < args.Count ; i++) 
            {
                if (TypeResolver.IsNull(args[i].ResultType)) 
                { 
                    args[i] = CmdTree.CreateNullExpression(methodMetadata.Parameters[i].Type);
                } 
            }

            //
            // Finally, create expression 
            //
#if CALCULATED_MEMBERS 
            ClrCalculatedMethod clrCalculatedMethod = methodMetadata as ClrCalculatedMethod; 
            if (null != clrCalculatedMethod)
            { 
                if (!isStatic)
                {
                    args.Insert(0, instance);
                } 

                methodExpression = clrCalculatedMethod.GetExpression(CmdTree, args); 
 
            }
            else 
            {
#endif
                if (isStatic)
                { 
                    methodExpression = CmdTree.CreateStaticMethodExpression(methodMetadata, args);
                } 
                else 
                {
                    methodExpression = CmdTree.CreateInstanceMethodExpression(methodMetadata, instance, args); 
                }
#if CALCULATED_MEMBERS
            }
#endif 

            Debug.Assert(null != methodExpression); 
 
            return methodExpression;
#endif 
            throw EntityUtil.EntitySqlError(methodExpr.ErrCtx, System.Data.Entity.Strings.MethodInvocationNotSupported);
        }

        ///  
        /// Ensure and typifies nulls if present
        ///  
        ///  
        /// 
        ///  
        /// Pair of Expressions with NullTypes inferred to the proper type
        internal Pair EnsureTypedNulls(DbExpression leftExpr,
                                                                DbExpression rightExpr,
                                                                ErrorContext errCtx, 
                                                                Func formatMessage)
        { 
            DbExpression newLeftExpr = leftExpr; 
            DbExpression newRightExpr = rightExpr;
            UntypedNullExpression untypedLeftExpr = leftExpr as UntypedNullExpression; 
            UntypedNullExpression untypedRightExpr = rightExpr as UntypedNullExpression;

            if (null != untypedLeftExpr)
            { 
                if (null != untypedRightExpr || null == rightExpr)
                { 
                    throw EntityUtil.EntitySqlError(errCtx, formatMessage()); 
                }
                else 
                {
                    newLeftExpr = CmdTree.CreateNullExpression(rightExpr.ResultType);
                }
            } 
            else if (null != untypedRightExpr)
            { 
                newRightExpr = CmdTree.CreateNullExpression(leftExpr.ResultType); 
            }
 
            return new Pair(newLeftExpr, newRightExpr);
        }

 
        /// 
        /// returns if an expresison is an untyped null expression 
        ///  
        /// 
        ///  
        internal static bool IsNullExpression(DbExpression expression)
        {
            return expression is UntypedNullExpression;
        } 

 
        ///  
        /// Set current source scope kind
        ///  
        /// 
        internal void SetCurrentScopeKind(ScopeEntryKind scopeKind)
        {
            CurrentScopeRegionFlags.ScopeEntryKind = scopeKind; 
        }
 
        ///  
        /// Get current source scope kind
        ///  
        internal ScopeEntryKind CurrentScopeKind
        {
            get { return CurrentScopeRegionFlags.ScopeEntryKind; }
        } 

 
        ///  
        /// Generates internal name to be used in cqt
        ///  
        /// 
        /// 
        internal string GenerateInternalName(string hint)
        { 
            // string concat is faster than String.Join and much faster than String.Format
            return "_##" + hint + unchecked(_namegenCounter++).ToString(CultureInfo.InvariantCulture); 
        } 

        private static DbExpressionKind[] joinMap = { DbExpressionKind.CrossJoin, DbExpressionKind.InnerJoin, DbExpressionKind.LeftOuterJoin, DbExpressionKind.FullOuterJoin }; 

        /// 
        /// maps ast jointype to cqt join type
        ///  
        /// 
        ///  
        internal static DbExpressionKind MapJoinKind(JoinKind joinKind) 
        {
            Debug.Assert(joinKind != JoinKind.RightOuter, "joinKind != JoinKind.RightOuter"); 
            return joinMap[(int)joinKind];
        }

 
        private static DbExpressionKind[] applyMap = { DbExpressionKind.CrossApply, DbExpressionKind.OuterApply };
 
        ///  
        /// maps ast applytype to cqt apply type
        ///  
        /// 
        /// 
        internal static DbExpressionKind MapApplyKind(ApplyKind applyKind)
        { 
            return applyMap[(int)applyKind];
        } 
 

        ///  
        /// returns current scope region savepoint
        /// 
        internal SavePoint CurrentScopeRegionSavePoint
        { 
            get
            { 
                Debug.Assert(_scopeRegionSavepoints.Count > 0, "_scopeRegionSavepoints.Count > 0"); 

                return _scopeRegionSavepoints[0]; 
            }
        }

        ///  
        /// propagates new ebinding up the tree for the vars in scope
        ///  
        ///  
        internal void FixupSourceVarBindings(DbVariableReferenceExpression newSourceVar)
        { 
            Debug.Assert(CurrentScopeRegionSavePoint.ScopeIndex + 1 <= CurrentScopeIndex, "CurrentScopeRegionSavePoint.ScopeIndex + 1 <= CurrentScopeIndex");

            for (int i = CurrentScopeRegionSavePoint.ScopeIndex + 1; i <= CurrentScopeIndex; i++)
            { 
                foreach (KeyValuePair scope in _staticContext.GetScopeByIndex(i))
                { 
                    SourceScopeEntry scopeEntry = scope.Value as SourceScopeEntry; 
                    if (null != scopeEntry)
                    { 
                        scopeEntry.SetNewSourceBinding(newSourceVar);
                    }
                }
            } 
        }
 
 
        /// 
        /// fixup new eb 
        /// 
        /// 
        internal void FixupNamedSourceVarBindings(DbVariableReferenceExpression newSourceVar)
        { 
            Debug.Assert(CurrentScopeRegionSavePoint.ScopeIndex + 1 <= CurrentScopeIndex, "CurrentScopeRegionSavePoint.ScopeIndex + 1 <= CurrentScopeIndex");
 
            for (int i = CurrentScopeRegionSavePoint.ScopeIndex + 1; i <= CurrentScopeIndex; i++) 
            {
                foreach (KeyValuePair scope in _staticContext.GetScopeByIndex(i)) 
                {
                    if (scope.Value.Kind == CurrentScopeKind && !scope.Value.IsHidden)
                    {
                        SourceScopeEntry scopeEntry = scope.Value as SourceScopeEntry; 
                        if (null != scopeEntry && TreePathTagger.IsChildNode(CurrentScopeRegionFlags.PathTagger.Tag, scopeEntry.VarTag))
                        { 
                            scopeEntry.AddBindingPrefix(newSourceVar.VariableName); 
                            scopeEntry.SetNewSourceBinding(newSourceVar);
                        } 
                    }
                }
            }
        } 

        internal void MarkGroupInputVars() 
        { 
            for (int i = CurrentScopeRegionSavePoint.ScopeIndex + 1; i <= CurrentScopeIndex; i++)
            { 
                foreach (KeyValuePair scope in _staticContext.GetScopeByIndex(i))
                {
                    if (scope.Value.VarKind != SourceVarKind.GroupAggregate && scope.Value.VarKind != SourceVarKind.GroupKey)
                    { 
                        scope.Value.VarKind = SourceVarKind.GroupInput;
                    } 
                } 
            }
        } 

        /// 
        /// Fixes up source vars and adds groupvar in case the var is referenced in an group aggregate fucntion
        ///  
        /// 
        ///  
        internal void FixupGroupSourceVarBindings(DbVariableReferenceExpression newSourceVar, DbVariableReferenceExpression newGroupVar) 
        {
            InternalFixupGroupSourceVarBindings(newSourceVar, newGroupVar); 
        }


        ///  
        /// undo group var
        ///  
        ///  
        internal void UndoFixupGroupSourceVarBindings(DbVariableReferenceExpression originalSourceVar)
        { 
            InternalFixupGroupSourceVarBindings(originalSourceVar, null);
        }

 
        private void InternalFixupGroupSourceVarBindings(DbVariableReferenceExpression newSourceVar, DbVariableReferenceExpression newGroupVar)
        { 
            Debug.Assert(CurrentScopeRegionSavePoint.ScopeIndex + 1 <= CurrentScopeIndex, "CurrentScopeRegionSavePoint.ScopeIndex + 1 <= CurrentScopeIndex"); 

            for (int i = CurrentScopeRegionSavePoint.ScopeIndex + 1; i <= CurrentScopeIndex; i++) 
            {
                foreach (KeyValuePair scope in _staticContext.GetScopeByIndex(i))
                {
                    if (scope.Value.Kind == CurrentScopeKind && !scope.Value.IsHidden) 
                    {
                        SourceScopeEntry scopeEntry = scope.Value as SourceScopeEntry; 
                        if (null != scopeEntry) 
                        {
                            scopeEntry.SetNewSourceBinding(newSourceVar); 
                            scopeEntry.GroupVarExpression = newGroupVar;
                        }
                    }
                } 
            }
        } 
 

        ///  
        /// Sets Current Scope Source Var Kind
        /// 
        /// 
        internal void SetCurrentScopeVarKind(FromClauseItemKind fromClauseItemKind) 
        {
            if (fromClauseItemKind == FromClauseItemKind.JoinFromClause) 
            { 
                SetCurrentScopeKind(ScopeEntryKind.JoinSourceVar);
            } 
            else if (fromClauseItemKind == FromClauseItemKind.ApplyFromClause)
            {
                SetCurrentScopeKind(ScopeEntryKind.ApplySourceVar);
            } 
            else
            { 
                SetCurrentScopeKind(ScopeEntryKind.SourceVar); 
            }
        } 


        /// 
        /// resets all source vars to default SourceVar Kind 
        /// 
        internal void ResetCurrentScopeVarKind() 
        { 
            for (int i = CurrentScopeRegionSavePoint.ScopeIndex + 1; i <= CurrentScopeIndex; i++)
            { 
                foreach (KeyValuePair scope in _staticContext.GetScopeByIndex(i))
                {
                    scope.Value.Kind = ScopeEntryKind.SourceVar;
                } 
            }
 
            SetCurrentScopeKind(ScopeEntryKind.SourceVar); 
        }
 

        /// 
        /// Infers and Creates a new Alias name based on expr information
        ///  
        /// 
        ///  
        private string CreateNewAlias(DbExpression expr) 
        {
            DbScanExpression extent = expr as DbScanExpression; 
            if (null != extent)
            {
                return extent.Target.Name;
            } 

            DbPropertyExpression property = expr as DbPropertyExpression; 
            if (null != property) 
            {
                return property.Property.Name; 
            }

            DbVariableReferenceExpression varRef = expr as DbVariableReferenceExpression;
            if (null != varRef) 
            {
                return varRef.VariableName; 
            } 

            return GenerateInternalName(String.Empty); 
        }


        ///  
        /// infers alias name from astNode information and converted expression.
        ///  
        ///  
        /// 
        ///  
        internal string InferAliasName(AliasExpr aliasExpr, DbExpression convertedExpression)
        {
            if (aliasExpr.HasAlias)
            { 
                return aliasExpr.AliasIdentifier.Name;
            } 
 
            Identifier id = aliasExpr.Expr as Identifier;
            if (null != id) 
            {
                return id.Name;
            }
 
            DotExpr dotExpr = aliasExpr.Expr as DotExpr;
            if (null != dotExpr && dotExpr.IsDottedIdentifier) 
            { 
                return dotExpr.Names[dotExpr.Length - 1];
            } 

            return CreateNewAlias(convertedExpression);
        }
 

        ///  
        /// represents scope region disposer helper 
        /// 
        internal sealed class ScopeRegionDisposer : IDisposable 
        {
            private SemanticResolver _semanticResolver;

            internal ScopeRegionDisposer(SemanticResolver semanticResolver) 
            {
                _semanticResolver = semanticResolver; 
            } 

            public void Dispose() 
            {
                _semanticResolver.LeaveScopeRegion();
            }
        } 

 
        ///  
        /// adds a scope entry to the scope
        ///  
        /// 
        /// 
        internal void AddToScope(string key, ScopeEntry scopeEntry)
        { 
            _staticContext.Add(key, scopeEntry);
        } 
 

        ///  
        /// Removes an entry from scope
        /// 
        /// 
        internal void RemoveFromScope(string key) 
        {
            _staticContext.RemoveFromScope(key); 
        } 

 
        /// 
        /// enters a scope region
        /// 
        ///  
        internal ScopeRegionDisposer EnterScopeRegion()
        { 
            Debug.Assert(_scopeRegionSavepoints.Count == _scopeRegionFlags.Count, "_scopeRegionSavepoints.Count == _scopeRegionFlags.Count"); 

            // 
            // push new savepoint
            //
            _scopeRegionSavepoints.Insert(0, CreateSavePoint());
 
            //
            // push new scope 
            // 
            _staticContext.EnterScope();
 
            //
            // push new scoperegion flags
            //
            _scopeRegionFlags.Insert(0, new ScopeRegionFlags()); 

            Debug.Assert(_scopeRegionSavepoints.Count == _scopeRegionFlags.Count, "_scopeRegionSavepoints.Count == _scopeRegionFlags.Count"); 
 
            //
            // return disposer 
            //
            return new ScopeRegionDisposer(this);
        }
 

        ///  
        /// Leaves a scope region 
        /// 
        internal void LeaveScopeRegion() 
        {
            Debug.Assert(_scopeRegionSavepoints.Count > 0, "_scopeRegionSavepoints.Count > 0");
            Debug.Assert(_scopeRegionFlags.Count > 0, "_scopeRegionFlags.Count > 0");
            Debug.Assert(_scopeRegionSavepoints.Count == _scopeRegionFlags.Count, "_scopeRegionSavepoints.Count == _scopeRegionFlags.Count"); 

            // 
            // roll back scopes to the ScopeRegion savepoint 
            //
            RollbackToSavepoint(CurrentScopeRegionSavePoint); 

            //
            // pop top ScopeRegion savepoint
            // 
            _scopeRegionSavepoints.RemoveAt(0);
 
            // 
            // cleanup all aggregates related to this scope region
            // 
            foreach (MethodExpr me in CurrentScopeRegionFlags.GroupAggregatesInfo.Keys)
            {
                me.ResetAggregateInfo();
            } 

            // 
            // pop top ScopeRegion flags 
            //
            _scopeRegionFlags.RemoveAt(0); 

            //
            // restore scope view to the previously save view
            // 
            SetScopeView(CurrentScopeRegionFlags.ScopeViewKind);
 
            Debug.Assert(_scopeRegionSavepoints.Count == _scopeRegionFlags.Count, "_scopeRegionSavepoints.Count == _scopeRegionFlags.Count"); 
        }
 
        /// 
        /// Creates a scope save point
        /// 
        ///  
        internal SavePoint CreateSavePoint()
        { 
            return new SavePoint(CurrentScopeIndex); 
        }
 
        /// 
        /// rolls back the scope to a give savepoint
        /// 
        ///  
        internal void RollbackToSavepoint(SavePoint sp)
        { 
            _staticContext.RollbackToSavepoint(sp); 
        }
 
        /// 
        /// returns current scope region flags
        /// 
        internal ScopeRegionFlags CurrentScopeRegionFlags 
        {
            get { return _scopeRegionFlags[0]; } 
        } 

        ///  
        /// scope disposer
        /// 
        internal sealed class ScopeDisposer : IDisposable
        { 
            private SemanticResolver _semanticResolver;
 
            internal ScopeDisposer(SemanticResolver semanticResolver) 
            {
                _semanticResolver = semanticResolver; 
            }

            public void Dispose()
            { 
                _semanticResolver.LeaveScope();
            } 
        } 

 
        /// 
        /// entry scope
        /// 
        ///  
        internal ScopeDisposer EnterScope()
        { 
            _staticContext.EnterScope(); 

            return new ScopeDisposer(this); 
        }


        ///  
        /// leave scope
        ///  
        internal void LeaveScope() 
        {
            _staticContext.LeaveScope(); 
        }

        /// 
        /// ensures the expression is typed 
        /// 
        ///  
        ///  
        /// 
        ///  
        /// 
        internal static void EnsureIsNotUntypedNull(DbExpression expression, ErrorContext errCtx)
        {
            if (expression is UntypedNullExpression) 
            {
                throw EntityUtil.EntitySqlError(errCtx, Strings.ExpressionCannotBeNull); 
            } 
        }
 
        /// 
        /// checks if a name is in the current scope
        /// 
        ///  
        /// 
        internal bool IsInCurrentScope(string key) 
        { 
            return _staticContext.IsInCurrentScope(key);
        } 


        /// 
        /// adds a source binding 
        /// 
        ///  
        internal void AddSourceBinding(DbExpressionBinding sourceBinding) 
        {
            _staticContext.AddSourceBinding(sourceBinding, this.CurrentScopeRegionFlags.ScopeEntryKind, this.CurrentScopeRegionFlags.PathTagger.Tag); 
        }

        /// 
        /// adds dummy group key to be consumed during aggregate search pahse 
        /// 
        ///  
        ///  
        /// 
        internal void AddDummyGroupKeyToScope(string groupKey, DbExpression varBasedExpression, DbExpression groupVarBasedExpression) 
        {
            _staticContext.AddGroupDummyVar(groupKey, varBasedExpression, groupVarBasedExpression);
        }
 
        /// 
        /// Replaces dummy key added during the aggregate search phase by the real group key 
        ///  
        /// 
        ///  
        internal void ReplaceGroupVarInScope(string groupVarName, DbVariableReferenceExpression groupSourceBinding)
        {
            _staticContext.ReplaceGroupVarInScope(groupVarName, groupSourceBinding);
        } 

        ///  
        /// Adds group aggregate vars to scope, including nested aggregate 
        /// 
        ///  
        /// 
        internal void AddGroupAggregateToScope(string aggregateName, DbVariableReferenceExpression sourceVar)
        {
            _staticContext.AddAggregateToScope(aggregateName, sourceVar); 
        }
 
        ///  
        /// Validates that the specified parameters have valid, non-duplicated names
        ///  
        /// The set of input parameter names and types
        /// A valid dictionary that maps parameter names to types using the current StringComparer
        private Dictionary ValidateParameters(Dictionary paramDefs)
        { 
            Dictionary retParams = new Dictionary(_stringComparer);
 
            if (paramDefs != null) 
            {
                foreach (KeyValuePair paramDef in paramDefs) 
                {
                    if (retParams.ContainsKey(paramDef.Key))
                    {
                        throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.MultipleDefinitionsOfParameter(paramDef.Key)); 
                    }
 
                    if (!ValidateParameterType(paramDef.Value)) 
                    {
                        throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.InvalidParameterType(paramDef.Key)); 
                    }

                    retParams.Add(paramDef.Key, paramDef.Value);
                } 
            }
 
            return retParams; 
        }
 

        /// 
        /// Validates that the specified variables have valid, non-duplicated names
        ///  
        /// The set of input parameter names and types
        /// A valid dictionary that maps variable names to types using the current StringComparer 
        private Dictionary> ValidateVariables(Dictionary varDefs) 
        {
            Dictionary> retVars = 
                new Dictionary>(_stringComparer);

            if (varDefs != null)
            { 
                foreach (KeyValuePair varDef in varDefs)
                { 
                    if (retVars.ContainsKey(varDef.Key)) 
                    {
                        throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.MultipleDefinitionsOfVariable(varDef.Key)); 
                    }

                    retVars.Add(varDef.Key, new KeyValuePair(varDef.Key, varDef.Value));
                } 
            }
 
            return retVars; 
        }
 
        private static bool ValidateParameterType(TypeUsage paramType)
        {
            return (paramType != null && paramType.EdmType != null &&
                (TypeSemantics.IsPrimitiveType(paramType) || paramType.EdmType is EnumType)); 
        }
 
        internal static void EnsureValidTypeForNullExpression(TypeUsage type, ErrorContext errCtx) 
        {
            if (TypeSemantics.IsCollectionType(type)) 
            {
                throw EntityUtil.EntitySqlError(errCtx, Strings.NullLiteralCannotBePromotedToCollectionOfNulls);
            }
        } 

        ///  
        /// Adds the group aggregate information to the innermost correlated scope. if the expression is not correlated 
        /// then add to the innermost scope.
        ///  
        /// 
        /// 
        /// 
        ///  
        internal void AddGroupAggregateInfoToScopeRegion(MethodExpr astNode, string aggregateName, DbAggregate aggregateExpression, int groupVarScopeIndex)
        { 
            int scopeRegionIndex = 0; 
            bool bFound = false;
 
            // if scope index is NonCorrelatedScope, it means the inner aggregate expression is not correlated and it is
            // just as constant expression
            if (groupVarScopeIndex == AggregateAstNodeInfo.NonCorrelatedScope)
            { 
                bFound = true;
                scopeRegionIndex = 0; 
            } 
            else
            { 
                // inner expression is correlated and we need to find the exact group var scope
                for (scopeRegionIndex = 0; scopeRegionIndex < _scopeRegionSavepoints.Count; scopeRegionIndex++)
                {
                    if (_scopeRegionSavepoints[scopeRegionIndex].ContainsScope(groupVarScopeIndex)) 
                    {
                        bFound = true; 
                        break; 
                    }
                } 
            }

            if (bFound)
            { 
                Debug.Assert(_scopeRegionFlags.Count > 0, "must have a scope region (_scopeRegionFlags.Count > 0)");
                _scopeRegionFlags[scopeRegionIndex].AddGroupAggregateInfo(astNode, new GroupAggregateInfo(aggregateName, aggregateExpression)); 
            } 
            else
            { 
                throw EntityUtil.EntitySqlError(Strings.GroupVarNotFoundInScope);
            }
        }
 
        /// 
        /// pushes aggregate ast node 
        ///  
        /// 
        internal void PushAggregateAstNode(MethodExpr astNode) 
        {
            _aggregateAstNodes.Insert(0, new AggregateAstNodeInfo(astNode));
        }
 
        /// 
        /// removes aggregate ast node from the top of the stack 
        ///  
        /// 
        internal AggregateAstNodeInfo PopAggregateAstNode() 
        {
            Debug.Assert(_aggregateAstNodes.Count > 0, "_aggregateAstNodeInfo.Count must be greater than zero to pop");
            AggregateAstNodeInfo result = _aggregateAstNodes[0];
            _aggregateAstNodes.RemoveAt(0); 
            return result;
        } 
 

        ///  
        /// returns true if any of the ScopeRegions from the closest to the outermost has a group scope
        /// 
        /// 
        internal bool IsInAnyGroupScope() 
        {
            for (int i = 0; i < _scopeRegionFlags.Count; i++) 
            { 
                if (_scopeRegionFlags[i].IsInGroupScope)
                { 
                    return true;
                }
            }
            return false; 
        }
 
        ///  
        /// resets correlation flag in current scope region
        ///  
        internal void ResetScopeRegionCorrelationFlag()
        {
            CurrentScopeRegionFlags.WasResolutionCorrelated = false;
        } 

        ///  
        /// sets the correlation flag based on the input var scope index 
        /// 
        ///  
        internal void SetScopeRegionCorrelationFlag(int scopeIndex)
        {
            Debug.Assert(_scopeRegionFlags.Count == _scopeRegionSavepoints.Count, "_scopeRegionFlags.Count == _scopeRegionSavepoints.Count pre-condition FAILED");
            for (int i = 0; i < _scopeRegionFlags.Count; i++) 
            {
                if (scopeIndex > _scopeRegionSavepoints[i].ScopeIndex) 
                { 
                    _scopeRegionFlags[i].WasResolutionCorrelated = true;
                    return; 
                }
            }
        }
 
        /// 
        /// ensures limit expression (used in TOP and LIMIT) have valid pre-conditions 
        /// NOTE that in M3.2 these preconditions are exactly the same for TOP and LIMIT. 
        /// 
        ///  
        /// 
        /// 
        internal void EnsureValidLimitExpression(ErrorContext errCtx, DbExpression expr, string subclauseName)
        { 
            //
            // ensure resolved expression have the right type 
            // 
            if (!TypeSemantics.IsPromotableTo(expr.ResultType, TypeResolver.Int64Type))
            { 
                throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.PlaceholderExpressionMustBeCompatibleWithEdm64(subclauseName, expr.ResultType.EdmType.FullName));
            }

            // 
            // if it is a literal, make sure it has the correct value
            // 
            DbConstantExpression constantExpr = expr as DbConstantExpression; 
            if (null != constantExpr && System.Convert.ToInt64(constantExpr.Value, CultureInfo.InvariantCulture) < 0)
            { 
                throw EntityUtil.EntitySqlError(errCtx, System.Data.Entity.Strings.PlaceholderExpressionMustBeGreaterThanOrEqualToZero(subclauseName));
            }
        }
 

        ///  
        /// Ensures Projection is valid for Distinct modifier 
        /// 
        ///  
        /// 
        internal static void ValidateDistinctProjection(SelectClause selectClause, TypeUsage projectionType)
        {
            TypeUsage elemType = TypeHelpers.GetElementTypeUsage(projectionType); 
            if (!TypeHelpers.IsValidDistinctOpType(elemType))
            { 
                ErrorContext errCtx = selectClause.Items[0].Expr.ErrCtx; 
                if (TypeSemantics.IsRowType(elemType))
                { 
                    RowType rowType = elemType.EdmType as RowType;
                    Debug.Assert(selectClause.Items.Count == rowType.Members.Count);
                    for (int i = 0; i < rowType.Members.Count; i++)
                    { 
                        if (!TypeSemantics.IsEqualComparable(rowType.Members[i].TypeUsage))
                        { 
                            errCtx = selectClause.Items[i].Expr.ErrCtx; 
                            break;
                        } 
                    }
                }
                throw EntityUtil.EntitySqlError(errCtx, Strings.SelectDistinctMustBeEqualComparable);
            } 
        }
 
        ///  
        /// Ensures that the result of a query expression is valid.
        ///  
        /// 
        /// 
        internal static void ValidateQueryResultType(TypeUsage resultType, ErrorContext errCtx)
        { 
            if (Helper.IsCollectionType(resultType.EdmType))
            { 
                ValidateQueryResultType(((CollectionType)resultType.EdmType).TypeUsage, errCtx); 
            }
            else if (Helper.IsRowType(resultType.EdmType)) 
            {
                foreach (EdmProperty property in ((RowType)resultType.EdmType).Properties)
                {
                    ValidateQueryResultType(property.TypeUsage, errCtx); 
                }
            } 
            else if (Helper.IsAssociationType(resultType.EdmType)) 
            {
                throw EntityUtil.EntitySqlError(errCtx, Strings.InvalidQueryResultType(resultType.Identity)); 
            }
        }
    }
 

    ///  
    /// represents a method ast node during aggregate resolution 
    /// 
    internal sealed class AggregateAstNodeInfo 
    {
        internal const int NonCorrelatedScope = Int32.MinValue;
        private MethodExpr _methodExpr;
        private int _scopeIndex; 

        internal AggregateAstNodeInfo( MethodExpr methodAstNode ) 
        { 
            _methodExpr = methodAstNode;
            _scopeIndex = NonCorrelatedScope; 
        }

        internal void AssertMethodExprEquivalent(MethodExpr other)
        { 
            Debug.Assert(_methodExpr == other, "method ast node from the top of the stack must be the same");
        } 
 
        internal int ScopeIndex
        { 
            get { return _scopeIndex; }
            set
            {
                Debug.Assert(value >= 0); 
                _scopeIndex = value;
            } 
        } 
    }
 
    /// 
    /// represents resolved group aggregate information
    /// 
    internal sealed class GroupAggregateInfo 
    {
        private DbAggregate _aggregateExpression = null; 
        private string _aggregateName = null; 

        internal GroupAggregateInfo( string aggregateName, DbAggregate aggregateExpression ) 
        {
            _aggregateName = aggregateName;
            _aggregateExpression = aggregateExpression;
        } 

        internal DbAggregate AggregateExpression 
        { 
            get { return _aggregateExpression; }
        } 

        internal string AggregateName
        {
            get { return _aggregateName; } 
        }
    } 
 
    ///
    /// represents set of flags for a ScopeRegion 
    ///
    internal sealed class ScopeRegionFlags
    {
        /// 
        /// used to indicate when JoinSourceVars are visible within the scope of join sub-expresion tree resolution.
        /// Join right sub-expressions must not refer to join left sub-expressions (recursively). Of course, by definition 
        /// ON predicate is allowed to refer to any previously defined join sources. General left correlation 
        /// is allowed though. for instance:
        ///     Select ... From A JOIN B JOIN A.x -> invalid 
        ///     Select ... From A JOIN B JOIN C ON A.x == C.x -> valid
        ///     Select ... From A JOIN B, C JOIN A.x ... -> valid
        ///
        private bool _isInsideJoinOnPredicate = false; 
        internal bool IsInsideJoinOnPredicate
        { 
            get { return _isInsideJoinOnPredicate; } 
            set { _isInsideJoinOnPredicate = value; }
        } 

        ///
        /// indicates if input scope has group scope semantics
        /// 
        private bool _isInGroupScope = false;
        internal bool IsInGroupScope 
        { 
            get { return _isInGroupScope; }
            set { _isInGroupScope = value; } 
        }

        /// 
        /// indicates expression being resolved is a candidate for group aggregate and 
        /// should reference groupVar instead of the sourceVar
        ///  
        private bool _isInsideGroupAggregate = false; 
        internal bool IsInsideGroupAggregate
        { 
            get { return _isInsideGroupAggregate; }
            set { _isInsideGroupAggregate = value; }
        }
 
        /// 
        /// tracks group aggregate nesting calls 
        ///  
        private int _groupAggregateNestingCount = 0;
        internal int GroupAggregateNestingCount 
        {
            get { return _groupAggregateNestingCount; }
        }
 
        /// 
        /// resets group aggregate function nesting call 
        ///  
        internal void ResetGroupAggregateNestingCount()
        { 
            _groupAggregateNestingCount = 0;
        }

        internal void IncrementGroupAggregateNestingCount() 
        {
            _groupAggregateNestingCount++; 
        } 

        internal void DecrementGroupAggregateNestingCount() 
        {
            _groupAggregateNestingCount--;
        }
 

        private Dictionary _groupAggregatesInfo = new Dictionary(); 
        internal void AddGroupAggregateInfo( MethodExpr astMethodNode, GroupAggregateInfo groupAggrInfo ) 
        {
            _groupAggregatesInfo.Add(astMethodNode, groupAggrInfo); 
        }

        internal Dictionary GroupAggregatesInfo
        { 
            get { return _groupAggregatesInfo; }
        } 
 
        /// 
        /// keep group aggregates names 
        /// 
        private HashSet _groupAggregateNames = new HashSet();
        internal bool ContainsGroupAggregate( string groupAggregateName )
        { 
            return _groupAggregateNames.Contains(groupAggregateName);
        } 
 
        /// 
        /// adds group aggregate name to scope region flags 
        /// 
        /// 
        internal void AddGroupAggregateToScopeFlags( string groupAggregateName )
        { 
            Debug.Assert(!_groupAggregateNames.Contains(groupAggregateName),"!_groupAggregateNames.ContainsKey(groupAggregateName)");
            _groupAggregateNames.Add(groupAggregateName); 
        } 

        ///  
        /// indicates if a nested group aggregate was referred by any sub-expression within
        /// a give group scope
        /// 
        private bool _wasNestedGroupAggregateReferredByInnerExpressions = false; 
        internal bool WasNestedGroupAggregateReferredByInnerExpressions
        { 
            get { return _wasNestedGroupAggregateReferredByInnerExpressions; } 
            set { _wasNestedGroupAggregateReferredByInnerExpressions = value; }
        } 

        private SemanticResolver.ScopeViewKind _scopeViewKind = SemanticResolver.ScopeViewKind.All;
        internal SemanticResolver.ScopeViewKind ScopeViewKind
        { 
            get { return _scopeViewKind; }
            set { _scopeViewKind = value; } 
        } 

        ///  
        /// indicates if current scope region holds an implicit group
        /// 
        internal bool IsImplicitGroup
        { 
            get { return _isImplicitGroup; }
            set { _isImplicitGroup = value; } 
        } 
        private bool _isImplicitGroup = false;
 
        /// 
        /// indicates the kind of the current scope entries
        /// 
        internal ScopeEntryKind ScopeEntryKind 
        {
            get { return _scopeEntryKind; } 
            set { _scopeEntryKind = value; } 
        }
        private ScopeEntryKind _scopeEntryKind = ScopeEntryKind.SourceVar; 

        /// 
        /// defines if a given expression resolution is correlated
        ///  
        internal bool WasResolutionCorrelated
        { 
            get { return _wasResolutionCorrelated; } 
            set { _wasResolutionCorrelated = value; }
        } 
        private bool _wasResolutionCorrelated = false;

        /// 
        /// Represents the path tagger in the current input scope 
        /// 
        private TreePathTagger _treePathTagger = new TreePathTagger(); 
        internal TreePathTagger PathTagger 
        {
            get { return _treePathTagger; } 
        }

    }
 

    ///  
    /// represents a pair of types to avoid uncessary enumerations to split kvp elements 
    /// 
    ///  
    /// 
    internal sealed class Pair
    {
        internal Pair( L left, R right ) 
        {
            Left = left; 
            Right = right; 
        }
        internal L Left; 
        internal R Right;
    }

 
    /// 
    /// represents a pair of types to avoid uncessary enumerations to split kvp lists 
    ///  
    /// 
    ///  
    internal sealed class PairOfLists /* : IEnumerable> */
    {
        private List _leftValues;
        internal List Left 
        {
            get { return _leftValues; } 
        } 

        private List _rightValues; 
        internal List Right
        {
            get { return _rightValues; }
        } 

        internal PairOfLists() 
        { 
            _leftValues = new List();
            _rightValues = new List(); 
        }

        internal PairOfLists( List leftValues, List rightValues )
        { 
            _leftValues = leftValues;
            _rightValues = rightValues; 
        } 

        internal int Count 
        {
            get { return _leftValues.Count; }
        }
 
        internal void Add( L left, R right )
        { 
            _leftValues.Add(left); 
            _rightValues.Add(right);
        } 

        internal Pair this[int index]
        {
            set 
            {
                Left[index] = value.Left; 
                Right[index] = value.Right; 
            }
        } 

#if EXTRA_ENTITYSQL_PARSER_DEBUGGING
        #region GetEnumerator()
        public IEnumerator> GetEnumerator() 
        {
            return new PairEnumerator(this); 
        } 

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
        {
            return GetEnumerator();
        }
        #endregion 

 
        #region Enumerator 
        internal struct PairEnumerator : IEnumerator>
        { 
            PairOfLists _pair;
            int _pos;

            internal PairEnumerator( PairOfLists pair ) 
            {
                _pair = pair; 
                _pos = -1; 
            }
 
            public Pair Current
            {
                get
                { 
                    return new Pair(_pair._leftValues[_pos], _pair._rightValues[_pos]);
                } 
            } 

            public bool MoveNext() 
            {
                _pos++;
                if (_pos >= _pair.Count)
                { 
                    return false;
                } 
                return true; 
            }
 
            public void Dispose()
            {
            }
 
            public void Reset()
            { 
            } 

            object System.Collections.IEnumerator.Current 
            {
                get { return null; }
            }
        } 
        #endregion
#endif 
 
    }
 
    /// 
    /// Helper class to enable tree path tagging in complex join/apply expressions
    /// Consider Moving to a bitmap or dictionary if needed.
    ///  
    internal class TreePathTagger
    { 
        private System.Text.StringBuilder _sb; 

        ///  
        /// defauls constructor
        /// 
        internal TreePathTagger()
        { 
            _sb = new System.Text.StringBuilder(8);
        } 
 
        /// 
        /// Marks a left visit in the path 
        /// 
        internal void VisitLeftNode() { _sb.Append('-'); }

        ///  
        /// Marks a right visit in the path
        ///  
        internal void VisitRightNode() { _sb.Append('+'); } 

        ///  
        /// leaves a path
        /// 
        internal void LeaveNode() { _sb.Remove(_sb.Length - 1, 1); }
 
        /// 
        /// returns the current path tag 
        ///  
        internal string Tag { get { return _sb.ToString(); } }
 
        /// 
        /// Validates if a given path tag is a child of another path tag.
        /// 
        /// ch 
        /// 
        ///  
        static internal bool IsChildNode( string parentNodePrefix, string childNodePrefix ) 
        {
            if (String.IsNullOrEmpty(childNodePrefix)) 
            {
                return true;
            }
 
            return (childNodePrefix.Length > parentNodePrefix.Length && childNodePrefix.StartsWith(parentNodePrefix, StringComparison.Ordinal));
        } 
    } 

} 

// 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