private void ProcessModificationFunction(EntityInfo info, ModificationFunction function)
        {
            if (function == null)
            {
                return;
            }

            // make sure that we don't have any extra scalars (i.e. from entities that are no longer parents of this entity)
            // so gather the list of all SPs we expect to be here
            var expectedMappedProperties = new List<Property>();
            expectedMappedProperties.AddRange(info.KeyProperties);
            expectedMappedProperties.AddRange(info.NonKeyProperties);
            if (info.Parent != null)
            {
                GatherNonKeyPropertiesFromAllParents(info.Parent, expectedMappedProperties);
            }

            // remove any that aren't in our expected list
            foreach (var sp in function.ScalarProperties())
            {
                if (expectedMappedProperties.Contains(sp.Name.Target) == false)
                {
                    AddToDeleteList(sp);
                }
            }

            // make sure that we don't have any extra AssociationEnds
            var cet = info.EntityType;
            Debug.Assert(cet != null, "EntityType is not a ConceptualEntityType");
            var selfAndBaseTypes = new List<ConceptualEntityType>(cet.SafeSelfAndBaseTypes);
            foreach (var end in function.AssociationEnds())
            {
                var from = end.From.Target;
                var to = end.To.Target;
                if (from != null
                    && to != null
                    && from.Role.Target != null
                    && to.Role.Target != null)
                {
                    var fromType = from.Role.Target.Type.Target as ConceptualEntityType;
                    var toType = to.Role.Target.Type.Target as ConceptualEntityType;

                    Debug.Assert(
                        from.Role.Target.Type.Target != null ? fromType != null : true, "fromType EntityType is not a ConceptualEntityType");
                    Debug.Assert(
                        to.Role.Target.Type.Target != null ? toType != null : true, "toType EntityType is not a ConceptualEntityType");

                    if (fromType != null
                        && toType != null)
                    {
                        if (selfAndBaseTypes.Contains(fromType)
                            || selfAndBaseTypes.Contains(toType))
                        {
                            continue;
                        }
                    }
                }

                AddToDeleteList(end);
            }
        }
        internal static FunctionScalarProperty CreateFunctionScalarPropertyInAssociationEnd(
            ModificationFunction mf, Property entityProperty, NavigationProperty pointingNavProperty, Parameter parm, string version)
        {
            // in creating the function scalar property, we modify the AssociationEnd depending on the navigation property that is
            // pointing to the actual property. If we don't have this navigation property we can't do anything.
            Debug.Assert(
                pointingNavProperty != null,
                "We need the navigation property pointing to the property in order to create the mapping function scalar property");
            if (pointingNavProperty == null)
            {
                throw new CannotLocateReferencedItemException();
            }

            Debug.Assert(pointingNavProperty.Relationship.Target != null, "Where is the Association for this navigation property?");
            if (pointingNavProperty.Relationship.Target == null)
            {
                throw new CannotLocateReferencedItemException();
            }

            var assocSet = pointingNavProperty.Relationship.Target.AssociationSet;
            var navPropFromEnd = pointingNavProperty.FromRole.Target;
            var navPropToEnd = pointingNavProperty.ToRole.Target;
            Debug.Assert(null != navPropFromEnd, "Null FromRole for pointingNavProperty " + pointingNavProperty.ToPrettyString());
            Debug.Assert(null != navPropToEnd, "Null ToRole for pointingNavProperty " + pointingNavProperty.ToPrettyString());

            AssociationSetEnd assocSetFromEnd = null;
            AssociationSetEnd assocSetToEnd = null;

            // figure which end is which
            // Note: it is valid for the NavigationProperty to point to
            // an EntityType in the same inheritance hierarchy
            foreach (var end in assocSet.AssociationSetEnds())
            {
                if (end.Role.Target == navPropFromEnd)
                {
                    Debug.Assert(
                        null == assocSetFromEnd,
                        "pointingNavProperty From End " + navPropFromEnd.ToPrettyString()
                        + " matches more than 1 AssociationSetEnd for AssociationSet " + assocSet.ToPrettyString());
                    assocSetFromEnd = end;
                }
                else if (end.Role.Target == navPropToEnd)
                {
                    Debug.Assert(
                        null == assocSetToEnd,
                        "pointingNavProperty To End " + navPropToEnd.ToPrettyString()
                        + " matches more than 1 AssociationSetEnd for AssociationSet " + assocSet.ToPrettyString());
                    assocSetToEnd = end;
                }
            }
            Debug.Assert(null != assocSetFromEnd, "Cannot find From end of AssociationSet " + assocSet.ToPrettyString());
            Debug.Assert(null != assocSetToEnd, "Cannot find To end of AssociationSet " + assocSet.ToPrettyString());

            // see if we already have this AssociationEnd
            FunctionAssociationEnd fae = null;
            foreach (var funcAssocEnd in mf.AssociationEnds())
            {
                if (funcAssocEnd.AssociationSet.Target == assocSet
                    && funcAssocEnd.From.Target == assocSetFromEnd
                    && funcAssocEnd.To.Target == assocSetToEnd)
                {
                    fae = funcAssocEnd;
                    break;
                }
            }

            // create the association end if needed
            if (fae == null)
            {
                fae = new FunctionAssociationEnd(mf, null);
                fae.AssociationSet.SetRefName(assocSet);
                fae.From.SetRefName(assocSetFromEnd);
                fae.To.SetRefName(assocSetToEnd);
                mf.AddAssociationEnd(fae);
                XmlModelHelper.NormalizeAndResolve(fae);
            }

            Debug.Assert(fae != null, "Failed to create the AssocationEnd to house this ScalarProperty");
            if (fae == null)
            {
                throw new ParentItemCreationFailureException();
            }

            // create the SP inside this
            return CreateFunctionScalarPropertyCommon(fae, entityProperty, parm, version);
        }