StorageMappingItemLoader.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataEntity / System / Data / Mapping / StorageMappingItemLoader.cs / 2 / StorageMappingItemLoader.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner [....], [....]
//--------------------------------------------------------------------- 
 
using System;
using System.Diagnostics; 
using System.Collections;
using System.IO;
using System.Text;
using System.Collections.Generic; 
using System.Xml;
using System.Xml.Schema; 
using System.Xml.XPath; 
using System.Data.Metadata.Edm;
using System.Data.Common.Utils; 
using System.Data.Mapping.ViewGeneration.Utils;
using System.Collections.ObjectModel;
using System.Data.EntityModel;
using System.Data.Entity; 
using System.Globalization;
using System.Linq; 
 

namespace System.Data.Mapping 
{
    using Triple = Pair>;

    ///  
    /// The class loads an MSL file into memory and exposes CSMappingMetadata interfaces.
    /// The primary consumers of the interfaces are view genration and tools. 
    ///  
    /// 
    /// For Example if conceptually you could represent the CS MSL file as following 
    /// --Mapping
    ///   --EntityContainerMapping ( CNorthwind-->SNorthwind )
    ///     --EntitySetMapping
    ///       --EntityTypeMapping 
    ///         --TableMappingFragment
    ///           --EntityKey 
    ///             --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata ) 
    ///           --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
    ///           --DiscriminatorProperyMap ( constant value-->SMemberMetadata ) 
    ///       --EntityTypeMapping
    ///         --TableMappingFragment
    ///           --EntityKey
    ///             --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata ) 
    ///           --ComplexPropertyMap
    ///             --ComplexTypeMap 
    ///               --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata ) 
    ///               --ScalarProperyMap ( CMemberMetadata-->SMemberMetadata )
    ///           --DiscriminatorProperyMap ( constant value-->SMemberMetadata ) 
    ///     --AssociationSetMapping
    ///       --AssociationTypeMapping
    ///         --TableMappingFragment
    ///           --EndPropertyMap 
    ///             --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
    ///             --ScalarProperyMap ( CMemberMetadata-->SMemberMetadata ) 
    ///           --EndPropertyMap 
    ///             --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
    ///   --EntityContainerMapping ( CMyDatabase-->SMyDatabase ) 
    ///     --CompositionSetMapping
    ///       --CompositionTypeMapping
    ///         --TableMappingFragment
    ///           --ParentEntityKey 
    ///             --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
    ///             --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata ) 
    ///           --EntityKey 
    ///             --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
    ///             --ScalarPropertyMap ( CMemberMetadata-->Constant value ) 
    ///           --ComplexPropertyMap
    ///             --ComplexTypeMap
    ///               --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
    ///               --DiscriminatorProperyMap ( constant value-->SMemberMetadata ) 
    ///           --ScalarPropertyMap ( CMemberMetadata-->Constant value )
    /// The CCMappingSchemaLoader loads an Xml file that has a conceptual structure 
    /// equivalent to the above example into in-memory data structure in a 
    /// top-dwon approach.
    ///  
    /// 
    /// The loader uses XPathNavigator to parse the XML. The advantage of using XPathNavigator
    /// over DOM is that it exposes the line number of the current xml content.
    /// This is really helpful when throwing exceptions. Another advantage is 
    /// 
    internal class StorageMappingItemLoader 
    { 
        #region Constructors
        ///  
        /// Public constructor.
        /// For Beta2 we wont support delay loading Mapping information and we would also support
        /// only one mapping file for workspace.
        ///  
        /// 
        ///  
        ///  
        /// Dictionary to keep the list of all scalar member mappings
        internal StorageMappingItemLoader(StorageMappingItemCollection storageMappingItemCollection, string fileName, Dictionary> scalarMemberMappings) 
        {
            Debug.Assert(storageMappingItemCollection != null);
            Debug.Assert(scalarMemberMappings != null);
 
            this.m_storageMappingItemCollection = storageMappingItemCollection;
            this.m_alias = new Dictionary(StringComparer.Ordinal); 
            //The fileName field in this class will always have absolute path since 
            //StorageMappingItemCollection would have already done it while
            //preparing the filePaths 
            if (fileName != null)
            {
                this.m_sourceLocation = fileName;
            } 
            else
            { 
                this.m_sourceLocation = null; 
            }
            m_parsingErrors = new List(); 
            this.m_scalarMemberMappings = scalarMemberMappings;
        }
        #endregion
 
        #region Fields
        private Dictionary m_alias;  //To support the aliasing mechanism provided by MSL. 
        private StorageMappingItemCollection m_storageMappingItemCollection; //StorageMappingItemCollection 
        private string m_sourceLocation; //location identifier for the MSL file.
        private List m_parsingErrors; 
        private Dictionary> m_scalarMemberMappings; // dictionary of all the scalar member mappings - this is to validate that no property is mapped to different store types across mappings.
        private bool m_hasQueryViews;  //set to true if any of the SetMaps have a query view so that

        // cached xsd schema 
        private static XmlSchemaSet s_mappingXmlSchema;
        #endregion 
 
        #region Properties
        internal IList ParsingErrors 
        {
            get
            {
                return m_parsingErrors; 
            }
 
        } 

        internal bool HasQueryViews 
        {
            get { return m_hasQueryViews; }
        }
 
        private EdmItemCollection EdmItemCollection
        { 
            get 
            {
                return m_storageMappingItemCollection.EdmItemCollection; 
            }
        }

        private StoreItemCollection StoreItemCollection 
        {
            get 
            { 
                return m_storageMappingItemCollection.StoreItemCollection;
            } 
        }
        #endregion

        #region Methods 
        /// 
        /// The LoadMappingSchema method loads the mapping file and initializes the 
        /// MappingSchema that represents this mapping file. 
        /// For Beta2 atleast, we will support only one EntityContainerMapping per mapping file.
        ///  
        /// 
        internal StorageEntityContainerMapping LoadMappingItems(XmlReader innerReader)
        {
            //Using XPathDocument to load the xml file into memory. 
            XmlReader reader = GetSchemaValidatingReader(innerReader);
 
            try 
            {
                XPathDocument doc = new XPathDocument(reader); 
                //If there were any xsd validation errors, we would have
                //caught these while creatring xpath document.
                if (m_parsingErrors.Count != 0)
                { 
                    //If the errors were only warnings continue, otherwise return the errors without
                    //loading the mapping 
                    if (!MetadataHelper.CheckIfAllErrorsAreWarnings(m_parsingErrors)) 
                    {
                        return null; 
                    }
                }

                //Create an XPathNavigator to navigate the document in a forward only manner. 
                //The XPathNavigator can also be used to run quries through the document while still maintaining
                //the current position. This will be helpful in running validation rules that are not part of Schema. 
                XPathNavigator nav = doc.CreateNavigator(); 
                return LoadMappingItems(nav);
            } 
            catch (XmlException xmlException)
            {
                //There must have been a xml parsing exception. Add the exception information
                //to the error list. 
                EdmSchemaError error = new EdmSchemaError(System.Data.Entity.Strings.Mapping_InvalidMappingSchema_Parsing_1(xmlException.Message)
                    , (int)StorageMappingErrorCode.XmlSchemaParsingError, EdmSchemaErrorSeverity.Error, m_sourceLocation, xmlException.LineNumber, xmlException.LinePosition); 
                m_parsingErrors.Add(error); 
            }
 
            // do not close the wrapping reader here, as doing so will close the inner reader;
            // see SQLBUDT 522950 for details

            return null; 
        }
 
        internal StorageEntityContainerMapping LoadMappingItems(XPathNavigator nav) 
        {
            //XSD validation is not validating missing Root element. 
            if ((!nav.MoveToChild(StorageMslConstructs.MappingElement, StorageMslConstructs.NamespaceURI)) || (nav.NodeType != XPathNodeType.Element))
            {
                StorageMappingItemLoader.AddToSchemaErrors(Strings.Mapping_Invalid_CSRootElementMissing_0, StorageMappingErrorCode.RootMappingElementMissing, m_sourceLocation,
                    (IXmlLineInfo)nav, m_parsingErrors); 
                //There is no point in going forward if the required root element is not found
                return null; 
            } 
            StorageEntityContainerMapping entityContainerMap =
                LoadMappingChildNodes(nav.Clone()); 
            //If there were any parsing errors, invalidate the entity container map and return null.
            if (m_parsingErrors.Count != 0)
            {
                //If all the schema errors are warnings, don't return null 
                if (!MetadataHelper.CheckIfAllErrorsAreWarnings(m_parsingErrors))
                { 
                    entityContainerMap = null; 
                }
            } 
            return entityContainerMap;
        }

        ///  
        /// The method loads the child nodes for the root Mapping node
        /// into the internal datastructures. 
        ///  
        /// 
        ///  
        private StorageEntityContainerMapping LoadMappingChildNodes(XPathNavigator nav)
        {
            IXmlLineInfo navLineInfo = (IXmlLineInfo)nav;
 
            bool hasContainerMapping;
            //If there are any Alias elements in the document, they should be the first ones. 
            //This method can only move to the Alias element since comments, PIS etc wont have any Namespace 
            //though they could have same name as Alias element
            if (nav.MoveToChild(StorageMslConstructs.AliasElement, StorageMslConstructs.NamespaceURI)) 
            {
                //Collect all the alias elements
                do
                { 
                    m_alias.Add(StorageMappingItemLoader.GetAttributeValue(nav.Clone(), StorageMslConstructs.AliasKeyAttribute), StorageMappingItemLoader.GetAttributeValue(nav.Clone(), StorageMslConstructs.AliasValueAttribute));
                } while (nav.MoveToNext(StorageMslConstructs.AliasElement, StorageMslConstructs.NamespaceURI)); 
                //Now move on to the Next element that will be "EntityContainer" element 
                hasContainerMapping = nav.MoveToNext(XPathNodeType.Element);
            } 
            else
            {
                //Since there was no Alias element, move on to the Container element
                hasContainerMapping = nav.MoveToChild(XPathNodeType.Element); 
            }
 
            //No container mappings found, so just return 
            if (!hasContainerMapping)
                return null; 
            //The element name can only be EntityContainerMapping element name since XSD validation should have guarneteed this.
            Debug.Assert(nav.LocalName == StorageMslConstructs.EntityContainerMappingElement);
            string entityContainerName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.CDMEntityContainerAttribute);
            string storageEntityContainerName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.StorageEntityContainerAttribute); 

            StorageEntityContainerMapping entityContainerMapping; 
            EntityContainer entityContainerType; 
            EntityContainer storageEntityContainerType;
 
            // Now that we support partial mapping, we should first check if the entity container mapping is
            // already present. If its already present, we should add the new child nodes to the existing entity container mapping
            if (m_storageMappingItemCollection.TryGetItem(
                    entityContainerName, out entityContainerMapping)) 
            {
                entityContainerType = entityContainerMapping.EdmEntityContainer; 
                storageEntityContainerType = entityContainerMapping.StorageEntityContainer; 

                // The only thing we need to make sure is that the storage entity container mapping is the same. 
                if (storageEntityContainerName != storageEntityContainerType.Name)
                {
                    AddToSchemaErrors(System.Data.Entity.Strings.StorageEntityContainerNameMismatchWhileSpecifyingPartialMapping(
                            storageEntityContainerName, storageEntityContainerType.Name, entityContainerType.Name), 
                        StorageMappingErrorCode.StorageEntityContainerNameMismatchWhileSpecifyingPartialMapping,
                        m_sourceLocation, navLineInfo, m_parsingErrors); 
 
                    return null;
                } 
            }
            else
            {
                //At this point we know that the EdmEntityContainer has not been 
                //mapped already. if we do find that StorageEntityContainer
                //has already been mapped, return null. 
                if (m_storageMappingItemCollection.ContainsStorageEntityContainer(storageEntityContainerName)) 
                {
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_AlreadyMapped_StorageEntityContainer_1, storageEntityContainerName, 
                        StorageMappingErrorCode.AlreadyMappedStorageEntityContainer, m_sourceLocation, navLineInfo, m_parsingErrors);
                    return null;
                }
 

                //Get the CDM EntityContainer by this name from the metadata workspace. 
                this.EdmItemCollection.TryGetEntityContainer(entityContainerName, out entityContainerType); 
                if (entityContainerType == null)
                { 
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_EntityContainer_1,
                        entityContainerName, StorageMappingErrorCode.InvalidEntityContainer, m_sourceLocation,
                        navLineInfo, m_parsingErrors);
                } 

                this.StoreItemCollection.TryGetEntityContainer(storageEntityContainerName, out storageEntityContainerType); 
                if (storageEntityContainerType == null) 
                {
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_StorageEntityContainer_1, storageEntityContainerName, 
                        StorageMappingErrorCode.InvalidEntityContainer, m_sourceLocation, navLineInfo, m_parsingErrors);
                }

                //If the EntityContainerTypes are not found, there is no point in 
                //continuing with the parsing.
                if ((entityContainerType == null) || (storageEntityContainerType == null)) 
                { 
                    return null;
                } 

                //Create an EntityContainerMapping object to hold the mapping information for this
                //EntityContainer. Create a MappingKey and pass it in.
                entityContainerMapping = new StorageEntityContainerMapping(entityContainerType, storageEntityContainerType, m_storageMappingItemCollection); 
                entityContainerMapping.StartLineNumber = navLineInfo.LineNumber;
                entityContainerMapping.StartLinePosition = navLineInfo.LinePosition; 
            } 

            //Load the child nodes for the created EntityContainerMapping 
            LoadEntityContainerMapping(nav.Clone(), entityContainerMapping, storageEntityContainerType);
            return entityContainerMapping;
        }
 
        /// 
        /// The method loads the child nodes for the EntityContainer Mapping node 
        /// into the internal datastructures. 
        /// 
        ///  
        /// 
        /// 
        private void LoadEntityContainerMapping(XPathNavigator nav, StorageEntityContainerMapping entityContainerMapping, EntityContainer storageEntityContainerType)
        { 
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
            bool anyEntitySetMapped = false; 
 
            //If there is no child node for the EntityContainerMapping Element, return.
            if (nav.MoveToChild(XPathNodeType.Element)) 
            {
                //The valid child nodes for EntityContainerMapping node are various SetMappings( EntitySet, AssociationSet etc ).
                //Loop through the child nodes and lod them as children of the EntityContainerMapping object.
                do 
                {
                    switch (nav.LocalName) 
                    { 
                        case StorageMslConstructs.EntitySetMappingElement:
                            { 
                                LoadEntitySetMapping(nav.Clone(), entityContainerMapping, storageEntityContainerType);
                                anyEntitySetMapped = true;
                                break;
                            } 
                        case StorageMslConstructs.AssociationSetMappingElement:
                            { 
                                LoadAssociationSetMapping(nav.Clone(), entityContainerMapping, storageEntityContainerType); 
                                break;
                            } 
                        case StorageMslConstructs.FunctionImportMappingElement:
                            {
                                LoadFunctionImportMapping(nav.Clone(), entityContainerMapping, storageEntityContainerType);
                                break; 
                            }
                        default: 
                            AddToSchemaErrors(Strings.Mapping_InvalidContent_Set_Mapping_0, 
                                StorageMappingErrorCode.SetMappingExpected, m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                            break; 
                    }
                } while (nav.MoveToNext(XPathNodeType.Element));
            }
 
            //If the EntityContainer contains entity sets but they are not mapped then we should add an error
            if (entityContainerMapping.EdmEntityContainer.BaseEntitySets.Count != 0 && !anyEntitySetMapped) 
            { 
                AddToSchemaErrorsWithMemberInfo(Strings.ViewGen_Missing_Sets_Mapping_0,
                    entityContainerMapping.EdmEntityContainer.Name, StorageMappingErrorCode.EmptyContainerMapping, 
                    this.m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                return;
            }
 
            ValidateFunctionMappingClosure(nav.Clone(), entityContainerMapping);
            ValidateFunctionAssociationFunctionMappingUnique(nav.Clone(), entityContainerMapping); 
            ValidateAssociationFunctionMappingConsistent(nav.Clone(), entityContainerMapping); 
            ValidateQueryViewsClosure(nav.Clone(), entityContainerMapping);
            //The fileName field in this class will always have absolute path since 
            //StorageMappingItemCollection would have already done it while
            //preparing the filePaths
            entityContainerMapping.SourceLocation = m_sourceLocation;
        } 

        ///  
        /// Validates that collocated association sets are consistently mapped for each entity set (all operations or none). In the case 
        /// of relationships between sub-types of an entity set, ensures the relationship mapping is legal.
        ///  
        /// 
        /// 
        private void ValidateAssociationFunctionMappingConsistent(XPathNavigator nav, StorageEntityContainerMapping entityContainerMapping)
        { 
            foreach (StorageEntitySetMapping entitySetMapping in entityContainerMapping.EntitySetMaps)
            { 
                if (entitySetMapping.FunctionMappings.Count > 0) 
                {
                    // determine the set of ----oication sets that should be mapped for every operation 
                    Set expectedEnds = new Set(
                        entitySetMapping.ImplicitlyMappedAssociationSetEnds).MakeReadOnly();

                    // check that each operation covers each association set 
                    foreach (StorageEntityTypeFunctionMapping entityTypeMapping in entitySetMapping.FunctionMappings)
                    { 
                        ValidateAssociationFunctionMappingConsistent(nav, entitySetMapping, entityTypeMapping, 
                            entityTypeMapping.DeleteFunctionMapping,
                            expectedEnds, StorageMslConstructs.DeleteFunctionElement); 
                        ValidateAssociationFunctionMappingConsistent(nav, entitySetMapping, entityTypeMapping,
                            entityTypeMapping.InsertFunctionMapping,
                            expectedEnds, StorageMslConstructs.InsertFunctionElement);
                        ValidateAssociationFunctionMappingConsistent(nav, entitySetMapping, entityTypeMapping, 
                            entityTypeMapping.UpdateFunctionMapping,
                            expectedEnds, StorageMslConstructs.UpdateFunctionElement); 
                    } 
                }
            } 
        }
        private void ValidateAssociationFunctionMappingConsistent(XPathNavigator nav,
            StorageEntitySetMapping entitySetMapping, StorageEntityTypeFunctionMapping entityTypeMapping,
            StorageFunctionMapping functionMapping, Set expectedEnds, string elementName) 
        {
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav; 
 
            // check that all expected association sets are mapped for in this function mapping
            Set actualEnds = new Set( 
                functionMapping.GetReferencedAssociationSetEnds((EntitySet)entitySetMapping.Set));
            actualEnds.MakeReadOnly();

            // check that all required ends are present 
            foreach (AssociationSetEnd expectedEnd in expectedEnds)
            { 
                // check that the association set is required based on the entity type 
                if (MetadataHelper.IsAssociationValidForEntityType(expectedEnd, entityTypeMapping.EntityType))
                { 
                    if (!actualEnds.Contains(expectedEnd))
                    {
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_Invalid_Function_Mapping_AssociationSetNotMappedForOperation_4(
                            entitySetMapping.Set.Name, 
                            expectedEnd.ParentAssociationSet.Name,
                            elementName, 
                            entityTypeMapping.EntityType.FullName), 
                            StorageMappingErrorCode.InvalidFunctionMappingAssociationSetNotMappedForOperation,
                            m_sourceLocation, 
                            xmlLineInfoNav,
                            m_parsingErrors);
                    }
                } 
            }
 
            // check that no ends with invalid types are included 
            foreach (AssociationSetEnd actualEnd in actualEnds)
            { 
                if (!MetadataHelper.IsAssociationValidForEntityType(actualEnd, entityTypeMapping.EntityType))
                {
                    AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_Invalid_Function_Mapping_AssociationEndMappingInvalidForEntityType_3(
                        entityTypeMapping.EntityType.FullName, 
                        actualEnd.ParentAssociationSet.Name,
                        MetadataHelper.GetEntityTypeForEnd(MetadataHelper.GetOppositeEnd(actualEnd).CorrespondingAssociationEndMember).FullName), 
                        StorageMappingErrorCode.InvalidFunctionMappingAssociationEndMappingInvalidForEntityType, 
                        m_sourceLocation,
                        xmlLineInfoNav, 
                        m_parsingErrors);
                }
            }
        } 

        ///  
        /// Validates that association sets are only mapped once. 
        /// 
        ///  
        /// Container to validate
        private void ValidateFunctionAssociationFunctionMappingUnique(XPathNavigator nav, StorageEntityContainerMapping entityContainerMapping)
        {
            Dictionary mappingCounts = new Dictionary(); 

            // Walk through all entity set mappings 
            foreach (StorageEntitySetMapping entitySetMapping in entityContainerMapping.EntitySetMaps) 
            {
                if (entitySetMapping.FunctionMappings.Count > 0) 
                {
                    // Get set of association sets implicitly mapped associations to avoid double counting
                    Set associationSets = new Set();
                    foreach (AssociationSetEnd end in entitySetMapping.ImplicitlyMappedAssociationSetEnds) 
                    {
                        associationSets.Add(end.ParentAssociationSet); 
                    } 

                    foreach (EntitySetBase associationSet in associationSets) 
                    {
                        IncrementCount(mappingCounts, associationSet);
                    }
                } 
            }
 
            // Walk through all association set mappings 
            foreach (StorageAssociationSetMapping associationSetMapping in entityContainerMapping.RelationshipSetMaps)
            { 
                if (null != associationSetMapping.FunctionMapping)
                {
                    IncrementCount(mappingCounts, associationSetMapping.Set);
                } 
            }
 
            // Check for redundantly mapped association sets 
            List violationNames = new List();
            foreach (KeyValuePair mappingCount in mappingCounts) 
            {
                if (mappingCount.Value > 1)
                {
                    violationNames.Add(mappingCount.Key.Name); 
                }
            } 
 
            if (0 < violationNames.Count)
            { 
                // Warn the user that association sets are mapped multiple times
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Invalid_Function_Mapping_AssociationSetAmbiguous_1,
                    StringUtil.ToCommaSeparatedString(violationNames), StorageMappingErrorCode.AmbiguousFunctionMappingForAssociationSet,
                    m_sourceLocation, (IXmlLineInfo)nav, m_parsingErrors); 

            } 
        } 

        private static void IncrementCount(Dictionary counts, T key) 
        {
            int count;
            if (counts.TryGetValue(key, out count))
            { 
                count++;
            } 
            else 
            {
                count = 1; 
            }
            counts[key] = count;
        }
 
        /// 
        /// Validates that all or no related extents have function mappings. If an EntitySet has a function mapping, 
        /// then all 'reference' association sets must also have function mappings. Similarly, if an AssociationSet has a function 
        /// mapping, 'reference' ends must have function mappings.
        ///  
        /// 
        /// Container to validate.
        private void ValidateFunctionMappingClosure(XPathNavigator nav, StorageEntityContainerMapping entityContainerMapping)
        { 
            // Check that function mappings apply to complete subgraph by tracking which extents have function
            // mappings and which extents must include function mappings 
            Set setsWithFunctionMapping = new Set(); 

            // Walk through all entity set mappings 
            foreach (StorageEntitySetMapping entitySetMapping in entityContainerMapping.EntitySetMaps)
            {
                if (entitySetMapping.FunctionMappings.Count > 0)
                { 
                    // a function mapping exists for this entity set
                    setsWithFunctionMapping.Add(entitySetMapping.Set); 
 
                    // add all implicitly mapped association sets
                    foreach (AssociationSetEnd end in entitySetMapping.ImplicitlyMappedAssociationSetEnds) 
                    {
                        setsWithFunctionMapping.Add(end.ParentAssociationSet);
                    }
                } 
            }
 
            // Walk through all association set mapping 
            foreach (StorageAssociationSetMapping associationSetMapping in entityContainerMapping.RelationshipSetMaps)
            { 
                if (null != associationSetMapping.FunctionMapping)
                {
                    setsWithFunctionMapping.Add(associationSetMapping.Set);
                } 
            }
 
            // Initialize sets requiring function mapping with the sets that are actually function mapped 
            Set setsRequiringFunctionMapping = FindMissingFunctionMappings(entityContainerMapping, setsWithFunctionMapping);
 
            // Check that no required entity or association sets are missing
            if (0 < setsRequiringFunctionMapping.Count)
            {
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Invalid_Function_Mapping_MissingSetClosure_1, 
                    StringUtil.ToCommaSeparatedString(setsRequiringFunctionMapping),
                    StorageMappingErrorCode.MissingSetClosureInFunctionMapping, m_sourceLocation, (IXmlLineInfo)nav 
                    , m_parsingErrors); 
            }
        } 

        private static Set FindMissingFunctionMappings(StorageEntityContainerMapping entityContainerMapping, Set setsWithFunctionMapping)
        {
            Set setsRequiringFunctionMapping = new Set(); 
            foreach (EntitySetBase entitySetBase in setsWithFunctionMapping)
            { 
                if (BuiltInTypeKind.AssociationSet == entitySetBase.BuiltInTypeKind) 
                {
                    AssociationSet associationSet = (AssociationSet)entitySetBase; 
                    // add the entity sets bound to the end roles to the required list
                    foreach (AssociationSetEnd end in associationSet.AssociationSetEnds)
                    {
                        var multiplicity = end.CorrespondingAssociationEndMember.RelationshipMultiplicity; 
                        if (multiplicity == RelationshipMultiplicity.One ||
                            multiplicity == RelationshipMultiplicity.ZeroOrOne) 
                        { 
                            // for 'reference' ends of associations, the entity set is required
                            EntitySet requiredSet = MetadataHelper.GetOppositeEnd(end).EntitySet; 
                            if (!setsWithFunctionMapping.Contains(requiredSet))
                            {
                                setsRequiringFunctionMapping.Add(MetadataHelper.GetOppositeEnd(end).EntitySet);
                            } 
                        }
                    } 
                } 
            }
 
            // Register all association sets referencing known entity sets
            foreach (EntitySetBase entitySetBase in entityContainerMapping.EdmEntityContainer.BaseEntitySets)
            {
                if (BuiltInTypeKind.AssociationSet == entitySetBase.BuiltInTypeKind) 
                {
                    AssociationSet associationSet = (AssociationSet)entitySetBase; 
                    // check that this association set isn't already mapped 
                    if (!setsWithFunctionMapping.Contains(associationSet))
                    { 
                        foreach (AssociationSetEnd end in associationSet.AssociationSetEnds)
                        {
                            var multiplicity = end.CorrespondingAssociationEndMember.RelationshipMultiplicity;
                            if (multiplicity == RelationshipMultiplicity.One || 
                                multiplicity == RelationshipMultiplicity.ZeroOrOne)
                            { 
                                var oppositeEnd = MetadataHelper.GetOppositeEnd(end); 

                                // check if the opposite end has a function mapping (which means 
                                // this AssociationSet is a required reference end)
                                if (setsWithFunctionMapping.Contains(oppositeEnd.EntitySet))
                                {
                                    setsRequiringFunctionMapping.Add(associationSet); 
                                }
                            } 
                        } 
                    }
                } 
            }

            return setsRequiringFunctionMapping;
        } 

        private static void ValidateClosureAmongSets(StorageEntityContainerMapping entityContainerMapping, Set sets, Set additionalSetsInClosure) 
        { 
            bool nodeFound;
            do 
            {
                nodeFound = false;
                List newNodes = new List();
 
                // Register entity sets dependencies for association sets
                foreach (EntitySetBase entitySetBase in additionalSetsInClosure) 
                { 
                    if (BuiltInTypeKind.AssociationSet == entitySetBase.BuiltInTypeKind)
                    { 
                        AssociationSet associationSet = (AssociationSet)entitySetBase;
                        // add the entity sets bound to the end roles to the required list
                        foreach (AssociationSetEnd end in associationSet.AssociationSetEnds)
                        { 
                            if (!additionalSetsInClosure.Contains(end.EntitySet))
                            { 
                                newNodes.Add(end.EntitySet); 
                            }
                        } 
                    }
                }

                // Register all association sets referencing known entity sets 
                foreach (EntitySetBase entitySetBase in entityContainerMapping.EdmEntityContainer.BaseEntitySets)
                { 
                    if (BuiltInTypeKind.AssociationSet == entitySetBase.BuiltInTypeKind) 
                    {
                        AssociationSet associationSet = (AssociationSet)entitySetBase; 
                        // check that this association set isn't already in the required set
                        if (!additionalSetsInClosure.Contains(associationSet))
                        {
                            foreach (AssociationSetEnd end in associationSet.AssociationSetEnds) 
                            {
                                if (additionalSetsInClosure.Contains(end.EntitySet)) 
                                { 
                                    // this association set must be added to the required list if
                                    // any of its ends are in that list 
                                    newNodes.Add(associationSet);
                                    break; // no point adding the association set twice
                                }
                            } 
                        }
                    } 
                } 

                if (0 < newNodes.Count) 
                {
                    nodeFound = true;
                    additionalSetsInClosure.AddRange(newNodes);
                } 
            }
            while (nodeFound); 
 
            additionalSetsInClosure.Subtract(sets);
        } 

        /// 
        /// Validates that all or no related extents have query views defined. If an extent has a query view defined, then
        /// all related extents must also have query views. 
        /// 
        ///  
        /// Container to validate. 

        private void ValidateQueryViewsClosure(XPathNavigator nav, StorageEntityContainerMapping entityContainerMapping) 
        {
            //If there is no query view defined, no need to validate
            if (!m_hasQueryViews)
            { 
                return;
            } 
            // Check that query views apply to complete subgraph by tracking which extents have query 
            // mappings and which extents must include query views
            Set setsWithQueryViews = new Set(); 
            Set setsRequiringQueryViews = new Set();

            // Walk through all set mappings
            foreach (StorageSetMapping setMapping in entityContainerMapping.AllSetMaps) 
            {
                if (setMapping.QueryView != null) 
                { 
                    // a function mapping exists for this entity set
                    setsWithQueryViews.Add(setMapping.Set); 
                }
            }

            // Initialize sets requiring function mapping with the sets that are actually function mapped 
            setsRequiringQueryViews.AddRange(setsWithQueryViews);
 
            ValidateClosureAmongSets(entityContainerMapping, setsWithQueryViews, setsRequiringQueryViews); 

            // Check that no required entity or association sets are missing 
            if (0 < setsRequiringQueryViews.Count)
            {
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Invalid_Query_Views_MissingSetClosure_1,
                    StringUtil.ToCommaSeparatedString(setsRequiringQueryViews), 
                    StorageMappingErrorCode.MissingSetClosureInQueryViews, m_sourceLocation, (IXmlLineInfo)nav
                    , m_parsingErrors); 
            } 
        }
 

        /// 
        /// The method loads the child nodes for the EntitySet Mapping node
        /// into the internal datastructures. 
        /// 
        ///  
        ///  
        /// 
        private void LoadEntitySetMapping(XPathNavigator nav, StorageEntityContainerMapping entityContainerMapping, EntityContainer storageEntityContainerType) 
        {
            //Get the EntitySet name
            string entitySetName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.EntitySetMappingNameAttribute);
            //Get the EntityType name, need to parse it if the mapping information is being specified for multiple types 
            string entityTypeName = StorageMappingItemLoader.GetAttributeValue(nav.Clone(), StorageMslConstructs.EntitySetMappingTypeNameAttribute);
            //Get the table name. This might be emptystring since the user can have a TableMappingFragment instead of this. 
            string tableName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.EntitySetMappingStoreEntitySetAttribute); 
            EntitySet entitySet;
 
            // First check to see if the Entity Set Mapping is already specified. It can be specified, in the same schema file later on
            // on a totally different file. Since we support partial mapping, we should just add mapping fragments or entity type
            // mappings to the existing entity set mapping
            StorageEntitySetMapping setMapping = (StorageEntitySetMapping)entityContainerMapping.GetEntitySetMapping(entitySetName); 

            // Update the info about the schema element 
            IXmlLineInfo navLineInfo = (IXmlLineInfo)nav; 

            if (setMapping == null) 
            {
                //Try to find the EntitySet with the given name in the EntityContainer.
                if (!entityContainerMapping.EdmEntityContainer.TryGetEntitySetByName(entitySetName, /*ignoreCase*/ false, out entitySet))
                { 
                    //If no EntitySet with the given name exists, than add a schema error and return
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Entity_Set_1, entitySetName, 
                        StorageMappingErrorCode.InvalidEntitySet, m_sourceLocation, navLineInfo, m_parsingErrors); 
                    //There is no point in continuing the loding of this EntitySetMapping if the EntitySet is not found
                    return; 
                }
                //Create the EntitySet Mapping which contains the mapping information for EntitySetMap.
                setMapping = new StorageEntitySetMapping(entitySet, entityContainerMapping);
            } 
            else
            { 
                entitySet = (EntitySet)setMapping.Set; 
            }
 
            //Set the Start Line Information on Fragment
            setMapping.StartLineNumber = navLineInfo.LineNumber;
            setMapping.StartLinePosition = navLineInfo.LinePosition;
            entityContainerMapping.AddEntitySetMapping(setMapping); 

            //If the TypeName was not specified as an attribute, than an EntityTypeMapping element should be present 
            if (String.IsNullOrEmpty(entityTypeName)) 
            {
                if (nav.MoveToChild(XPathNodeType.Element)) 
                {

                    do
                    { 
                        switch (nav.LocalName)
                        { 
                            case StorageMslConstructs.EntityTypeMappingElement: 
                                {
                                    //TableName could also be specified on EntityTypeMapping element 
                                    tableName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.EntityTypeMappingStoreEntitySetAttribute);
                                    //Load the EntityTypeMapping into memory.
                                    LoadEntityTypeMapping(nav.Clone(), setMapping, tableName, storageEntityContainerType);
                                    break; 
                                }
                            case StorageMslConstructs.QueryViewElement: 
                                { 
                                    if (!(String.IsNullOrEmpty(tableName)))
                                    { 
                                        AddToSchemaErrorsWithMemberInfo(Strings.Mapping_TableName_QueryView_1, entitySetName,
                                            StorageMappingErrorCode.TableNameAttributeWithQueryView, m_sourceLocation, navLineInfo, m_parsingErrors);
                                        return;
                                    } 
                                    //Load the Query View into the set mapping,
                                    //if you get an error, return immediately since 
                                    //you go on, you could be giving lot of dubious errors 
                                    if(!LoadQueryView(nav.Clone(), setMapping))
                                    { 
                                        return;
                                    }
                                    break;
                                } 
                            default:
                                AddToSchemaErrors(Strings.Mapping_InvalidContent_TypeMapping_QueryView, 
                                    StorageMappingErrorCode.InvalidContent, m_sourceLocation, navLineInfo, m_parsingErrors); 
                                break;
                        } 
                    } while (nav.MoveToNext(XPathNodeType.Element));
                }
            }
            else 
            {
                //Load the EntityTypeMapping into memory. 
                LoadEntityTypeMapping(nav.Clone(), setMapping, tableName, storageEntityContainerType); 
            }
            ValidateAllEntityTypesHaveFunctionMapping(nav.Clone(), setMapping); 
            //Add a schema error if the set mapping has no content
            if (setMapping.HasNoContent)
            {
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Emtpty_SetMap_1, entitySet.Name, 
                    StorageMappingErrorCode.EmptySetMapping, m_sourceLocation, navLineInfo, m_parsingErrors);
            } 
        } 

        // Ensure if any type has a function mapping, all types have function mappings 
        private void ValidateAllEntityTypesHaveFunctionMapping(XPathNavigator nav, StorageEntitySetMapping setMapping)
        {
            Set functionMappedTypes = new Set();
            foreach (StorageEntityTypeFunctionMapping functionMapping in setMapping.FunctionMappings) 
            {
                functionMappedTypes.Add(functionMapping.EntityType); 
            } 
            if (0 < functionMappedTypes.Count)
            { 
                Set unmappedTypes = new Set(MetadataHelper.GetTypeAndSubtypesOf(setMapping.Set.ElementType, EdmItemCollection, false /*includeAbstractTypes*/));
                unmappedTypes.Subtract(functionMappedTypes);

                // Remove abstract types 
                Set abstractTypes = new Set();
                foreach (EntityType unmappedType in unmappedTypes) 
                { 
                    if (unmappedType.Abstract)
                    { 
                        abstractTypes.Add(unmappedType);
                    }
                }
                unmappedTypes.Subtract(abstractTypes); 

                // See if there are any remaining entity types requiring function mapping 
                if (0 < unmappedTypes.Count) 
                {
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Invalid_Function_Mapping_MissingEntityType_1, 
                        StringUtil.ToCommaSeparatedString(unmappedTypes),
                        StorageMappingErrorCode.MissingFunctionMappingForEntityType, m_sourceLocation, (IXmlLineInfo)nav
                        , m_parsingErrors);
                } 
            }
        } 
 
        private bool TryParseEntityTypeAttribute(XPathNavigator nav, EntityType rootEntityType,
            Func typeNotAssignableMessage, 
            out Set isOfTypeEntityTypes, out Set entityTypes)
        {
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
            string entityTypeAttribute = GetAttributeValue(nav.Clone(), StorageMslConstructs.EntitySetMappingTypeNameAttribute); 

            isOfTypeEntityTypes = new Set(); 
            entityTypes = new Set(); 

            // get components of type declaration 
            var entityTypeNames = entityTypeAttribute.Split(StorageMslConstructs.TypeNameSperator).Select(s => s.Trim());

            // figure out each component
            foreach (var name in entityTypeNames) 
            {
                bool isTypeOf = name.StartsWith(StorageMslConstructs.IsTypeOf, StringComparison.Ordinal); 
                string entityTypeName; 
                if (isTypeOf)
                { 
                    // get entityTypeName of OfType(entityTypeName)
                    if (!name.EndsWith(StorageMslConstructs.IsTypeOfTerminal, StringComparison.Ordinal))
                    {
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_InvalidContent_IsTypeOfNotTerminated, 
                            StorageMappingErrorCode.InvalidEntityType, m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                        // No point in continuing with an error in the entitytype name 
                        return false; 
                    }
                    entityTypeName = name.Substring(StorageMslConstructs.IsTypeOf.Length); 
                    entityTypeName = entityTypeName.Substring(0, entityTypeName.Length - StorageMslConstructs.IsTypeOfTerminal.Length).Trim();
                }
                else
                { 
                    entityTypeName = name;
                } 
 
                // resolve aliases
                entityTypeName = GetAliasResolvedValue(entityTypeName); 

                EntityType entityType;
                if (!this.EdmItemCollection.TryGetItem(entityTypeName, out entityType))
                { 
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Entity_Type_1, entityTypeName,
                        StorageMappingErrorCode.InvalidEntityType, m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                    // No point in continuing with an error in the entitytype name 
                    return false;
                } 
                if (!(Helper.IsAssignableFrom(rootEntityType, entityType)))
                {
                    IXmlLineInfo lineInfo = xmlLineInfoNav;
                    AddToSchemaErrorWithMessage( 
                        typeNotAssignableMessage(entityType),
                        StorageMappingErrorCode.InvalidEntityType, m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                    //no point in continuing with an error in the entitytype name 
                    return false;
                } 

                // Using TypeOf construct on an abstract type that does not have
                // any concrete descendants is not allowed
                if (entityType.Abstract) 
                {
                    if (isTypeOf) 
                    { 
                        IEnumerable typeAndSubTypes = MetadataHelper.GetTypeAndSubtypesOf(entityType, EdmItemCollection, false /*includeAbstractTypes*/);
                        if (!typeAndSubTypes.GetEnumerator().MoveNext()) 
                        {
                            AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_AbstractEntity_IsOfType_1, entityType.FullName,
                                StorageMappingErrorCode.MappingForAbstractEntityType, m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                            return false; 
                        }
                    } 
                    else 
                    {
                        AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_AbstractEntity_Type_1, entityType.FullName, 
                            StorageMappingErrorCode.MappingForAbstractEntityType, m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                        return false;
                    }
                } 

                // Add type to set 
                if (isTypeOf) 
                {
                    isOfTypeEntityTypes.Add(entityType); 
                }
                else
                {
                    entityTypes.Add(entityType); 
                }
            } 
 
            // No failures
            return true; 
        }

        /// 
        /// The method loads the child nodes for the EntityType Mapping node 
        /// into the internal datastructures.
        ///  
        ///  
        /// 
        ///  
        /// 
        private void LoadEntityTypeMapping(XPathNavigator nav, StorageEntitySetMapping entitySetMapping, string tableName, EntityContainer storageEntityContainerType)
        {
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav; 

            //Create an EntityTypeMapping to hold the information for EntityType mapping. 
            StorageEntityTypeMapping entityTypeMapping = new StorageEntityTypeMapping(entitySetMapping); 

            //Get entity types 
            Set entityTypes;
            Set isOfTypeEntityTypes;
            EntityType rootEntityType = (EntityType)entitySetMapping.Set.ElementType;
            if (!TryParseEntityTypeAttribute(nav.Clone(), rootEntityType, 
                e => System.Data.Entity.Strings.Mapping_InvalidContent_Entity_Type_For_Entity_Set_3(e.FullName, rootEntityType.FullName, entitySetMapping.Set.Name),
                out isOfTypeEntityTypes, 
                out entityTypes)) 
            {
                // Return if we cannot parse entity types 
                return;
            }

            // Register all mapped types 
            foreach (EntityType entityType in entityTypes)
            { 
                entityTypeMapping.AddType(entityType); 
            }
            foreach (EntityType isOfTypeEntityType in isOfTypeEntityTypes) 
            {
                entityTypeMapping.AddIsOfType(isOfTypeEntityType);
            }
 
            //If the table name was not specified on the EntitySetMapping element nor the EntityTypeMapping element
            //than a table mapping fragment element should be present 
            //Loop through the TableMappingFragment elements and add them to EntityTypeMappings 
            if (String.IsNullOrEmpty(tableName))
            { 
                if (!nav.MoveToChild(XPathNodeType.Element))
                    return;
                do
                { 
                    if (nav.LocalName == StorageMslConstructs.ModificationFunctionMappingElement)
                    { 
                        LoadEntityTypeFunctionMapping(nav.Clone(), entitySetMapping, entityTypeMapping); 
                    }
                    else if (nav.LocalName != StorageMslConstructs.MappingFragmentElement) 
                    {
                        AddToSchemaErrors(Strings.Mapping_InvalidContent_Table_Expected_0,
                            StorageMappingErrorCode.TableMappingFragmentExpected, m_sourceLocation, xmlLineInfoNav
                            , m_parsingErrors); 
                    }
                    else 
                    { 
                        tableName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.MappingFragmentStoreEntitySetAttribute);
                        StorageMappingFragment fragment = LoadMappingFragment(nav.Clone(), entityTypeMapping, tableName, 
                        storageEntityContainerType);
                        //The fragment can be null in the cases of validation errors.
                        if (fragment != null)
                        { 
                            entityTypeMapping.AddFragment(fragment);
                        } 
                    } 
                } while (nav.MoveToNext(XPathNodeType.Element));
            } 
            else
            {
                if (nav.LocalName == StorageMslConstructs.ModificationFunctionMappingElement)
                { 
                    // function mappings cannot exist in the context of a table mapping
                    AddToSchemaErrors(Strings.Mapping_Invalid_Function_Mapping_In_Table_Context_0, 
                        StorageMappingErrorCode.InvalidTableNameAttributeWithFunctionMapping, 
                        m_sourceLocation, xmlLineInfoNav
                        , m_parsingErrors); 
                }

                StorageMappingFragment fragment = LoadMappingFragment(nav.Clone(), entityTypeMapping, tableName,
                    storageEntityContainerType); 
                //The fragment can be null in the cases of validation errors.
                if (fragment != null) 
                { 
                    entityTypeMapping.AddFragment(fragment);
                } 
            }
            entitySetMapping.AddTypeMapping(entityTypeMapping);
        }
 

        ///  
        /// Loads function mappings for entity type. 
        /// 
        ///  
        /// 
        /// 
        private void LoadEntityTypeFunctionMapping(XPathNavigator nav, StorageEntitySetMapping entitySetMapping,
            StorageEntityTypeMapping entityTypeMapping) 
        {
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav; 
 
            // Function mappings can apply only to a single type.
            if (entityTypeMapping.IsOfTypes.Count != 0 || entityTypeMapping.Types.Count != 1) 
            {
                AddToSchemaErrors(Strings.Mapping_Invalid_Function_Mapping_Multiple_Types_0,
                    StorageMappingErrorCode.InvalidFunctionMappingForMultipleTypes,
                    m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                return;
            } 
            EntityType entityType = (EntityType)entityTypeMapping.Types[0]; 
            //Function Mapping is not allowed to be defined for Abstract Types
            if (entityType.Abstract) 
            {
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_AbstractEntity_FunctionMapping_1, entityType.FullName,
                    StorageMappingErrorCode.MappingForAbstractEntityType, m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                return; 
            }
 
            // check that no mapping exists for this entity type already 
            foreach (StorageEntityTypeFunctionMapping existingFunctionMapping in entitySetMapping.FunctionMappings)
            { 
                if (existingFunctionMapping.EntityType.Equals(entityType))
                {
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Invalid_Function_Mapping_RedundantEntityTypeMapping_1,
                        entityType.Name, StorageMappingErrorCode.RedundantEntityTypeMappingInFunctionMapping, m_sourceLocation, xmlLineInfoNav 
                        , m_parsingErrors);
                    return; 
                } 
            }
 
            // create function loader
            FunctionMappingLoader functionLoader = new FunctionMappingLoader(this, entitySetMapping.Set);

            // Load all function definitions (for insert, delete and update) 
            StorageFunctionMapping deleteFunctionMapping = null;
            StorageFunctionMapping insertFunctionMapping = null; 
            StorageFunctionMapping updateFunctionMapping = null; 
            if (nav.MoveToChild(XPathNodeType.Element))
            { 
                do
                {
                    switch (nav.LocalName)
                    { 
                        case StorageMslConstructs.DeleteFunctionElement:
                            deleteFunctionMapping = functionLoader.LoadEntityTypeFunctionMapping(nav.Clone(), false, true, entityType); 
                            break; 
                        case StorageMslConstructs.InsertFunctionElement:
                            insertFunctionMapping = functionLoader.LoadEntityTypeFunctionMapping(nav.Clone(), true, false, entityType); 
                            break;
                        case StorageMslConstructs.UpdateFunctionElement:
                            updateFunctionMapping = functionLoader.LoadEntityTypeFunctionMapping(nav.Clone(), true, true, entityType);
                            break; 
                    }
                } while (nav.MoveToNext(XPathNodeType.Element)); 
            } 

            //We might be returned null because of schema errors 
            if (null == deleteFunctionMapping || null == insertFunctionMapping
                || null == updateFunctionMapping)
            {
                return; 
            }
 
            // Ensure that assocation set end mappings bind to the same end (e.g., in Person Manages Person 
            // self-association, ensure that the manager end or the report end is mapped but not both)
            Dictionary associationEnds = new Dictionary(); 
            foreach (StorageFunctionParameterBinding parameterBinding in Helper.Concat(
                deleteFunctionMapping.ParameterBindings,
                insertFunctionMapping.ParameterBindings,
                updateFunctionMapping.ParameterBindings)) 
            {
                if (null != parameterBinding.MemberPath.AssociationSetEnd) 
                { 
                    AssociationSet associationSet = parameterBinding.MemberPath.AssociationSetEnd.ParentAssociationSet;
                    // the "end" corresponds to the second member in the path, e.g. 
                    // ID<-Manager where Manager is the end
                    EdmMember currentEnd = parameterBinding.MemberPath.AssociationSetEnd.CorrespondingAssociationEndMember;

                    EdmMember existingEnd; 
                    if (associationEnds.TryGetValue(associationSet, out existingEnd) &&
                        existingEnd != currentEnd) 
                    { 
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_Invalid_Function_Mapping_MultipleEndsOfAssociationMapped_3(
                            currentEnd.Name, existingEnd.Name, associationSet.Name), 
                            StorageMappingErrorCode.InvalidFunctionMappingMultipleEndsOfAssociationMapped, m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                        return;
                    }
                    else 
                    {
                        associationEnds[associationSet] = currentEnd; 
                    } 
                }
            } 

            // Register the function mapping on the entity set mapping
            StorageEntityTypeFunctionMapping functionMapping = new StorageEntityTypeFunctionMapping(
                entityType, deleteFunctionMapping, insertFunctionMapping, updateFunctionMapping); 
            entitySetMapping.AddFunctionMapping(functionMapping);
        } 
 
        /// 
        /// The method loads the query view for the Set Mapping node 
        /// into the internal datastructures.
        /// 
        private bool LoadQueryView(XPathNavigator nav, StorageSetMapping setMapping)
        { 
            Debug.Assert(nav.LocalName == StorageMslConstructs.QueryViewElement);
 
            string queryView = nav.Value; 
            bool includeSubtypes = false;
 

            string typeNameString = StorageMappingItemLoader.GetAttributeValue(nav.Clone(), StorageMslConstructs.EntitySetMappingTypeNameAttribute);
            if (typeNameString != null)
            { 
                typeNameString = typeNameString.Trim();
            } 
 
            if (setMapping.QueryView == null)
            { 

                //QV must be the special-case first view
                if (typeNameString != null)
                { 
                    AddToSchemaErrorsWithMemberInfo(val => Strings.Mapping_TypeName_For_First_QueryView,
                        setMapping.Set.Name, StorageMappingErrorCode.TypeNameForFirstQueryView, 
                        m_sourceLocation, (IXmlLineInfo)nav, m_parsingErrors); 
                    return false;
                } 


                if (String.IsNullOrEmpty(queryView))
                { 
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Empty_QueryView_1,
                        setMapping.Set.Name, StorageMappingErrorCode.EmptyQueryView, 
                        m_sourceLocation, (IXmlLineInfo)nav, m_parsingErrors); 
                    return false;
                } 
                setMapping.QueryView = queryView;
                this.m_hasQueryViews = true;
                return true;
            } 
            else
            { 
                //QV must be typeof or typeofonly view 
                if (typeNameString == null || typeNameString.Trim().Length == 0)
                { 
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_QueryView_TypeName_Not_Defined,
                        setMapping.Set.Name, StorageMappingErrorCode.NoTypeNameForTypeSpecificQueryView,
                        m_sourceLocation, (IXmlLineInfo)nav, m_parsingErrors);
                    return false; 
                }
 
                //Get entity types 
                Set entityTypes;
                Set isOfTypeEntityTypes; 
                EntityType rootEntityType = (EntityType)setMapping.Set.ElementType;
                if (!TryParseEntityTypeAttribute(nav.Clone(), rootEntityType,
                    e => System.Data.Entity.Strings.Mapping_InvalidContent_Entity_Type_For_Entity_Set_3(e.FullName, rootEntityType.FullName, setMapping.Set.Name),
                    out isOfTypeEntityTypes, 
                    out entityTypes))
                { 
                    // Return if we cannot parse entity types 
                    return false;
                } 
                Debug.Assert(isOfTypeEntityTypes.Count > 0 || entityTypes.Count > 0);
                Debug.Assert(!(isOfTypeEntityTypes.Count > 0 && entityTypes.Count > 0));

                EntityType entityType; 
                if (isOfTypeEntityTypes.Count == 1)
                {   //OfType View 
                    entityType = isOfTypeEntityTypes.First(); 
                    includeSubtypes = true;
                } 
                else if (entityTypes.Count == 1)
                {   //OfTypeOnly View
                    entityType = entityTypes.First();
                    includeSubtypes = false; 
                }
                else 
                { 
                    //More than one type
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_QueryViewMultipleTypeInTypeName, setMapping.Set.ToString(), 
                        StorageMappingErrorCode.TypeNameContainsMultipleTypesForQueryView, m_sourceLocation, (IXmlLineInfo)nav, m_parsingErrors);
                    return false;
                }
 
                //Check if IsTypeOf(A) and A is the base type
                if (includeSubtypes && setMapping.Set.ElementType.EdmEquals(entityType)) 
                {   //Don't allow TypeOFOnly(a) if a is a base type. 
                    AddToSchemaErrorWithMemberAndStructure(Strings.Mapping_QueryView_For_Base_Type, entityType.ToString(), setMapping.Set.ToString(),
                        StorageMappingErrorCode.IsTypeOfQueryViewForBaseType, m_sourceLocation, (IXmlLineInfo)nav, m_parsingErrors); 
                    return false;
                }

                if (String.IsNullOrEmpty(queryView)) 
                {
                    if (includeSubtypes) 
                    { 
                        AddToSchemaErrorWithMemberAndStructure(Strings.Mapping_Empty_QueryView_OfType_2,
                            entityType.Name, setMapping.Set.Name, StorageMappingErrorCode.EmptyQueryView, 
                            m_sourceLocation, (IXmlLineInfo)nav, m_parsingErrors);
                        return false;
                    }
                    else 
                    {
                        AddToSchemaErrorWithMemberAndStructure(Strings.Mapping_Empty_QueryView_OfTypeOnly_2, 
                            setMapping.Set.Name, entityType.Name, StorageMappingErrorCode.EmptyQueryView, 
                            m_sourceLocation, (IXmlLineInfo)nav, m_parsingErrors);
                        return false; 
                    }
                }

 
                //Add it to the QV cache
                Triple key = new Triple(setMapping.Set, new Pair(entityType, includeSubtypes)); 
 

                if (setMapping.ContainsTypeSpecificQueryView(key)) 
                { //two QVs for the same type

                    EdmSchemaError error = null;
                    if (includeSubtypes) 
                    {
                        error = 
                            new EdmSchemaError( 
                                Strings.Mapping_QueryView_Duplicate_OfType(setMapping.Set, entityType),
                                (int)StorageMappingErrorCode.QueryViewExistsForEntitySetAndType, EdmSchemaErrorSeverity.Error, m_sourceLocation, 
                                ((IXmlLineInfo)nav).LineNumber, ((IXmlLineInfo)nav).LinePosition);
                    }
                    else
                    { 
                        error =
                            new EdmSchemaError( 
                                Strings.Mapping_QueryView_Duplicate_OfTypeOnly(setMapping.Set, entityType), 
                                (int)StorageMappingErrorCode.QueryViewExistsForEntitySetAndType, EdmSchemaErrorSeverity.Error, m_sourceLocation,
                                ((IXmlLineInfo)nav).LineNumber, ((IXmlLineInfo)nav).LinePosition); 
                    }

                    m_parsingErrors.Add(error);
                    return false; 
                }
 
                setMapping.AddTypeSpecificQueryView(key, queryView); 
                return true;
            } 
        }

        /// 
        /// The method loads the child nodes for the AssociationSet Mapping node 
        /// into the internal datastructures.
        ///  
        ///  
        /// 
        ///  
        private void LoadAssociationSetMapping(XPathNavigator nav, StorageEntityContainerMapping entityContainerMapping, EntityContainer storageEntityContainerType)
        {
            IXmlLineInfo navLineInfo = (IXmlLineInfo)nav;
 
            //Get the AssociationSet name
            string associationSetName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.AssociationSetMappingNameAttribute); 
            //Get the AssociationType name, need to parse it if the mapping information is being specified for multiple types 
            string associationTypeName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.AssociationSetMappingTypeNameAttribute);
            //Get the table name. This might be emptystring since the user can have a TableMappingFragment instead of this. 
            string tableName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.EntitySetMappingStoreEntitySetAttribute);
            //Try to find the AssociationSet with the given name in the EntityContainer.
            RelationshipSet relationshipSet;
            entityContainerMapping.EdmEntityContainer.TryGetRelationshipSetByName(associationSetName, false /*ignoreCase*/, out relationshipSet); 
            AssociationSet associationSet = relationshipSet as AssociationSet;
            //If no AssociationSet with the given name exists, than Add a schema error and return 
            if (associationSet == null) 
            {
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Association_Set_1, associationSetName, 
                    StorageMappingErrorCode.InvalidAssociationSet, m_sourceLocation, navLineInfo, m_parsingErrors);
                //There is no point in continuing the loading of association set map if the AssociationSetName has a problem
                return;
            } 

            if (entityContainerMapping.ContainsAssociationSetMapping(associationSet)) 
            { 
                //Can not add this set mapping since our storage dictionary won't allow
                //duplicate maps 
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Duplicate_CdmAssociationSet_StorageMap_1, associationSetName,
                    StorageMappingErrorCode.DuplicateSetMapping, m_sourceLocation, navLineInfo, m_parsingErrors);
                return;
 
            }
            //Create the AssociationSet Mapping which contains the mapping information for association set. 
            StorageAssociationSetMapping setMapping = new StorageAssociationSetMapping(associationSet, entityContainerMapping); 

            //Set the Start Line Information on Fragment 
            setMapping.StartLineNumber = navLineInfo.LineNumber;
            setMapping.StartLinePosition = navLineInfo.LinePosition;

 
            if (!nav.MoveToChild(XPathNodeType.Element))
            { 
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Emtpty_SetMap_1, associationSet.Name, 
                    StorageMappingErrorCode.EmptySetMapping, m_sourceLocation, navLineInfo, m_parsingErrors);
                return; 
            }

            entityContainerMapping.AddAssociationSetMapping(setMapping);
 
            //If there is a query view it has to be the first element
            if (nav.LocalName == StorageMslConstructs.QueryViewElement) 
            { 
                if (!(String.IsNullOrEmpty(tableName)))
                { 
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_TableName_QueryView_1, associationSetName,
                        StorageMappingErrorCode.TableNameAttributeWithQueryView, m_sourceLocation, navLineInfo, m_parsingErrors);
                    return;
                } 
                //Load the Query View into the set mapping,
                //if you get an error, return immediately since 
                //you go on, you could be giving lot of dubious errors 
                if (!LoadQueryView(nav.Clone(), setMapping))
                { 
                    return;
                }
                //If there are no more elements just return
                if (!nav.MoveToNext(XPathNodeType.Element)) 
                {
                    return; 
                } 
            }
 
            if ((nav.LocalName == StorageMslConstructs.EndPropertyMappingElement) ||
                     (nav.LocalName == StorageMslConstructs.ModificationFunctionMappingElement))
            {
                if ((String.IsNullOrEmpty(associationTypeName))) 
                {
                    AddToSchemaErrors(Strings.Mapping_InvalidContent_Association_Type_Empty_0, 
                        StorageMappingErrorCode.InvalidAssociationType, m_sourceLocation, navLineInfo, m_parsingErrors); 
                    return;
                } 
                //Load the AssociationTypeMapping into memory.
                LoadAssociationTypeMapping(nav.Clone(), setMapping, associationTypeName, tableName, storageEntityContainerType);
            }
            else if (nav.LocalName == StorageMslConstructs.ConditionElement) 
            {
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_AssociationSet_Condition_1, associationSetName, 
                    StorageMappingErrorCode.InvalidContent, m_sourceLocation, navLineInfo, m_parsingErrors); 
                return;
            } 
            else
            {

                Debug.Assert(false, "XSD validation should ensure this"); 
            }
        } 
 
        /// 
        /// The method loads a function import mapping element 
        /// 
        /// 
        /// 
        ///  
        private void LoadFunctionImportMapping(XPathNavigator nav, StorageEntityContainerMapping entityContainerMapping, EntityContainer storageEntityContainerType)
        { 
            IXmlLineInfo lineInfo = (IXmlLineInfo)(nav.Clone()); 

            // Get target (store) function 
            EdmFunction targetFunction;
            if (!TryGetFunctionImportStoreFunction(nav, out targetFunction))
            {
                return; 
            }
 
            // Get source (model) function 
            EdmFunction functionImport;
            if (!TryGetFunctionImportModelFunction(nav, entityContainerMapping, out functionImport)) 
            {
                return;
            }
 
            // Validate parameters are compatible between the store and model functions
            ValidateFunctionImportMappingParameters(nav, targetFunction, functionImport); 
 
            // Process type mapping information
            List typeMappings = new List(); 
            if (nav.MoveToChild(XPathNodeType.Element))
            {
                if (nav.LocalName == StorageMslConstructs.FunctionImportMappingResultMapping)
                { 
                    if (nav.MoveToChild(XPathNodeType.Element))
                    { 
                        do 
                        {
                            if (nav.LocalName == StorageMslConstructs.EntityTypeMappingElement) 
                            {
                                FunctionImportEntityTypeMapping typeMapping;
                                if (TryLoadFunctionImportEntityTypeMapping(nav.Clone(), targetFunction, functionImport, out typeMapping))
                                { 
                                    typeMappings.Add(typeMapping);
                                } 
                            } 
                        }
                        while (nav.MoveToNext(XPathNodeType.Element)); 
                    }
                }
            }
 
            // Add import mapping to list
            FunctionImportMapping mapping = new FunctionImportMapping(targetFunction, functionImport, typeMappings, this.EdmItemCollection); 
            entityContainerMapping.AddFunctionImportMapping(functionImport, mapping); 

            // Verify that all types can be produced 
            KeyToListMap unreachableEntityTypes;
            KeyToListMap unreachableIsTypeOfs;
            mapping.GetUnreachableTypes(EdmItemCollection, out unreachableEntityTypes, out unreachableIsTypeOfs);
 
            foreach (var unreachableEntityType in unreachableEntityTypes.KeyValuePairs)
            { 
                string lines = StringUtil.ToCommaSeparatedString(unreachableEntityType.Value.Select(li => li.LineNumber)); 
                AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_UnreachableType(unreachableEntityType.Key.FullName, lines),
                    StorageMappingErrorCode.MappingFunctionImportAmbiguousTypeConditions, m_sourceLocation, lineInfo, m_parsingErrors); 
            }
            foreach (var unreachableIsTypeOf in unreachableIsTypeOfs.KeyValuePairs)
            {
                string lines = StringUtil.ToCommaSeparatedString(unreachableIsTypeOf.Value.Select(li => li.LineNumber)); 
                string isTypeOfDescription = StorageMslConstructs.IsTypeOf + unreachableIsTypeOf.Key.FullName + StorageMslConstructs.IsTypeOfTerminal;
                AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_UnreachableIsTypeOf(isTypeOfDescription, lines), 
                    StorageMappingErrorCode.MappingFunctionImportAmbiguousTypeConditions, m_sourceLocation, lineInfo, m_parsingErrors); 
            }
 
            // Verify that function imports returning abstract types include explicit mappings
            EntityType returnEntityType;
            if (MetadataHelper.TryGetFunctionImportReturnEntityType(functionImport, out returnEntityType) &&
                returnEntityType.Abstract && 
                mapping.NormalizedEntityTypeMappings.Count == 0)
            { 
                AddToSchemaErrorWithMemberAndStructure(Strings.Mapping_InvalidContent_ImplicitMappingForAbstractReturnType_FunctionMapping_1, returnEntityType.FullName, 
                    functionImport.FullName, StorageMappingErrorCode.MappingForAbstractEntityType, m_sourceLocation, lineInfo, m_parsingErrors);
            } 
        }

        private bool TryGetFunctionImportStoreFunction(XPathNavigator nav, out EdmFunction targetFunction)
        { 
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
            targetFunction = null; 
 
            // Get the function name
            string functionName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.FunctionImportMappingFunctionNameAttribute); 

            // Try to find the function definition
            ReadOnlyCollection functionOverloads = this.StoreItemCollection.GetFunctions(functionName);
 
            if (functionOverloads.Count == 0)
            { 
                AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_StoreFunctionDoesNotExist(functionName), 
                    StorageMappingErrorCode.MappingFunctionImportStoreFunctionDoesNotExist,
                    m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                return false;
            }
            else if (1 < functionOverloads.Count)
            { 
                AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_StoreFunctionAmbiguous(functionName),
                    StorageMappingErrorCode.MappingFunctionImportStoreFunctionAmbiguous, 
                    m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                return false;
            } 

            targetFunction = functionOverloads.Single();

            // validate target function is supported (non-composable, etc.) 
            if (targetFunction.IsComposableAttribute)
            { 
                AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_TargetFunctionMustBeComposable(targetFunction.FullName), 
                    StorageMappingErrorCode.MappingFunctionImportTargetFunctionMustBeComposable,
                    m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                return false;
            }

            return true; 
        }
 
        private bool TryGetFunctionImportModelFunction(XPathNavigator nav, StorageEntityContainerMapping entityContainerMapping, 
            out EdmFunction functionImport)
        { 
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;

            // Get the function import name
            string functionImportName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.FunctionImportMappingFunctionImportNameAttribute); 

            // Try to find the function import 
            EntityContainer modelContainer = entityContainerMapping.EdmEntityContainer; 
            functionImport = null;
            foreach (EdmFunction functionImportCandidate in modelContainer.FunctionImports) 
            {
                if (functionImportCandidate.Name == functionImportName)
                {
                    functionImport = functionImportCandidate; 
                    break;
                } 
            } 
            if (null == functionImport)
            { 
                AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_FunctionImportDoesNotExist(functionImportName, entityContainerMapping.EdmEntityContainer.Name),
                    StorageMappingErrorCode.MappingFunctionImportFunctionImportDoesNotExist,
                    m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                return false; 
            }
 
            // check that no existing mapping exists for this function import 
            FunctionImportMapping targetFunctionCollision;
            if (entityContainerMapping.TryGetFunctionImportMapping(functionImport, out targetFunctionCollision)) 
            {
                AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_FunctionImportMappedMultipleTimes(functionImportName),
                    StorageMappingErrorCode.MappingFunctionImportFunctionImportMappedMultipleTimes,
                    m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                return false;
            } 
            return true; 
        }
 
        private void ValidateFunctionImportMappingParameters(XPathNavigator nav, EdmFunction targetFunction, EdmFunction functionImport)
        {
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
 
            foreach (FunctionParameter targetParameter in targetFunction.Parameters)
            { 
                // find corresponding import parameter 
                FunctionParameter importParameter;
                if (!functionImport.Parameters.TryGetValue(targetParameter.Name, false, out importParameter)) 
                {
                    AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_TargetParameterHasNoCorrespondingImportParameter(targetParameter.Name),
                        StorageMappingErrorCode.MappingFunctionImportTargetParameterHasNoCorrespondingImportParameter,
                        m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                }
                else 
                { 
                    // parameters must have the same direction (in|out)
                    if (targetParameter.Mode != importParameter.Mode) 
                    {
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_IncompatibleParameterMode(targetParameter.Name, targetParameter.Mode, importParameter.Mode),
                            StorageMappingErrorCode.MappingFunctionImportIncompatibleParameterMode,
                            m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                    }
 
                    // there are no type facets declared for function parameter types; 
                    // we simply verify the primitive type kind is equivalent
                    PrimitiveType importType = (PrimitiveType)importParameter.TypeUsage.EdmType; 
                    PrimitiveType cspaceTargetType = (PrimitiveType)StoreItemCollection.StoreProviderManifest.GetEdmType(targetParameter.TypeUsage).EdmType;

                    if (cspaceTargetType == null)
                    { 
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_ProviderReturnsNullType(targetParameter.Name),
                            StorageMappingErrorCode.MappingStoreProviderReturnsNullEdmType, 
                            m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                        return;
                    } 

                    if (cspaceTargetType.PrimitiveTypeKind != importType.PrimitiveTypeKind)
                    {
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_IncompatibleParameterType(targetParameter.Name, cspaceTargetType.Name, importType.Name), 
                            StorageMappingErrorCode.MappingFunctionImportIncompatibleParameterType,
                            m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                    } 
                }
            } 

            foreach (FunctionParameter importParameter in functionImport.Parameters)
            {
                // find corresponding target parameter 
                FunctionParameter targetParameter;
                if (!targetFunction.Parameters.TryGetValue(importParameter.Name, false, out targetParameter)) 
                { 
                    AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_ImportParameterHasNoCorrespondingTargetParameter(importParameter.Name),
                        StorageMappingErrorCode.MappingFunctionImportImportParameterHasNoCorrespondingTargetParameter, 
                        m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                }
            }
        } 

        private bool TryLoadFunctionImportEntityTypeMapping(XPathNavigator nav, EdmFunction targetFunction, EdmFunction functionImport, 
            out FunctionImportEntityTypeMapping typeMapping) 
        {
            typeMapping = null; 
            IXmlLineInfo lineInfo = (IXmlLineInfo)(nav.Clone());

            // cannot specify an entity type mapping for a function import that does not return members
            // of an entity set 
            if (null == functionImport.EntitySet)
            { 
                AddToSchemaErrors(System.Data.Entity.Strings.Mapping_FunctionImport_EntityTypeMappingForFunctionNotReturningEntitySet( 
                    StorageMslConstructs.EntityTypeMappingElement, functionImport.FullName),
                    StorageMappingErrorCode.MappingFunctionImportEntityTypeMappingForFunctionNotReturningEntitySet, 
                    m_sourceLocation, lineInfo, m_parsingErrors);
            }

            // process entity type 
            Set isOfTypeEntityTypes;
            Set entityTypes; 
            { 
                string entityTypeName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.EntityTypeMappingTypeNameAttribute);
 
                // verify the entity type is appropriate to the function import's entity type
                EntityType rootEntityType;
                if (!MetadataHelper.TryGetFunctionImportReturnEntityType(functionImport, out rootEntityType) ||
                    !TryParseEntityTypeAttribute(nav.Clone(), rootEntityType, 
                        e => System.Data.Entity.Strings.Mapping_FunctionImport_InvalidContentEntityTypeForEntitySet(e.FullName, rootEntityType.FullName,
                            functionImport.EntitySet.Name, functionImport.FullName), 
                        out isOfTypeEntityTypes, 
                        out entityTypes))
                { 
                    return false;
                }
            }
 
            // process all conditions
            List conditions = new List(); 
            if (nav.MoveToChild(XPathNodeType.Element)) 
            {
                do 
                {
                    if (nav.LocalName == StorageMslConstructs.ConditionElement)
                    {
                        LoadFunctionImportEntityTypeMappingCondition(nav, conditions); 
                    }
                } 
                while (nav.MoveToNext(XPathNodeType.Element)); 
            }
 
            // make sure a single condition is specified per column
            HashSet columnsWithConditions = new HashSet();
            foreach (var condition in conditions)
            { 
                if (!columnsWithConditions.Add(condition.ColumnName))
                { 
                    AddToSchemaErrorWithMessage( 
                        System.Data.Entity.Strings.Mapping_FunctionImport_MultipleConditionsOnSingleColumn(condition.ColumnName),
                        StorageMappingErrorCode.MappingFunctionMultipleTypeConditionsForOneColumn, 
                        m_sourceLocation, lineInfo, m_parsingErrors);
                    return false;
                }
            } 

            typeMapping = new FunctionImportEntityTypeMapping(isOfTypeEntityTypes, entityTypes, conditions, lineInfo); 
            return true; 
        }
 
        private void LoadFunctionImportEntityTypeMappingCondition(XPathNavigator nav, List conditions)
        {
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
 
            string columnName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ConditionColumnNameAttribute);
            string value = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ConditionValueAttribute); 
            string isNull = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ConditionIsNullAttribute); 

            //Either Value or NotNull need to be specifid on the condition mapping but not both 
            if ((isNull != null) && (value != null))
            {
                AddToSchemaErrors(Strings.Mapping_InvalidContent_ConditionMapping_Both_Values_0,
                    StorageMappingErrorCode.ConditionError, m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
            }
            else if ((isNull == null) && (value == null)) 
            { 
                AddToSchemaErrors(Strings.Mapping_InvalidContent_ConditionMapping_Either_Values_0,
                    StorageMappingErrorCode.ConditionError, m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
            }
            else
            {
                if (isNull != null) 
                {
                    bool isNullValue = Convert.ToBoolean(isNull, CultureInfo.InvariantCulture); 
                    conditions.Add(new FunctionImportEntityTypeMappingConditionIsNull(columnName, isNullValue)); 
                }
                else 
                {
                    XPathNavigator columnValue = nav.Clone();
                    columnValue.MoveToAttribute(StorageMslConstructs.ConditionValueAttribute, string.Empty);
                    conditions.Add(new FunctionImportEntityTypeMappingConditionValue(columnName, columnValue)); 
                }
            } 
        } 

        ///  
        /// The method loads the child nodes for the AssociationType Mapping node
        /// into the internal datastructures.
        /// 
        ///  
        /// 
        ///  
        ///  
        /// 
        private void LoadAssociationTypeMapping(XPathNavigator nav, StorageAssociationSetMapping associationSetMapping, string associationTypeName, string tableName, EntityContainer storageEntityContainerType) 
        {
            IXmlLineInfo navLineInfo = (IXmlLineInfo)nav;

            //Get the association type for association type name specified in MSL 
            //If no AssociationType with the given name exists, add a schema error and return
            AssociationType associationType; 
            this.EdmItemCollection.TryGetItem(associationTypeName, out associationType); 
            if (associationType == null)
            { 
                //There is no point in continuing loading if the AssociationType is null
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Association_Type_1, associationTypeName,
                    StorageMappingErrorCode.InvalidAssociationType, m_sourceLocation, navLineInfo, m_parsingErrors);
                return; 
            }
            //Verify that AssociationType specified should be the declared type of 
            //AssociationSet or a derived Type of it. 
            //Future Enhancement : Change the code to use EdmEquals
            if ((!(associationSetMapping.Set.ElementType.Equals(associationType)))) 
            {
                AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_Invalid_Association_Type_For_Association_Set_3(associationTypeName,
                    associationSetMapping.Set.ElementType.FullName, associationSetMapping.Set.Name),
                    StorageMappingErrorCode.DuplicateTypeMapping, m_sourceLocation, navLineInfo, m_parsingErrors); 
                return;
            } 
 
            //Create an AssociationTypeMapping to hold the information for AssociationType mapping.
            StorageAssociationTypeMapping associationTypeMapping = new StorageAssociationTypeMapping(associationType, associationSetMapping); 
            associationSetMapping.AddTypeMapping(associationTypeMapping);
            //If the table name was not specified on the AssociationSetMapping element
            //Then there should have been a query view. Otherwise throw.
            if (String.IsNullOrEmpty(tableName) && (associationSetMapping.QueryView == null)) 
            {
                AddToSchemaErrors(Strings.Mapping_InvalidContent_Table_Expected_0, StorageMappingErrorCode.InvalidTable, 
                    m_sourceLocation, navLineInfo, m_parsingErrors); 
            }
            else 
            {
                StorageMappingFragment fragment = LoadAssociationMappingFragment(nav.Clone(), associationSetMapping, associationTypeMapping, tableName, storageEntityContainerType);
                if (fragment != null)
                { 
                    //Fragment can be null because of validation errors
                    associationTypeMapping.AddFragment(fragment); 
                } 
            }
        } 

        /// 
        /// Loads function mappings for the entity type.
        ///  
        /// 
        ///  
        ///  
        private void LoadAssociationTypeFunctionMapping(XPathNavigator nav, StorageAssociationSetMapping associationSetMapping,
            StorageAssociationTypeMapping associationTypeMapping) 
        {
            // create function loader
            FunctionMappingLoader functionLoader = new FunctionMappingLoader(this, associationSetMapping.Set);
 
            // Load all function definitions (for insert, delete and update)
            StorageFunctionMapping deleteFunctionMapping = null; 
            StorageFunctionMapping insertFunctionMapping = null; 
            if (nav.MoveToChild(XPathNodeType.Element))
            { 
                do
                {
                    switch (nav.LocalName)
                    { 
                        case StorageMslConstructs.DeleteFunctionElement:
                            deleteFunctionMapping = functionLoader.LoadAssociationSetFunctionMapping(nav.Clone(), false); 
                            break; 
                        case StorageMslConstructs.InsertFunctionElement:
                            insertFunctionMapping = functionLoader.LoadAssociationSetFunctionMapping(nav.Clone(), true); 
                            break;
                    }
                } while (nav.MoveToNext(XPathNodeType.Element));
            } 

            //We might be returned null because of schema errors 
            if (null == deleteFunctionMapping || null == insertFunctionMapping) 
            {
                return; 
            }

            // register function mapping information
            associationSetMapping.FunctionMapping = new StorageAssociationSetFunctionMapping( 
                (AssociationSet)associationSetMapping.Set, deleteFunctionMapping, insertFunctionMapping);
        } 
 
        /// 
        /// The method loads the child nodes for the TableMappingFragment under the EntityType node 
        /// into the internal datastructures.
        /// 
        /// 
        ///  
        /// 
        ///  
        ///  
        private StorageMappingFragment LoadMappingFragment(XPathNavigator nav, StorageEntityTypeMapping typeMapping, string tableName
            , EntityContainer storageEntityContainerType) 
        {
            IXmlLineInfo navLineInfo = (IXmlLineInfo)nav;

            //First make sure that there was no QueryView specified for this Set 
            if (typeMapping.SetMapping.QueryView != null)
            { 
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_QueryView_PropertyMaps_1, typeMapping.SetMapping.Set.Name, 
                    StorageMappingErrorCode.PropertyMapsWithQueryView, m_sourceLocation, navLineInfo, m_parsingErrors);
                return null; 
            }

            //Get the table type that represents this table
            EntitySet tableMember; 
            storageEntityContainerType.TryGetEntitySetByName(tableName, false /*ignoreCase*/, out tableMember);
            if (tableMember == null) 
            { 
                //There is no point in continuing loading if the Table on S side can not be found
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Table_1, tableName, 
                    StorageMappingErrorCode.InvalidTable, m_sourceLocation, navLineInfo, m_parsingErrors);
                return null;
            }
            EntityType tableType = tableMember.ElementType; 
            //Create a table mapping fragment to hold the mapping information for a TableMappingFragment node
            StorageMappingFragment fragment = new StorageMappingFragment(tableMember, typeMapping); 
            //Set the Start Line Information on Fragment 
            fragment.StartLineNumber = navLineInfo.LineNumber;
            fragment.StartLinePosition = navLineInfo.LinePosition; 

            //Go through the property mappings for this TableMappingFragment and load them in memory.
            if (nav.MoveToChild(XPathNodeType.Element))
            { 
                do
                { 
                    //need to get the type that this member exists in 
                    EdmType containerType = null;
                    string propertyName = StorageMappingItemLoader.GetAttributeValue(nav.Clone(), StorageMslConstructs.ComplexPropertyNameAttribute); 
                    //PropertyName could be null for Condition Maps
                    if (propertyName != null)
                    {
                        containerType = typeMapping.GetContainerType(propertyName); 
                    }
                    switch (nav.LocalName) 
                    { 
                        case StorageMslConstructs.ScalarPropertyElement:
                            StorageScalarPropertyMapping scalarMap = LoadScalarPropertyMapping(nav.Clone(), 
                                containerType, tableType);
                            if (scalarMap != null)
                            {
                                //scalarMap can be null in invalid cases 
                                fragment.AddProperty(scalarMap);
                            } 
                            break; 
                        case StorageMslConstructs.ComplexPropertyElement:
                            StorageComplexPropertyMapping complexMap = 
                                LoadComplexPropertyMapping(nav.Clone(), containerType, tableType);
                            //Complex Map can be null in case of invalid MSL files.
                            if (complexMap != null)
                            { 
                                fragment.AddProperty(complexMap);
                            } 
                            break; 
                        case StorageMslConstructs.ConditionElement:
                            StorageConditionPropertyMapping conditionMap = 
                                LoadConditionPropertyMapping(nav.Clone(), containerType, tableType);
                            //conditionMap can be null in cases of invalid Map
                            if (conditionMap != null)
                            { 
                                if (!fragment.AddConditionProperty(conditionMap))
                                { 
                                    EdmProperty conditionMember = (conditionMap.EdmProperty != null) ? conditionMap.EdmProperty : conditionMap.ColumnProperty; 

                                    AddToSchemaErrorsWithMemberInfo( 
                                                        Strings.Mapping_InvalidContent_Duplicate_Condition_Member_1,
                                                        conditionMember.Name,
                                                        StorageMappingErrorCode.ConditionError,
                                                        m_sourceLocation, 
                                                        navLineInfo,
                                                        m_parsingErrors); 
                                    return null; 
                                }
                            } 
                            break;
                        default:
                            AddToSchemaErrors(Strings.Mapping_InvalidContent_General_0,
                                StorageMappingErrorCode.InvalidContent, m_sourceLocation, navLineInfo, m_parsingErrors); 
                            break;
                    } 
                } while (nav.MoveToNext(XPathNodeType.Element)); 
            }
            //Set the end Line Information on Fragment 
            fragment.EndLineNumber = navLineInfo.LineNumber;
            fragment.EndLinePosition = navLineInfo.LinePosition;
            nav.MoveToChild(XPathNodeType.Element);
            return fragment; 
        }
 
        ///  
        /// The method loads the child nodes for the TableMappingFragment under the AssociationType node
        /// into the internal datastructures. 
        /// 
        /// 
        /// 
        ///  
        /// 
        ///  
        ///  
        private StorageMappingFragment LoadAssociationMappingFragment(XPathNavigator nav, StorageAssociationSetMapping setMapping, StorageAssociationTypeMapping typeMapping, string tableName, EntityContainer storageEntityContainerType)
        { 
            IXmlLineInfo navLineInfo = (IXmlLineInfo)nav;
            StorageMappingFragment fragment = null;
            EntityType tableType = null;
 
            //If there is a query view, Dont create a mapping fragment since there should n't be one
            if (setMapping.QueryView == null) 
            { 
                //Get the table type that represents this table
                EntitySet tableMember; 
                storageEntityContainerType.TryGetEntitySetByName(tableName, false /*ignoreCase*/, out tableMember);
                if (tableMember == null)
                {
                    //There is no point in continuing loading if the Table is null 
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Table_1, tableName,
                        StorageMappingErrorCode.InvalidTable, m_sourceLocation, navLineInfo, m_parsingErrors); 
                    return null; 
                }
                tableType = tableMember.ElementType; 
                //Create a Mapping fragment and load all the End node under it
                fragment = new StorageMappingFragment(tableMember, typeMapping);
                //Set the Start Line Information on Fragment, For AssociationSet there are
                //no fragments, so the start Line Info is same as that of Set 
                fragment.StartLineNumber = setMapping.StartLineNumber;
                fragment.StartLinePosition = setMapping.StartLinePosition; 
            } 

            do 
            {
                //need to get the type that this member exists in
                switch (nav.LocalName)
                { 
                    case StorageMslConstructs.EndPropertyMappingElement:
                        //Make sure that there was no QueryView specified for this Set 
                        if (setMapping.QueryView != null) 
                        {
                            AddToSchemaErrorsWithMemberInfo(Strings.Mapping_QueryView_PropertyMaps_1, setMapping.Set.Name, 
                                StorageMappingErrorCode.PropertyMapsWithQueryView, m_sourceLocation, navLineInfo, m_parsingErrors);
                            return null;
                        }
                        string endName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.EndPropertyMappingNameAttribute); 
                        EdmMember endMember = null;
                        typeMapping.AssociationType.Members.TryGetValue(endName, false, out endMember); 
                        AssociationEndMember end = endMember as AssociationEndMember; 
                        if (end == null)
                        { 
                            //Don't try to load the end property map if the end property itself is null
                            AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_End_1, endName,
                                StorageMappingErrorCode.InvalidEdmMember, m_sourceLocation, navLineInfo, m_parsingErrors);
                            continue; 
                        }
                        fragment.AddProperty((LoadEndPropertyMapping(nav.Clone(), end, tableType))); 
                        break; 
                    case StorageMslConstructs.ConditionElement:
                        //Make sure that there was no QueryView specified for this Set 
                        if (setMapping.QueryView != null)
                        {
                            AddToSchemaErrorsWithMemberInfo(Strings.Mapping_QueryView_PropertyMaps_1, setMapping.Set.Name,
                                StorageMappingErrorCode.PropertyMapsWithQueryView, m_sourceLocation, navLineInfo, m_parsingErrors); 
                            return null;
                        } 
                        //Need to add validation for conditions in Association mapping fragment. 
                        StorageConditionPropertyMapping conditionMap =
                            LoadConditionPropertyMapping(nav.Clone(), null /*containerType*/, tableType); 
                        //conditionMap can be null in cases of invalid Map
                        if (conditionMap != null)
                        {
                            if (!fragment.AddConditionProperty(conditionMap)) 
                            {
                                EdmProperty conditionMember = (conditionMap.EdmProperty != null) ? conditionMap.EdmProperty : conditionMap.ColumnProperty; 
 
                                AddToSchemaErrorsWithMemberInfo(
                                                Strings.Mapping_InvalidContent_Duplicate_Condition_Member_1, 
                                                conditionMember.Name,
                                                StorageMappingErrorCode.ConditionError,
                                                m_sourceLocation,
                                                navLineInfo, 
                                                m_parsingErrors);
                                return null; 
                            } 
                        }
                        break; 
                    case StorageMslConstructs.ModificationFunctionMappingElement:
                        LoadAssociationTypeFunctionMapping(nav.Clone(), setMapping, typeMapping);
                        break;
                    default: 
                        AddToSchemaErrors(Strings.Mapping_InvalidContent_General_0,
                            StorageMappingErrorCode.InvalidContent, m_sourceLocation, navLineInfo, m_parsingErrors); 
                        break; 
                }
            } while (nav.MoveToNext(XPathNodeType.Element)); 

            if (setMapping.QueryView == null)
            {
                Debug.Assert(fragment != null, "There should be Fragment when there is no query view"); 
                //Set the end Line Information on Fragment
                fragment.EndLineNumber = navLineInfo.LineNumber; 
                fragment.EndLinePosition = navLineInfo.LinePosition; 
            }
            return fragment; 
        }

        /// 
        /// The method loads the ScalarProperty mapping 
        /// into the internal datastructures.
        ///  
        ///  
        /// 
        ///  
        /// 
        private StorageScalarPropertyMapping LoadScalarPropertyMapping(XPathNavigator nav, EdmType containerType, EntityType tableType)
        {
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav; 

            //Get the property name from MSL. 
            string propertyName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ScalarPropertyNameAttribute); 
            EdmProperty member = null;
            if (!String.IsNullOrEmpty(propertyName)) 
            {
                //If the container type is a collection type, there wouldn't be a member to represent this scalar property
                if (containerType == null || !(Helper.IsCollectionType(containerType)))
                { 
                    //If container type is null that means we have not found the member in any of the IsOfTypes.
                    if (containerType != null) 
                    { 
                        if (Helper.IsRefType(containerType))
                        { 
                            RefType refType = (RefType)containerType;
                            ((EntityType)refType.ElementType).Properties.TryGetValue(propertyName, false /*ignoreCase*/, out member);
                        }
                        else 
                        {
                            EdmMember tempMember; 
                            (containerType as StructuralType).Members.TryGetValue(propertyName, false, out tempMember); 
                            member = tempMember as EdmProperty;
                        } 
                    }
                    if (member == null)
                    {
                        AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Cdm_Member_1, propertyName, 
                            StorageMappingErrorCode.InvalidEdmMember, m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                    } 
                } 
            }
            //Get the property from Storeside 
            string columnName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ScalarPropertyColumnNameAttribute);
            Debug.Assert(columnName != null, "XSD validation should have caught this");
            EdmProperty columnMember;
            tableType.Properties.TryGetValue(columnName, false, out columnMember); 
            if (columnMember == null)
            { 
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Column_1, columnName, 
                    StorageMappingErrorCode.InvalidStorageMember, m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
            } 
            //Don't create scalar property map if the property or column metadata is null
            if ((member == null) || (columnMember == null))
            {
                return null; 
            }
 
            if (!Helper.IsPrimitiveType(member.TypeUsage.EdmType)) 
            {
                EdmSchemaError error = new EdmSchemaError( 
                    System.Data.Entity.Strings.Mapping_Invalid_CSide_ScalarProperty_1(
                        member.Name),
                    (int)StorageMappingErrorCode.InvalidTypeInScalarProperty,
                    EdmSchemaErrorSeverity.Error, 
                    m_sourceLocation,
                    xmlLineInfoNav.LineNumber, 
                    xmlLineInfoNav.LinePosition); 
                m_parsingErrors.Add(error);
                return null; 
            }

            ValidateAndUpdateScalarMemberMapping(member, columnMember, xmlLineInfoNav);
            StorageScalarPropertyMapping scalarPropertyMapping = new StorageScalarPropertyMapping(member, columnMember); 
            return scalarPropertyMapping;
        } 
 
        /// 
        /// The method loads the ComplexProperty mapping 
        /// into the internal datastructures.
        /// 
        /// 
        ///  
        /// 
        ///  
        private StorageComplexPropertyMapping LoadComplexPropertyMapping(XPathNavigator nav, EdmType containerType, EntityType tableType) 
        {
            IXmlLineInfo navLineInfo = (IXmlLineInfo)nav; 

            CollectionType collectionType = containerType as CollectionType;
            //Get the property name from MSL
            string propertyName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ComplexPropertyNameAttribute); 
            //Get the member metadata from the contianer type passed in.
            //But if the continer type is collection type, there would n't be any member to represent the member. 
            EdmProperty member = null; 
            EdmType memberType = null;
            //If member specified the type name, it takes precedence 
            string memberTypeName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ComplexTypeMappingTypeNameAttribute);
            StructuralType containerStructuralType = containerType as StructuralType;

            if (String.IsNullOrEmpty(memberTypeName)) 
            {
                if (collectionType == null) 
                { 
                    EdmMember tempMember;
                    containerStructuralType.Members.TryGetValue(propertyName, false /*ignoreCase*/, out tempMember); 
                    member = tempMember as EdmProperty;
                    if (member == null)
                    {
                        AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Cdm_Member_1, propertyName, 
                            StorageMappingErrorCode.InvalidEdmMember, m_sourceLocation, navLineInfo, m_parsingErrors);
                    } 
                    memberType = member.TypeUsage.EdmType; 
                }
                else 
                {
                    memberType = collectionType.TypeUsage.EdmType;
                }
            } 
            else
            { 
                //If container type is null that means we have not found the member in any of the IsOfTypes. 
                if (containerType != null)
                { 
                    EdmMember tempMember;
                    containerStructuralType.Members.TryGetValue(propertyName, false /*ignoreCase*/, out tempMember);
                    member = tempMember as EdmProperty;
                } 
                if (member == null)
                { 
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Cdm_Member_1, propertyName, 
                        StorageMappingErrorCode.InvalidEdmMember, m_sourceLocation, navLineInfo, m_parsingErrors);
                } 
                this.EdmItemCollection.TryGetItem(memberTypeName, out memberType);
                memberType = memberType as ComplexType;
                // If member type is null, that means the type wasn't found in the workspace
                if (memberType == null) 
                {
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Complex_Type_1, memberTypeName, 
                        StorageMappingErrorCode.InvalidComplexType, m_sourceLocation, navLineInfo, m_parsingErrors); 
                }
            } 

            StorageComplexPropertyMapping complexPropertyMapping = new StorageComplexPropertyMapping(member);

            XPathNavigator cloneNav = nav.Clone(); 
            bool hasComplexTypeMappingElements = false;
            if (cloneNav.MoveToChild(XPathNodeType.Element)) 
            { 
                if (cloneNav.LocalName == StorageMslConstructs.ComplexTypeMappingElement)
                { 
                    hasComplexTypeMappingElements = true;
                }
            }
 
            //There is no point in continuing if the complex member or complex member type is null
            if ((member == null) || (memberType == null)) 
            { 
                return null;
            } 

            if (hasComplexTypeMappingElements)
            {
                nav.MoveToChild(XPathNodeType.Element); 
                do
                { 
                    complexPropertyMapping.AddTypeMapping(LoadComplexTypeMapping(nav.Clone(), null, tableType)); 
                } while (nav.MoveToNext(XPathNodeType.Element));
            } 
            else
            {
                complexPropertyMapping.AddTypeMapping(LoadComplexTypeMapping(nav.Clone(), memberType, tableType));
            } 
            return complexPropertyMapping;
        } 
 

 
        /// 
        /// 
        /// 
        ///  
        /// 
        private StorageComplexTypeMapping LoadComplexTypeMapping(XPathNavigator nav, EdmType type, EntityType tableType) 
        { 
            //Get the IsPartial attribute from MSL
            bool isPartial = false; 
            string partialAttribute = StorageMappingItemLoader.GetAttributeValue(nav.Clone(), StorageMslConstructs.ComplexPropertyIsPartialAttribute);
            if (!String.IsNullOrEmpty(partialAttribute))
            {
                //XSD validation should have guarenteed that the attribute value can only be true or false 
                Debug.Assert(partialAttribute == "true" || partialAttribute == "false");
                isPartial = Convert.ToBoolean(partialAttribute, System.Globalization.CultureInfo.InvariantCulture); 
            } 
            //Create an ComplexTypeMapping to hold the information for Type mapping.
            StorageComplexTypeMapping typeMapping = new StorageComplexTypeMapping(isPartial); 
            if (type != null)
            {
                typeMapping.AddType(type as ComplexType);
            } 
            else
            { 
                Debug.Assert(nav.LocalName == StorageMslConstructs.ComplexTypeMappingElement); 
                string typeName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ComplexTypeMappingTypeNameAttribute);
                int index = typeName.IndexOf(StorageMslConstructs.TypeNameSperator); 
                string currentTypeName = null;
                do
                {
                    if (index != -1) 
                    {
                        currentTypeName = typeName.Substring(0, index); 
                        typeName = typeName.Substring(index + 1, (typeName.Length - (index + 1))); 
                    }
                    else 
                    {
                        currentTypeName = typeName;
                        typeName = string.Empty;
                    } 

                    int isTypeOfIndex = currentTypeName.IndexOf(StorageMslConstructs.IsTypeOf, StringComparison.Ordinal); 
                    if (isTypeOfIndex == 0) 
                    {
                        currentTypeName = currentTypeName.Substring(StorageMslConstructs.IsTypeOf.Length, (currentTypeName.Length - (StorageMslConstructs.IsTypeOf.Length + 1))); 
                        currentTypeName = GetAliasResolvedValue(currentTypeName);
                    }
                    else
                    { 
                        currentTypeName = GetAliasResolvedValue(currentTypeName);
                    } 
                    ComplexType complexType; 
                    this.EdmItemCollection.TryGetItem(currentTypeName, out complexType);
                    if (complexType == null) 
                    {
                        AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Complex_Type_1, currentTypeName,
                            StorageMappingErrorCode.InvalidComplexType, m_sourceLocation, (IXmlLineInfo)nav, m_parsingErrors);
                        index = typeName.IndexOf(StorageMslConstructs.TypeNameSperator); 
                        continue;
                    } 
                    if (isTypeOfIndex == 0) 
                    {
                        typeMapping.AddIsOfType(complexType); 
                    }
                    else
                    {
                        typeMapping.AddType(complexType); 
                    }
                    index = typeName.IndexOf(StorageMslConstructs.TypeNameSperator); 
                } while (typeName.Length != 0); 
            }
 
            //Now load the children of ComplexTypeMapping
            if (nav.MoveToChild(XPathNodeType.Element))
            {
                do 
                {
                    EdmType containerType = typeMapping.GetOwnerType(StorageMappingItemLoader.GetAttributeValue(nav.Clone(), StorageMslConstructs.ComplexPropertyNameAttribute)); 
                    switch (nav.LocalName) 
                    {
                        case StorageMslConstructs.ScalarPropertyElement: 
                            StorageScalarPropertyMapping scalarMap =
                                LoadScalarPropertyMapping(nav.Clone(), containerType, tableType);
                            //ScalarMap can be null in case of invalid MSL files
                            if (scalarMap != null) 
                            {
                                typeMapping.AddProperty(scalarMap); 
                            } 
                            break;
                        case StorageMslConstructs.ComplexPropertyElement: 
                            StorageComplexPropertyMapping complexMap =
                                LoadComplexPropertyMapping(nav.Clone(), containerType, tableType);
                            //complexMap can be null in case of invalid maps
                            if (complexMap != null) 
                            {
                                typeMapping.AddProperty(complexMap); 
                            } 
                            break;
                        case StorageMslConstructs.ConditionElement: 
                            StorageConditionPropertyMapping conditionMap =
                                LoadConditionPropertyMapping(nav.Clone(), containerType, tableType);
                            if (conditionMap != null)
                            { 
                                typeMapping.AddConditionProperty(conditionMap);
                            } 
                            break; 
                        default:
                            throw System.Data.Entity.Error.NotSupported(); 
                    }
                } while (nav.MoveToNext(XPathNodeType.Element));
            }
            return typeMapping; 

        } 
 
        /// 
        /// The method loads the EndProperty mapping 
        /// into the internal datastructures.
        /// 
        /// 
        ///  
        /// 
        ///  
        private StorageEndPropertyMapping LoadEndPropertyMapping(XPathNavigator nav, AssociationEndMember end, EntityType tableType) 
        {
            //FutureEnhancement : Change End Property Mapping to not derive from 
            //                    StoragePropertyMapping
            StorageEndPropertyMapping endMapping = new StorageEndPropertyMapping(null);
            endMapping.EndMember = end;
 
            nav.MoveToChild(XPathNodeType.Element);
            do 
            { 
                switch (nav.LocalName)
                { 
                    case StorageMslConstructs.ScalarPropertyElement:
                        RefType endRef = end.TypeUsage.EdmType as RefType;
                        Debug.Assert(endRef != null);
                        EntityTypeBase containerType = endRef.ElementType; 
                        StorageScalarPropertyMapping scalarMap =
                            LoadScalarPropertyMapping(nav.Clone(), containerType, tableType); 
                        //Scalar Property Mapping can be null 
                        //in case of invalid MSL files.
                        if (scalarMap != null) 
                        {
                            endMapping.AddProperty(scalarMap);
                        }
                        break; 
                    default:
                        Debug.Fail("XSD validation should have ensured that End EdmProperty Maps only have Schalar properties"); 
                        break; 
                }
            } while (nav.MoveToNext(XPathNodeType.Element)); 
            return endMapping;
        }

        ///  
        /// The method loads the ConditionProperty mapping
        /// into the internal datastructures. 
        ///  
        /// 
        ///  
        /// 
        /// 
        private StorageConditionPropertyMapping LoadConditionPropertyMapping(XPathNavigator nav, EdmType containerType, EntityType tableType)
        { 
            //Get the CDM side property name.
            string propertyName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ConditionNameAttribute); 
            //Get the Store side property name from Storeside 
            string columnName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ConditionColumnNameAttribute);
 
            IXmlLineInfo navLineInfo = (IXmlLineInfo)nav;

            //Either the property name or column name can be specified but both can not be.
            if ((propertyName != null) && (columnName != null)) 
            {
                AddToSchemaErrors(Strings.Mapping_InvalidContent_ConditionMapping_Both_Members_0, 
                    StorageMappingErrorCode.ConditionError, m_sourceLocation, navLineInfo, m_parsingErrors); 
                return null;
            } 
            if ((propertyName == null) && (columnName == null))
            {
                AddToSchemaErrors(Strings.Mapping_InvalidContent_ConditionMapping_Either_Members_0,
                    StorageMappingErrorCode.ConditionError, m_sourceLocation, navLineInfo, m_parsingErrors); 
                return null;
            } 
 
            EdmProperty member = null;
            //Get the CDM EdmMember reprsented by the name specified. 
            if (propertyName != null)
            {
                EdmMember tempMember;
                //If container type is null that means we have not found the member in any of the IsOfTypes. 
                if (containerType != null)
                { 
                    ((StructuralType)containerType).Members.TryGetValue(propertyName, false /*ignoreCase*/, out tempMember); 
                    member = tempMember as EdmProperty;
                } 
            }

            //Get the column EdmMember represented by the column name specified
            EdmProperty columnMember = null; 
            if (columnName != null)
            { 
                tableType.Properties.TryGetValue(columnName, false, out columnMember); 
            }
 
            //Get the member for which the condition is being specified
            EdmProperty conditionMember = (columnMember != null) ? columnMember : member;
            if (conditionMember == null)
            { 
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_ConditionMapping_InvalidMember_1, ((columnName != null) ? columnName : propertyName),
                    StorageMappingErrorCode.ConditionError, m_sourceLocation, navLineInfo, m_parsingErrors); 
                return null; 
            }
 
            Nullable isNullValue = null;
            object value = null;
            //Get the attribute value for IsNull attribute
            string isNullAttribute = StorageMappingItemLoader.GetAttributeValue(nav.Clone(), StorageMslConstructs.ConditionIsNullAttribute); 

            //Get strongly Typed value if the condition was specified for a specific condition 
            EdmType edmType = conditionMember.TypeUsage.EdmType; 
            if (Helper.IsPrimitiveType(edmType))
            { 
                //Decide if the member is of a type that we would allow a condition on.
                //First convert the type to C space, if this is a condition in s space( before checking this).
                TypeUsage cspaceTypeUsage;
                if (conditionMember.DeclaringType.GetDataSpace() == DataSpace.SSpace) 
                {
                    cspaceTypeUsage = StoreItemCollection.StoreProviderManifest.GetEdmType(conditionMember.TypeUsage); 
                    if (cspaceTypeUsage == null) 
                    {
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_ProviderReturnsNullType(conditionMember.Name), 
                            StorageMappingErrorCode.MappingStoreProviderReturnsNullEdmType,
                            m_sourceLocation, navLineInfo, m_parsingErrors);
                        return null;
                    } 
                }
                else 
                { 
                    cspaceTypeUsage = conditionMember.TypeUsage;
                } 
                PrimitiveType memberType = ((PrimitiveType)cspaceTypeUsage.EdmType);
                Type clrMemberType = memberType.ClrEquivalentType;
                PrimitiveTypeKind primitiveTypeKind = memberType.PrimitiveTypeKind;
                //Only a subset of primitive types can be used in Conditions that are specified over values. 
                //IsNull conditions can be specified on any primitive types
                if ((isNullAttribute == null) && !IsTypeSupportedForCondition(primitiveTypeKind)) 
                { 
                    AddToSchemaErrorWithMemberAndStructure(Strings.Mapping_InvalidContent_ConditionMapping_InvalidPrimitiveTypeKind_2,
                        conditionMember.Name, memberType.FullName, StorageMappingErrorCode.ConditionError, 
                        m_sourceLocation, navLineInfo, m_parsingErrors);
                    return null;
                }
                Debug.Assert(clrMemberType != null, "Scalar Types should have associated clr type"); 
                //If the value is not compatible with the type, just add an error and return
                if(!StorageMappingItemLoader.TryGetTypedAttributeValue(nav.Clone(), StorageMslConstructs.ConditionValueAttribute, clrMemberType, m_sourceLocation, m_parsingErrors, out value)) 
                { 
                    return null;
                } 
            }
            else if (Helper.IsEnumType(edmType))
            {
                // Enumeration type - get the actual value 
                value = StorageMappingItemLoader.GetEnumAttributeValue(nav.Clone(), StorageMslConstructs.ConditionValueAttribute, (EnumType)edmType, m_sourceLocation, m_parsingErrors);
            } 
            else 
            {
                // Since NullableComplexTypes are not being supported, 
                // we don't allow conditions on complex types
                AddToSchemaErrors(Strings.Mapping_InvalidContent_ConditionMapping_NonScalar_0,
                    StorageMappingErrorCode.ConditionError, m_sourceLocation, navLineInfo, m_parsingErrors);
                return null; 

            } 
            //Either Value or NotNull need to be specifid on the condition mapping but not both 
            if ((isNullAttribute != null) && (value != null))
            { 
                AddToSchemaErrors(Strings.Mapping_InvalidContent_ConditionMapping_Both_Values_0,
                    StorageMappingErrorCode.ConditionError, m_sourceLocation, navLineInfo, m_parsingErrors);
                return null;
            } 
            if ((isNullAttribute == null) && (value == null))
            { 
                AddToSchemaErrors(Strings.Mapping_InvalidContent_ConditionMapping_Either_Values_0, 
                    StorageMappingErrorCode.ConditionError, m_sourceLocation, navLineInfo, m_parsingErrors);
                return null; 
            }

            if (isNullAttribute != null)
            { 
                //XSD validation should have guarenteed that the attribute value can only be true or false
                Debug.Assert(isNullAttribute == "true" || isNullAttribute == "false"); 
                isNullValue = Convert.ToBoolean(isNullAttribute, System.Globalization.CultureInfo.InvariantCulture); 
            }
 
            if (columnMember != null && (columnMember.IsStoreGeneratedComputed || columnMember.IsStoreGeneratedIdentity))
            {
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_ConditionMapping_Computed, columnMember.Name,
                    StorageMappingErrorCode.ConditionError, m_sourceLocation, navLineInfo, m_parsingErrors); 
                return null;
            } 
 
            StorageConditionPropertyMapping conditionPropertyMapping = new StorageConditionPropertyMapping(member, columnMember, value, isNullValue);
            return conditionPropertyMapping; 
        }

        internal static bool IsTypeSupportedForCondition(PrimitiveTypeKind primitiveTypeKind)
        { 
            switch (primitiveTypeKind)
            { 
                case PrimitiveTypeKind.Boolean: 
                case PrimitiveTypeKind.Byte:
                case PrimitiveTypeKind.Int16: 
                case PrimitiveTypeKind.Int32:
                case PrimitiveTypeKind.Int64:
                case PrimitiveTypeKind.String:
                case PrimitiveTypeKind.SByte: 
                    return true;
                case PrimitiveTypeKind.Binary: 
                case PrimitiveTypeKind.DateTime: 
                case PrimitiveTypeKind.Time:
                case PrimitiveTypeKind.DateTimeOffset: 
                case PrimitiveTypeKind.Double:
                case PrimitiveTypeKind.Guid:
                case PrimitiveTypeKind.Single:
                case PrimitiveTypeKind.Decimal: 
                    return false;
                default: 
                    Debug.Fail("New primitive type kind added?"); 
                    return false;
            } 
        }

        private static XmlSchemaSet GetOrCreateSchemaSet()
        { 
            if (s_mappingXmlSchema == null)
            { 
                //Get the xsd stream for CS MSL Xsd. 
                Stream xsdStream = typeof(StorageMappingItemLoader).Assembly.GetManifestResourceStream(StorageMslConstructs.ResourceXsdName);
                using (XmlReader xsdReader = XmlReader.Create(xsdStream)) 
                {
                    XmlSchema xmlSchema = XmlSchema.Read(xsdReader, null);
                    XmlSchemaSet set = new XmlSchemaSet();
                    set.Add(xmlSchema); 
                    System.Threading.Interlocked.CompareExchange(ref s_mappingXmlSchema, set, null);
                } 
            } 

            return s_mappingXmlSchema; 
        }

        /// 
        /// Throws a new MappingException giving out the line number and 
        /// File Name where the error in Mapping specification is present.
        ///  
        ///  
        /// 
        ///  
        /// 
        /// Error Collection where the parsing errors are collected
        internal static void AddToSchemaErrors(string message, StorageMappingErrorCode errorCode, string location, IXmlLineInfo lineInfo, IList parsingErrors)
        { 
            EdmSchemaError error = new EdmSchemaError(message, (int)errorCode, EdmSchemaErrorSeverity.Error, location, lineInfo.LineNumber, lineInfo.LinePosition);
            parsingErrors.Add(error); 
        } 

        internal static void AddToSchemaErrorsWithMemberInfo(Func messageFormat, string errorMember, StorageMappingErrorCode errorCode, string location, IXmlLineInfo lineInfo, IList parsingErrors) 
        {
            EdmSchemaError error = new EdmSchemaError(messageFormat(errorMember), (int)errorCode, EdmSchemaErrorSeverity.Error, location, lineInfo.LineNumber, lineInfo.LinePosition);
            parsingErrors.Add(error);
        } 

        internal static void AddToSchemaErrorWithMemberAndStructure(Func messageFormat, string errorMember, 
            string errorStructure, StorageMappingErrorCode errorCode, string location, IXmlLineInfo lineInfo, IList parsingErrors) 
        {
            EdmSchemaError error = new EdmSchemaError( 
                messageFormat(errorMember, errorStructure)
                , (int)errorCode, EdmSchemaErrorSeverity.Error, location, lineInfo.LineNumber, lineInfo.LinePosition);
            parsingErrors.Add(error);
        } 

        internal static void AddToSchemaErrorWithMessage(string errorMessage, StorageMappingErrorCode errorCode, string location, IXmlLineInfo lineInfo, IList parsingErrors) 
        { 
            EdmSchemaError error = new EdmSchemaError(errorMessage, (int)errorCode, EdmSchemaErrorSeverity.Error, location, lineInfo.LineNumber, lineInfo.LinePosition);
            parsingErrors.Add(error); 
        }

        /// 
        /// Resolve the attribute value based on the aliases provided as part of MSL file. 
        /// 
        ///  
        ///  
        /// 
        private string GetAliasResolvedAttributeValue(XPathNavigator nav, string attributeName) 
        {
            return GetAliasResolvedValue(StorageMappingItemLoader.GetAttributeValue(nav, attributeName));
        }
 
        /// 
        /// The method simply calls the helper method on Helper class with the 
        /// namespaceURI that is default for CSMapping. 
        /// 
        ///  
        /// 
        /// 
        private static string GetAttributeValue(XPathNavigator nav, string attributeName)
        { 
            return Helper.GetAttributeValue(nav, attributeName);
        } 
 
        /// 
        /// The method simply calls the helper method on Helper class with the 
        /// namespaceURI that is default for CSMapping.
        /// 
        /// 
        ///  
        /// 
        ///  
        /// Error Collection where the parsing errors are collected 
        /// 
        private static bool TryGetTypedAttributeValue(XPathNavigator nav, string attributeName, Type clrType, string sourceLocation, IList parsingErrors, out object value) 
        {
            value = null;
            try
            { 
                value = Helper.GetTypedAttributeValue(nav, attributeName, clrType);
            } 
            catch (FormatException) 
            {
                StorageMappingItemLoader.AddToSchemaErrors(Strings.Mapping_ConditionValueTypeMismatch_0, 
                    StorageMappingErrorCode.ConditionError, sourceLocation, (IXmlLineInfo)nav, parsingErrors);
                return false;
            }
            return true; 
        }
 
        ///  
        /// Returns the enum EdmMember corresponding to attribute name in enumType.
        ///  
        /// 
        /// 
        /// 
        ///  
        /// Error Collection where the parsing errors are collected
        ///  
        private static EnumMember GetEnumAttributeValue(XPathNavigator nav, string attributeName, EnumType enumType, string sourceLocation, IList parsingErrors) 
        {
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav; 

            string value = GetAttributeValue(nav, attributeName);
            if (String.IsNullOrEmpty(value))
            { 
                StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Enum_EmptyValue_1, enumType.FullName,
                    StorageMappingErrorCode.InvalidEnumValue, sourceLocation, xmlLineInfoNav, parsingErrors); 
            } 

            EnumMember result; 
            bool found = enumType.EnumMembers.TryGetValue(value, false, out result);
            if (!found)
            {
                StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Enum_InvalidValue_1, value, 
                    StorageMappingErrorCode.InvalidEnumValue, sourceLocation, xmlLineInfoNav, parsingErrors);
            } 
            return result; 
        }
 
        /// 
        /// Resolve the string value based on the aliases provided as part of MSL file.
        /// 
        ///  
        /// 
        private string GetAliasResolvedValue(string aliasedString) 
        { 
            if ((aliasedString == null) || (aliasedString.Length == 0))
                return aliasedString; 
            //For now all attributes have no namespace
            int aliasIndex = aliasedString.LastIndexOf('.');
            //If no '.' in the string, than obviously the string is not aliased
            if (aliasIndex == -1) 
                return aliasedString;
            string aliasKey = aliasedString.Substring(0, aliasIndex); 
            string aliasValue; 
            m_alias.TryGetValue(aliasKey, out aliasValue);
            if (aliasValue != null) 
            {
                aliasedString = aliasValue + aliasedString.Substring(aliasIndex);
            }
            return aliasedString; 
        }
 
        ///  
        /// Creates Xml Reader with settings required for
        /// XSD validation. 
        /// 
        /// 
        internal XmlReader GetSchemaValidatingReader(XmlReader innerReader)
        { 
            //Create the reader setting that will be used while
            //loading the MSL. 
            XmlReaderSettings readerSettings = GetXmlReaderSettings(); 
            XmlReader reader = XmlReader.Create(innerReader, readerSettings);
 
            return reader;
        }

 
        private XmlReaderSettings GetXmlReaderSettings()
        { 
            XmlReaderSettings readerSettings = System.Data.EntityModel.SchemaObjectModel.Schema.CreateEdmStandardXmlReaderSettings(); 

            readerSettings.ValidationFlags |= System.Xml.Schema.XmlSchemaValidationFlags.ReportValidationWarnings; 
            readerSettings.ValidationEventHandler += this.XsdValidationCallBack;
            readerSettings.ValidationType = ValidationType.Schema;
            readerSettings.Schemas = GetOrCreateSchemaSet();
            return readerSettings; 
        }
 
 
        /// 
        /// The method is called by the XSD validation event handler when 
        /// ever there are warnings or errors.
        /// We ignore the warnings but the errors will result in exception.
        /// 
        ///  
        /// 
        internal void XsdValidationCallBack(object sender, ValidationEventArgs args) 
        { 
            if (args.Severity != XmlSeverityType.Warning)
            { 
                string sourceLocation = null;
                if (!string.IsNullOrEmpty(args.Exception.SourceUri))
                {
                    sourceLocation = Helper.GetFileNameFromUri(new Uri(args.Exception.SourceUri)); 
                }
                EdmSchemaErrorSeverity severity = EdmSchemaErrorSeverity.Error; 
                if (args.Severity == XmlSeverityType.Warning) 
                    severity = EdmSchemaErrorSeverity.Warning;
                EdmSchemaError error = new EdmSchemaError(System.Data.Entity.Strings.Mapping_InvalidMappingSchema_validation_1(args.Exception.Message) 
                    , (int)StorageMappingErrorCode.XmlSchemaValidationError, severity, sourceLocation, args.Exception.LineNumber, args.Exception.LinePosition);
                m_parsingErrors.Add(error);
            }
        } 

 
        ///  
        /// Validate the scalar property mapping - makes sure that the cspace type is promotable to the store side and updates
        /// the store type usage 
        /// 
        /// 
        /// 
        ///  
        private void ValidateAndUpdateScalarMemberMapping(EdmProperty member, EdmProperty columnMember, IXmlLineInfo lineInfo)
        { 
            Debug.Assert(Helper.IsPrimitiveType(member.TypeUsage.EdmType), "cspaceTypeusage must contain a scalar type"); 
            Debug.Assert(Helper.IsPrimitiveType(columnMember.TypeUsage.EdmType), "sspaceTypeusage must contain a scalar type");
 
            KeyValuePair memberMappingInfo;

            if (!m_scalarMemberMappings.TryGetValue(member, out memberMappingInfo))
            { 
                int errorCount = m_parsingErrors.Count;
 
                // Validates that the CSpace member type is promotable to the SSpace member types and returns a typeUsage which contains 
                // the store equivalent type for the CSpace member type.
                // For e.g. If a CSpace member of type Edm.Int32 maps to SqlServer.Int64, the return type usage will contain SqlServer.int 
                //          which is store equivalent type for Edm.Int32
                TypeUsage storeEquivalentTypeUsage = Helper.ValidateAndConvertTypeUsage(member,
                    columnMember, lineInfo, m_sourceLocation, m_parsingErrors, StoreItemCollection);
 
                // If the cspace type is not compatible with the store type, add a schema error and return
                if (storeEquivalentTypeUsage == null) 
                { 
                    if (errorCount == m_parsingErrors.Count)
                    { 
                        EdmSchemaError error = new EdmSchemaError(
                        System.Data.Entity.Strings.Mapping_Invalid_Member_Mapping_6(
                                                             member.TypeUsage.EdmType + GetFacetsForDisplay(member.TypeUsage),
                                                             member.Name, 
                                                             member.DeclaringType.FullName,
                                                             columnMember.TypeUsage.EdmType + GetFacetsForDisplay(columnMember.TypeUsage), 
                                                             columnMember.Name, 
                                                             columnMember.DeclaringType.FullName),
                        (int)StorageMappingErrorCode.IncompatibleMemberMapping, EdmSchemaErrorSeverity.Error, 
                        m_sourceLocation, lineInfo.LineNumber,
                        lineInfo.LinePosition);
                        m_parsingErrors.Add(error);
                    } 
                }
                else 
                { 
                    m_scalarMemberMappings.Add(member, new KeyValuePair(storeEquivalentTypeUsage, columnMember.TypeUsage));
                } 
            }
            else
            {
                // Get the store member type to which the cspace member was mapped to previously 
                TypeUsage storeMappedTypeUsage = memberMappingInfo.Value;
                TypeUsage modelColumnMember = columnMember.TypeUsage.GetModelTypeUsage(); 
                if (!Object.ReferenceEquals(columnMember.TypeUsage.EdmType, storeMappedTypeUsage.EdmType)) 
                {
                    EdmSchemaError error = new EdmSchemaError( 
                        System.Data.Entity.Strings.Mapping_StoreTypeMismatch_ScalarPropertyMapping_2(
                                                             member.Name,
                                                             storeMappedTypeUsage.EdmType.Name),
                        (int)StorageMappingErrorCode.CSpaceMemberMappedToMultipleSSpaceMemberWithDifferentTypes, 
                        EdmSchemaErrorSeverity.Error,
                        m_sourceLocation, 
                        lineInfo.LineNumber, 
                        lineInfo.LinePosition);
                    m_parsingErrors.Add(error); 
                }
                // Check if the cspace facets are promotable to the new store type facets
                else if (!TypeSemantics.IsSubTypeOf(member.TypeUsage, modelColumnMember))
                { 
                    EdmSchemaError error = new EdmSchemaError(
                        System.Data.Entity.Strings.Mapping_Invalid_Member_Mapping_6( 
                                                             member.TypeUsage.EdmType + GetFacetsForDisplay(member.TypeUsage), 
                                                             member.Name,
                                                             member.DeclaringType.FullName, 
                                                             columnMember.TypeUsage.EdmType + GetFacetsForDisplay(columnMember.TypeUsage),
                                                             columnMember.Name,
                                                             columnMember.DeclaringType.FullName),
                        (int)StorageMappingErrorCode.IncompatibleMemberMapping, EdmSchemaErrorSeverity.Error, 
                        m_sourceLocation, lineInfo.LineNumber,
                        lineInfo.LinePosition); 
                    m_parsingErrors.Add(error); 
                }
            } 
        }

        private string GetFacetsForDisplay(TypeUsage typeUsage)
        { 
            Debug.Assert(typeUsage != null);
 
            ReadOnlyMetadataCollection facets = typeUsage.Facets; 
            if (facets == null || facets.Count == 0)
            { 
                return string.Empty;
            }

            int numFacets = facets.Count; 

            StringBuilder facetDisplay = new StringBuilder("["); 
 
            for (int i = 0; i < numFacets-1; ++i)
            { 
                facetDisplay.AppendFormat("{0}={1},", facets[i].Name, facets[i].Value ?? string.Empty);
            }

            facetDisplay.AppendFormat("{0}={1}]", facets[numFacets - 1].Name, facets[numFacets-1].Value ?? string.Empty); 

            return facetDisplay.ToString(); 
        } 

        #endregion 

        #region Nested types
        /// 
        /// Encapsulates state and functionality for loading a mapping function. 
        /// 
        private class FunctionMappingLoader 
        { 
            // Storage mapping loader
            private readonly StorageMappingItemLoader m_parentLoader; 

            // Mapped function
            private EdmFunction m_function;
 
            // Entity set mapped by this function (may be null)
            private readonly EntitySet m_entitySet; 
 
            // Association set mapped by this function (may be null)
            private readonly AssociationSet m_associationSet; 

            // Model entity container (used to resolve set names)
            private readonly EntityContainer m_modelContainer;
 
            // Item collection (used to resolve function and type names)
            private readonly EdmItemCollection m_edmItemCollection; 
 
            // Item collection (used to resolve function and type names)
            private readonly StoreItemCollection m_storeItemCollection; 

            // Indicates whether the function can be bound to "current"
            // versions of properties (i.e., inserts and updates)
            private bool m_allowCurrentVersion; 

            // Indicates whether the function can be bound to "original" 
            // versions of properties (i.e., deletes and updates) 
            private bool m_allowOriginalVersion;
 
            // Tracks which function parameters have been seen so far.
            private readonly Set m_seenParameters;

            // Tracks members navigated to arrive at the current element 
            private readonly Stack m_members;
 
            // When set, indicates we are interpreting a navigation property on the given set. 
            private AssociationSet m_associationSetNavigation;
 
            // Initialize loader
            internal FunctionMappingLoader(
                StorageMappingItemLoader parentLoader,
                EntitySetBase extent) 
            {
                m_parentLoader = EntityUtil.CheckArgumentNull(parentLoader, "parentLoader"); 
                // initialize member fields 
                m_modelContainer = EntityUtil.CheckArgumentNull(extent, "extent").EntityContainer;
                m_edmItemCollection = parentLoader.EdmItemCollection; 
                m_storeItemCollection = parentLoader.StoreItemCollection;
                m_entitySet = extent as EntitySet;
                if (null == m_entitySet)
                { 
                    // do a cast here since the extent must either be an entity set
                    // or an association set 
                    m_associationSet = (AssociationSet)extent; 
                }
                m_seenParameters = new Set(); 
                m_members = new Stack();
            }

            // Loads a function mapping for an entity type 
            internal StorageFunctionMapping LoadEntityTypeFunctionMapping(XPathNavigator nav, bool allowCurrentVersion, bool allowOriginalVersion, EntityType entityType)
            { 
                FunctionParameter rowsAffectedParameter; 
                m_function = LoadAndValidateFunctionMetadata(nav.Clone(), out rowsAffectedParameter);
                if (m_function == null) 
                {
                    return null;
                }
                m_allowCurrentVersion = allowCurrentVersion; 
                m_allowOriginalVersion = allowOriginalVersion;
 
                // Load all parameter bindings and result bindings 
                IEnumerable parameters = LoadParameterBindings(nav.Clone(), entityType);
                IEnumerable resultBindings = LoadResultBindings(nav.Clone(), entityType); 

                StorageFunctionMapping functionMapping = new StorageFunctionMapping(m_function, parameters, rowsAffectedParameter, resultBindings);

                return functionMapping; 
            }
 
 
            // Loads a function mapping for an association set
            internal StorageFunctionMapping LoadAssociationSetFunctionMapping(XPathNavigator nav, bool isInsert) 
            {
                FunctionParameter rowsAffectedParameter;
                m_function = LoadAndValidateFunctionMetadata(nav.Clone(), out rowsAffectedParameter);
                if (m_function == null) 
                {
                    return null; 
                } 
                if (isInsert)
                { 
                    m_allowCurrentVersion = true;
                    m_allowOriginalVersion = false;
                }
                else 
                {
                    m_allowCurrentVersion = false; 
                    m_allowOriginalVersion = true; 
                }
 
                // Load all parameter bindings
                IEnumerable parameters = LoadParameterBindings(nav.Clone(), m_associationSet.ElementType);

                StorageFunctionMapping functionMapping = new StorageFunctionMapping(m_function, parameters, rowsAffectedParameter, null); 
                return functionMapping;
            } 
 
            // Loads all result bindings.
            private IEnumerable LoadResultBindings(XPathNavigator nav, EntityType entityType) 
            {
                List resultBindings = new List();
                IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
 
                // walk through all children, filtering on result bindings
                if (nav.MoveToChild(XPathNodeType.Element)) 
                { 
                    do
                    { 
                        if (nav.LocalName == StorageMslConstructs.ResultBindingElement)
                        {
                            // retrieve attributes
                            string propertyName = m_parentLoader.GetAliasResolvedAttributeValue(nav.Clone(), 
                                StorageMslConstructs.ResultBindingPropertyNameAttribute);
                            string columnName = m_parentLoader.GetAliasResolvedAttributeValue(nav.Clone(), 
                                StorageMslConstructs.ScalarPropertyColumnNameAttribute); 

                            // resolve metadata 
                            EdmProperty property = null;
                            if (null == propertyName ||
                                !entityType.Properties.TryGetValue(propertyName, false, out property))
                            { 
                                // add a schema error and return if the property does not exist
                                StorageMappingItemLoader.AddToSchemaErrorWithMemberAndStructure( 
                                    Strings.Mapping_Invalid_Function_Mapping_PropertyNotFound_2, 
                                    propertyName, entityType.Name,
                                    StorageMappingErrorCode.InvalidEdmMember, m_parentLoader.m_sourceLocation, 
                                    xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                                return new List();
                            }
 
                            // construct element binding (no type checking is required at mapping load time)
                            StorageFunctionResultBinding resultBinding = new StorageFunctionResultBinding(columnName, property); 
                            resultBindings.Add(resultBinding); 
                        }
                    } while (nav.MoveToNext(XPathNodeType.Element)); 
                }

                // check for duplicate mappings of single properties
                KeyToListMap propertyToColumnNamesMap = new KeyToListMap(EqualityComparer.Default); 
                foreach (StorageFunctionResultBinding resultBinding in resultBindings)
                { 
                    propertyToColumnNamesMap.Add(resultBinding.Property, resultBinding.ColumnName); 
                }
                foreach (EdmProperty property in propertyToColumnNamesMap.Keys) 
                {
                    ReadOnlyCollection columnNames = propertyToColumnNamesMap.ListForKey(property);
                    if (1 < columnNames.Count)
                    { 
                        StorageMappingItemLoader.AddToSchemaErrorWithMemberAndStructure(
                            Strings.Mapping_Invalid_Function_Mapping_AmbiguousResultBinding_2, 
                            property.Name, StringUtil.ToCommaSeparatedString(columnNames), 
                            StorageMappingErrorCode.AmbiguousResultBindingInFunctionMapping,
                            m_parentLoader.m_sourceLocation, xmlLineInfoNav, 
                            m_parentLoader.m_parsingErrors);
                        return new List();
                    }
                } 

                return resultBindings; 
            } 

            // Loads parameter bindings from the given node, validating bindings: 
            // - All parameters are covered
            // - Referenced names exist in type
            // - Parameter and scalar type are compatible
            // - Legal versions are given 
            private IEnumerable LoadParameterBindings(XPathNavigator nav, StructuralType type)
            { 
                // recursively retrieve bindings (current member path is empty) 
                // immediately construct a list of bindings to force execution of the LoadParameterBindings
                // yield method 
                List parameterBindings = new List(
                    LoadParameterBindings(nav.Clone(), type, false /* restrictToKeyMembers */));

                // check that all parameters have been mapped 
                Set unmappedParameters = new Set(m_function.Parameters);
                unmappedParameters.Subtract(m_seenParameters); 
                if (0 != unmappedParameters.Count) 
                {
                    AddToSchemaErrorWithMemberAndStructure(Strings.Mapping_Invalid_Function_Mapping_MissingParameter_2, 
                        m_function.FullName, StringUtil.ToCommaSeparatedString(unmappedParameters),
                        StorageMappingErrorCode.InvalidParameterInFunctionMapping,
                        m_parentLoader.m_sourceLocation, (IXmlLineInfo)nav,
                        m_parentLoader.m_parsingErrors); 
                    return new List();
                } 
 
                return parameterBindings;
            } 

            private IEnumerable LoadParameterBindings(XPathNavigator nav, StructuralType type,
                bool restrictToKeyMembers)
            { 
                // walk through all child bindings
                if (nav.MoveToChild(XPathNodeType.Element)) 
                { 
                    do
                    { 
                        switch (nav.LocalName)
                        {
                            case StorageMslConstructs.ScalarPropertyElement:
                                { 
                                    StorageFunctionParameterBinding binding = LoadScalarPropertyParameterBinding(
                                        nav.Clone(), type, restrictToKeyMembers); 
                                    if (binding != null) 
                                    {
                                        yield return binding; 
                                    }
                                    else
                                    {
                                        yield break; 
                                    }
                                } 
                                break; 
                            case StorageMslConstructs.ComplexPropertyElement:
                                { 
                                    ComplexType complexType;
                                    EdmMember property = LoadComplexTypeProperty(
                                        nav.Clone(), type, out complexType);
                                    if (property != null) 
                                    {
 
                                        // recursively retrieve mappings 
                                        m_members.Push(property);
                                        foreach (StorageFunctionParameterBinding binding in 
                                            LoadParameterBindings(nav.Clone(), complexType, restrictToKeyMembers))
                                        {
                                            yield return binding;
                                        } 
                                        m_members.Pop();
                                    } 
                                } 
                                break;
                            case StorageMslConstructs.AssociationEndElement: 
                                {
                                    AssociationSetEnd toEnd = LoadAssociationEnd(nav.Clone());
                                    if (toEnd != null)
                                    { 

                                        // translate the bindings for the association end 
                                        m_members.Push(toEnd.CorrespondingAssociationEndMember); 
                                        m_associationSetNavigation = toEnd.ParentAssociationSet;
                                        foreach (StorageFunctionParameterBinding binding in 
                                            LoadParameterBindings(nav.Clone(), toEnd.EntitySet.ElementType, true /* restrictToKeyMembers */))
                                        {
                                            yield return binding;
                                        } 
                                        m_associationSetNavigation = null;
                                        m_members.Pop(); 
                                    } 
                                }
                                break; 
                            case StorageMslConstructs.EndPropertyMappingElement:
                                {
                                    AssociationSetEnd end = LoadEndProperty(nav.Clone());
                                    if (end != null) 
                                    {
 
                                        // translate the bindings for the end property 
                                        m_members.Push(end.CorrespondingAssociationEndMember);
                                        foreach (StorageFunctionParameterBinding binding in 
                                            LoadParameterBindings(nav.Clone(), end.EntitySet.ElementType, true /* restrictToKeyMembers */))
                                        {
                                            yield return binding;
                                        } 
                                        m_members.Pop();
                                    } 
                                } 
                                break;
                        } 
                    } while (nav.MoveToNext(XPathNodeType.Element));
                }
            }
 
            private AssociationSetEnd LoadAssociationEnd(XPathNavigator nav)
            { 
 
                IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
 
                // retrieve element attributes
                string associationSetName = m_parentLoader.GetAliasResolvedAttributeValue(
                    nav.Clone(), StorageMslConstructs.AssociationSetAttribute);
                string fromRole = m_parentLoader.GetAliasResolvedAttributeValue( 
                    nav.Clone(), StorageMslConstructs.FromAttribute);
                string toRole = m_parentLoader.GetAliasResolvedAttributeValue( 
                    nav.Clone(), StorageMslConstructs.ToAttribute); 

                // retrieve metadata 
                RelationshipSet relationshipSet = null;
                AssociationSet associationSet;

                // validate the association set exists 
                if (null == associationSetName ||
                    !m_modelContainer.TryGetRelationshipSetByName(associationSetName, false, out relationshipSet) || 
                    BuiltInTypeKind.AssociationSet != relationshipSet.BuiltInTypeKind) 
                {
                    StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo( 
                        Strings.Mapping_Invalid_Function_Mapping_AssociationSetDoesNotExist_1,
                        associationSetName, StorageMappingErrorCode.InvalidAssociationSet,
                        m_parentLoader.m_sourceLocation, xmlLineInfoNav,
                        m_parentLoader.m_parsingErrors); 
                    return null;
                } 
                associationSet = (AssociationSet)relationshipSet; 

                // validate the from end exists 
                AssociationSetEnd fromEnd = null;
                if (null == fromRole ||
                    !associationSet.AssociationSetEnds.TryGetValue(fromRole, false, out fromEnd))
                { 
                    StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo(
                        Strings.Mapping_Invalid_Function_Mapping_AssociationSetRoleDoesNotExist_1, 
                        fromRole, StorageMappingErrorCode.InvalidAssociationSetRoleInFunctionMapping, 
                        m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                    return null; 
                }

                // validate the to end exists
                AssociationSetEnd toEnd = null; 
                if (null == toRole ||
                    !associationSet.AssociationSetEnds.TryGetValue(toRole, false, out toEnd)) 
                { 
                    StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo(
                    Strings.Mapping_Invalid_Function_Mapping_AssociationSetRoleDoesNotExist_1, 
                    toRole, StorageMappingErrorCode.InvalidAssociationSetRoleInFunctionMapping,
                    m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                    return null;
                } 

                // validate ends reference the current entity set 
                if (!fromEnd.EntitySet.Equals(m_entitySet)) 
                {
                    StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo( 
                        Strings.Mapping_Invalid_Function_Mapping_AssociationSetFromRoleIsNotEntitySet_1,
                        fromRole, StorageMappingErrorCode.InvalidAssociationSetRoleInFunctionMapping,
                        m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                    return null; 
                }
 
                // validate cardinality of to end (can be at most one) 
                if (toEnd.CorrespondingAssociationEndMember.RelationshipMultiplicity != RelationshipMultiplicity.One &&
                    toEnd.CorrespondingAssociationEndMember.RelationshipMultiplicity != RelationshipMultiplicity.ZeroOrOne) 
                {
                    StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo(
                    Strings.Mapping_Invalid_Function_Mapping_AssociationSetCardinality_1,
                    toRole, StorageMappingErrorCode.InvalidAssociationSetCardinalityInFunctionMapping, 
                    m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                    return null; 
                } 
                return toEnd;
            } 

            private AssociationSetEnd LoadEndProperty(XPathNavigator nav)
            {
                // retrieve element attributes 
                string role = m_parentLoader.GetAliasResolvedAttributeValue(
                    nav.Clone(), StorageMslConstructs.EndPropertyMappingNameAttribute); 
 
                // validate the role exists
                AssociationSetEnd end = null; 
                if (null == role ||
                    !m_associationSet.AssociationSetEnds.TryGetValue(role, false, out end))
                {
                    StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo( 
                    Strings.Mapping_Invalid_Function_Mapping_AssociationSetRoleDoesNotExist_1,
                    role, StorageMappingErrorCode.InvalidAssociationSetRoleInFunctionMapping, 
                    m_parentLoader.m_sourceLocation, (IXmlLineInfo)nav, m_parentLoader.m_parsingErrors); 
                    return null;
                } 

                return end;
            }
 
            private EdmMember LoadComplexTypeProperty(XPathNavigator nav, StructuralType type, out ComplexType complexType)
            { 
 
                IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
 
                // retrieve element attributes
                string propertyName = m_parentLoader.GetAliasResolvedAttributeValue(
                    nav.Clone(), StorageMslConstructs.ComplexPropertyNameAttribute);
                string typeName = m_parentLoader.GetAliasResolvedAttributeValue( 
                    nav.Clone(), StorageMslConstructs.ComplexTypeMappingTypeNameAttribute);
 
                // retrieve metadata 
                EdmMember property = null;
                if (null == propertyName || 
                    !type.Members.TryGetValue(propertyName, false, out property))
                {
                    // raise exception if the property does not exist
                    StorageMappingItemLoader.AddToSchemaErrorWithMemberAndStructure( 
                        Strings.Mapping_Invalid_Function_Mapping_PropertyNotFound_2,
                        propertyName, type.Name, StorageMappingErrorCode.InvalidEdmMember, 
                        m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors); 
                    complexType = null;
                    return null; 
                }
                complexType = null;
                if (null == typeName ||
                    !m_edmItemCollection.TryGetItem(typeName, out complexType)) 
                {
                    // raise exception if the type does not exist 
                    StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo( 
                    Strings.Mapping_Invalid_Function_Mapping_ComplexTypeNotFound_1,
                    typeName, StorageMappingErrorCode.InvalidComplexType, 
                    m_parentLoader.m_sourceLocation, xmlLineInfoNav
                    , m_parentLoader.m_parsingErrors);
                    return null;
                } 
                if (!property.TypeUsage.EdmType.Equals(complexType) &&
                    !Helper.IsSubtypeOf(property.TypeUsage.EdmType, complexType)) 
                { 
                    // raise exception if the complex type is incorrect
                    StorageMappingItemLoader.AddToSchemaErrorWithMemberAndStructure( 
                        Strings.Mapping_Invalid_Function_Mapping_WrongComplexType_2,
                        typeName, property.Name, StorageMappingErrorCode.InvalidComplexType,
                        m_parentLoader.m_sourceLocation, xmlLineInfoNav
                        , m_parentLoader.m_parsingErrors); 
                    return null;
                } 
                return property; 
            }
 
            private StorageFunctionParameterBinding LoadScalarPropertyParameterBinding(XPathNavigator nav, StructuralType type, bool restrictToKeyMembers)
            {
                IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
 
                // get attribute values
                string parameterName = m_parentLoader.GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ParameterNameAttribute); 
                string propertyName = m_parentLoader.GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ScalarPropertyNameAttribute); 
                string version = m_parentLoader.GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ParameterVersionAttribute);
 
                // determine version
                bool isCurrent = false;
                if (null == version)
                { 
                    // use default
                    if (!m_allowOriginalVersion) 
                    { 
                        isCurrent = true;
                    } 
                    else if (!m_allowCurrentVersion)
                    {
                        isCurrent = false;
                    } 
                    else
                    { 
                        // add a schema error and return as there is no default 
                        StorageMappingItemLoader.AddToSchemaErrors(
                            Strings.Mapping_Invalid_Function_Mapping_MissingVersion_0, 
                            StorageMappingErrorCode.MissingVersionInFunctionMapping, m_parentLoader.m_sourceLocation,
                            xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                        return null;
 
                    }
                } 
                else 
                {
                    // check the value given by the user 
                    isCurrent = version == StorageMslConstructs.ParameterVersionAttributeCurrentValue;
                }
                if (isCurrent && !m_allowCurrentVersion)
                { 
                    //Add a schema error and return  since the 'current' property version is not available
                    StorageMappingItemLoader.AddToSchemaErrors( 
                        Strings.Mapping_Invalid_Function_Mapping_VersionMustBeOriginal_0, 
                        StorageMappingErrorCode.InvalidVersionInFunctionMapping,
                        m_parentLoader.m_sourceLocation, xmlLineInfoNav 
                        , m_parentLoader.m_parsingErrors);
                    return null;
                }
                if (!isCurrent && !m_allowOriginalVersion) 
                {
                    // Add a schema error and return  since the 'original' property version is not available 
                    StorageMappingItemLoader.AddToSchemaErrors( 
                        Strings.Mapping_Invalid_Function_Mapping_VersionMustBeCurrent_0,
                        StorageMappingErrorCode.InvalidVersionInFunctionMapping, 
                        m_parentLoader.m_sourceLocation, xmlLineInfoNav
                        , m_parentLoader.m_parsingErrors);
                    return null;
                } 

                // retrieve metadata 
                FunctionParameter parameter = null; 
                if (null == parameterName ||
                    !m_function.Parameters.TryGetValue(parameterName, false, out parameter)) 
                {
                    //Add a schema error and return  if the parameter does not exist
                    StorageMappingItemLoader.AddToSchemaErrorWithMemberAndStructure(
                        Strings.Mapping_Invalid_Function_Mapping_ParameterNotFound_2, 
                        parameterName, m_function.Name,
                        StorageMappingErrorCode.InvalidParameterInFunctionMapping, 
                        m_parentLoader.m_sourceLocation, xmlLineInfoNav 
                        , m_parentLoader.m_parsingErrors);
                    return null; 
                }
                EdmMember property = null;
                if (restrictToKeyMembers)
                { 
                    if (null == propertyName ||
                        !((EntityType)type).KeyMembers.TryGetValue(propertyName, false, out property)) 
                    { 
                        // raise exception if the property does not exist
                        StorageMappingItemLoader.AddToSchemaErrorWithMemberAndStructure( 
                            Strings.Mapping_Invalid_Function_Mapping_PropertyNotKey_2,
                            propertyName, type.Name,
                            StorageMappingErrorCode.InvalidEdmMember,
                            m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors); 
                        return null;
                    } 
                } 
                else
                { 
                    if (null == propertyName ||
                        !type.Members.TryGetValue(propertyName, false, out property))
                    {
                        // raise exception if the property does not exist 
                        StorageMappingItemLoader.AddToSchemaErrorWithMemberAndStructure(
                            Strings.Mapping_Invalid_Function_Mapping_PropertyNotFound_2, 
                            propertyName, type.Name, 
                            StorageMappingErrorCode.InvalidEdmMember,
                            m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors); 
                        return null;
                    }
                }
 
                // check that the parameter hasn't already been seen
                if (m_seenParameters.Contains(parameter)) 
                { 
                    StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo(
                        Strings.Mapping_Invalid_Function_Mapping_ParameterBoundTwice_1, 
                        parameterName, StorageMappingErrorCode.ParameterBoundTwiceInFunctionMapping,
                        m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                    return null;
                } 

                int errorCount = m_parentLoader.m_parsingErrors.Count; 
 
                TypeUsage mappedStoreType = Helper.ValidateAndConvertTypeUsage(property,
                                                                               xmlLineInfoNav, 
                                                                               m_parentLoader.m_sourceLocation,
                                                                               property.TypeUsage,
                                                                               parameter.TypeUsage,
                                                                               m_parentLoader.m_parsingErrors, 
                                                                               m_storeItemCollection);
 
                // validate type compatibility 
                if (mappedStoreType == null && errorCount == m_parentLoader.m_parsingErrors.Count)
                { 
                    AddToSchemaErrorWithMessage(
                        System.Data.Entity.Strings.Mapping_Invalid_Function_Mapping_PropertyParameterTypeMismatch_6(
                                                             property.TypeUsage.EdmType,
                                                             property.Name, 
                                                             property.DeclaringType.FullName,
                                                             parameter.TypeUsage.EdmType, 
                                                             parameter.Name, 
                                                             m_function.FullName),
                        StorageMappingErrorCode.InvalidFunctionMappingPropertyParameterTypeMismatch, 
                        m_parentLoader.m_sourceLocation,
                        xmlLineInfoNav,
                        m_parentLoader.m_parsingErrors);
                } 

                // create the binding object 
                m_members.Push(property); 
                StorageFunctionParameterBinding binding = new StorageFunctionParameterBinding(parameter, new StorageFunctionMemberPath(
                    m_members, m_associationSetNavigation), isCurrent); 
                m_members.Pop();

                // remember that we've seen a binding for this parameter
                m_seenParameters.Add(parameter); 

                return binding; 
            } 

            ///  
            /// Loads function metadata and ensures the function is supportable for function mapping.
            /// 
            private EdmFunction LoadAndValidateFunctionMetadata(XPathNavigator nav, out FunctionParameter rowsAffectedParameter)
            { 
                IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
 
                // retrieve function attributes from the current element 
                string functionName = m_parentLoader.GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.FunctionNameAttribute);
                rowsAffectedParameter = null; 

                // find function metadata
                System.Collections.ObjectModel.ReadOnlyCollection functionOverloads =
                    m_storeItemCollection.GetFunctions(functionName); 

                if (functionOverloads.Count == 0) 
                { 
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Invalid_Function_Mapping_UnknownFunction_1, functionName,
                        StorageMappingErrorCode.InvalidFunctionMappingUnknownFunction, m_parentLoader.m_sourceLocation, 
                        xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                    return null;
                }
 
                if (1 < functionOverloads.Count)
                { 
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Invalid_Function_Mapping_AmbiguousFunction_1, functionName, 
                        StorageMappingErrorCode.InvalidFunctionMappingAmbiguousFunction, m_parentLoader.m_sourceLocation,
                        xmlLineInfoNav, m_parentLoader.m_parsingErrors); 
                    return null;
                }

                EdmFunction function = functionOverloads[0]; 

                // check function is legal for function mapping 
                if (MetadataHelper.IsComposable(function)) 
                { // only non-composable functions are permitted
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Invalid_Function_Mapping_NotValidFunction_1, functionName, 
                        StorageMappingErrorCode.InvalidFunctionMappingNotValidFunction, m_parentLoader.m_sourceLocation,
                        xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                    return null;
                } 

                // check for parameter 
                string rowsAffectedParameterName = GetAttributeValue(nav, StorageMslConstructs.RowsAffectedParameterAttribute); 
                if (!string.IsNullOrEmpty(rowsAffectedParameterName))
                { 
                    // check that the parameter exists
                    if (!function.Parameters.TryGetValue(rowsAffectedParameterName, false, out rowsAffectedParameter))
                    {
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_RowsAffectedParameterDoesNotExist_2( 
                            rowsAffectedParameterName, function.FullName),
                            StorageMappingErrorCode.MappingFunctionImportRowsAffectedParameterDoesNotExist, 
                            m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors); 
                        return null;
                    } 
                    // check that the parameter is an out parameter
                    if (ParameterMode.Out != rowsAffectedParameter.Mode)
                    {
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_RowsAffectedParameterHasWrongMode_3( 
                            rowsAffectedParameterName, rowsAffectedParameter.Mode, ParameterMode.Out),
                            StorageMappingErrorCode.MappingFunctionImportRowsAffectedParameterHasWrongMode, 
                            m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors); 
                        return null;
                    } 
                    // check that the parameter type is Int32
                    PrimitiveType rowsAffectedParameterType = (PrimitiveType)rowsAffectedParameter.TypeUsage.EdmType;
                    if (rowsAffectedParameterType.PrimitiveTypeKind != PrimitiveTypeKind.Int32)
                    { 
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_RowsAffectedParameterHasWrongType_3(
                            rowsAffectedParameterName, rowsAffectedParameterType.PrimitiveTypeKind, PrimitiveTypeKind.Int32), 
                            StorageMappingErrorCode.MappingFunctionImportRowsAffectedParameterHasWrongType, 
                            m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                        return null; 
                    }
                    m_seenParameters.Add(rowsAffectedParameter);
                }
 
                // check that all parameters are allowed
                foreach (FunctionParameter parameter in function.Parameters) 
                { 
                    if (ParameterMode.In != parameter.Mode && rowsAffectedParameterName != parameter.Name)
                    { // rows affected is 'out' not 'in' 
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_Invalid_Function_Mapping_NotValidFunctionParameter_3(functionName,
                            parameter.Name, StorageMslConstructs.RowsAffectedParameterAttribute), StorageMappingErrorCode.InvalidFunctionMappingNotValidFunctionParameter,
                            m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                        return null; 
                    }
                } 
 
                return function;
            } 
        }
        #endregion
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner [....], [....]
//--------------------------------------------------------------------- 
 
using System;
using System.Diagnostics; 
using System.Collections;
using System.IO;
using System.Text;
using System.Collections.Generic; 
using System.Xml;
using System.Xml.Schema; 
using System.Xml.XPath; 
using System.Data.Metadata.Edm;
using System.Data.Common.Utils; 
using System.Data.Mapping.ViewGeneration.Utils;
using System.Collections.ObjectModel;
using System.Data.EntityModel;
using System.Data.Entity; 
using System.Globalization;
using System.Linq; 
 

namespace System.Data.Mapping 
{
    using Triple = Pair>;

    ///  
    /// The class loads an MSL file into memory and exposes CSMappingMetadata interfaces.
    /// The primary consumers of the interfaces are view genration and tools. 
    ///  
    /// 
    /// For Example if conceptually you could represent the CS MSL file as following 
    /// --Mapping
    ///   --EntityContainerMapping ( CNorthwind-->SNorthwind )
    ///     --EntitySetMapping
    ///       --EntityTypeMapping 
    ///         --TableMappingFragment
    ///           --EntityKey 
    ///             --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata ) 
    ///           --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
    ///           --DiscriminatorProperyMap ( constant value-->SMemberMetadata ) 
    ///       --EntityTypeMapping
    ///         --TableMappingFragment
    ///           --EntityKey
    ///             --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata ) 
    ///           --ComplexPropertyMap
    ///             --ComplexTypeMap 
    ///               --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata ) 
    ///               --ScalarProperyMap ( CMemberMetadata-->SMemberMetadata )
    ///           --DiscriminatorProperyMap ( constant value-->SMemberMetadata ) 
    ///     --AssociationSetMapping
    ///       --AssociationTypeMapping
    ///         --TableMappingFragment
    ///           --EndPropertyMap 
    ///             --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
    ///             --ScalarProperyMap ( CMemberMetadata-->SMemberMetadata ) 
    ///           --EndPropertyMap 
    ///             --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
    ///   --EntityContainerMapping ( CMyDatabase-->SMyDatabase ) 
    ///     --CompositionSetMapping
    ///       --CompositionTypeMapping
    ///         --TableMappingFragment
    ///           --ParentEntityKey 
    ///             --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
    ///             --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata ) 
    ///           --EntityKey 
    ///             --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
    ///             --ScalarPropertyMap ( CMemberMetadata-->Constant value ) 
    ///           --ComplexPropertyMap
    ///             --ComplexTypeMap
    ///               --ScalarPropertyMap ( CMemberMetadata-->SMemberMetadata )
    ///               --DiscriminatorProperyMap ( constant value-->SMemberMetadata ) 
    ///           --ScalarPropertyMap ( CMemberMetadata-->Constant value )
    /// The CCMappingSchemaLoader loads an Xml file that has a conceptual structure 
    /// equivalent to the above example into in-memory data structure in a 
    /// top-dwon approach.
    ///  
    /// 
    /// The loader uses XPathNavigator to parse the XML. The advantage of using XPathNavigator
    /// over DOM is that it exposes the line number of the current xml content.
    /// This is really helpful when throwing exceptions. Another advantage is 
    /// 
    internal class StorageMappingItemLoader 
    { 
        #region Constructors
        ///  
        /// Public constructor.
        /// For Beta2 we wont support delay loading Mapping information and we would also support
        /// only one mapping file for workspace.
        ///  
        /// 
        ///  
        ///  
        /// Dictionary to keep the list of all scalar member mappings
        internal StorageMappingItemLoader(StorageMappingItemCollection storageMappingItemCollection, string fileName, Dictionary> scalarMemberMappings) 
        {
            Debug.Assert(storageMappingItemCollection != null);
            Debug.Assert(scalarMemberMappings != null);
 
            this.m_storageMappingItemCollection = storageMappingItemCollection;
            this.m_alias = new Dictionary(StringComparer.Ordinal); 
            //The fileName field in this class will always have absolute path since 
            //StorageMappingItemCollection would have already done it while
            //preparing the filePaths 
            if (fileName != null)
            {
                this.m_sourceLocation = fileName;
            } 
            else
            { 
                this.m_sourceLocation = null; 
            }
            m_parsingErrors = new List(); 
            this.m_scalarMemberMappings = scalarMemberMappings;
        }
        #endregion
 
        #region Fields
        private Dictionary m_alias;  //To support the aliasing mechanism provided by MSL. 
        private StorageMappingItemCollection m_storageMappingItemCollection; //StorageMappingItemCollection 
        private string m_sourceLocation; //location identifier for the MSL file.
        private List m_parsingErrors; 
        private Dictionary> m_scalarMemberMappings; // dictionary of all the scalar member mappings - this is to validate that no property is mapped to different store types across mappings.
        private bool m_hasQueryViews;  //set to true if any of the SetMaps have a query view so that

        // cached xsd schema 
        private static XmlSchemaSet s_mappingXmlSchema;
        #endregion 
 
        #region Properties
        internal IList ParsingErrors 
        {
            get
            {
                return m_parsingErrors; 
            }
 
        } 

        internal bool HasQueryViews 
        {
            get { return m_hasQueryViews; }
        }
 
        private EdmItemCollection EdmItemCollection
        { 
            get 
            {
                return m_storageMappingItemCollection.EdmItemCollection; 
            }
        }

        private StoreItemCollection StoreItemCollection 
        {
            get 
            { 
                return m_storageMappingItemCollection.StoreItemCollection;
            } 
        }
        #endregion

        #region Methods 
        /// 
        /// The LoadMappingSchema method loads the mapping file and initializes the 
        /// MappingSchema that represents this mapping file. 
        /// For Beta2 atleast, we will support only one EntityContainerMapping per mapping file.
        ///  
        /// 
        internal StorageEntityContainerMapping LoadMappingItems(XmlReader innerReader)
        {
            //Using XPathDocument to load the xml file into memory. 
            XmlReader reader = GetSchemaValidatingReader(innerReader);
 
            try 
            {
                XPathDocument doc = new XPathDocument(reader); 
                //If there were any xsd validation errors, we would have
                //caught these while creatring xpath document.
                if (m_parsingErrors.Count != 0)
                { 
                    //If the errors were only warnings continue, otherwise return the errors without
                    //loading the mapping 
                    if (!MetadataHelper.CheckIfAllErrorsAreWarnings(m_parsingErrors)) 
                    {
                        return null; 
                    }
                }

                //Create an XPathNavigator to navigate the document in a forward only manner. 
                //The XPathNavigator can also be used to run quries through the document while still maintaining
                //the current position. This will be helpful in running validation rules that are not part of Schema. 
                XPathNavigator nav = doc.CreateNavigator(); 
                return LoadMappingItems(nav);
            } 
            catch (XmlException xmlException)
            {
                //There must have been a xml parsing exception. Add the exception information
                //to the error list. 
                EdmSchemaError error = new EdmSchemaError(System.Data.Entity.Strings.Mapping_InvalidMappingSchema_Parsing_1(xmlException.Message)
                    , (int)StorageMappingErrorCode.XmlSchemaParsingError, EdmSchemaErrorSeverity.Error, m_sourceLocation, xmlException.LineNumber, xmlException.LinePosition); 
                m_parsingErrors.Add(error); 
            }
 
            // do not close the wrapping reader here, as doing so will close the inner reader;
            // see SQLBUDT 522950 for details

            return null; 
        }
 
        internal StorageEntityContainerMapping LoadMappingItems(XPathNavigator nav) 
        {
            //XSD validation is not validating missing Root element. 
            if ((!nav.MoveToChild(StorageMslConstructs.MappingElement, StorageMslConstructs.NamespaceURI)) || (nav.NodeType != XPathNodeType.Element))
            {
                StorageMappingItemLoader.AddToSchemaErrors(Strings.Mapping_Invalid_CSRootElementMissing_0, StorageMappingErrorCode.RootMappingElementMissing, m_sourceLocation,
                    (IXmlLineInfo)nav, m_parsingErrors); 
                //There is no point in going forward if the required root element is not found
                return null; 
            } 
            StorageEntityContainerMapping entityContainerMap =
                LoadMappingChildNodes(nav.Clone()); 
            //If there were any parsing errors, invalidate the entity container map and return null.
            if (m_parsingErrors.Count != 0)
            {
                //If all the schema errors are warnings, don't return null 
                if (!MetadataHelper.CheckIfAllErrorsAreWarnings(m_parsingErrors))
                { 
                    entityContainerMap = null; 
                }
            } 
            return entityContainerMap;
        }

        ///  
        /// The method loads the child nodes for the root Mapping node
        /// into the internal datastructures. 
        ///  
        /// 
        ///  
        private StorageEntityContainerMapping LoadMappingChildNodes(XPathNavigator nav)
        {
            IXmlLineInfo navLineInfo = (IXmlLineInfo)nav;
 
            bool hasContainerMapping;
            //If there are any Alias elements in the document, they should be the first ones. 
            //This method can only move to the Alias element since comments, PIS etc wont have any Namespace 
            //though they could have same name as Alias element
            if (nav.MoveToChild(StorageMslConstructs.AliasElement, StorageMslConstructs.NamespaceURI)) 
            {
                //Collect all the alias elements
                do
                { 
                    m_alias.Add(StorageMappingItemLoader.GetAttributeValue(nav.Clone(), StorageMslConstructs.AliasKeyAttribute), StorageMappingItemLoader.GetAttributeValue(nav.Clone(), StorageMslConstructs.AliasValueAttribute));
                } while (nav.MoveToNext(StorageMslConstructs.AliasElement, StorageMslConstructs.NamespaceURI)); 
                //Now move on to the Next element that will be "EntityContainer" element 
                hasContainerMapping = nav.MoveToNext(XPathNodeType.Element);
            } 
            else
            {
                //Since there was no Alias element, move on to the Container element
                hasContainerMapping = nav.MoveToChild(XPathNodeType.Element); 
            }
 
            //No container mappings found, so just return 
            if (!hasContainerMapping)
                return null; 
            //The element name can only be EntityContainerMapping element name since XSD validation should have guarneteed this.
            Debug.Assert(nav.LocalName == StorageMslConstructs.EntityContainerMappingElement);
            string entityContainerName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.CDMEntityContainerAttribute);
            string storageEntityContainerName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.StorageEntityContainerAttribute); 

            StorageEntityContainerMapping entityContainerMapping; 
            EntityContainer entityContainerType; 
            EntityContainer storageEntityContainerType;
 
            // Now that we support partial mapping, we should first check if the entity container mapping is
            // already present. If its already present, we should add the new child nodes to the existing entity container mapping
            if (m_storageMappingItemCollection.TryGetItem(
                    entityContainerName, out entityContainerMapping)) 
            {
                entityContainerType = entityContainerMapping.EdmEntityContainer; 
                storageEntityContainerType = entityContainerMapping.StorageEntityContainer; 

                // The only thing we need to make sure is that the storage entity container mapping is the same. 
                if (storageEntityContainerName != storageEntityContainerType.Name)
                {
                    AddToSchemaErrors(System.Data.Entity.Strings.StorageEntityContainerNameMismatchWhileSpecifyingPartialMapping(
                            storageEntityContainerName, storageEntityContainerType.Name, entityContainerType.Name), 
                        StorageMappingErrorCode.StorageEntityContainerNameMismatchWhileSpecifyingPartialMapping,
                        m_sourceLocation, navLineInfo, m_parsingErrors); 
 
                    return null;
                } 
            }
            else
            {
                //At this point we know that the EdmEntityContainer has not been 
                //mapped already. if we do find that StorageEntityContainer
                //has already been mapped, return null. 
                if (m_storageMappingItemCollection.ContainsStorageEntityContainer(storageEntityContainerName)) 
                {
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_AlreadyMapped_StorageEntityContainer_1, storageEntityContainerName, 
                        StorageMappingErrorCode.AlreadyMappedStorageEntityContainer, m_sourceLocation, navLineInfo, m_parsingErrors);
                    return null;
                }
 

                //Get the CDM EntityContainer by this name from the metadata workspace. 
                this.EdmItemCollection.TryGetEntityContainer(entityContainerName, out entityContainerType); 
                if (entityContainerType == null)
                { 
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_EntityContainer_1,
                        entityContainerName, StorageMappingErrorCode.InvalidEntityContainer, m_sourceLocation,
                        navLineInfo, m_parsingErrors);
                } 

                this.StoreItemCollection.TryGetEntityContainer(storageEntityContainerName, out storageEntityContainerType); 
                if (storageEntityContainerType == null) 
                {
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_StorageEntityContainer_1, storageEntityContainerName, 
                        StorageMappingErrorCode.InvalidEntityContainer, m_sourceLocation, navLineInfo, m_parsingErrors);
                }

                //If the EntityContainerTypes are not found, there is no point in 
                //continuing with the parsing.
                if ((entityContainerType == null) || (storageEntityContainerType == null)) 
                { 
                    return null;
                } 

                //Create an EntityContainerMapping object to hold the mapping information for this
                //EntityContainer. Create a MappingKey and pass it in.
                entityContainerMapping = new StorageEntityContainerMapping(entityContainerType, storageEntityContainerType, m_storageMappingItemCollection); 
                entityContainerMapping.StartLineNumber = navLineInfo.LineNumber;
                entityContainerMapping.StartLinePosition = navLineInfo.LinePosition; 
            } 

            //Load the child nodes for the created EntityContainerMapping 
            LoadEntityContainerMapping(nav.Clone(), entityContainerMapping, storageEntityContainerType);
            return entityContainerMapping;
        }
 
        /// 
        /// The method loads the child nodes for the EntityContainer Mapping node 
        /// into the internal datastructures. 
        /// 
        ///  
        /// 
        /// 
        private void LoadEntityContainerMapping(XPathNavigator nav, StorageEntityContainerMapping entityContainerMapping, EntityContainer storageEntityContainerType)
        { 
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
            bool anyEntitySetMapped = false; 
 
            //If there is no child node for the EntityContainerMapping Element, return.
            if (nav.MoveToChild(XPathNodeType.Element)) 
            {
                //The valid child nodes for EntityContainerMapping node are various SetMappings( EntitySet, AssociationSet etc ).
                //Loop through the child nodes and lod them as children of the EntityContainerMapping object.
                do 
                {
                    switch (nav.LocalName) 
                    { 
                        case StorageMslConstructs.EntitySetMappingElement:
                            { 
                                LoadEntitySetMapping(nav.Clone(), entityContainerMapping, storageEntityContainerType);
                                anyEntitySetMapped = true;
                                break;
                            } 
                        case StorageMslConstructs.AssociationSetMappingElement:
                            { 
                                LoadAssociationSetMapping(nav.Clone(), entityContainerMapping, storageEntityContainerType); 
                                break;
                            } 
                        case StorageMslConstructs.FunctionImportMappingElement:
                            {
                                LoadFunctionImportMapping(nav.Clone(), entityContainerMapping, storageEntityContainerType);
                                break; 
                            }
                        default: 
                            AddToSchemaErrors(Strings.Mapping_InvalidContent_Set_Mapping_0, 
                                StorageMappingErrorCode.SetMappingExpected, m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                            break; 
                    }
                } while (nav.MoveToNext(XPathNodeType.Element));
            }
 
            //If the EntityContainer contains entity sets but they are not mapped then we should add an error
            if (entityContainerMapping.EdmEntityContainer.BaseEntitySets.Count != 0 && !anyEntitySetMapped) 
            { 
                AddToSchemaErrorsWithMemberInfo(Strings.ViewGen_Missing_Sets_Mapping_0,
                    entityContainerMapping.EdmEntityContainer.Name, StorageMappingErrorCode.EmptyContainerMapping, 
                    this.m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                return;
            }
 
            ValidateFunctionMappingClosure(nav.Clone(), entityContainerMapping);
            ValidateFunctionAssociationFunctionMappingUnique(nav.Clone(), entityContainerMapping); 
            ValidateAssociationFunctionMappingConsistent(nav.Clone(), entityContainerMapping); 
            ValidateQueryViewsClosure(nav.Clone(), entityContainerMapping);
            //The fileName field in this class will always have absolute path since 
            //StorageMappingItemCollection would have already done it while
            //preparing the filePaths
            entityContainerMapping.SourceLocation = m_sourceLocation;
        } 

        ///  
        /// Validates that collocated association sets are consistently mapped for each entity set (all operations or none). In the case 
        /// of relationships between sub-types of an entity set, ensures the relationship mapping is legal.
        ///  
        /// 
        /// 
        private void ValidateAssociationFunctionMappingConsistent(XPathNavigator nav, StorageEntityContainerMapping entityContainerMapping)
        { 
            foreach (StorageEntitySetMapping entitySetMapping in entityContainerMapping.EntitySetMaps)
            { 
                if (entitySetMapping.FunctionMappings.Count > 0) 
                {
                    // determine the set of ----oication sets that should be mapped for every operation 
                    Set expectedEnds = new Set(
                        entitySetMapping.ImplicitlyMappedAssociationSetEnds).MakeReadOnly();

                    // check that each operation covers each association set 
                    foreach (StorageEntityTypeFunctionMapping entityTypeMapping in entitySetMapping.FunctionMappings)
                    { 
                        ValidateAssociationFunctionMappingConsistent(nav, entitySetMapping, entityTypeMapping, 
                            entityTypeMapping.DeleteFunctionMapping,
                            expectedEnds, StorageMslConstructs.DeleteFunctionElement); 
                        ValidateAssociationFunctionMappingConsistent(nav, entitySetMapping, entityTypeMapping,
                            entityTypeMapping.InsertFunctionMapping,
                            expectedEnds, StorageMslConstructs.InsertFunctionElement);
                        ValidateAssociationFunctionMappingConsistent(nav, entitySetMapping, entityTypeMapping, 
                            entityTypeMapping.UpdateFunctionMapping,
                            expectedEnds, StorageMslConstructs.UpdateFunctionElement); 
                    } 
                }
            } 
        }
        private void ValidateAssociationFunctionMappingConsistent(XPathNavigator nav,
            StorageEntitySetMapping entitySetMapping, StorageEntityTypeFunctionMapping entityTypeMapping,
            StorageFunctionMapping functionMapping, Set expectedEnds, string elementName) 
        {
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav; 
 
            // check that all expected association sets are mapped for in this function mapping
            Set actualEnds = new Set( 
                functionMapping.GetReferencedAssociationSetEnds((EntitySet)entitySetMapping.Set));
            actualEnds.MakeReadOnly();

            // check that all required ends are present 
            foreach (AssociationSetEnd expectedEnd in expectedEnds)
            { 
                // check that the association set is required based on the entity type 
                if (MetadataHelper.IsAssociationValidForEntityType(expectedEnd, entityTypeMapping.EntityType))
                { 
                    if (!actualEnds.Contains(expectedEnd))
                    {
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_Invalid_Function_Mapping_AssociationSetNotMappedForOperation_4(
                            entitySetMapping.Set.Name, 
                            expectedEnd.ParentAssociationSet.Name,
                            elementName, 
                            entityTypeMapping.EntityType.FullName), 
                            StorageMappingErrorCode.InvalidFunctionMappingAssociationSetNotMappedForOperation,
                            m_sourceLocation, 
                            xmlLineInfoNav,
                            m_parsingErrors);
                    }
                } 
            }
 
            // check that no ends with invalid types are included 
            foreach (AssociationSetEnd actualEnd in actualEnds)
            { 
                if (!MetadataHelper.IsAssociationValidForEntityType(actualEnd, entityTypeMapping.EntityType))
                {
                    AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_Invalid_Function_Mapping_AssociationEndMappingInvalidForEntityType_3(
                        entityTypeMapping.EntityType.FullName, 
                        actualEnd.ParentAssociationSet.Name,
                        MetadataHelper.GetEntityTypeForEnd(MetadataHelper.GetOppositeEnd(actualEnd).CorrespondingAssociationEndMember).FullName), 
                        StorageMappingErrorCode.InvalidFunctionMappingAssociationEndMappingInvalidForEntityType, 
                        m_sourceLocation,
                        xmlLineInfoNav, 
                        m_parsingErrors);
                }
            }
        } 

        ///  
        /// Validates that association sets are only mapped once. 
        /// 
        ///  
        /// Container to validate
        private void ValidateFunctionAssociationFunctionMappingUnique(XPathNavigator nav, StorageEntityContainerMapping entityContainerMapping)
        {
            Dictionary mappingCounts = new Dictionary(); 

            // Walk through all entity set mappings 
            foreach (StorageEntitySetMapping entitySetMapping in entityContainerMapping.EntitySetMaps) 
            {
                if (entitySetMapping.FunctionMappings.Count > 0) 
                {
                    // Get set of association sets implicitly mapped associations to avoid double counting
                    Set associationSets = new Set();
                    foreach (AssociationSetEnd end in entitySetMapping.ImplicitlyMappedAssociationSetEnds) 
                    {
                        associationSets.Add(end.ParentAssociationSet); 
                    } 

                    foreach (EntitySetBase associationSet in associationSets) 
                    {
                        IncrementCount(mappingCounts, associationSet);
                    }
                } 
            }
 
            // Walk through all association set mappings 
            foreach (StorageAssociationSetMapping associationSetMapping in entityContainerMapping.RelationshipSetMaps)
            { 
                if (null != associationSetMapping.FunctionMapping)
                {
                    IncrementCount(mappingCounts, associationSetMapping.Set);
                } 
            }
 
            // Check for redundantly mapped association sets 
            List violationNames = new List();
            foreach (KeyValuePair mappingCount in mappingCounts) 
            {
                if (mappingCount.Value > 1)
                {
                    violationNames.Add(mappingCount.Key.Name); 
                }
            } 
 
            if (0 < violationNames.Count)
            { 
                // Warn the user that association sets are mapped multiple times
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Invalid_Function_Mapping_AssociationSetAmbiguous_1,
                    StringUtil.ToCommaSeparatedString(violationNames), StorageMappingErrorCode.AmbiguousFunctionMappingForAssociationSet,
                    m_sourceLocation, (IXmlLineInfo)nav, m_parsingErrors); 

            } 
        } 

        private static void IncrementCount(Dictionary counts, T key) 
        {
            int count;
            if (counts.TryGetValue(key, out count))
            { 
                count++;
            } 
            else 
            {
                count = 1; 
            }
            counts[key] = count;
        }
 
        /// 
        /// Validates that all or no related extents have function mappings. If an EntitySet has a function mapping, 
        /// then all 'reference' association sets must also have function mappings. Similarly, if an AssociationSet has a function 
        /// mapping, 'reference' ends must have function mappings.
        ///  
        /// 
        /// Container to validate.
        private void ValidateFunctionMappingClosure(XPathNavigator nav, StorageEntityContainerMapping entityContainerMapping)
        { 
            // Check that function mappings apply to complete subgraph by tracking which extents have function
            // mappings and which extents must include function mappings 
            Set setsWithFunctionMapping = new Set(); 

            // Walk through all entity set mappings 
            foreach (StorageEntitySetMapping entitySetMapping in entityContainerMapping.EntitySetMaps)
            {
                if (entitySetMapping.FunctionMappings.Count > 0)
                { 
                    // a function mapping exists for this entity set
                    setsWithFunctionMapping.Add(entitySetMapping.Set); 
 
                    // add all implicitly mapped association sets
                    foreach (AssociationSetEnd end in entitySetMapping.ImplicitlyMappedAssociationSetEnds) 
                    {
                        setsWithFunctionMapping.Add(end.ParentAssociationSet);
                    }
                } 
            }
 
            // Walk through all association set mapping 
            foreach (StorageAssociationSetMapping associationSetMapping in entityContainerMapping.RelationshipSetMaps)
            { 
                if (null != associationSetMapping.FunctionMapping)
                {
                    setsWithFunctionMapping.Add(associationSetMapping.Set);
                } 
            }
 
            // Initialize sets requiring function mapping with the sets that are actually function mapped 
            Set setsRequiringFunctionMapping = FindMissingFunctionMappings(entityContainerMapping, setsWithFunctionMapping);
 
            // Check that no required entity or association sets are missing
            if (0 < setsRequiringFunctionMapping.Count)
            {
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Invalid_Function_Mapping_MissingSetClosure_1, 
                    StringUtil.ToCommaSeparatedString(setsRequiringFunctionMapping),
                    StorageMappingErrorCode.MissingSetClosureInFunctionMapping, m_sourceLocation, (IXmlLineInfo)nav 
                    , m_parsingErrors); 
            }
        } 

        private static Set FindMissingFunctionMappings(StorageEntityContainerMapping entityContainerMapping, Set setsWithFunctionMapping)
        {
            Set setsRequiringFunctionMapping = new Set(); 
            foreach (EntitySetBase entitySetBase in setsWithFunctionMapping)
            { 
                if (BuiltInTypeKind.AssociationSet == entitySetBase.BuiltInTypeKind) 
                {
                    AssociationSet associationSet = (AssociationSet)entitySetBase; 
                    // add the entity sets bound to the end roles to the required list
                    foreach (AssociationSetEnd end in associationSet.AssociationSetEnds)
                    {
                        var multiplicity = end.CorrespondingAssociationEndMember.RelationshipMultiplicity; 
                        if (multiplicity == RelationshipMultiplicity.One ||
                            multiplicity == RelationshipMultiplicity.ZeroOrOne) 
                        { 
                            // for 'reference' ends of associations, the entity set is required
                            EntitySet requiredSet = MetadataHelper.GetOppositeEnd(end).EntitySet; 
                            if (!setsWithFunctionMapping.Contains(requiredSet))
                            {
                                setsRequiringFunctionMapping.Add(MetadataHelper.GetOppositeEnd(end).EntitySet);
                            } 
                        }
                    } 
                } 
            }
 
            // Register all association sets referencing known entity sets
            foreach (EntitySetBase entitySetBase in entityContainerMapping.EdmEntityContainer.BaseEntitySets)
            {
                if (BuiltInTypeKind.AssociationSet == entitySetBase.BuiltInTypeKind) 
                {
                    AssociationSet associationSet = (AssociationSet)entitySetBase; 
                    // check that this association set isn't already mapped 
                    if (!setsWithFunctionMapping.Contains(associationSet))
                    { 
                        foreach (AssociationSetEnd end in associationSet.AssociationSetEnds)
                        {
                            var multiplicity = end.CorrespondingAssociationEndMember.RelationshipMultiplicity;
                            if (multiplicity == RelationshipMultiplicity.One || 
                                multiplicity == RelationshipMultiplicity.ZeroOrOne)
                            { 
                                var oppositeEnd = MetadataHelper.GetOppositeEnd(end); 

                                // check if the opposite end has a function mapping (which means 
                                // this AssociationSet is a required reference end)
                                if (setsWithFunctionMapping.Contains(oppositeEnd.EntitySet))
                                {
                                    setsRequiringFunctionMapping.Add(associationSet); 
                                }
                            } 
                        } 
                    }
                } 
            }

            return setsRequiringFunctionMapping;
        } 

        private static void ValidateClosureAmongSets(StorageEntityContainerMapping entityContainerMapping, Set sets, Set additionalSetsInClosure) 
        { 
            bool nodeFound;
            do 
            {
                nodeFound = false;
                List newNodes = new List();
 
                // Register entity sets dependencies for association sets
                foreach (EntitySetBase entitySetBase in additionalSetsInClosure) 
                { 
                    if (BuiltInTypeKind.AssociationSet == entitySetBase.BuiltInTypeKind)
                    { 
                        AssociationSet associationSet = (AssociationSet)entitySetBase;
                        // add the entity sets bound to the end roles to the required list
                        foreach (AssociationSetEnd end in associationSet.AssociationSetEnds)
                        { 
                            if (!additionalSetsInClosure.Contains(end.EntitySet))
                            { 
                                newNodes.Add(end.EntitySet); 
                            }
                        } 
                    }
                }

                // Register all association sets referencing known entity sets 
                foreach (EntitySetBase entitySetBase in entityContainerMapping.EdmEntityContainer.BaseEntitySets)
                { 
                    if (BuiltInTypeKind.AssociationSet == entitySetBase.BuiltInTypeKind) 
                    {
                        AssociationSet associationSet = (AssociationSet)entitySetBase; 
                        // check that this association set isn't already in the required set
                        if (!additionalSetsInClosure.Contains(associationSet))
                        {
                            foreach (AssociationSetEnd end in associationSet.AssociationSetEnds) 
                            {
                                if (additionalSetsInClosure.Contains(end.EntitySet)) 
                                { 
                                    // this association set must be added to the required list if
                                    // any of its ends are in that list 
                                    newNodes.Add(associationSet);
                                    break; // no point adding the association set twice
                                }
                            } 
                        }
                    } 
                } 

                if (0 < newNodes.Count) 
                {
                    nodeFound = true;
                    additionalSetsInClosure.AddRange(newNodes);
                } 
            }
            while (nodeFound); 
 
            additionalSetsInClosure.Subtract(sets);
        } 

        /// 
        /// Validates that all or no related extents have query views defined. If an extent has a query view defined, then
        /// all related extents must also have query views. 
        /// 
        ///  
        /// Container to validate. 

        private void ValidateQueryViewsClosure(XPathNavigator nav, StorageEntityContainerMapping entityContainerMapping) 
        {
            //If there is no query view defined, no need to validate
            if (!m_hasQueryViews)
            { 
                return;
            } 
            // Check that query views apply to complete subgraph by tracking which extents have query 
            // mappings and which extents must include query views
            Set setsWithQueryViews = new Set(); 
            Set setsRequiringQueryViews = new Set();

            // Walk through all set mappings
            foreach (StorageSetMapping setMapping in entityContainerMapping.AllSetMaps) 
            {
                if (setMapping.QueryView != null) 
                { 
                    // a function mapping exists for this entity set
                    setsWithQueryViews.Add(setMapping.Set); 
                }
            }

            // Initialize sets requiring function mapping with the sets that are actually function mapped 
            setsRequiringQueryViews.AddRange(setsWithQueryViews);
 
            ValidateClosureAmongSets(entityContainerMapping, setsWithQueryViews, setsRequiringQueryViews); 

            // Check that no required entity or association sets are missing 
            if (0 < setsRequiringQueryViews.Count)
            {
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Invalid_Query_Views_MissingSetClosure_1,
                    StringUtil.ToCommaSeparatedString(setsRequiringQueryViews), 
                    StorageMappingErrorCode.MissingSetClosureInQueryViews, m_sourceLocation, (IXmlLineInfo)nav
                    , m_parsingErrors); 
            } 
        }
 

        /// 
        /// The method loads the child nodes for the EntitySet Mapping node
        /// into the internal datastructures. 
        /// 
        ///  
        ///  
        /// 
        private void LoadEntitySetMapping(XPathNavigator nav, StorageEntityContainerMapping entityContainerMapping, EntityContainer storageEntityContainerType) 
        {
            //Get the EntitySet name
            string entitySetName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.EntitySetMappingNameAttribute);
            //Get the EntityType name, need to parse it if the mapping information is being specified for multiple types 
            string entityTypeName = StorageMappingItemLoader.GetAttributeValue(nav.Clone(), StorageMslConstructs.EntitySetMappingTypeNameAttribute);
            //Get the table name. This might be emptystring since the user can have a TableMappingFragment instead of this. 
            string tableName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.EntitySetMappingStoreEntitySetAttribute); 
            EntitySet entitySet;
 
            // First check to see if the Entity Set Mapping is already specified. It can be specified, in the same schema file later on
            // on a totally different file. Since we support partial mapping, we should just add mapping fragments or entity type
            // mappings to the existing entity set mapping
            StorageEntitySetMapping setMapping = (StorageEntitySetMapping)entityContainerMapping.GetEntitySetMapping(entitySetName); 

            // Update the info about the schema element 
            IXmlLineInfo navLineInfo = (IXmlLineInfo)nav; 

            if (setMapping == null) 
            {
                //Try to find the EntitySet with the given name in the EntityContainer.
                if (!entityContainerMapping.EdmEntityContainer.TryGetEntitySetByName(entitySetName, /*ignoreCase*/ false, out entitySet))
                { 
                    //If no EntitySet with the given name exists, than add a schema error and return
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Entity_Set_1, entitySetName, 
                        StorageMappingErrorCode.InvalidEntitySet, m_sourceLocation, navLineInfo, m_parsingErrors); 
                    //There is no point in continuing the loding of this EntitySetMapping if the EntitySet is not found
                    return; 
                }
                //Create the EntitySet Mapping which contains the mapping information for EntitySetMap.
                setMapping = new StorageEntitySetMapping(entitySet, entityContainerMapping);
            } 
            else
            { 
                entitySet = (EntitySet)setMapping.Set; 
            }
 
            //Set the Start Line Information on Fragment
            setMapping.StartLineNumber = navLineInfo.LineNumber;
            setMapping.StartLinePosition = navLineInfo.LinePosition;
            entityContainerMapping.AddEntitySetMapping(setMapping); 

            //If the TypeName was not specified as an attribute, than an EntityTypeMapping element should be present 
            if (String.IsNullOrEmpty(entityTypeName)) 
            {
                if (nav.MoveToChild(XPathNodeType.Element)) 
                {

                    do
                    { 
                        switch (nav.LocalName)
                        { 
                            case StorageMslConstructs.EntityTypeMappingElement: 
                                {
                                    //TableName could also be specified on EntityTypeMapping element 
                                    tableName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.EntityTypeMappingStoreEntitySetAttribute);
                                    //Load the EntityTypeMapping into memory.
                                    LoadEntityTypeMapping(nav.Clone(), setMapping, tableName, storageEntityContainerType);
                                    break; 
                                }
                            case StorageMslConstructs.QueryViewElement: 
                                { 
                                    if (!(String.IsNullOrEmpty(tableName)))
                                    { 
                                        AddToSchemaErrorsWithMemberInfo(Strings.Mapping_TableName_QueryView_1, entitySetName,
                                            StorageMappingErrorCode.TableNameAttributeWithQueryView, m_sourceLocation, navLineInfo, m_parsingErrors);
                                        return;
                                    } 
                                    //Load the Query View into the set mapping,
                                    //if you get an error, return immediately since 
                                    //you go on, you could be giving lot of dubious errors 
                                    if(!LoadQueryView(nav.Clone(), setMapping))
                                    { 
                                        return;
                                    }
                                    break;
                                } 
                            default:
                                AddToSchemaErrors(Strings.Mapping_InvalidContent_TypeMapping_QueryView, 
                                    StorageMappingErrorCode.InvalidContent, m_sourceLocation, navLineInfo, m_parsingErrors); 
                                break;
                        } 
                    } while (nav.MoveToNext(XPathNodeType.Element));
                }
            }
            else 
            {
                //Load the EntityTypeMapping into memory. 
                LoadEntityTypeMapping(nav.Clone(), setMapping, tableName, storageEntityContainerType); 
            }
            ValidateAllEntityTypesHaveFunctionMapping(nav.Clone(), setMapping); 
            //Add a schema error if the set mapping has no content
            if (setMapping.HasNoContent)
            {
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Emtpty_SetMap_1, entitySet.Name, 
                    StorageMappingErrorCode.EmptySetMapping, m_sourceLocation, navLineInfo, m_parsingErrors);
            } 
        } 

        // Ensure if any type has a function mapping, all types have function mappings 
        private void ValidateAllEntityTypesHaveFunctionMapping(XPathNavigator nav, StorageEntitySetMapping setMapping)
        {
            Set functionMappedTypes = new Set();
            foreach (StorageEntityTypeFunctionMapping functionMapping in setMapping.FunctionMappings) 
            {
                functionMappedTypes.Add(functionMapping.EntityType); 
            } 
            if (0 < functionMappedTypes.Count)
            { 
                Set unmappedTypes = new Set(MetadataHelper.GetTypeAndSubtypesOf(setMapping.Set.ElementType, EdmItemCollection, false /*includeAbstractTypes*/));
                unmappedTypes.Subtract(functionMappedTypes);

                // Remove abstract types 
                Set abstractTypes = new Set();
                foreach (EntityType unmappedType in unmappedTypes) 
                { 
                    if (unmappedType.Abstract)
                    { 
                        abstractTypes.Add(unmappedType);
                    }
                }
                unmappedTypes.Subtract(abstractTypes); 

                // See if there are any remaining entity types requiring function mapping 
                if (0 < unmappedTypes.Count) 
                {
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Invalid_Function_Mapping_MissingEntityType_1, 
                        StringUtil.ToCommaSeparatedString(unmappedTypes),
                        StorageMappingErrorCode.MissingFunctionMappingForEntityType, m_sourceLocation, (IXmlLineInfo)nav
                        , m_parsingErrors);
                } 
            }
        } 
 
        private bool TryParseEntityTypeAttribute(XPathNavigator nav, EntityType rootEntityType,
            Func typeNotAssignableMessage, 
            out Set isOfTypeEntityTypes, out Set entityTypes)
        {
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
            string entityTypeAttribute = GetAttributeValue(nav.Clone(), StorageMslConstructs.EntitySetMappingTypeNameAttribute); 

            isOfTypeEntityTypes = new Set(); 
            entityTypes = new Set(); 

            // get components of type declaration 
            var entityTypeNames = entityTypeAttribute.Split(StorageMslConstructs.TypeNameSperator).Select(s => s.Trim());

            // figure out each component
            foreach (var name in entityTypeNames) 
            {
                bool isTypeOf = name.StartsWith(StorageMslConstructs.IsTypeOf, StringComparison.Ordinal); 
                string entityTypeName; 
                if (isTypeOf)
                { 
                    // get entityTypeName of OfType(entityTypeName)
                    if (!name.EndsWith(StorageMslConstructs.IsTypeOfTerminal, StringComparison.Ordinal))
                    {
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_InvalidContent_IsTypeOfNotTerminated, 
                            StorageMappingErrorCode.InvalidEntityType, m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                        // No point in continuing with an error in the entitytype name 
                        return false; 
                    }
                    entityTypeName = name.Substring(StorageMslConstructs.IsTypeOf.Length); 
                    entityTypeName = entityTypeName.Substring(0, entityTypeName.Length - StorageMslConstructs.IsTypeOfTerminal.Length).Trim();
                }
                else
                { 
                    entityTypeName = name;
                } 
 
                // resolve aliases
                entityTypeName = GetAliasResolvedValue(entityTypeName); 

                EntityType entityType;
                if (!this.EdmItemCollection.TryGetItem(entityTypeName, out entityType))
                { 
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Entity_Type_1, entityTypeName,
                        StorageMappingErrorCode.InvalidEntityType, m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                    // No point in continuing with an error in the entitytype name 
                    return false;
                } 
                if (!(Helper.IsAssignableFrom(rootEntityType, entityType)))
                {
                    IXmlLineInfo lineInfo = xmlLineInfoNav;
                    AddToSchemaErrorWithMessage( 
                        typeNotAssignableMessage(entityType),
                        StorageMappingErrorCode.InvalidEntityType, m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                    //no point in continuing with an error in the entitytype name 
                    return false;
                } 

                // Using TypeOf construct on an abstract type that does not have
                // any concrete descendants is not allowed
                if (entityType.Abstract) 
                {
                    if (isTypeOf) 
                    { 
                        IEnumerable typeAndSubTypes = MetadataHelper.GetTypeAndSubtypesOf(entityType, EdmItemCollection, false /*includeAbstractTypes*/);
                        if (!typeAndSubTypes.GetEnumerator().MoveNext()) 
                        {
                            AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_AbstractEntity_IsOfType_1, entityType.FullName,
                                StorageMappingErrorCode.MappingForAbstractEntityType, m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                            return false; 
                        }
                    } 
                    else 
                    {
                        AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_AbstractEntity_Type_1, entityType.FullName, 
                            StorageMappingErrorCode.MappingForAbstractEntityType, m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                        return false;
                    }
                } 

                // Add type to set 
                if (isTypeOf) 
                {
                    isOfTypeEntityTypes.Add(entityType); 
                }
                else
                {
                    entityTypes.Add(entityType); 
                }
            } 
 
            // No failures
            return true; 
        }

        /// 
        /// The method loads the child nodes for the EntityType Mapping node 
        /// into the internal datastructures.
        ///  
        ///  
        /// 
        ///  
        /// 
        private void LoadEntityTypeMapping(XPathNavigator nav, StorageEntitySetMapping entitySetMapping, string tableName, EntityContainer storageEntityContainerType)
        {
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav; 

            //Create an EntityTypeMapping to hold the information for EntityType mapping. 
            StorageEntityTypeMapping entityTypeMapping = new StorageEntityTypeMapping(entitySetMapping); 

            //Get entity types 
            Set entityTypes;
            Set isOfTypeEntityTypes;
            EntityType rootEntityType = (EntityType)entitySetMapping.Set.ElementType;
            if (!TryParseEntityTypeAttribute(nav.Clone(), rootEntityType, 
                e => System.Data.Entity.Strings.Mapping_InvalidContent_Entity_Type_For_Entity_Set_3(e.FullName, rootEntityType.FullName, entitySetMapping.Set.Name),
                out isOfTypeEntityTypes, 
                out entityTypes)) 
            {
                // Return if we cannot parse entity types 
                return;
            }

            // Register all mapped types 
            foreach (EntityType entityType in entityTypes)
            { 
                entityTypeMapping.AddType(entityType); 
            }
            foreach (EntityType isOfTypeEntityType in isOfTypeEntityTypes) 
            {
                entityTypeMapping.AddIsOfType(isOfTypeEntityType);
            }
 
            //If the table name was not specified on the EntitySetMapping element nor the EntityTypeMapping element
            //than a table mapping fragment element should be present 
            //Loop through the TableMappingFragment elements and add them to EntityTypeMappings 
            if (String.IsNullOrEmpty(tableName))
            { 
                if (!nav.MoveToChild(XPathNodeType.Element))
                    return;
                do
                { 
                    if (nav.LocalName == StorageMslConstructs.ModificationFunctionMappingElement)
                    { 
                        LoadEntityTypeFunctionMapping(nav.Clone(), entitySetMapping, entityTypeMapping); 
                    }
                    else if (nav.LocalName != StorageMslConstructs.MappingFragmentElement) 
                    {
                        AddToSchemaErrors(Strings.Mapping_InvalidContent_Table_Expected_0,
                            StorageMappingErrorCode.TableMappingFragmentExpected, m_sourceLocation, xmlLineInfoNav
                            , m_parsingErrors); 
                    }
                    else 
                    { 
                        tableName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.MappingFragmentStoreEntitySetAttribute);
                        StorageMappingFragment fragment = LoadMappingFragment(nav.Clone(), entityTypeMapping, tableName, 
                        storageEntityContainerType);
                        //The fragment can be null in the cases of validation errors.
                        if (fragment != null)
                        { 
                            entityTypeMapping.AddFragment(fragment);
                        } 
                    } 
                } while (nav.MoveToNext(XPathNodeType.Element));
            } 
            else
            {
                if (nav.LocalName == StorageMslConstructs.ModificationFunctionMappingElement)
                { 
                    // function mappings cannot exist in the context of a table mapping
                    AddToSchemaErrors(Strings.Mapping_Invalid_Function_Mapping_In_Table_Context_0, 
                        StorageMappingErrorCode.InvalidTableNameAttributeWithFunctionMapping, 
                        m_sourceLocation, xmlLineInfoNav
                        , m_parsingErrors); 
                }

                StorageMappingFragment fragment = LoadMappingFragment(nav.Clone(), entityTypeMapping, tableName,
                    storageEntityContainerType); 
                //The fragment can be null in the cases of validation errors.
                if (fragment != null) 
                { 
                    entityTypeMapping.AddFragment(fragment);
                } 
            }
            entitySetMapping.AddTypeMapping(entityTypeMapping);
        }
 

        ///  
        /// Loads function mappings for entity type. 
        /// 
        ///  
        /// 
        /// 
        private void LoadEntityTypeFunctionMapping(XPathNavigator nav, StorageEntitySetMapping entitySetMapping,
            StorageEntityTypeMapping entityTypeMapping) 
        {
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav; 
 
            // Function mappings can apply only to a single type.
            if (entityTypeMapping.IsOfTypes.Count != 0 || entityTypeMapping.Types.Count != 1) 
            {
                AddToSchemaErrors(Strings.Mapping_Invalid_Function_Mapping_Multiple_Types_0,
                    StorageMappingErrorCode.InvalidFunctionMappingForMultipleTypes,
                    m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                return;
            } 
            EntityType entityType = (EntityType)entityTypeMapping.Types[0]; 
            //Function Mapping is not allowed to be defined for Abstract Types
            if (entityType.Abstract) 
            {
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_AbstractEntity_FunctionMapping_1, entityType.FullName,
                    StorageMappingErrorCode.MappingForAbstractEntityType, m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                return; 
            }
 
            // check that no mapping exists for this entity type already 
            foreach (StorageEntityTypeFunctionMapping existingFunctionMapping in entitySetMapping.FunctionMappings)
            { 
                if (existingFunctionMapping.EntityType.Equals(entityType))
                {
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Invalid_Function_Mapping_RedundantEntityTypeMapping_1,
                        entityType.Name, StorageMappingErrorCode.RedundantEntityTypeMappingInFunctionMapping, m_sourceLocation, xmlLineInfoNav 
                        , m_parsingErrors);
                    return; 
                } 
            }
 
            // create function loader
            FunctionMappingLoader functionLoader = new FunctionMappingLoader(this, entitySetMapping.Set);

            // Load all function definitions (for insert, delete and update) 
            StorageFunctionMapping deleteFunctionMapping = null;
            StorageFunctionMapping insertFunctionMapping = null; 
            StorageFunctionMapping updateFunctionMapping = null; 
            if (nav.MoveToChild(XPathNodeType.Element))
            { 
                do
                {
                    switch (nav.LocalName)
                    { 
                        case StorageMslConstructs.DeleteFunctionElement:
                            deleteFunctionMapping = functionLoader.LoadEntityTypeFunctionMapping(nav.Clone(), false, true, entityType); 
                            break; 
                        case StorageMslConstructs.InsertFunctionElement:
                            insertFunctionMapping = functionLoader.LoadEntityTypeFunctionMapping(nav.Clone(), true, false, entityType); 
                            break;
                        case StorageMslConstructs.UpdateFunctionElement:
                            updateFunctionMapping = functionLoader.LoadEntityTypeFunctionMapping(nav.Clone(), true, true, entityType);
                            break; 
                    }
                } while (nav.MoveToNext(XPathNodeType.Element)); 
            } 

            //We might be returned null because of schema errors 
            if (null == deleteFunctionMapping || null == insertFunctionMapping
                || null == updateFunctionMapping)
            {
                return; 
            }
 
            // Ensure that assocation set end mappings bind to the same end (e.g., in Person Manages Person 
            // self-association, ensure that the manager end or the report end is mapped but not both)
            Dictionary associationEnds = new Dictionary(); 
            foreach (StorageFunctionParameterBinding parameterBinding in Helper.Concat(
                deleteFunctionMapping.ParameterBindings,
                insertFunctionMapping.ParameterBindings,
                updateFunctionMapping.ParameterBindings)) 
            {
                if (null != parameterBinding.MemberPath.AssociationSetEnd) 
                { 
                    AssociationSet associationSet = parameterBinding.MemberPath.AssociationSetEnd.ParentAssociationSet;
                    // the "end" corresponds to the second member in the path, e.g. 
                    // ID<-Manager where Manager is the end
                    EdmMember currentEnd = parameterBinding.MemberPath.AssociationSetEnd.CorrespondingAssociationEndMember;

                    EdmMember existingEnd; 
                    if (associationEnds.TryGetValue(associationSet, out existingEnd) &&
                        existingEnd != currentEnd) 
                    { 
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_Invalid_Function_Mapping_MultipleEndsOfAssociationMapped_3(
                            currentEnd.Name, existingEnd.Name, associationSet.Name), 
                            StorageMappingErrorCode.InvalidFunctionMappingMultipleEndsOfAssociationMapped, m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                        return;
                    }
                    else 
                    {
                        associationEnds[associationSet] = currentEnd; 
                    } 
                }
            } 

            // Register the function mapping on the entity set mapping
            StorageEntityTypeFunctionMapping functionMapping = new StorageEntityTypeFunctionMapping(
                entityType, deleteFunctionMapping, insertFunctionMapping, updateFunctionMapping); 
            entitySetMapping.AddFunctionMapping(functionMapping);
        } 
 
        /// 
        /// The method loads the query view for the Set Mapping node 
        /// into the internal datastructures.
        /// 
        private bool LoadQueryView(XPathNavigator nav, StorageSetMapping setMapping)
        { 
            Debug.Assert(nav.LocalName == StorageMslConstructs.QueryViewElement);
 
            string queryView = nav.Value; 
            bool includeSubtypes = false;
 

            string typeNameString = StorageMappingItemLoader.GetAttributeValue(nav.Clone(), StorageMslConstructs.EntitySetMappingTypeNameAttribute);
            if (typeNameString != null)
            { 
                typeNameString = typeNameString.Trim();
            } 
 
            if (setMapping.QueryView == null)
            { 

                //QV must be the special-case first view
                if (typeNameString != null)
                { 
                    AddToSchemaErrorsWithMemberInfo(val => Strings.Mapping_TypeName_For_First_QueryView,
                        setMapping.Set.Name, StorageMappingErrorCode.TypeNameForFirstQueryView, 
                        m_sourceLocation, (IXmlLineInfo)nav, m_parsingErrors); 
                    return false;
                } 


                if (String.IsNullOrEmpty(queryView))
                { 
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Empty_QueryView_1,
                        setMapping.Set.Name, StorageMappingErrorCode.EmptyQueryView, 
                        m_sourceLocation, (IXmlLineInfo)nav, m_parsingErrors); 
                    return false;
                } 
                setMapping.QueryView = queryView;
                this.m_hasQueryViews = true;
                return true;
            } 
            else
            { 
                //QV must be typeof or typeofonly view 
                if (typeNameString == null || typeNameString.Trim().Length == 0)
                { 
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_QueryView_TypeName_Not_Defined,
                        setMapping.Set.Name, StorageMappingErrorCode.NoTypeNameForTypeSpecificQueryView,
                        m_sourceLocation, (IXmlLineInfo)nav, m_parsingErrors);
                    return false; 
                }
 
                //Get entity types 
                Set entityTypes;
                Set isOfTypeEntityTypes; 
                EntityType rootEntityType = (EntityType)setMapping.Set.ElementType;
                if (!TryParseEntityTypeAttribute(nav.Clone(), rootEntityType,
                    e => System.Data.Entity.Strings.Mapping_InvalidContent_Entity_Type_For_Entity_Set_3(e.FullName, rootEntityType.FullName, setMapping.Set.Name),
                    out isOfTypeEntityTypes, 
                    out entityTypes))
                { 
                    // Return if we cannot parse entity types 
                    return false;
                } 
                Debug.Assert(isOfTypeEntityTypes.Count > 0 || entityTypes.Count > 0);
                Debug.Assert(!(isOfTypeEntityTypes.Count > 0 && entityTypes.Count > 0));

                EntityType entityType; 
                if (isOfTypeEntityTypes.Count == 1)
                {   //OfType View 
                    entityType = isOfTypeEntityTypes.First(); 
                    includeSubtypes = true;
                } 
                else if (entityTypes.Count == 1)
                {   //OfTypeOnly View
                    entityType = entityTypes.First();
                    includeSubtypes = false; 
                }
                else 
                { 
                    //More than one type
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_QueryViewMultipleTypeInTypeName, setMapping.Set.ToString(), 
                        StorageMappingErrorCode.TypeNameContainsMultipleTypesForQueryView, m_sourceLocation, (IXmlLineInfo)nav, m_parsingErrors);
                    return false;
                }
 
                //Check if IsTypeOf(A) and A is the base type
                if (includeSubtypes && setMapping.Set.ElementType.EdmEquals(entityType)) 
                {   //Don't allow TypeOFOnly(a) if a is a base type. 
                    AddToSchemaErrorWithMemberAndStructure(Strings.Mapping_QueryView_For_Base_Type, entityType.ToString(), setMapping.Set.ToString(),
                        StorageMappingErrorCode.IsTypeOfQueryViewForBaseType, m_sourceLocation, (IXmlLineInfo)nav, m_parsingErrors); 
                    return false;
                }

                if (String.IsNullOrEmpty(queryView)) 
                {
                    if (includeSubtypes) 
                    { 
                        AddToSchemaErrorWithMemberAndStructure(Strings.Mapping_Empty_QueryView_OfType_2,
                            entityType.Name, setMapping.Set.Name, StorageMappingErrorCode.EmptyQueryView, 
                            m_sourceLocation, (IXmlLineInfo)nav, m_parsingErrors);
                        return false;
                    }
                    else 
                    {
                        AddToSchemaErrorWithMemberAndStructure(Strings.Mapping_Empty_QueryView_OfTypeOnly_2, 
                            setMapping.Set.Name, entityType.Name, StorageMappingErrorCode.EmptyQueryView, 
                            m_sourceLocation, (IXmlLineInfo)nav, m_parsingErrors);
                        return false; 
                    }
                }

 
                //Add it to the QV cache
                Triple key = new Triple(setMapping.Set, new Pair(entityType, includeSubtypes)); 
 

                if (setMapping.ContainsTypeSpecificQueryView(key)) 
                { //two QVs for the same type

                    EdmSchemaError error = null;
                    if (includeSubtypes) 
                    {
                        error = 
                            new EdmSchemaError( 
                                Strings.Mapping_QueryView_Duplicate_OfType(setMapping.Set, entityType),
                                (int)StorageMappingErrorCode.QueryViewExistsForEntitySetAndType, EdmSchemaErrorSeverity.Error, m_sourceLocation, 
                                ((IXmlLineInfo)nav).LineNumber, ((IXmlLineInfo)nav).LinePosition);
                    }
                    else
                    { 
                        error =
                            new EdmSchemaError( 
                                Strings.Mapping_QueryView_Duplicate_OfTypeOnly(setMapping.Set, entityType), 
                                (int)StorageMappingErrorCode.QueryViewExistsForEntitySetAndType, EdmSchemaErrorSeverity.Error, m_sourceLocation,
                                ((IXmlLineInfo)nav).LineNumber, ((IXmlLineInfo)nav).LinePosition); 
                    }

                    m_parsingErrors.Add(error);
                    return false; 
                }
 
                setMapping.AddTypeSpecificQueryView(key, queryView); 
                return true;
            } 
        }

        /// 
        /// The method loads the child nodes for the AssociationSet Mapping node 
        /// into the internal datastructures.
        ///  
        ///  
        /// 
        ///  
        private void LoadAssociationSetMapping(XPathNavigator nav, StorageEntityContainerMapping entityContainerMapping, EntityContainer storageEntityContainerType)
        {
            IXmlLineInfo navLineInfo = (IXmlLineInfo)nav;
 
            //Get the AssociationSet name
            string associationSetName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.AssociationSetMappingNameAttribute); 
            //Get the AssociationType name, need to parse it if the mapping information is being specified for multiple types 
            string associationTypeName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.AssociationSetMappingTypeNameAttribute);
            //Get the table name. This might be emptystring since the user can have a TableMappingFragment instead of this. 
            string tableName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.EntitySetMappingStoreEntitySetAttribute);
            //Try to find the AssociationSet with the given name in the EntityContainer.
            RelationshipSet relationshipSet;
            entityContainerMapping.EdmEntityContainer.TryGetRelationshipSetByName(associationSetName, false /*ignoreCase*/, out relationshipSet); 
            AssociationSet associationSet = relationshipSet as AssociationSet;
            //If no AssociationSet with the given name exists, than Add a schema error and return 
            if (associationSet == null) 
            {
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Association_Set_1, associationSetName, 
                    StorageMappingErrorCode.InvalidAssociationSet, m_sourceLocation, navLineInfo, m_parsingErrors);
                //There is no point in continuing the loading of association set map if the AssociationSetName has a problem
                return;
            } 

            if (entityContainerMapping.ContainsAssociationSetMapping(associationSet)) 
            { 
                //Can not add this set mapping since our storage dictionary won't allow
                //duplicate maps 
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Duplicate_CdmAssociationSet_StorageMap_1, associationSetName,
                    StorageMappingErrorCode.DuplicateSetMapping, m_sourceLocation, navLineInfo, m_parsingErrors);
                return;
 
            }
            //Create the AssociationSet Mapping which contains the mapping information for association set. 
            StorageAssociationSetMapping setMapping = new StorageAssociationSetMapping(associationSet, entityContainerMapping); 

            //Set the Start Line Information on Fragment 
            setMapping.StartLineNumber = navLineInfo.LineNumber;
            setMapping.StartLinePosition = navLineInfo.LinePosition;

 
            if (!nav.MoveToChild(XPathNodeType.Element))
            { 
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Emtpty_SetMap_1, associationSet.Name, 
                    StorageMappingErrorCode.EmptySetMapping, m_sourceLocation, navLineInfo, m_parsingErrors);
                return; 
            }

            entityContainerMapping.AddAssociationSetMapping(setMapping);
 
            //If there is a query view it has to be the first element
            if (nav.LocalName == StorageMslConstructs.QueryViewElement) 
            { 
                if (!(String.IsNullOrEmpty(tableName)))
                { 
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_TableName_QueryView_1, associationSetName,
                        StorageMappingErrorCode.TableNameAttributeWithQueryView, m_sourceLocation, navLineInfo, m_parsingErrors);
                    return;
                } 
                //Load the Query View into the set mapping,
                //if you get an error, return immediately since 
                //you go on, you could be giving lot of dubious errors 
                if (!LoadQueryView(nav.Clone(), setMapping))
                { 
                    return;
                }
                //If there are no more elements just return
                if (!nav.MoveToNext(XPathNodeType.Element)) 
                {
                    return; 
                } 
            }
 
            if ((nav.LocalName == StorageMslConstructs.EndPropertyMappingElement) ||
                     (nav.LocalName == StorageMslConstructs.ModificationFunctionMappingElement))
            {
                if ((String.IsNullOrEmpty(associationTypeName))) 
                {
                    AddToSchemaErrors(Strings.Mapping_InvalidContent_Association_Type_Empty_0, 
                        StorageMappingErrorCode.InvalidAssociationType, m_sourceLocation, navLineInfo, m_parsingErrors); 
                    return;
                } 
                //Load the AssociationTypeMapping into memory.
                LoadAssociationTypeMapping(nav.Clone(), setMapping, associationTypeName, tableName, storageEntityContainerType);
            }
            else if (nav.LocalName == StorageMslConstructs.ConditionElement) 
            {
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_AssociationSet_Condition_1, associationSetName, 
                    StorageMappingErrorCode.InvalidContent, m_sourceLocation, navLineInfo, m_parsingErrors); 
                return;
            } 
            else
            {

                Debug.Assert(false, "XSD validation should ensure this"); 
            }
        } 
 
        /// 
        /// The method loads a function import mapping element 
        /// 
        /// 
        /// 
        ///  
        private void LoadFunctionImportMapping(XPathNavigator nav, StorageEntityContainerMapping entityContainerMapping, EntityContainer storageEntityContainerType)
        { 
            IXmlLineInfo lineInfo = (IXmlLineInfo)(nav.Clone()); 

            // Get target (store) function 
            EdmFunction targetFunction;
            if (!TryGetFunctionImportStoreFunction(nav, out targetFunction))
            {
                return; 
            }
 
            // Get source (model) function 
            EdmFunction functionImport;
            if (!TryGetFunctionImportModelFunction(nav, entityContainerMapping, out functionImport)) 
            {
                return;
            }
 
            // Validate parameters are compatible between the store and model functions
            ValidateFunctionImportMappingParameters(nav, targetFunction, functionImport); 
 
            // Process type mapping information
            List typeMappings = new List(); 
            if (nav.MoveToChild(XPathNodeType.Element))
            {
                if (nav.LocalName == StorageMslConstructs.FunctionImportMappingResultMapping)
                { 
                    if (nav.MoveToChild(XPathNodeType.Element))
                    { 
                        do 
                        {
                            if (nav.LocalName == StorageMslConstructs.EntityTypeMappingElement) 
                            {
                                FunctionImportEntityTypeMapping typeMapping;
                                if (TryLoadFunctionImportEntityTypeMapping(nav.Clone(), targetFunction, functionImport, out typeMapping))
                                { 
                                    typeMappings.Add(typeMapping);
                                } 
                            } 
                        }
                        while (nav.MoveToNext(XPathNodeType.Element)); 
                    }
                }
            }
 
            // Add import mapping to list
            FunctionImportMapping mapping = new FunctionImportMapping(targetFunction, functionImport, typeMappings, this.EdmItemCollection); 
            entityContainerMapping.AddFunctionImportMapping(functionImport, mapping); 

            // Verify that all types can be produced 
            KeyToListMap unreachableEntityTypes;
            KeyToListMap unreachableIsTypeOfs;
            mapping.GetUnreachableTypes(EdmItemCollection, out unreachableEntityTypes, out unreachableIsTypeOfs);
 
            foreach (var unreachableEntityType in unreachableEntityTypes.KeyValuePairs)
            { 
                string lines = StringUtil.ToCommaSeparatedString(unreachableEntityType.Value.Select(li => li.LineNumber)); 
                AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_UnreachableType(unreachableEntityType.Key.FullName, lines),
                    StorageMappingErrorCode.MappingFunctionImportAmbiguousTypeConditions, m_sourceLocation, lineInfo, m_parsingErrors); 
            }
            foreach (var unreachableIsTypeOf in unreachableIsTypeOfs.KeyValuePairs)
            {
                string lines = StringUtil.ToCommaSeparatedString(unreachableIsTypeOf.Value.Select(li => li.LineNumber)); 
                string isTypeOfDescription = StorageMslConstructs.IsTypeOf + unreachableIsTypeOf.Key.FullName + StorageMslConstructs.IsTypeOfTerminal;
                AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_UnreachableIsTypeOf(isTypeOfDescription, lines), 
                    StorageMappingErrorCode.MappingFunctionImportAmbiguousTypeConditions, m_sourceLocation, lineInfo, m_parsingErrors); 
            }
 
            // Verify that function imports returning abstract types include explicit mappings
            EntityType returnEntityType;
            if (MetadataHelper.TryGetFunctionImportReturnEntityType(functionImport, out returnEntityType) &&
                returnEntityType.Abstract && 
                mapping.NormalizedEntityTypeMappings.Count == 0)
            { 
                AddToSchemaErrorWithMemberAndStructure(Strings.Mapping_InvalidContent_ImplicitMappingForAbstractReturnType_FunctionMapping_1, returnEntityType.FullName, 
                    functionImport.FullName, StorageMappingErrorCode.MappingForAbstractEntityType, m_sourceLocation, lineInfo, m_parsingErrors);
            } 
        }

        private bool TryGetFunctionImportStoreFunction(XPathNavigator nav, out EdmFunction targetFunction)
        { 
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
            targetFunction = null; 
 
            // Get the function name
            string functionName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.FunctionImportMappingFunctionNameAttribute); 

            // Try to find the function definition
            ReadOnlyCollection functionOverloads = this.StoreItemCollection.GetFunctions(functionName);
 
            if (functionOverloads.Count == 0)
            { 
                AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_StoreFunctionDoesNotExist(functionName), 
                    StorageMappingErrorCode.MappingFunctionImportStoreFunctionDoesNotExist,
                    m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                return false;
            }
            else if (1 < functionOverloads.Count)
            { 
                AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_StoreFunctionAmbiguous(functionName),
                    StorageMappingErrorCode.MappingFunctionImportStoreFunctionAmbiguous, 
                    m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                return false;
            } 

            targetFunction = functionOverloads.Single();

            // validate target function is supported (non-composable, etc.) 
            if (targetFunction.IsComposableAttribute)
            { 
                AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_TargetFunctionMustBeComposable(targetFunction.FullName), 
                    StorageMappingErrorCode.MappingFunctionImportTargetFunctionMustBeComposable,
                    m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                return false;
            }

            return true; 
        }
 
        private bool TryGetFunctionImportModelFunction(XPathNavigator nav, StorageEntityContainerMapping entityContainerMapping, 
            out EdmFunction functionImport)
        { 
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;

            // Get the function import name
            string functionImportName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.FunctionImportMappingFunctionImportNameAttribute); 

            // Try to find the function import 
            EntityContainer modelContainer = entityContainerMapping.EdmEntityContainer; 
            functionImport = null;
            foreach (EdmFunction functionImportCandidate in modelContainer.FunctionImports) 
            {
                if (functionImportCandidate.Name == functionImportName)
                {
                    functionImport = functionImportCandidate; 
                    break;
                } 
            } 
            if (null == functionImport)
            { 
                AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_FunctionImportDoesNotExist(functionImportName, entityContainerMapping.EdmEntityContainer.Name),
                    StorageMappingErrorCode.MappingFunctionImportFunctionImportDoesNotExist,
                    m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                return false; 
            }
 
            // check that no existing mapping exists for this function import 
            FunctionImportMapping targetFunctionCollision;
            if (entityContainerMapping.TryGetFunctionImportMapping(functionImport, out targetFunctionCollision)) 
            {
                AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_FunctionImportMappedMultipleTimes(functionImportName),
                    StorageMappingErrorCode.MappingFunctionImportFunctionImportMappedMultipleTimes,
                    m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                return false;
            } 
            return true; 
        }
 
        private void ValidateFunctionImportMappingParameters(XPathNavigator nav, EdmFunction targetFunction, EdmFunction functionImport)
        {
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
 
            foreach (FunctionParameter targetParameter in targetFunction.Parameters)
            { 
                // find corresponding import parameter 
                FunctionParameter importParameter;
                if (!functionImport.Parameters.TryGetValue(targetParameter.Name, false, out importParameter)) 
                {
                    AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_TargetParameterHasNoCorrespondingImportParameter(targetParameter.Name),
                        StorageMappingErrorCode.MappingFunctionImportTargetParameterHasNoCorrespondingImportParameter,
                        m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                }
                else 
                { 
                    // parameters must have the same direction (in|out)
                    if (targetParameter.Mode != importParameter.Mode) 
                    {
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_IncompatibleParameterMode(targetParameter.Name, targetParameter.Mode, importParameter.Mode),
                            StorageMappingErrorCode.MappingFunctionImportIncompatibleParameterMode,
                            m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                    }
 
                    // there are no type facets declared for function parameter types; 
                    // we simply verify the primitive type kind is equivalent
                    PrimitiveType importType = (PrimitiveType)importParameter.TypeUsage.EdmType; 
                    PrimitiveType cspaceTargetType = (PrimitiveType)StoreItemCollection.StoreProviderManifest.GetEdmType(targetParameter.TypeUsage).EdmType;

                    if (cspaceTargetType == null)
                    { 
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_ProviderReturnsNullType(targetParameter.Name),
                            StorageMappingErrorCode.MappingStoreProviderReturnsNullEdmType, 
                            m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                        return;
                    } 

                    if (cspaceTargetType.PrimitiveTypeKind != importType.PrimitiveTypeKind)
                    {
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_IncompatibleParameterType(targetParameter.Name, cspaceTargetType.Name, importType.Name), 
                            StorageMappingErrorCode.MappingFunctionImportIncompatibleParameterType,
                            m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
                    } 
                }
            } 

            foreach (FunctionParameter importParameter in functionImport.Parameters)
            {
                // find corresponding target parameter 
                FunctionParameter targetParameter;
                if (!targetFunction.Parameters.TryGetValue(importParameter.Name, false, out targetParameter)) 
                { 
                    AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_ImportParameterHasNoCorrespondingTargetParameter(importParameter.Name),
                        StorageMappingErrorCode.MappingFunctionImportImportParameterHasNoCorrespondingTargetParameter, 
                        m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                }
            }
        } 

        private bool TryLoadFunctionImportEntityTypeMapping(XPathNavigator nav, EdmFunction targetFunction, EdmFunction functionImport, 
            out FunctionImportEntityTypeMapping typeMapping) 
        {
            typeMapping = null; 
            IXmlLineInfo lineInfo = (IXmlLineInfo)(nav.Clone());

            // cannot specify an entity type mapping for a function import that does not return members
            // of an entity set 
            if (null == functionImport.EntitySet)
            { 
                AddToSchemaErrors(System.Data.Entity.Strings.Mapping_FunctionImport_EntityTypeMappingForFunctionNotReturningEntitySet( 
                    StorageMslConstructs.EntityTypeMappingElement, functionImport.FullName),
                    StorageMappingErrorCode.MappingFunctionImportEntityTypeMappingForFunctionNotReturningEntitySet, 
                    m_sourceLocation, lineInfo, m_parsingErrors);
            }

            // process entity type 
            Set isOfTypeEntityTypes;
            Set entityTypes; 
            { 
                string entityTypeName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.EntityTypeMappingTypeNameAttribute);
 
                // verify the entity type is appropriate to the function import's entity type
                EntityType rootEntityType;
                if (!MetadataHelper.TryGetFunctionImportReturnEntityType(functionImport, out rootEntityType) ||
                    !TryParseEntityTypeAttribute(nav.Clone(), rootEntityType, 
                        e => System.Data.Entity.Strings.Mapping_FunctionImport_InvalidContentEntityTypeForEntitySet(e.FullName, rootEntityType.FullName,
                            functionImport.EntitySet.Name, functionImport.FullName), 
                        out isOfTypeEntityTypes, 
                        out entityTypes))
                { 
                    return false;
                }
            }
 
            // process all conditions
            List conditions = new List(); 
            if (nav.MoveToChild(XPathNodeType.Element)) 
            {
                do 
                {
                    if (nav.LocalName == StorageMslConstructs.ConditionElement)
                    {
                        LoadFunctionImportEntityTypeMappingCondition(nav, conditions); 
                    }
                } 
                while (nav.MoveToNext(XPathNodeType.Element)); 
            }
 
            // make sure a single condition is specified per column
            HashSet columnsWithConditions = new HashSet();
            foreach (var condition in conditions)
            { 
                if (!columnsWithConditions.Add(condition.ColumnName))
                { 
                    AddToSchemaErrorWithMessage( 
                        System.Data.Entity.Strings.Mapping_FunctionImport_MultipleConditionsOnSingleColumn(condition.ColumnName),
                        StorageMappingErrorCode.MappingFunctionMultipleTypeConditionsForOneColumn, 
                        m_sourceLocation, lineInfo, m_parsingErrors);
                    return false;
                }
            } 

            typeMapping = new FunctionImportEntityTypeMapping(isOfTypeEntityTypes, entityTypes, conditions, lineInfo); 
            return true; 
        }
 
        private void LoadFunctionImportEntityTypeMappingCondition(XPathNavigator nav, List conditions)
        {
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
 
            string columnName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ConditionColumnNameAttribute);
            string value = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ConditionValueAttribute); 
            string isNull = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ConditionIsNullAttribute); 

            //Either Value or NotNull need to be specifid on the condition mapping but not both 
            if ((isNull != null) && (value != null))
            {
                AddToSchemaErrors(Strings.Mapping_InvalidContent_ConditionMapping_Both_Values_0,
                    StorageMappingErrorCode.ConditionError, m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
            }
            else if ((isNull == null) && (value == null)) 
            { 
                AddToSchemaErrors(Strings.Mapping_InvalidContent_ConditionMapping_Either_Values_0,
                    StorageMappingErrorCode.ConditionError, m_sourceLocation, xmlLineInfoNav, m_parsingErrors); 
            }
            else
            {
                if (isNull != null) 
                {
                    bool isNullValue = Convert.ToBoolean(isNull, CultureInfo.InvariantCulture); 
                    conditions.Add(new FunctionImportEntityTypeMappingConditionIsNull(columnName, isNullValue)); 
                }
                else 
                {
                    XPathNavigator columnValue = nav.Clone();
                    columnValue.MoveToAttribute(StorageMslConstructs.ConditionValueAttribute, string.Empty);
                    conditions.Add(new FunctionImportEntityTypeMappingConditionValue(columnName, columnValue)); 
                }
            } 
        } 

        ///  
        /// The method loads the child nodes for the AssociationType Mapping node
        /// into the internal datastructures.
        /// 
        ///  
        /// 
        ///  
        ///  
        /// 
        private void LoadAssociationTypeMapping(XPathNavigator nav, StorageAssociationSetMapping associationSetMapping, string associationTypeName, string tableName, EntityContainer storageEntityContainerType) 
        {
            IXmlLineInfo navLineInfo = (IXmlLineInfo)nav;

            //Get the association type for association type name specified in MSL 
            //If no AssociationType with the given name exists, add a schema error and return
            AssociationType associationType; 
            this.EdmItemCollection.TryGetItem(associationTypeName, out associationType); 
            if (associationType == null)
            { 
                //There is no point in continuing loading if the AssociationType is null
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Association_Type_1, associationTypeName,
                    StorageMappingErrorCode.InvalidAssociationType, m_sourceLocation, navLineInfo, m_parsingErrors);
                return; 
            }
            //Verify that AssociationType specified should be the declared type of 
            //AssociationSet or a derived Type of it. 
            //Future Enhancement : Change the code to use EdmEquals
            if ((!(associationSetMapping.Set.ElementType.Equals(associationType)))) 
            {
                AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_Invalid_Association_Type_For_Association_Set_3(associationTypeName,
                    associationSetMapping.Set.ElementType.FullName, associationSetMapping.Set.Name),
                    StorageMappingErrorCode.DuplicateTypeMapping, m_sourceLocation, navLineInfo, m_parsingErrors); 
                return;
            } 
 
            //Create an AssociationTypeMapping to hold the information for AssociationType mapping.
            StorageAssociationTypeMapping associationTypeMapping = new StorageAssociationTypeMapping(associationType, associationSetMapping); 
            associationSetMapping.AddTypeMapping(associationTypeMapping);
            //If the table name was not specified on the AssociationSetMapping element
            //Then there should have been a query view. Otherwise throw.
            if (String.IsNullOrEmpty(tableName) && (associationSetMapping.QueryView == null)) 
            {
                AddToSchemaErrors(Strings.Mapping_InvalidContent_Table_Expected_0, StorageMappingErrorCode.InvalidTable, 
                    m_sourceLocation, navLineInfo, m_parsingErrors); 
            }
            else 
            {
                StorageMappingFragment fragment = LoadAssociationMappingFragment(nav.Clone(), associationSetMapping, associationTypeMapping, tableName, storageEntityContainerType);
                if (fragment != null)
                { 
                    //Fragment can be null because of validation errors
                    associationTypeMapping.AddFragment(fragment); 
                } 
            }
        } 

        /// 
        /// Loads function mappings for the entity type.
        ///  
        /// 
        ///  
        ///  
        private void LoadAssociationTypeFunctionMapping(XPathNavigator nav, StorageAssociationSetMapping associationSetMapping,
            StorageAssociationTypeMapping associationTypeMapping) 
        {
            // create function loader
            FunctionMappingLoader functionLoader = new FunctionMappingLoader(this, associationSetMapping.Set);
 
            // Load all function definitions (for insert, delete and update)
            StorageFunctionMapping deleteFunctionMapping = null; 
            StorageFunctionMapping insertFunctionMapping = null; 
            if (nav.MoveToChild(XPathNodeType.Element))
            { 
                do
                {
                    switch (nav.LocalName)
                    { 
                        case StorageMslConstructs.DeleteFunctionElement:
                            deleteFunctionMapping = functionLoader.LoadAssociationSetFunctionMapping(nav.Clone(), false); 
                            break; 
                        case StorageMslConstructs.InsertFunctionElement:
                            insertFunctionMapping = functionLoader.LoadAssociationSetFunctionMapping(nav.Clone(), true); 
                            break;
                    }
                } while (nav.MoveToNext(XPathNodeType.Element));
            } 

            //We might be returned null because of schema errors 
            if (null == deleteFunctionMapping || null == insertFunctionMapping) 
            {
                return; 
            }

            // register function mapping information
            associationSetMapping.FunctionMapping = new StorageAssociationSetFunctionMapping( 
                (AssociationSet)associationSetMapping.Set, deleteFunctionMapping, insertFunctionMapping);
        } 
 
        /// 
        /// The method loads the child nodes for the TableMappingFragment under the EntityType node 
        /// into the internal datastructures.
        /// 
        /// 
        ///  
        /// 
        ///  
        ///  
        private StorageMappingFragment LoadMappingFragment(XPathNavigator nav, StorageEntityTypeMapping typeMapping, string tableName
            , EntityContainer storageEntityContainerType) 
        {
            IXmlLineInfo navLineInfo = (IXmlLineInfo)nav;

            //First make sure that there was no QueryView specified for this Set 
            if (typeMapping.SetMapping.QueryView != null)
            { 
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_QueryView_PropertyMaps_1, typeMapping.SetMapping.Set.Name, 
                    StorageMappingErrorCode.PropertyMapsWithQueryView, m_sourceLocation, navLineInfo, m_parsingErrors);
                return null; 
            }

            //Get the table type that represents this table
            EntitySet tableMember; 
            storageEntityContainerType.TryGetEntitySetByName(tableName, false /*ignoreCase*/, out tableMember);
            if (tableMember == null) 
            { 
                //There is no point in continuing loading if the Table on S side can not be found
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Table_1, tableName, 
                    StorageMappingErrorCode.InvalidTable, m_sourceLocation, navLineInfo, m_parsingErrors);
                return null;
            }
            EntityType tableType = tableMember.ElementType; 
            //Create a table mapping fragment to hold the mapping information for a TableMappingFragment node
            StorageMappingFragment fragment = new StorageMappingFragment(tableMember, typeMapping); 
            //Set the Start Line Information on Fragment 
            fragment.StartLineNumber = navLineInfo.LineNumber;
            fragment.StartLinePosition = navLineInfo.LinePosition; 

            //Go through the property mappings for this TableMappingFragment and load them in memory.
            if (nav.MoveToChild(XPathNodeType.Element))
            { 
                do
                { 
                    //need to get the type that this member exists in 
                    EdmType containerType = null;
                    string propertyName = StorageMappingItemLoader.GetAttributeValue(nav.Clone(), StorageMslConstructs.ComplexPropertyNameAttribute); 
                    //PropertyName could be null for Condition Maps
                    if (propertyName != null)
                    {
                        containerType = typeMapping.GetContainerType(propertyName); 
                    }
                    switch (nav.LocalName) 
                    { 
                        case StorageMslConstructs.ScalarPropertyElement:
                            StorageScalarPropertyMapping scalarMap = LoadScalarPropertyMapping(nav.Clone(), 
                                containerType, tableType);
                            if (scalarMap != null)
                            {
                                //scalarMap can be null in invalid cases 
                                fragment.AddProperty(scalarMap);
                            } 
                            break; 
                        case StorageMslConstructs.ComplexPropertyElement:
                            StorageComplexPropertyMapping complexMap = 
                                LoadComplexPropertyMapping(nav.Clone(), containerType, tableType);
                            //Complex Map can be null in case of invalid MSL files.
                            if (complexMap != null)
                            { 
                                fragment.AddProperty(complexMap);
                            } 
                            break; 
                        case StorageMslConstructs.ConditionElement:
                            StorageConditionPropertyMapping conditionMap = 
                                LoadConditionPropertyMapping(nav.Clone(), containerType, tableType);
                            //conditionMap can be null in cases of invalid Map
                            if (conditionMap != null)
                            { 
                                if (!fragment.AddConditionProperty(conditionMap))
                                { 
                                    EdmProperty conditionMember = (conditionMap.EdmProperty != null) ? conditionMap.EdmProperty : conditionMap.ColumnProperty; 

                                    AddToSchemaErrorsWithMemberInfo( 
                                                        Strings.Mapping_InvalidContent_Duplicate_Condition_Member_1,
                                                        conditionMember.Name,
                                                        StorageMappingErrorCode.ConditionError,
                                                        m_sourceLocation, 
                                                        navLineInfo,
                                                        m_parsingErrors); 
                                    return null; 
                                }
                            } 
                            break;
                        default:
                            AddToSchemaErrors(Strings.Mapping_InvalidContent_General_0,
                                StorageMappingErrorCode.InvalidContent, m_sourceLocation, navLineInfo, m_parsingErrors); 
                            break;
                    } 
                } while (nav.MoveToNext(XPathNodeType.Element)); 
            }
            //Set the end Line Information on Fragment 
            fragment.EndLineNumber = navLineInfo.LineNumber;
            fragment.EndLinePosition = navLineInfo.LinePosition;
            nav.MoveToChild(XPathNodeType.Element);
            return fragment; 
        }
 
        ///  
        /// The method loads the child nodes for the TableMappingFragment under the AssociationType node
        /// into the internal datastructures. 
        /// 
        /// 
        /// 
        ///  
        /// 
        ///  
        ///  
        private StorageMappingFragment LoadAssociationMappingFragment(XPathNavigator nav, StorageAssociationSetMapping setMapping, StorageAssociationTypeMapping typeMapping, string tableName, EntityContainer storageEntityContainerType)
        { 
            IXmlLineInfo navLineInfo = (IXmlLineInfo)nav;
            StorageMappingFragment fragment = null;
            EntityType tableType = null;
 
            //If there is a query view, Dont create a mapping fragment since there should n't be one
            if (setMapping.QueryView == null) 
            { 
                //Get the table type that represents this table
                EntitySet tableMember; 
                storageEntityContainerType.TryGetEntitySetByName(tableName, false /*ignoreCase*/, out tableMember);
                if (tableMember == null)
                {
                    //There is no point in continuing loading if the Table is null 
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Table_1, tableName,
                        StorageMappingErrorCode.InvalidTable, m_sourceLocation, navLineInfo, m_parsingErrors); 
                    return null; 
                }
                tableType = tableMember.ElementType; 
                //Create a Mapping fragment and load all the End node under it
                fragment = new StorageMappingFragment(tableMember, typeMapping);
                //Set the Start Line Information on Fragment, For AssociationSet there are
                //no fragments, so the start Line Info is same as that of Set 
                fragment.StartLineNumber = setMapping.StartLineNumber;
                fragment.StartLinePosition = setMapping.StartLinePosition; 
            } 

            do 
            {
                //need to get the type that this member exists in
                switch (nav.LocalName)
                { 
                    case StorageMslConstructs.EndPropertyMappingElement:
                        //Make sure that there was no QueryView specified for this Set 
                        if (setMapping.QueryView != null) 
                        {
                            AddToSchemaErrorsWithMemberInfo(Strings.Mapping_QueryView_PropertyMaps_1, setMapping.Set.Name, 
                                StorageMappingErrorCode.PropertyMapsWithQueryView, m_sourceLocation, navLineInfo, m_parsingErrors);
                            return null;
                        }
                        string endName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.EndPropertyMappingNameAttribute); 
                        EdmMember endMember = null;
                        typeMapping.AssociationType.Members.TryGetValue(endName, false, out endMember); 
                        AssociationEndMember end = endMember as AssociationEndMember; 
                        if (end == null)
                        { 
                            //Don't try to load the end property map if the end property itself is null
                            AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_End_1, endName,
                                StorageMappingErrorCode.InvalidEdmMember, m_sourceLocation, navLineInfo, m_parsingErrors);
                            continue; 
                        }
                        fragment.AddProperty((LoadEndPropertyMapping(nav.Clone(), end, tableType))); 
                        break; 
                    case StorageMslConstructs.ConditionElement:
                        //Make sure that there was no QueryView specified for this Set 
                        if (setMapping.QueryView != null)
                        {
                            AddToSchemaErrorsWithMemberInfo(Strings.Mapping_QueryView_PropertyMaps_1, setMapping.Set.Name,
                                StorageMappingErrorCode.PropertyMapsWithQueryView, m_sourceLocation, navLineInfo, m_parsingErrors); 
                            return null;
                        } 
                        //Need to add validation for conditions in Association mapping fragment. 
                        StorageConditionPropertyMapping conditionMap =
                            LoadConditionPropertyMapping(nav.Clone(), null /*containerType*/, tableType); 
                        //conditionMap can be null in cases of invalid Map
                        if (conditionMap != null)
                        {
                            if (!fragment.AddConditionProperty(conditionMap)) 
                            {
                                EdmProperty conditionMember = (conditionMap.EdmProperty != null) ? conditionMap.EdmProperty : conditionMap.ColumnProperty; 
 
                                AddToSchemaErrorsWithMemberInfo(
                                                Strings.Mapping_InvalidContent_Duplicate_Condition_Member_1, 
                                                conditionMember.Name,
                                                StorageMappingErrorCode.ConditionError,
                                                m_sourceLocation,
                                                navLineInfo, 
                                                m_parsingErrors);
                                return null; 
                            } 
                        }
                        break; 
                    case StorageMslConstructs.ModificationFunctionMappingElement:
                        LoadAssociationTypeFunctionMapping(nav.Clone(), setMapping, typeMapping);
                        break;
                    default: 
                        AddToSchemaErrors(Strings.Mapping_InvalidContent_General_0,
                            StorageMappingErrorCode.InvalidContent, m_sourceLocation, navLineInfo, m_parsingErrors); 
                        break; 
                }
            } while (nav.MoveToNext(XPathNodeType.Element)); 

            if (setMapping.QueryView == null)
            {
                Debug.Assert(fragment != null, "There should be Fragment when there is no query view"); 
                //Set the end Line Information on Fragment
                fragment.EndLineNumber = navLineInfo.LineNumber; 
                fragment.EndLinePosition = navLineInfo.LinePosition; 
            }
            return fragment; 
        }

        /// 
        /// The method loads the ScalarProperty mapping 
        /// into the internal datastructures.
        ///  
        ///  
        /// 
        ///  
        /// 
        private StorageScalarPropertyMapping LoadScalarPropertyMapping(XPathNavigator nav, EdmType containerType, EntityType tableType)
        {
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav; 

            //Get the property name from MSL. 
            string propertyName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ScalarPropertyNameAttribute); 
            EdmProperty member = null;
            if (!String.IsNullOrEmpty(propertyName)) 
            {
                //If the container type is a collection type, there wouldn't be a member to represent this scalar property
                if (containerType == null || !(Helper.IsCollectionType(containerType)))
                { 
                    //If container type is null that means we have not found the member in any of the IsOfTypes.
                    if (containerType != null) 
                    { 
                        if (Helper.IsRefType(containerType))
                        { 
                            RefType refType = (RefType)containerType;
                            ((EntityType)refType.ElementType).Properties.TryGetValue(propertyName, false /*ignoreCase*/, out member);
                        }
                        else 
                        {
                            EdmMember tempMember; 
                            (containerType as StructuralType).Members.TryGetValue(propertyName, false, out tempMember); 
                            member = tempMember as EdmProperty;
                        } 
                    }
                    if (member == null)
                    {
                        AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Cdm_Member_1, propertyName, 
                            StorageMappingErrorCode.InvalidEdmMember, m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
                    } 
                } 
            }
            //Get the property from Storeside 
            string columnName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ScalarPropertyColumnNameAttribute);
            Debug.Assert(columnName != null, "XSD validation should have caught this");
            EdmProperty columnMember;
            tableType.Properties.TryGetValue(columnName, false, out columnMember); 
            if (columnMember == null)
            { 
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Column_1, columnName, 
                    StorageMappingErrorCode.InvalidStorageMember, m_sourceLocation, xmlLineInfoNav, m_parsingErrors);
            } 
            //Don't create scalar property map if the property or column metadata is null
            if ((member == null) || (columnMember == null))
            {
                return null; 
            }
 
            if (!Helper.IsPrimitiveType(member.TypeUsage.EdmType)) 
            {
                EdmSchemaError error = new EdmSchemaError( 
                    System.Data.Entity.Strings.Mapping_Invalid_CSide_ScalarProperty_1(
                        member.Name),
                    (int)StorageMappingErrorCode.InvalidTypeInScalarProperty,
                    EdmSchemaErrorSeverity.Error, 
                    m_sourceLocation,
                    xmlLineInfoNav.LineNumber, 
                    xmlLineInfoNav.LinePosition); 
                m_parsingErrors.Add(error);
                return null; 
            }

            ValidateAndUpdateScalarMemberMapping(member, columnMember, xmlLineInfoNav);
            StorageScalarPropertyMapping scalarPropertyMapping = new StorageScalarPropertyMapping(member, columnMember); 
            return scalarPropertyMapping;
        } 
 
        /// 
        /// The method loads the ComplexProperty mapping 
        /// into the internal datastructures.
        /// 
        /// 
        ///  
        /// 
        ///  
        private StorageComplexPropertyMapping LoadComplexPropertyMapping(XPathNavigator nav, EdmType containerType, EntityType tableType) 
        {
            IXmlLineInfo navLineInfo = (IXmlLineInfo)nav; 

            CollectionType collectionType = containerType as CollectionType;
            //Get the property name from MSL
            string propertyName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ComplexPropertyNameAttribute); 
            //Get the member metadata from the contianer type passed in.
            //But if the continer type is collection type, there would n't be any member to represent the member. 
            EdmProperty member = null; 
            EdmType memberType = null;
            //If member specified the type name, it takes precedence 
            string memberTypeName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ComplexTypeMappingTypeNameAttribute);
            StructuralType containerStructuralType = containerType as StructuralType;

            if (String.IsNullOrEmpty(memberTypeName)) 
            {
                if (collectionType == null) 
                { 
                    EdmMember tempMember;
                    containerStructuralType.Members.TryGetValue(propertyName, false /*ignoreCase*/, out tempMember); 
                    member = tempMember as EdmProperty;
                    if (member == null)
                    {
                        AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Cdm_Member_1, propertyName, 
                            StorageMappingErrorCode.InvalidEdmMember, m_sourceLocation, navLineInfo, m_parsingErrors);
                    } 
                    memberType = member.TypeUsage.EdmType; 
                }
                else 
                {
                    memberType = collectionType.TypeUsage.EdmType;
                }
            } 
            else
            { 
                //If container type is null that means we have not found the member in any of the IsOfTypes. 
                if (containerType != null)
                { 
                    EdmMember tempMember;
                    containerStructuralType.Members.TryGetValue(propertyName, false /*ignoreCase*/, out tempMember);
                    member = tempMember as EdmProperty;
                } 
                if (member == null)
                { 
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Cdm_Member_1, propertyName, 
                        StorageMappingErrorCode.InvalidEdmMember, m_sourceLocation, navLineInfo, m_parsingErrors);
                } 
                this.EdmItemCollection.TryGetItem(memberTypeName, out memberType);
                memberType = memberType as ComplexType;
                // If member type is null, that means the type wasn't found in the workspace
                if (memberType == null) 
                {
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Complex_Type_1, memberTypeName, 
                        StorageMappingErrorCode.InvalidComplexType, m_sourceLocation, navLineInfo, m_parsingErrors); 
                }
            } 

            StorageComplexPropertyMapping complexPropertyMapping = new StorageComplexPropertyMapping(member);

            XPathNavigator cloneNav = nav.Clone(); 
            bool hasComplexTypeMappingElements = false;
            if (cloneNav.MoveToChild(XPathNodeType.Element)) 
            { 
                if (cloneNav.LocalName == StorageMslConstructs.ComplexTypeMappingElement)
                { 
                    hasComplexTypeMappingElements = true;
                }
            }
 
            //There is no point in continuing if the complex member or complex member type is null
            if ((member == null) || (memberType == null)) 
            { 
                return null;
            } 

            if (hasComplexTypeMappingElements)
            {
                nav.MoveToChild(XPathNodeType.Element); 
                do
                { 
                    complexPropertyMapping.AddTypeMapping(LoadComplexTypeMapping(nav.Clone(), null, tableType)); 
                } while (nav.MoveToNext(XPathNodeType.Element));
            } 
            else
            {
                complexPropertyMapping.AddTypeMapping(LoadComplexTypeMapping(nav.Clone(), memberType, tableType));
            } 
            return complexPropertyMapping;
        } 
 

 
        /// 
        /// 
        /// 
        ///  
        /// 
        private StorageComplexTypeMapping LoadComplexTypeMapping(XPathNavigator nav, EdmType type, EntityType tableType) 
        { 
            //Get the IsPartial attribute from MSL
            bool isPartial = false; 
            string partialAttribute = StorageMappingItemLoader.GetAttributeValue(nav.Clone(), StorageMslConstructs.ComplexPropertyIsPartialAttribute);
            if (!String.IsNullOrEmpty(partialAttribute))
            {
                //XSD validation should have guarenteed that the attribute value can only be true or false 
                Debug.Assert(partialAttribute == "true" || partialAttribute == "false");
                isPartial = Convert.ToBoolean(partialAttribute, System.Globalization.CultureInfo.InvariantCulture); 
            } 
            //Create an ComplexTypeMapping to hold the information for Type mapping.
            StorageComplexTypeMapping typeMapping = new StorageComplexTypeMapping(isPartial); 
            if (type != null)
            {
                typeMapping.AddType(type as ComplexType);
            } 
            else
            { 
                Debug.Assert(nav.LocalName == StorageMslConstructs.ComplexTypeMappingElement); 
                string typeName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ComplexTypeMappingTypeNameAttribute);
                int index = typeName.IndexOf(StorageMslConstructs.TypeNameSperator); 
                string currentTypeName = null;
                do
                {
                    if (index != -1) 
                    {
                        currentTypeName = typeName.Substring(0, index); 
                        typeName = typeName.Substring(index + 1, (typeName.Length - (index + 1))); 
                    }
                    else 
                    {
                        currentTypeName = typeName;
                        typeName = string.Empty;
                    } 

                    int isTypeOfIndex = currentTypeName.IndexOf(StorageMslConstructs.IsTypeOf, StringComparison.Ordinal); 
                    if (isTypeOfIndex == 0) 
                    {
                        currentTypeName = currentTypeName.Substring(StorageMslConstructs.IsTypeOf.Length, (currentTypeName.Length - (StorageMslConstructs.IsTypeOf.Length + 1))); 
                        currentTypeName = GetAliasResolvedValue(currentTypeName);
                    }
                    else
                    { 
                        currentTypeName = GetAliasResolvedValue(currentTypeName);
                    } 
                    ComplexType complexType; 
                    this.EdmItemCollection.TryGetItem(currentTypeName, out complexType);
                    if (complexType == null) 
                    {
                        AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_Complex_Type_1, currentTypeName,
                            StorageMappingErrorCode.InvalidComplexType, m_sourceLocation, (IXmlLineInfo)nav, m_parsingErrors);
                        index = typeName.IndexOf(StorageMslConstructs.TypeNameSperator); 
                        continue;
                    } 
                    if (isTypeOfIndex == 0) 
                    {
                        typeMapping.AddIsOfType(complexType); 
                    }
                    else
                    {
                        typeMapping.AddType(complexType); 
                    }
                    index = typeName.IndexOf(StorageMslConstructs.TypeNameSperator); 
                } while (typeName.Length != 0); 
            }
 
            //Now load the children of ComplexTypeMapping
            if (nav.MoveToChild(XPathNodeType.Element))
            {
                do 
                {
                    EdmType containerType = typeMapping.GetOwnerType(StorageMappingItemLoader.GetAttributeValue(nav.Clone(), StorageMslConstructs.ComplexPropertyNameAttribute)); 
                    switch (nav.LocalName) 
                    {
                        case StorageMslConstructs.ScalarPropertyElement: 
                            StorageScalarPropertyMapping scalarMap =
                                LoadScalarPropertyMapping(nav.Clone(), containerType, tableType);
                            //ScalarMap can be null in case of invalid MSL files
                            if (scalarMap != null) 
                            {
                                typeMapping.AddProperty(scalarMap); 
                            } 
                            break;
                        case StorageMslConstructs.ComplexPropertyElement: 
                            StorageComplexPropertyMapping complexMap =
                                LoadComplexPropertyMapping(nav.Clone(), containerType, tableType);
                            //complexMap can be null in case of invalid maps
                            if (complexMap != null) 
                            {
                                typeMapping.AddProperty(complexMap); 
                            } 
                            break;
                        case StorageMslConstructs.ConditionElement: 
                            StorageConditionPropertyMapping conditionMap =
                                LoadConditionPropertyMapping(nav.Clone(), containerType, tableType);
                            if (conditionMap != null)
                            { 
                                typeMapping.AddConditionProperty(conditionMap);
                            } 
                            break; 
                        default:
                            throw System.Data.Entity.Error.NotSupported(); 
                    }
                } while (nav.MoveToNext(XPathNodeType.Element));
            }
            return typeMapping; 

        } 
 
        /// 
        /// The method loads the EndProperty mapping 
        /// into the internal datastructures.
        /// 
        /// 
        ///  
        /// 
        ///  
        private StorageEndPropertyMapping LoadEndPropertyMapping(XPathNavigator nav, AssociationEndMember end, EntityType tableType) 
        {
            //FutureEnhancement : Change End Property Mapping to not derive from 
            //                    StoragePropertyMapping
            StorageEndPropertyMapping endMapping = new StorageEndPropertyMapping(null);
            endMapping.EndMember = end;
 
            nav.MoveToChild(XPathNodeType.Element);
            do 
            { 
                switch (nav.LocalName)
                { 
                    case StorageMslConstructs.ScalarPropertyElement:
                        RefType endRef = end.TypeUsage.EdmType as RefType;
                        Debug.Assert(endRef != null);
                        EntityTypeBase containerType = endRef.ElementType; 
                        StorageScalarPropertyMapping scalarMap =
                            LoadScalarPropertyMapping(nav.Clone(), containerType, tableType); 
                        //Scalar Property Mapping can be null 
                        //in case of invalid MSL files.
                        if (scalarMap != null) 
                        {
                            endMapping.AddProperty(scalarMap);
                        }
                        break; 
                    default:
                        Debug.Fail("XSD validation should have ensured that End EdmProperty Maps only have Schalar properties"); 
                        break; 
                }
            } while (nav.MoveToNext(XPathNodeType.Element)); 
            return endMapping;
        }

        ///  
        /// The method loads the ConditionProperty mapping
        /// into the internal datastructures. 
        ///  
        /// 
        ///  
        /// 
        /// 
        private StorageConditionPropertyMapping LoadConditionPropertyMapping(XPathNavigator nav, EdmType containerType, EntityType tableType)
        { 
            //Get the CDM side property name.
            string propertyName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ConditionNameAttribute); 
            //Get the Store side property name from Storeside 
            string columnName = GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ConditionColumnNameAttribute);
 
            IXmlLineInfo navLineInfo = (IXmlLineInfo)nav;

            //Either the property name or column name can be specified but both can not be.
            if ((propertyName != null) && (columnName != null)) 
            {
                AddToSchemaErrors(Strings.Mapping_InvalidContent_ConditionMapping_Both_Members_0, 
                    StorageMappingErrorCode.ConditionError, m_sourceLocation, navLineInfo, m_parsingErrors); 
                return null;
            } 
            if ((propertyName == null) && (columnName == null))
            {
                AddToSchemaErrors(Strings.Mapping_InvalidContent_ConditionMapping_Either_Members_0,
                    StorageMappingErrorCode.ConditionError, m_sourceLocation, navLineInfo, m_parsingErrors); 
                return null;
            } 
 
            EdmProperty member = null;
            //Get the CDM EdmMember reprsented by the name specified. 
            if (propertyName != null)
            {
                EdmMember tempMember;
                //If container type is null that means we have not found the member in any of the IsOfTypes. 
                if (containerType != null)
                { 
                    ((StructuralType)containerType).Members.TryGetValue(propertyName, false /*ignoreCase*/, out tempMember); 
                    member = tempMember as EdmProperty;
                } 
            }

            //Get the column EdmMember represented by the column name specified
            EdmProperty columnMember = null; 
            if (columnName != null)
            { 
                tableType.Properties.TryGetValue(columnName, false, out columnMember); 
            }
 
            //Get the member for which the condition is being specified
            EdmProperty conditionMember = (columnMember != null) ? columnMember : member;
            if (conditionMember == null)
            { 
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_ConditionMapping_InvalidMember_1, ((columnName != null) ? columnName : propertyName),
                    StorageMappingErrorCode.ConditionError, m_sourceLocation, navLineInfo, m_parsingErrors); 
                return null; 
            }
 
            Nullable isNullValue = null;
            object value = null;
            //Get the attribute value for IsNull attribute
            string isNullAttribute = StorageMappingItemLoader.GetAttributeValue(nav.Clone(), StorageMslConstructs.ConditionIsNullAttribute); 

            //Get strongly Typed value if the condition was specified for a specific condition 
            EdmType edmType = conditionMember.TypeUsage.EdmType; 
            if (Helper.IsPrimitiveType(edmType))
            { 
                //Decide if the member is of a type that we would allow a condition on.
                //First convert the type to C space, if this is a condition in s space( before checking this).
                TypeUsage cspaceTypeUsage;
                if (conditionMember.DeclaringType.GetDataSpace() == DataSpace.SSpace) 
                {
                    cspaceTypeUsage = StoreItemCollection.StoreProviderManifest.GetEdmType(conditionMember.TypeUsage); 
                    if (cspaceTypeUsage == null) 
                    {
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_ProviderReturnsNullType(conditionMember.Name), 
                            StorageMappingErrorCode.MappingStoreProviderReturnsNullEdmType,
                            m_sourceLocation, navLineInfo, m_parsingErrors);
                        return null;
                    } 
                }
                else 
                { 
                    cspaceTypeUsage = conditionMember.TypeUsage;
                } 
                PrimitiveType memberType = ((PrimitiveType)cspaceTypeUsage.EdmType);
                Type clrMemberType = memberType.ClrEquivalentType;
                PrimitiveTypeKind primitiveTypeKind = memberType.PrimitiveTypeKind;
                //Only a subset of primitive types can be used in Conditions that are specified over values. 
                //IsNull conditions can be specified on any primitive types
                if ((isNullAttribute == null) && !IsTypeSupportedForCondition(primitiveTypeKind)) 
                { 
                    AddToSchemaErrorWithMemberAndStructure(Strings.Mapping_InvalidContent_ConditionMapping_InvalidPrimitiveTypeKind_2,
                        conditionMember.Name, memberType.FullName, StorageMappingErrorCode.ConditionError, 
                        m_sourceLocation, navLineInfo, m_parsingErrors);
                    return null;
                }
                Debug.Assert(clrMemberType != null, "Scalar Types should have associated clr type"); 
                //If the value is not compatible with the type, just add an error and return
                if(!StorageMappingItemLoader.TryGetTypedAttributeValue(nav.Clone(), StorageMslConstructs.ConditionValueAttribute, clrMemberType, m_sourceLocation, m_parsingErrors, out value)) 
                { 
                    return null;
                } 
            }
            else if (Helper.IsEnumType(edmType))
            {
                // Enumeration type - get the actual value 
                value = StorageMappingItemLoader.GetEnumAttributeValue(nav.Clone(), StorageMslConstructs.ConditionValueAttribute, (EnumType)edmType, m_sourceLocation, m_parsingErrors);
            } 
            else 
            {
                // Since NullableComplexTypes are not being supported, 
                // we don't allow conditions on complex types
                AddToSchemaErrors(Strings.Mapping_InvalidContent_ConditionMapping_NonScalar_0,
                    StorageMappingErrorCode.ConditionError, m_sourceLocation, navLineInfo, m_parsingErrors);
                return null; 

            } 
            //Either Value or NotNull need to be specifid on the condition mapping but not both 
            if ((isNullAttribute != null) && (value != null))
            { 
                AddToSchemaErrors(Strings.Mapping_InvalidContent_ConditionMapping_Both_Values_0,
                    StorageMappingErrorCode.ConditionError, m_sourceLocation, navLineInfo, m_parsingErrors);
                return null;
            } 
            if ((isNullAttribute == null) && (value == null))
            { 
                AddToSchemaErrors(Strings.Mapping_InvalidContent_ConditionMapping_Either_Values_0, 
                    StorageMappingErrorCode.ConditionError, m_sourceLocation, navLineInfo, m_parsingErrors);
                return null; 
            }

            if (isNullAttribute != null)
            { 
                //XSD validation should have guarenteed that the attribute value can only be true or false
                Debug.Assert(isNullAttribute == "true" || isNullAttribute == "false"); 
                isNullValue = Convert.ToBoolean(isNullAttribute, System.Globalization.CultureInfo.InvariantCulture); 
            }
 
            if (columnMember != null && (columnMember.IsStoreGeneratedComputed || columnMember.IsStoreGeneratedIdentity))
            {
                AddToSchemaErrorsWithMemberInfo(Strings.Mapping_InvalidContent_ConditionMapping_Computed, columnMember.Name,
                    StorageMappingErrorCode.ConditionError, m_sourceLocation, navLineInfo, m_parsingErrors); 
                return null;
            } 
 
            StorageConditionPropertyMapping conditionPropertyMapping = new StorageConditionPropertyMapping(member, columnMember, value, isNullValue);
            return conditionPropertyMapping; 
        }

        internal static bool IsTypeSupportedForCondition(PrimitiveTypeKind primitiveTypeKind)
        { 
            switch (primitiveTypeKind)
            { 
                case PrimitiveTypeKind.Boolean: 
                case PrimitiveTypeKind.Byte:
                case PrimitiveTypeKind.Int16: 
                case PrimitiveTypeKind.Int32:
                case PrimitiveTypeKind.Int64:
                case PrimitiveTypeKind.String:
                case PrimitiveTypeKind.SByte: 
                    return true;
                case PrimitiveTypeKind.Binary: 
                case PrimitiveTypeKind.DateTime: 
                case PrimitiveTypeKind.Time:
                case PrimitiveTypeKind.DateTimeOffset: 
                case PrimitiveTypeKind.Double:
                case PrimitiveTypeKind.Guid:
                case PrimitiveTypeKind.Single:
                case PrimitiveTypeKind.Decimal: 
                    return false;
                default: 
                    Debug.Fail("New primitive type kind added?"); 
                    return false;
            } 
        }

        private static XmlSchemaSet GetOrCreateSchemaSet()
        { 
            if (s_mappingXmlSchema == null)
            { 
                //Get the xsd stream for CS MSL Xsd. 
                Stream xsdStream = typeof(StorageMappingItemLoader).Assembly.GetManifestResourceStream(StorageMslConstructs.ResourceXsdName);
                using (XmlReader xsdReader = XmlReader.Create(xsdStream)) 
                {
                    XmlSchema xmlSchema = XmlSchema.Read(xsdReader, null);
                    XmlSchemaSet set = new XmlSchemaSet();
                    set.Add(xmlSchema); 
                    System.Threading.Interlocked.CompareExchange(ref s_mappingXmlSchema, set, null);
                } 
            } 

            return s_mappingXmlSchema; 
        }

        /// 
        /// Throws a new MappingException giving out the line number and 
        /// File Name where the error in Mapping specification is present.
        ///  
        ///  
        /// 
        ///  
        /// 
        /// Error Collection where the parsing errors are collected
        internal static void AddToSchemaErrors(string message, StorageMappingErrorCode errorCode, string location, IXmlLineInfo lineInfo, IList parsingErrors)
        { 
            EdmSchemaError error = new EdmSchemaError(message, (int)errorCode, EdmSchemaErrorSeverity.Error, location, lineInfo.LineNumber, lineInfo.LinePosition);
            parsingErrors.Add(error); 
        } 

        internal static void AddToSchemaErrorsWithMemberInfo(Func messageFormat, string errorMember, StorageMappingErrorCode errorCode, string location, IXmlLineInfo lineInfo, IList parsingErrors) 
        {
            EdmSchemaError error = new EdmSchemaError(messageFormat(errorMember), (int)errorCode, EdmSchemaErrorSeverity.Error, location, lineInfo.LineNumber, lineInfo.LinePosition);
            parsingErrors.Add(error);
        } 

        internal static void AddToSchemaErrorWithMemberAndStructure(Func messageFormat, string errorMember, 
            string errorStructure, StorageMappingErrorCode errorCode, string location, IXmlLineInfo lineInfo, IList parsingErrors) 
        {
            EdmSchemaError error = new EdmSchemaError( 
                messageFormat(errorMember, errorStructure)
                , (int)errorCode, EdmSchemaErrorSeverity.Error, location, lineInfo.LineNumber, lineInfo.LinePosition);
            parsingErrors.Add(error);
        } 

        internal static void AddToSchemaErrorWithMessage(string errorMessage, StorageMappingErrorCode errorCode, string location, IXmlLineInfo lineInfo, IList parsingErrors) 
        { 
            EdmSchemaError error = new EdmSchemaError(errorMessage, (int)errorCode, EdmSchemaErrorSeverity.Error, location, lineInfo.LineNumber, lineInfo.LinePosition);
            parsingErrors.Add(error); 
        }

        /// 
        /// Resolve the attribute value based on the aliases provided as part of MSL file. 
        /// 
        ///  
        ///  
        /// 
        private string GetAliasResolvedAttributeValue(XPathNavigator nav, string attributeName) 
        {
            return GetAliasResolvedValue(StorageMappingItemLoader.GetAttributeValue(nav, attributeName));
        }
 
        /// 
        /// The method simply calls the helper method on Helper class with the 
        /// namespaceURI that is default for CSMapping. 
        /// 
        ///  
        /// 
        /// 
        private static string GetAttributeValue(XPathNavigator nav, string attributeName)
        { 
            return Helper.GetAttributeValue(nav, attributeName);
        } 
 
        /// 
        /// The method simply calls the helper method on Helper class with the 
        /// namespaceURI that is default for CSMapping.
        /// 
        /// 
        ///  
        /// 
        ///  
        /// Error Collection where the parsing errors are collected 
        /// 
        private static bool TryGetTypedAttributeValue(XPathNavigator nav, string attributeName, Type clrType, string sourceLocation, IList parsingErrors, out object value) 
        {
            value = null;
            try
            { 
                value = Helper.GetTypedAttributeValue(nav, attributeName, clrType);
            } 
            catch (FormatException) 
            {
                StorageMappingItemLoader.AddToSchemaErrors(Strings.Mapping_ConditionValueTypeMismatch_0, 
                    StorageMappingErrorCode.ConditionError, sourceLocation, (IXmlLineInfo)nav, parsingErrors);
                return false;
            }
            return true; 
        }
 
        ///  
        /// Returns the enum EdmMember corresponding to attribute name in enumType.
        ///  
        /// 
        /// 
        /// 
        ///  
        /// Error Collection where the parsing errors are collected
        ///  
        private static EnumMember GetEnumAttributeValue(XPathNavigator nav, string attributeName, EnumType enumType, string sourceLocation, IList parsingErrors) 
        {
            IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav; 

            string value = GetAttributeValue(nav, attributeName);
            if (String.IsNullOrEmpty(value))
            { 
                StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Enum_EmptyValue_1, enumType.FullName,
                    StorageMappingErrorCode.InvalidEnumValue, sourceLocation, xmlLineInfoNav, parsingErrors); 
            } 

            EnumMember result; 
            bool found = enumType.EnumMembers.TryGetValue(value, false, out result);
            if (!found)
            {
                StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Enum_InvalidValue_1, value, 
                    StorageMappingErrorCode.InvalidEnumValue, sourceLocation, xmlLineInfoNav, parsingErrors);
            } 
            return result; 
        }
 
        /// 
        /// Resolve the string value based on the aliases provided as part of MSL file.
        /// 
        ///  
        /// 
        private string GetAliasResolvedValue(string aliasedString) 
        { 
            if ((aliasedString == null) || (aliasedString.Length == 0))
                return aliasedString; 
            //For now all attributes have no namespace
            int aliasIndex = aliasedString.LastIndexOf('.');
            //If no '.' in the string, than obviously the string is not aliased
            if (aliasIndex == -1) 
                return aliasedString;
            string aliasKey = aliasedString.Substring(0, aliasIndex); 
            string aliasValue; 
            m_alias.TryGetValue(aliasKey, out aliasValue);
            if (aliasValue != null) 
            {
                aliasedString = aliasValue + aliasedString.Substring(aliasIndex);
            }
            return aliasedString; 
        }
 
        ///  
        /// Creates Xml Reader with settings required for
        /// XSD validation. 
        /// 
        /// 
        internal XmlReader GetSchemaValidatingReader(XmlReader innerReader)
        { 
            //Create the reader setting that will be used while
            //loading the MSL. 
            XmlReaderSettings readerSettings = GetXmlReaderSettings(); 
            XmlReader reader = XmlReader.Create(innerReader, readerSettings);
 
            return reader;
        }

 
        private XmlReaderSettings GetXmlReaderSettings()
        { 
            XmlReaderSettings readerSettings = System.Data.EntityModel.SchemaObjectModel.Schema.CreateEdmStandardXmlReaderSettings(); 

            readerSettings.ValidationFlags |= System.Xml.Schema.XmlSchemaValidationFlags.ReportValidationWarnings; 
            readerSettings.ValidationEventHandler += this.XsdValidationCallBack;
            readerSettings.ValidationType = ValidationType.Schema;
            readerSettings.Schemas = GetOrCreateSchemaSet();
            return readerSettings; 
        }
 
 
        /// 
        /// The method is called by the XSD validation event handler when 
        /// ever there are warnings or errors.
        /// We ignore the warnings but the errors will result in exception.
        /// 
        ///  
        /// 
        internal void XsdValidationCallBack(object sender, ValidationEventArgs args) 
        { 
            if (args.Severity != XmlSeverityType.Warning)
            { 
                string sourceLocation = null;
                if (!string.IsNullOrEmpty(args.Exception.SourceUri))
                {
                    sourceLocation = Helper.GetFileNameFromUri(new Uri(args.Exception.SourceUri)); 
                }
                EdmSchemaErrorSeverity severity = EdmSchemaErrorSeverity.Error; 
                if (args.Severity == XmlSeverityType.Warning) 
                    severity = EdmSchemaErrorSeverity.Warning;
                EdmSchemaError error = new EdmSchemaError(System.Data.Entity.Strings.Mapping_InvalidMappingSchema_validation_1(args.Exception.Message) 
                    , (int)StorageMappingErrorCode.XmlSchemaValidationError, severity, sourceLocation, args.Exception.LineNumber, args.Exception.LinePosition);
                m_parsingErrors.Add(error);
            }
        } 

 
        ///  
        /// Validate the scalar property mapping - makes sure that the cspace type is promotable to the store side and updates
        /// the store type usage 
        /// 
        /// 
        /// 
        ///  
        private void ValidateAndUpdateScalarMemberMapping(EdmProperty member, EdmProperty columnMember, IXmlLineInfo lineInfo)
        { 
            Debug.Assert(Helper.IsPrimitiveType(member.TypeUsage.EdmType), "cspaceTypeusage must contain a scalar type"); 
            Debug.Assert(Helper.IsPrimitiveType(columnMember.TypeUsage.EdmType), "sspaceTypeusage must contain a scalar type");
 
            KeyValuePair memberMappingInfo;

            if (!m_scalarMemberMappings.TryGetValue(member, out memberMappingInfo))
            { 
                int errorCount = m_parsingErrors.Count;
 
                // Validates that the CSpace member type is promotable to the SSpace member types and returns a typeUsage which contains 
                // the store equivalent type for the CSpace member type.
                // For e.g. If a CSpace member of type Edm.Int32 maps to SqlServer.Int64, the return type usage will contain SqlServer.int 
                //          which is store equivalent type for Edm.Int32
                TypeUsage storeEquivalentTypeUsage = Helper.ValidateAndConvertTypeUsage(member,
                    columnMember, lineInfo, m_sourceLocation, m_parsingErrors, StoreItemCollection);
 
                // If the cspace type is not compatible with the store type, add a schema error and return
                if (storeEquivalentTypeUsage == null) 
                { 
                    if (errorCount == m_parsingErrors.Count)
                    { 
                        EdmSchemaError error = new EdmSchemaError(
                        System.Data.Entity.Strings.Mapping_Invalid_Member_Mapping_6(
                                                             member.TypeUsage.EdmType + GetFacetsForDisplay(member.TypeUsage),
                                                             member.Name, 
                                                             member.DeclaringType.FullName,
                                                             columnMember.TypeUsage.EdmType + GetFacetsForDisplay(columnMember.TypeUsage), 
                                                             columnMember.Name, 
                                                             columnMember.DeclaringType.FullName),
                        (int)StorageMappingErrorCode.IncompatibleMemberMapping, EdmSchemaErrorSeverity.Error, 
                        m_sourceLocation, lineInfo.LineNumber,
                        lineInfo.LinePosition);
                        m_parsingErrors.Add(error);
                    } 
                }
                else 
                { 
                    m_scalarMemberMappings.Add(member, new KeyValuePair(storeEquivalentTypeUsage, columnMember.TypeUsage));
                } 
            }
            else
            {
                // Get the store member type to which the cspace member was mapped to previously 
                TypeUsage storeMappedTypeUsage = memberMappingInfo.Value;
                TypeUsage modelColumnMember = columnMember.TypeUsage.GetModelTypeUsage(); 
                if (!Object.ReferenceEquals(columnMember.TypeUsage.EdmType, storeMappedTypeUsage.EdmType)) 
                {
                    EdmSchemaError error = new EdmSchemaError( 
                        System.Data.Entity.Strings.Mapping_StoreTypeMismatch_ScalarPropertyMapping_2(
                                                             member.Name,
                                                             storeMappedTypeUsage.EdmType.Name),
                        (int)StorageMappingErrorCode.CSpaceMemberMappedToMultipleSSpaceMemberWithDifferentTypes, 
                        EdmSchemaErrorSeverity.Error,
                        m_sourceLocation, 
                        lineInfo.LineNumber, 
                        lineInfo.LinePosition);
                    m_parsingErrors.Add(error); 
                }
                // Check if the cspace facets are promotable to the new store type facets
                else if (!TypeSemantics.IsSubTypeOf(member.TypeUsage, modelColumnMember))
                { 
                    EdmSchemaError error = new EdmSchemaError(
                        System.Data.Entity.Strings.Mapping_Invalid_Member_Mapping_6( 
                                                             member.TypeUsage.EdmType + GetFacetsForDisplay(member.TypeUsage), 
                                                             member.Name,
                                                             member.DeclaringType.FullName, 
                                                             columnMember.TypeUsage.EdmType + GetFacetsForDisplay(columnMember.TypeUsage),
                                                             columnMember.Name,
                                                             columnMember.DeclaringType.FullName),
                        (int)StorageMappingErrorCode.IncompatibleMemberMapping, EdmSchemaErrorSeverity.Error, 
                        m_sourceLocation, lineInfo.LineNumber,
                        lineInfo.LinePosition); 
                    m_parsingErrors.Add(error); 
                }
            } 
        }

        private string GetFacetsForDisplay(TypeUsage typeUsage)
        { 
            Debug.Assert(typeUsage != null);
 
            ReadOnlyMetadataCollection facets = typeUsage.Facets; 
            if (facets == null || facets.Count == 0)
            { 
                return string.Empty;
            }

            int numFacets = facets.Count; 

            StringBuilder facetDisplay = new StringBuilder("["); 
 
            for (int i = 0; i < numFacets-1; ++i)
            { 
                facetDisplay.AppendFormat("{0}={1},", facets[i].Name, facets[i].Value ?? string.Empty);
            }

            facetDisplay.AppendFormat("{0}={1}]", facets[numFacets - 1].Name, facets[numFacets-1].Value ?? string.Empty); 

            return facetDisplay.ToString(); 
        } 

        #endregion 

        #region Nested types
        /// 
        /// Encapsulates state and functionality for loading a mapping function. 
        /// 
        private class FunctionMappingLoader 
        { 
            // Storage mapping loader
            private readonly StorageMappingItemLoader m_parentLoader; 

            // Mapped function
            private EdmFunction m_function;
 
            // Entity set mapped by this function (may be null)
            private readonly EntitySet m_entitySet; 
 
            // Association set mapped by this function (may be null)
            private readonly AssociationSet m_associationSet; 

            // Model entity container (used to resolve set names)
            private readonly EntityContainer m_modelContainer;
 
            // Item collection (used to resolve function and type names)
            private readonly EdmItemCollection m_edmItemCollection; 
 
            // Item collection (used to resolve function and type names)
            private readonly StoreItemCollection m_storeItemCollection; 

            // Indicates whether the function can be bound to "current"
            // versions of properties (i.e., inserts and updates)
            private bool m_allowCurrentVersion; 

            // Indicates whether the function can be bound to "original" 
            // versions of properties (i.e., deletes and updates) 
            private bool m_allowOriginalVersion;
 
            // Tracks which function parameters have been seen so far.
            private readonly Set m_seenParameters;

            // Tracks members navigated to arrive at the current element 
            private readonly Stack m_members;
 
            // When set, indicates we are interpreting a navigation property on the given set. 
            private AssociationSet m_associationSetNavigation;
 
            // Initialize loader
            internal FunctionMappingLoader(
                StorageMappingItemLoader parentLoader,
                EntitySetBase extent) 
            {
                m_parentLoader = EntityUtil.CheckArgumentNull(parentLoader, "parentLoader"); 
                // initialize member fields 
                m_modelContainer = EntityUtil.CheckArgumentNull(extent, "extent").EntityContainer;
                m_edmItemCollection = parentLoader.EdmItemCollection; 
                m_storeItemCollection = parentLoader.StoreItemCollection;
                m_entitySet = extent as EntitySet;
                if (null == m_entitySet)
                { 
                    // do a cast here since the extent must either be an entity set
                    // or an association set 
                    m_associationSet = (AssociationSet)extent; 
                }
                m_seenParameters = new Set(); 
                m_members = new Stack();
            }

            // Loads a function mapping for an entity type 
            internal StorageFunctionMapping LoadEntityTypeFunctionMapping(XPathNavigator nav, bool allowCurrentVersion, bool allowOriginalVersion, EntityType entityType)
            { 
                FunctionParameter rowsAffectedParameter; 
                m_function = LoadAndValidateFunctionMetadata(nav.Clone(), out rowsAffectedParameter);
                if (m_function == null) 
                {
                    return null;
                }
                m_allowCurrentVersion = allowCurrentVersion; 
                m_allowOriginalVersion = allowOriginalVersion;
 
                // Load all parameter bindings and result bindings 
                IEnumerable parameters = LoadParameterBindings(nav.Clone(), entityType);
                IEnumerable resultBindings = LoadResultBindings(nav.Clone(), entityType); 

                StorageFunctionMapping functionMapping = new StorageFunctionMapping(m_function, parameters, rowsAffectedParameter, resultBindings);

                return functionMapping; 
            }
 
 
            // Loads a function mapping for an association set
            internal StorageFunctionMapping LoadAssociationSetFunctionMapping(XPathNavigator nav, bool isInsert) 
            {
                FunctionParameter rowsAffectedParameter;
                m_function = LoadAndValidateFunctionMetadata(nav.Clone(), out rowsAffectedParameter);
                if (m_function == null) 
                {
                    return null; 
                } 
                if (isInsert)
                { 
                    m_allowCurrentVersion = true;
                    m_allowOriginalVersion = false;
                }
                else 
                {
                    m_allowCurrentVersion = false; 
                    m_allowOriginalVersion = true; 
                }
 
                // Load all parameter bindings
                IEnumerable parameters = LoadParameterBindings(nav.Clone(), m_associationSet.ElementType);

                StorageFunctionMapping functionMapping = new StorageFunctionMapping(m_function, parameters, rowsAffectedParameter, null); 
                return functionMapping;
            } 
 
            // Loads all result bindings.
            private IEnumerable LoadResultBindings(XPathNavigator nav, EntityType entityType) 
            {
                List resultBindings = new List();
                IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
 
                // walk through all children, filtering on result bindings
                if (nav.MoveToChild(XPathNodeType.Element)) 
                { 
                    do
                    { 
                        if (nav.LocalName == StorageMslConstructs.ResultBindingElement)
                        {
                            // retrieve attributes
                            string propertyName = m_parentLoader.GetAliasResolvedAttributeValue(nav.Clone(), 
                                StorageMslConstructs.ResultBindingPropertyNameAttribute);
                            string columnName = m_parentLoader.GetAliasResolvedAttributeValue(nav.Clone(), 
                                StorageMslConstructs.ScalarPropertyColumnNameAttribute); 

                            // resolve metadata 
                            EdmProperty property = null;
                            if (null == propertyName ||
                                !entityType.Properties.TryGetValue(propertyName, false, out property))
                            { 
                                // add a schema error and return if the property does not exist
                                StorageMappingItemLoader.AddToSchemaErrorWithMemberAndStructure( 
                                    Strings.Mapping_Invalid_Function_Mapping_PropertyNotFound_2, 
                                    propertyName, entityType.Name,
                                    StorageMappingErrorCode.InvalidEdmMember, m_parentLoader.m_sourceLocation, 
                                    xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                                return new List();
                            }
 
                            // construct element binding (no type checking is required at mapping load time)
                            StorageFunctionResultBinding resultBinding = new StorageFunctionResultBinding(columnName, property); 
                            resultBindings.Add(resultBinding); 
                        }
                    } while (nav.MoveToNext(XPathNodeType.Element)); 
                }

                // check for duplicate mappings of single properties
                KeyToListMap propertyToColumnNamesMap = new KeyToListMap(EqualityComparer.Default); 
                foreach (StorageFunctionResultBinding resultBinding in resultBindings)
                { 
                    propertyToColumnNamesMap.Add(resultBinding.Property, resultBinding.ColumnName); 
                }
                foreach (EdmProperty property in propertyToColumnNamesMap.Keys) 
                {
                    ReadOnlyCollection columnNames = propertyToColumnNamesMap.ListForKey(property);
                    if (1 < columnNames.Count)
                    { 
                        StorageMappingItemLoader.AddToSchemaErrorWithMemberAndStructure(
                            Strings.Mapping_Invalid_Function_Mapping_AmbiguousResultBinding_2, 
                            property.Name, StringUtil.ToCommaSeparatedString(columnNames), 
                            StorageMappingErrorCode.AmbiguousResultBindingInFunctionMapping,
                            m_parentLoader.m_sourceLocation, xmlLineInfoNav, 
                            m_parentLoader.m_parsingErrors);
                        return new List();
                    }
                } 

                return resultBindings; 
            } 

            // Loads parameter bindings from the given node, validating bindings: 
            // - All parameters are covered
            // - Referenced names exist in type
            // - Parameter and scalar type are compatible
            // - Legal versions are given 
            private IEnumerable LoadParameterBindings(XPathNavigator nav, StructuralType type)
            { 
                // recursively retrieve bindings (current member path is empty) 
                // immediately construct a list of bindings to force execution of the LoadParameterBindings
                // yield method 
                List parameterBindings = new List(
                    LoadParameterBindings(nav.Clone(), type, false /* restrictToKeyMembers */));

                // check that all parameters have been mapped 
                Set unmappedParameters = new Set(m_function.Parameters);
                unmappedParameters.Subtract(m_seenParameters); 
                if (0 != unmappedParameters.Count) 
                {
                    AddToSchemaErrorWithMemberAndStructure(Strings.Mapping_Invalid_Function_Mapping_MissingParameter_2, 
                        m_function.FullName, StringUtil.ToCommaSeparatedString(unmappedParameters),
                        StorageMappingErrorCode.InvalidParameterInFunctionMapping,
                        m_parentLoader.m_sourceLocation, (IXmlLineInfo)nav,
                        m_parentLoader.m_parsingErrors); 
                    return new List();
                } 
 
                return parameterBindings;
            } 

            private IEnumerable LoadParameterBindings(XPathNavigator nav, StructuralType type,
                bool restrictToKeyMembers)
            { 
                // walk through all child bindings
                if (nav.MoveToChild(XPathNodeType.Element)) 
                { 
                    do
                    { 
                        switch (nav.LocalName)
                        {
                            case StorageMslConstructs.ScalarPropertyElement:
                                { 
                                    StorageFunctionParameterBinding binding = LoadScalarPropertyParameterBinding(
                                        nav.Clone(), type, restrictToKeyMembers); 
                                    if (binding != null) 
                                    {
                                        yield return binding; 
                                    }
                                    else
                                    {
                                        yield break; 
                                    }
                                } 
                                break; 
                            case StorageMslConstructs.ComplexPropertyElement:
                                { 
                                    ComplexType complexType;
                                    EdmMember property = LoadComplexTypeProperty(
                                        nav.Clone(), type, out complexType);
                                    if (property != null) 
                                    {
 
                                        // recursively retrieve mappings 
                                        m_members.Push(property);
                                        foreach (StorageFunctionParameterBinding binding in 
                                            LoadParameterBindings(nav.Clone(), complexType, restrictToKeyMembers))
                                        {
                                            yield return binding;
                                        } 
                                        m_members.Pop();
                                    } 
                                } 
                                break;
                            case StorageMslConstructs.AssociationEndElement: 
                                {
                                    AssociationSetEnd toEnd = LoadAssociationEnd(nav.Clone());
                                    if (toEnd != null)
                                    { 

                                        // translate the bindings for the association end 
                                        m_members.Push(toEnd.CorrespondingAssociationEndMember); 
                                        m_associationSetNavigation = toEnd.ParentAssociationSet;
                                        foreach (StorageFunctionParameterBinding binding in 
                                            LoadParameterBindings(nav.Clone(), toEnd.EntitySet.ElementType, true /* restrictToKeyMembers */))
                                        {
                                            yield return binding;
                                        } 
                                        m_associationSetNavigation = null;
                                        m_members.Pop(); 
                                    } 
                                }
                                break; 
                            case StorageMslConstructs.EndPropertyMappingElement:
                                {
                                    AssociationSetEnd end = LoadEndProperty(nav.Clone());
                                    if (end != null) 
                                    {
 
                                        // translate the bindings for the end property 
                                        m_members.Push(end.CorrespondingAssociationEndMember);
                                        foreach (StorageFunctionParameterBinding binding in 
                                            LoadParameterBindings(nav.Clone(), end.EntitySet.ElementType, true /* restrictToKeyMembers */))
                                        {
                                            yield return binding;
                                        } 
                                        m_members.Pop();
                                    } 
                                } 
                                break;
                        } 
                    } while (nav.MoveToNext(XPathNodeType.Element));
                }
            }
 
            private AssociationSetEnd LoadAssociationEnd(XPathNavigator nav)
            { 
 
                IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
 
                // retrieve element attributes
                string associationSetName = m_parentLoader.GetAliasResolvedAttributeValue(
                    nav.Clone(), StorageMslConstructs.AssociationSetAttribute);
                string fromRole = m_parentLoader.GetAliasResolvedAttributeValue( 
                    nav.Clone(), StorageMslConstructs.FromAttribute);
                string toRole = m_parentLoader.GetAliasResolvedAttributeValue( 
                    nav.Clone(), StorageMslConstructs.ToAttribute); 

                // retrieve metadata 
                RelationshipSet relationshipSet = null;
                AssociationSet associationSet;

                // validate the association set exists 
                if (null == associationSetName ||
                    !m_modelContainer.TryGetRelationshipSetByName(associationSetName, false, out relationshipSet) || 
                    BuiltInTypeKind.AssociationSet != relationshipSet.BuiltInTypeKind) 
                {
                    StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo( 
                        Strings.Mapping_Invalid_Function_Mapping_AssociationSetDoesNotExist_1,
                        associationSetName, StorageMappingErrorCode.InvalidAssociationSet,
                        m_parentLoader.m_sourceLocation, xmlLineInfoNav,
                        m_parentLoader.m_parsingErrors); 
                    return null;
                } 
                associationSet = (AssociationSet)relationshipSet; 

                // validate the from end exists 
                AssociationSetEnd fromEnd = null;
                if (null == fromRole ||
                    !associationSet.AssociationSetEnds.TryGetValue(fromRole, false, out fromEnd))
                { 
                    StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo(
                        Strings.Mapping_Invalid_Function_Mapping_AssociationSetRoleDoesNotExist_1, 
                        fromRole, StorageMappingErrorCode.InvalidAssociationSetRoleInFunctionMapping, 
                        m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                    return null; 
                }

                // validate the to end exists
                AssociationSetEnd toEnd = null; 
                if (null == toRole ||
                    !associationSet.AssociationSetEnds.TryGetValue(toRole, false, out toEnd)) 
                { 
                    StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo(
                    Strings.Mapping_Invalid_Function_Mapping_AssociationSetRoleDoesNotExist_1, 
                    toRole, StorageMappingErrorCode.InvalidAssociationSetRoleInFunctionMapping,
                    m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                    return null;
                } 

                // validate ends reference the current entity set 
                if (!fromEnd.EntitySet.Equals(m_entitySet)) 
                {
                    StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo( 
                        Strings.Mapping_Invalid_Function_Mapping_AssociationSetFromRoleIsNotEntitySet_1,
                        fromRole, StorageMappingErrorCode.InvalidAssociationSetRoleInFunctionMapping,
                        m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                    return null; 
                }
 
                // validate cardinality of to end (can be at most one) 
                if (toEnd.CorrespondingAssociationEndMember.RelationshipMultiplicity != RelationshipMultiplicity.One &&
                    toEnd.CorrespondingAssociationEndMember.RelationshipMultiplicity != RelationshipMultiplicity.ZeroOrOne) 
                {
                    StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo(
                    Strings.Mapping_Invalid_Function_Mapping_AssociationSetCardinality_1,
                    toRole, StorageMappingErrorCode.InvalidAssociationSetCardinalityInFunctionMapping, 
                    m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                    return null; 
                } 
                return toEnd;
            } 

            private AssociationSetEnd LoadEndProperty(XPathNavigator nav)
            {
                // retrieve element attributes 
                string role = m_parentLoader.GetAliasResolvedAttributeValue(
                    nav.Clone(), StorageMslConstructs.EndPropertyMappingNameAttribute); 
 
                // validate the role exists
                AssociationSetEnd end = null; 
                if (null == role ||
                    !m_associationSet.AssociationSetEnds.TryGetValue(role, false, out end))
                {
                    StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo( 
                    Strings.Mapping_Invalid_Function_Mapping_AssociationSetRoleDoesNotExist_1,
                    role, StorageMappingErrorCode.InvalidAssociationSetRoleInFunctionMapping, 
                    m_parentLoader.m_sourceLocation, (IXmlLineInfo)nav, m_parentLoader.m_parsingErrors); 
                    return null;
                } 

                return end;
            }
 
            private EdmMember LoadComplexTypeProperty(XPathNavigator nav, StructuralType type, out ComplexType complexType)
            { 
 
                IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
 
                // retrieve element attributes
                string propertyName = m_parentLoader.GetAliasResolvedAttributeValue(
                    nav.Clone(), StorageMslConstructs.ComplexPropertyNameAttribute);
                string typeName = m_parentLoader.GetAliasResolvedAttributeValue( 
                    nav.Clone(), StorageMslConstructs.ComplexTypeMappingTypeNameAttribute);
 
                // retrieve metadata 
                EdmMember property = null;
                if (null == propertyName || 
                    !type.Members.TryGetValue(propertyName, false, out property))
                {
                    // raise exception if the property does not exist
                    StorageMappingItemLoader.AddToSchemaErrorWithMemberAndStructure( 
                        Strings.Mapping_Invalid_Function_Mapping_PropertyNotFound_2,
                        propertyName, type.Name, StorageMappingErrorCode.InvalidEdmMember, 
                        m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors); 
                    complexType = null;
                    return null; 
                }
                complexType = null;
                if (null == typeName ||
                    !m_edmItemCollection.TryGetItem(typeName, out complexType)) 
                {
                    // raise exception if the type does not exist 
                    StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo( 
                    Strings.Mapping_Invalid_Function_Mapping_ComplexTypeNotFound_1,
                    typeName, StorageMappingErrorCode.InvalidComplexType, 
                    m_parentLoader.m_sourceLocation, xmlLineInfoNav
                    , m_parentLoader.m_parsingErrors);
                    return null;
                } 
                if (!property.TypeUsage.EdmType.Equals(complexType) &&
                    !Helper.IsSubtypeOf(property.TypeUsage.EdmType, complexType)) 
                { 
                    // raise exception if the complex type is incorrect
                    StorageMappingItemLoader.AddToSchemaErrorWithMemberAndStructure( 
                        Strings.Mapping_Invalid_Function_Mapping_WrongComplexType_2,
                        typeName, property.Name, StorageMappingErrorCode.InvalidComplexType,
                        m_parentLoader.m_sourceLocation, xmlLineInfoNav
                        , m_parentLoader.m_parsingErrors); 
                    return null;
                } 
                return property; 
            }
 
            private StorageFunctionParameterBinding LoadScalarPropertyParameterBinding(XPathNavigator nav, StructuralType type, bool restrictToKeyMembers)
            {
                IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
 
                // get attribute values
                string parameterName = m_parentLoader.GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ParameterNameAttribute); 
                string propertyName = m_parentLoader.GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ScalarPropertyNameAttribute); 
                string version = m_parentLoader.GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.ParameterVersionAttribute);
 
                // determine version
                bool isCurrent = false;
                if (null == version)
                { 
                    // use default
                    if (!m_allowOriginalVersion) 
                    { 
                        isCurrent = true;
                    } 
                    else if (!m_allowCurrentVersion)
                    {
                        isCurrent = false;
                    } 
                    else
                    { 
                        // add a schema error and return as there is no default 
                        StorageMappingItemLoader.AddToSchemaErrors(
                            Strings.Mapping_Invalid_Function_Mapping_MissingVersion_0, 
                            StorageMappingErrorCode.MissingVersionInFunctionMapping, m_parentLoader.m_sourceLocation,
                            xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                        return null;
 
                    }
                } 
                else 
                {
                    // check the value given by the user 
                    isCurrent = version == StorageMslConstructs.ParameterVersionAttributeCurrentValue;
                }
                if (isCurrent && !m_allowCurrentVersion)
                { 
                    //Add a schema error and return  since the 'current' property version is not available
                    StorageMappingItemLoader.AddToSchemaErrors( 
                        Strings.Mapping_Invalid_Function_Mapping_VersionMustBeOriginal_0, 
                        StorageMappingErrorCode.InvalidVersionInFunctionMapping,
                        m_parentLoader.m_sourceLocation, xmlLineInfoNav 
                        , m_parentLoader.m_parsingErrors);
                    return null;
                }
                if (!isCurrent && !m_allowOriginalVersion) 
                {
                    // Add a schema error and return  since the 'original' property version is not available 
                    StorageMappingItemLoader.AddToSchemaErrors( 
                        Strings.Mapping_Invalid_Function_Mapping_VersionMustBeCurrent_0,
                        StorageMappingErrorCode.InvalidVersionInFunctionMapping, 
                        m_parentLoader.m_sourceLocation, xmlLineInfoNav
                        , m_parentLoader.m_parsingErrors);
                    return null;
                } 

                // retrieve metadata 
                FunctionParameter parameter = null; 
                if (null == parameterName ||
                    !m_function.Parameters.TryGetValue(parameterName, false, out parameter)) 
                {
                    //Add a schema error and return  if the parameter does not exist
                    StorageMappingItemLoader.AddToSchemaErrorWithMemberAndStructure(
                        Strings.Mapping_Invalid_Function_Mapping_ParameterNotFound_2, 
                        parameterName, m_function.Name,
                        StorageMappingErrorCode.InvalidParameterInFunctionMapping, 
                        m_parentLoader.m_sourceLocation, xmlLineInfoNav 
                        , m_parentLoader.m_parsingErrors);
                    return null; 
                }
                EdmMember property = null;
                if (restrictToKeyMembers)
                { 
                    if (null == propertyName ||
                        !((EntityType)type).KeyMembers.TryGetValue(propertyName, false, out property)) 
                    { 
                        // raise exception if the property does not exist
                        StorageMappingItemLoader.AddToSchemaErrorWithMemberAndStructure( 
                            Strings.Mapping_Invalid_Function_Mapping_PropertyNotKey_2,
                            propertyName, type.Name,
                            StorageMappingErrorCode.InvalidEdmMember,
                            m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors); 
                        return null;
                    } 
                } 
                else
                { 
                    if (null == propertyName ||
                        !type.Members.TryGetValue(propertyName, false, out property))
                    {
                        // raise exception if the property does not exist 
                        StorageMappingItemLoader.AddToSchemaErrorWithMemberAndStructure(
                            Strings.Mapping_Invalid_Function_Mapping_PropertyNotFound_2, 
                            propertyName, type.Name, 
                            StorageMappingErrorCode.InvalidEdmMember,
                            m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors); 
                        return null;
                    }
                }
 
                // check that the parameter hasn't already been seen
                if (m_seenParameters.Contains(parameter)) 
                { 
                    StorageMappingItemLoader.AddToSchemaErrorsWithMemberInfo(
                        Strings.Mapping_Invalid_Function_Mapping_ParameterBoundTwice_1, 
                        parameterName, StorageMappingErrorCode.ParameterBoundTwiceInFunctionMapping,
                        m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                    return null;
                } 

                int errorCount = m_parentLoader.m_parsingErrors.Count; 
 
                TypeUsage mappedStoreType = Helper.ValidateAndConvertTypeUsage(property,
                                                                               xmlLineInfoNav, 
                                                                               m_parentLoader.m_sourceLocation,
                                                                               property.TypeUsage,
                                                                               parameter.TypeUsage,
                                                                               m_parentLoader.m_parsingErrors, 
                                                                               m_storeItemCollection);
 
                // validate type compatibility 
                if (mappedStoreType == null && errorCount == m_parentLoader.m_parsingErrors.Count)
                { 
                    AddToSchemaErrorWithMessage(
                        System.Data.Entity.Strings.Mapping_Invalid_Function_Mapping_PropertyParameterTypeMismatch_6(
                                                             property.TypeUsage.EdmType,
                                                             property.Name, 
                                                             property.DeclaringType.FullName,
                                                             parameter.TypeUsage.EdmType, 
                                                             parameter.Name, 
                                                             m_function.FullName),
                        StorageMappingErrorCode.InvalidFunctionMappingPropertyParameterTypeMismatch, 
                        m_parentLoader.m_sourceLocation,
                        xmlLineInfoNav,
                        m_parentLoader.m_parsingErrors);
                } 

                // create the binding object 
                m_members.Push(property); 
                StorageFunctionParameterBinding binding = new StorageFunctionParameterBinding(parameter, new StorageFunctionMemberPath(
                    m_members, m_associationSetNavigation), isCurrent); 
                m_members.Pop();

                // remember that we've seen a binding for this parameter
                m_seenParameters.Add(parameter); 

                return binding; 
            } 

            ///  
            /// Loads function metadata and ensures the function is supportable for function mapping.
            /// 
            private EdmFunction LoadAndValidateFunctionMetadata(XPathNavigator nav, out FunctionParameter rowsAffectedParameter)
            { 
                IXmlLineInfo xmlLineInfoNav = (IXmlLineInfo)nav;
 
                // retrieve function attributes from the current element 
                string functionName = m_parentLoader.GetAliasResolvedAttributeValue(nav.Clone(), StorageMslConstructs.FunctionNameAttribute);
                rowsAffectedParameter = null; 

                // find function metadata
                System.Collections.ObjectModel.ReadOnlyCollection functionOverloads =
                    m_storeItemCollection.GetFunctions(functionName); 

                if (functionOverloads.Count == 0) 
                { 
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Invalid_Function_Mapping_UnknownFunction_1, functionName,
                        StorageMappingErrorCode.InvalidFunctionMappingUnknownFunction, m_parentLoader.m_sourceLocation, 
                        xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                    return null;
                }
 
                if (1 < functionOverloads.Count)
                { 
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Invalid_Function_Mapping_AmbiguousFunction_1, functionName, 
                        StorageMappingErrorCode.InvalidFunctionMappingAmbiguousFunction, m_parentLoader.m_sourceLocation,
                        xmlLineInfoNav, m_parentLoader.m_parsingErrors); 
                    return null;
                }

                EdmFunction function = functionOverloads[0]; 

                // check function is legal for function mapping 
                if (MetadataHelper.IsComposable(function)) 
                { // only non-composable functions are permitted
                    AddToSchemaErrorsWithMemberInfo(Strings.Mapping_Invalid_Function_Mapping_NotValidFunction_1, functionName, 
                        StorageMappingErrorCode.InvalidFunctionMappingNotValidFunction, m_parentLoader.m_sourceLocation,
                        xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                    return null;
                } 

                // check for parameter 
                string rowsAffectedParameterName = GetAttributeValue(nav, StorageMslConstructs.RowsAffectedParameterAttribute); 
                if (!string.IsNullOrEmpty(rowsAffectedParameterName))
                { 
                    // check that the parameter exists
                    if (!function.Parameters.TryGetValue(rowsAffectedParameterName, false, out rowsAffectedParameter))
                    {
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_RowsAffectedParameterDoesNotExist_2( 
                            rowsAffectedParameterName, function.FullName),
                            StorageMappingErrorCode.MappingFunctionImportRowsAffectedParameterDoesNotExist, 
                            m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors); 
                        return null;
                    } 
                    // check that the parameter is an out parameter
                    if (ParameterMode.Out != rowsAffectedParameter.Mode)
                    {
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_RowsAffectedParameterHasWrongMode_3( 
                            rowsAffectedParameterName, rowsAffectedParameter.Mode, ParameterMode.Out),
                            StorageMappingErrorCode.MappingFunctionImportRowsAffectedParameterHasWrongMode, 
                            m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors); 
                        return null;
                    } 
                    // check that the parameter type is Int32
                    PrimitiveType rowsAffectedParameterType = (PrimitiveType)rowsAffectedParameter.TypeUsage.EdmType;
                    if (rowsAffectedParameterType.PrimitiveTypeKind != PrimitiveTypeKind.Int32)
                    { 
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_FunctionImport_RowsAffectedParameterHasWrongType_3(
                            rowsAffectedParameterName, rowsAffectedParameterType.PrimitiveTypeKind, PrimitiveTypeKind.Int32), 
                            StorageMappingErrorCode.MappingFunctionImportRowsAffectedParameterHasWrongType, 
                            m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                        return null; 
                    }
                    m_seenParameters.Add(rowsAffectedParameter);
                }
 
                // check that all parameters are allowed
                foreach (FunctionParameter parameter in function.Parameters) 
                { 
                    if (ParameterMode.In != parameter.Mode && rowsAffectedParameterName != parameter.Name)
                    { // rows affected is 'out' not 'in' 
                        AddToSchemaErrorWithMessage(System.Data.Entity.Strings.Mapping_Invalid_Function_Mapping_NotValidFunctionParameter_3(functionName,
                            parameter.Name, StorageMslConstructs.RowsAffectedParameterAttribute), StorageMappingErrorCode.InvalidFunctionMappingNotValidFunctionParameter,
                            m_parentLoader.m_sourceLocation, xmlLineInfoNav, m_parentLoader.m_parsingErrors);
                        return null; 
                    }
                } 
 
                return function;
            } 
        }
        #endregion
    }
} 

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

Link Menu

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