ResourceType.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataWeb / Server / System / Data / Services / Providers / ResourceType.cs / 1305376 / ResourceType.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//  
//      Contains information about a particular resource.
//  
// 
// @owner  [....]
//--------------------------------------------------------------------- 

namespace System.Data.Services.Providers
{
    #region Namespaces. 

    using System; 
    using System.Collections.Generic; 
    using System.Collections.ObjectModel;
    using System.Data.Services.Common; 
    using System.Data.Services.Parsing;
    using System.Data.Services.Serializers;
    using System.Diagnostics;
    using System.Linq; 
    using System.Linq.Expressions;
    using System.Reflection; 
 
    #endregion Namespaces.
 
    /// Use this class to represent a DataService type (primitive, complex or entity).
    [DebuggerDisplay("{Name}: {InstanceType}, {ResourceTypeKind}")]
    public class ResourceType
    { 
        #region Fields.
 
        ///  empty list of properties  
        internal static readonly ReadOnlyCollection EmptyProperties = new ReadOnlyCollection(new ResourceProperty[0]);
 
        /// Primitive string resource type.
        internal static readonly ResourceType PrimitiveStringResourceType = ResourceType.GetPrimitiveResourceType(typeof(string));

        /// MethodInfo for object DataServiceProviderWrapper.GetPropertyValue(object target, ResourceProperty resourceProperty, ResourceType resourceType). 
        private static readonly MethodInfo GetPropertyValueMethodInfo = typeof(DataServiceProviderWrapper).GetMethod(
            "GetPropertyValue", 
            WebUtil.PublicInstanceBindingFlags); 

        /// MethodInfo for object IProjectedResult.GetProjectedPropertyValue(this IProjectedResult value, string propertyName). 
        private static readonly MethodInfo IProjectedResultGetProjectedPropertyValueMethodInfo = typeof(IProjectedResult).GetMethod(
            "GetProjectedPropertyValue",
            WebUtil.PublicInstanceBindingFlags);
 
        ///  ResourceTypeKind for the type that this structure represents 
        private readonly ResourceTypeKind resourceTypeKind; 
 
        ///  Reference to clr type that this resource represents 
        private readonly Type type; 

        ///  Reference to base resource type 
        private readonly ResourceType baseType;
 
        ///  name of the resource.
        private readonly string name; 
 
        ///  full name of the resource.
        private readonly string fullName; 

        ///  Namespace for this type.
        private readonly string namespaceName;
 
        /// Whether this type is abstract.
        private readonly bool abstractType; 
 
        /// Whether the resource type has open properties.
        private bool isOpenType; 

        /// Whether the corresponding instance type actually represents this node's CLR type.
        private bool canReflectOnInstanceType;
 
        /// Cached delegate to create a new instance of this type.
        private Func constructorDelegate; 
 
        /// Cached delegate to serialize parts of this resource into a dictionary.
        private Action dictionarySerializerDelegate; 

        ///  List of properties declared in this type (includes properties only defined in this type, not in the base type) 
        private IList propertiesDeclaredOnThisType;
 
        ///  List of all properties for this type (includes properties defined in the base type also) 
        private ReadOnlyCollection allProperties; 
 
        ///  list of key properties for this type
        private ReadOnlyCollection keyProperties; 

        ///  list of etag properties for this type.
        private ReadOnlyCollection etagProperties;
 
        /// If ResourceProperty.CanReflectOnInstanceTypeProperty is true, we cache the PropertyInfo object.
        private Dictionary propertyInfosDeclaredOnThisType = new Dictionary(ReferenceEqualityComparer.Instance); 
 
        /// EpmInfo for this 
        private EpmInfoPerResourceType epmInfo; 

        /// Indicates whether one of the base class of this resource type has EpmInfo.
        private bool? basesHaveEpmInfo;
 
        /// is true, if the type is set to readonly.
        private bool isReadOnly; 
 
        /// True if the resource type includes a default stream 
        private bool isMediaLinkEntry; 

        /// True if the virtual load properties is already called, otherwise false.
        private bool isLoadPropertiesMethodCalled;
 
        #endregion Fields.
 
        #region Constructors. 

        ///  
        /// Constructs a new instance of Astoria type using the specified clr type
        /// 
        /// clr type that represents the flow format inside the Astoria runtime
        ///  kind of the resource type 
        /// base type of the resource type
        /// Namespace name of the given resource type. 
        /// name of the given resource type. 
        /// whether the resource type is an abstract type or not.
        public ResourceType( 
                    Type instanceType,
                    ResourceTypeKind resourceTypeKind,
                    ResourceType baseType,
                    string namespaceName, 
                    string name,
                    bool isAbstract) 
            : this(instanceType, baseType, namespaceName, name, isAbstract) 
        {
            WebUtil.CheckArgumentNull(instanceType, "instanceType"); 
            WebUtil.CheckStringArgumentNull(name, "name");
            WebUtil.CheckResourceTypeKind(resourceTypeKind, "resourceTypeKind");
            if (resourceTypeKind == ResourceTypeKind.Primitive)
            { 
                throw new ArgumentException(Strings.ResourceType_InvalidValueForResourceTypeKind, "resourceTypeKind");
            } 
 
            if (instanceType.IsValueType)
            { 
                throw new ArgumentException(Strings.ResourceType_TypeCannotBeValueType, "instanceType");
            }

            this.resourceTypeKind = resourceTypeKind; 
        }
 
        ///  
        /// Constructs a new instance of Resource type for the given clr primitive type. This constructor must be called only for primitive types.
        ///  
        /// clr type representing the primitive type.
        /// namespace of the primitive type.
        /// name of the primitive type.
        internal ResourceType(Type type, string namespaceName, string name) 
            : this(type, null, namespaceName, name, false)
        { 
            Debug.Assert(WebUtil.IsPrimitiveType(type), "This constructor should be called only for primitive types"); 
            this.resourceTypeKind = ResourceTypeKind.Primitive;
            this.isReadOnly = true; 
        }

        /// 
        /// Constructs a new instance of Astoria type using the specified clr type 
        /// 
        /// clr type from which metadata needs to be pulled  
        /// base type of the resource type 
        /// Namespace name of the given resource type.
        /// name of the given resource type. 
        /// whether the resource type is an abstract type or not.
        private ResourceType(
                    Type type,
                    ResourceType baseType, 
                    string namespaceName,
                    string name, 
                    bool isAbstract) 
        {
            WebUtil.CheckArgumentNull(type, "type"); 
            WebUtil.CheckArgumentNull(name, "name");

            this.name = name;
            this.namespaceName = namespaceName ?? string.Empty; 

            // This is to optimize the string property name in PlainXmlSerializer.WriteStartElementWithType function. 
            // Checking here is a fixed overhead, and the gain is every time we serialize a string property. 
            if (name == "String" && Object.ReferenceEquals(namespaceName, XmlConstants.EdmNamespace))
            { 
                this.fullName = XmlConstants.EdmStringTypeName;
            }
            else
            { 
                this.fullName = string.IsNullOrEmpty(namespaceName) ? name : namespaceName + "." + name;
            } 
 
            this.type = type;
            this.abstractType = isAbstract; 
            this.canReflectOnInstanceType = true;

            if (baseType != null)
            { 
                this.baseType = baseType;
            } 
        } 

        #endregion Constructors. 

        #region Properties.

        /// True if the resource type includes a default stream 
        public bool IsMediaLinkEntry
        { 
            [DebuggerStepThrough] 
            get
            { 
                return this.isMediaLinkEntry;
            }

            set 
            {
                this.ThrowIfSealed(); 
                if (this.resourceTypeKind != ResourceTypeKind.EntityType && value == true) 
                {
                    throw new InvalidOperationException(Strings.ReflectionProvider_HasStreamAttributeOnlyAppliesToEntityType(this.name)); 
                }

                this.isMediaLinkEntry = value;
            } 
        }
 
        ///  Reference to clr type that this resource represents  
        public Type InstanceType
        { 
            [DebuggerStepThrough]
            get { return this.type; }
        }
 
        ///  Reference to base resource type, if any 
        public ResourceType BaseType 
        { 
            [DebuggerStepThrough]
            get { return this.baseType; } 
        }

        ///  ResourceTypeKind of this type 
        public ResourceTypeKind ResourceTypeKind 
        {
            [DebuggerStepThrough] 
            get { return this.resourceTypeKind; } 
        }
 
        ///  Returns the list of properties for this type 
        public ReadOnlyCollection Properties
        {
            get 
            {
                return this.InitializeProperties(); 
            } 
        }
 
        ///  list of properties declared on this type 
        public ReadOnlyCollection PropertiesDeclaredOnThisType
        {
            get 
            {
                ReadOnlyCollection readOnlyProperties = this.propertiesDeclaredOnThisType as ReadOnlyCollection; 
                if (readOnlyProperties == null) 
                {
                    // This method will call the virtual method, if that's not been called yet and add the list of properties 
                    // returned by the virtual method to the properties collection.
                    this.GetPropertiesDeclaredOnThisType();
                    readOnlyProperties = new ReadOnlyCollection(this.propertiesDeclaredOnThisType ?? ResourceType.EmptyProperties);
 
                    if (!this.isReadOnly)
                    { 
                        return readOnlyProperties; 
                    }
 
                    // First try and validate the type. If that succeeds, then cache the results. otherwise we need to revert the results.
                    IList propertyCollection = this.propertiesDeclaredOnThisType;
                    this.propertiesDeclaredOnThisType = readOnlyProperties;
 
                    try
                    { 
                        this.ValidateType(); 
                    }
                    catch (Exception) 
                    {
                        this.propertiesDeclaredOnThisType = propertyCollection;
                        throw;
                    } 
                }
 
                Debug.Assert(this.isReadOnly, "PropetiesDeclaredInThisType - at this point, the resource type must be readonly"); 
                return readOnlyProperties;
            } 
        }

        ///  Returns the list of key properties for this type, if this type is entity type.
        public ReadOnlyCollection KeyProperties 
        {
            get 
            { 
                if (this.keyProperties == null)
                { 
                    ResourceType rootType = this;
                    while (rootType.BaseType != null)
                    {
                        rootType = rootType.BaseType; 
                    }
 
                    ReadOnlyCollection readOnlyKeyProperties; 
                    if (rootType.Properties == null)
                    { 
                        readOnlyKeyProperties = ResourceType.EmptyProperties;
                    }
                    else
                    { 
                        List key = rootType.Properties.Where(p => p.IsOfKind(ResourcePropertyKind.Key)).ToList();
                        key.Sort(ResourceType.ResourcePropertyComparison); 
                        readOnlyKeyProperties = new ReadOnlyCollection(key); 
                    }
 
                    if (!this.isReadOnly)
                    {
                        return readOnlyKeyProperties;
                    } 

                    this.keyProperties = readOnlyKeyProperties; 
                } 

                Debug.Assert(this.isReadOnly, "KeyProperties - at this point, the resource type must be readonly"); 
                Debug.Assert(
                    (this.ResourceTypeKind != ResourceTypeKind.EntityType && this.keyProperties.Count == 0) ||
                    (this.ResourceTypeKind == ResourceTypeKind.EntityType && this.keyProperties.Count > 0),
                    "Entity type must have key properties and non-entity types cannot have key properties"); 

                return this.keyProperties; 
            } 
        }
 
        /// Returns the list of etag properties for this type.
        public ReadOnlyCollection ETagProperties
        {
            get 
            {
                if (this.etagProperties == null) 
                { 
                    ReadOnlyCollection etag = new ReadOnlyCollection(this.Properties.Where(p => p.IsOfKind(ResourcePropertyKind.ETag)).ToList());
                    if (!this.isReadOnly) 
                    {
                        return etag;
                    }
 
                    this.etagProperties = etag;
                } 
 
                Debug.Assert(this.isReadOnly, "ETagProperties - at this point, the resource type must be readonly");
                return this.etagProperties; 
            }
        }

        ///  Gets the name of the resource. 
        public string Name
        { 
            get { return this.name; } 
        }
 
        ///  Gets the fullname of the resource.
        public string FullName
        {
            get { return this.fullName; } 
        }
 
        ///  Returns the namespace of this type. 
        public string Namespace
        { 
            get { return this.namespaceName; }
        }

        /// Indicates whether this is an abstract type. 
        public bool IsAbstract
        { 
            get { return this.abstractType; } 
        }
 
        /// Indicates whether the resource type has open properties.
        public bool IsOpenType
        {
            [DebuggerStepThrough] 
            get
            { 
                return this.isOpenType; 
            }
 
            set
            {
                this.ThrowIfSealed();
 
                // Complex types can not be marked as open.
                if (this.resourceTypeKind == ResourceTypeKind.ComplexType && value == true) 
                { 
                    throw new InvalidOperationException(Strings.ResourceType_ComplexTypeCannotBeOpen(this.FullName));
                } 

                this.isOpenType = value;
            }
        } 

        /// Whether the corresponding instance type actually represents this node's CLR type. 
        public bool CanReflectOnInstanceType 
        {
            [DebuggerStepThrough] 
            get
            {
                return this.canReflectOnInstanceType;
            } 

            set 
            { 
                this.ThrowIfSealed();
                this.canReflectOnInstanceType = value; 
            }
        }

        ///  
        /// PlaceHolder to hold custom state information about resource type.
        ///  
        public object CustomState 
        {
            get; 
            set;
        }

        ///  
        /// Returns true, if this resource type has been set to read only. Otherwise returns false.
        ///  
        public bool IsReadOnly 
        {
            get { return this.isReadOnly; } 
        }

        /// Cached delegate to create a new instance of this type.
        internal Func ConstructorDelegate 
        {
            get 
            { 
                if (this.constructorDelegate == null)
                { 
                    this.constructorDelegate = (Func)
                        WebUtil.CreateNewInstanceConstructor(this.InstanceType, this.FullName, typeof(object));
                }
 
                return this.constructorDelegate;
            } 
        } 

        /// Cached delegate to serialize parts of this resource into a dictionary. 
        internal Action DictionarySerializerDelegate
        {
            get { return this.dictionarySerializerDelegate; }
            set { this.dictionarySerializerDelegate = value; } 
        }
 
        ///  
        /// Do we have entity property mappings for this 
        ///  
        internal bool HasEntityPropertyMappings
        {
            get
            { 
                Debug.Assert(this.IsReadOnly, "Type must be read-only.");
 
                if (this.epmInfo != null) 
                {
                    return true; 
                }

                if (this.basesHaveEpmInfo == null)
                { 
                    this.basesHaveEpmInfo = this.BaseType != null ? this.BaseType.HasEntityPropertyMappings  : false;
                } 
 
                return this.basesHaveEpmInfo.Value;
            } 
        }

        /// 
        /// Property used to mark the fact that EpmInfo for the resource type has been initialized 
        /// 
        internal bool EpmInfoInitialized 
        { 
            get;
            set; 
        }

        /// The mappings for friendly feeds are V1 compatible or not
        internal bool EpmIsV1Compatible 
        {
            get 
            { 
                Debug.Assert(this.isReadOnly, "Resource type must already be read-only.");
                this.InitializeProperties(); 
                return !this.HasEntityPropertyMappings || this.EpmTargetTree.IsV1Compatible;
            }
        }
 
        /// 
        /// Tree of source paths for EntityPropertyMappingAttributes on this resource type 
        ///  
        internal EpmSourceTree EpmSourceTree
        { 
            get
            {
                if (this.epmInfo == null)
                { 
                    this.epmInfo = new EpmInfoPerResourceType();
                } 
 
                return this.epmInfo.EpmSourceTree;
            } 
        }

        /// 
        /// Tree of target paths for EntityPropertyMappingAttributes on this resource type 
        /// 
        internal EpmTargetTree EpmTargetTree 
        { 
            get
            { 
                Debug.Assert(this.epmInfo != null, "Must have valid EpmInfo");
                return this.epmInfo.EpmTargetTree;
            }
        } 

        /// Inherited EpmInfo 
        internal IList InheritedEpmInfo 
        {
            get 
            {
                Debug.Assert(this.epmInfo != null, "Must have valid EpmInfo");
                return this.epmInfo.InheritedEpmInfo;
            } 
        }
 
        /// Own EpmInfo 
        internal IList OwnEpmInfo
        { 
            get
            {
                Debug.Assert(this.epmInfo != null, "Must have valid EpmInfo");
                return this.epmInfo.OwnEpmInfo; 
            }
        } 
 
        /// All EpmInfo i.e. both own and inherited.
        internal IEnumerable AllEpmInfo 
        {
            get
            {
                Debug.Assert(this.epmInfo != null, "Must have valid EpmInfo"); 
                return this.epmInfo.OwnEpmInfo.Concat(this.epmInfo.InheritedEpmInfo);
            } 
        } 

        #endregion Properties. 

        #region Methods.

        ///  
        /// Get a ResourceType representing a primitive type given a .NET System.Type object
        ///  
        /// .NET type to get the primitive type from 
        /// A ResourceType object representing the primitive type or null if not primitive
        public static ResourceType GetPrimitiveResourceType(Type type) 
        {
            WebUtil.CheckArgumentNull(type, "type");

            foreach (ResourceType resourceType in WebUtil.GetPrimitiveTypes()) 
            {
                if (resourceType.InstanceType == type) 
                { 
                    return resourceType;
                } 
            }

            return null;
        } 

        ///  
        /// Adds the given property to this ResourceType instance 
        /// 
        /// resource property to be added 
        public void AddProperty(ResourceProperty property)
        {
            WebUtil.CheckArgumentNull(property, "property");
 
            // only check whether the property with the same name exists in this type.
            // we will look in base types properties when the type is sealed. 
            this.ThrowIfSealed(); 

            // add the property to the list of properties declared on this type. 
            this.AddPropertyInternal(property);
        }

        ///  
        /// Adds an  for the resource type.
        ///  
        /// Given  
        public void AddEntityPropertyMappingAttribute(EntityPropertyMappingAttribute attribute)
        { 
            WebUtil.CheckArgumentNull(attribute, "attribute");

            // EntityPropertyMapping attribute can not be added to readonly resource types.
            this.ThrowIfSealed(); 

            if (this.ResourceTypeKind != ResourceTypeKind.EntityType) 
            { 
                throw new InvalidOperationException(Strings.EpmOnlyAllowedOnEntityTypes(this.Name));
            } 

            if (this.epmInfo == null)
            {
                this.epmInfo = new EpmInfoPerResourceType(); 
            }
 
            this.OwnEpmInfo.Add(attribute); 
        }
 
        /// 
        /// Make the resource type readonly from now on. This means that no more changes can be made to the resource type anymore.
        /// 
        public void SetReadOnly() 
        {
#if DEBUG 
            IList currentPropertyCollection = this.propertiesDeclaredOnThisType; 
#endif
            // if its already sealed, its a no-op 
            if (this.isReadOnly)
            {
                return;
            } 

            // We need to set readonly at the start to avoid any circular loops that may result due to navigation properties. 
            // If there are any exceptions, we need to set readonly to false. 
            this.isReadOnly = true;
 
            // There can be properties with the same name in the base class also (using the new construct)
            // if the base type is not null, then we need to make sure that there is no property with the same name.
            // Otherwise, we are only populating property declared for this type and clr gaurantees that they are unique
            if (this.BaseType != null) 
            {
                this.BaseType.SetReadOnly(); 
 
                // Mark current type as OpenType if base is an OpenType
                if (this.BaseType.IsOpenType && this.ResourceTypeKind != ResourceTypeKind.ComplexType) 
                {
                    this.isOpenType = true;
                }
 
                // Mark the current type as being a Media Link Entry if the base type is a Media Link Entry.
                if (this.BaseType.IsMediaLinkEntry) 
                { 
                    this.isMediaLinkEntry = true;
                } 

                // Make sure current type is not a CLR type if base is not a CLR type.
                if (!this.BaseType.CanReflectOnInstanceType)
                { 
                    this.canReflectOnInstanceType = false;
                } 
            } 

            // set all the properties to readonly 
            if (this.propertiesDeclaredOnThisType != null)
            {
                foreach (ResourceProperty p in this.propertiesDeclaredOnThisType)
                { 
                    p.SetReadOnly();
                } 
            } 
#if DEBUG
            // We cannot change the properties collection method. Basically, we should not be calling Properties or PropertiesDeclaredOnThisType properties 
            // since they call the virtual LoadPropertiesDeclaredOnThisType and we want to postpone that virtual call until we actually need to do something
            // more useful with the properties
            Debug.Assert(Object.ReferenceEquals(this.propertiesDeclaredOnThisType, currentPropertyCollection), "We should not have modified the properties collection instance");
#endif 
        }
 
        /// By initializing the EpmInfo for the resource type, ensures that the information is available for de-serialization. 
        internal void EnsureEpmInfoAvailability()
        { 
            this.InitializeProperties();
        }

        /// Given a resource type, builds the EntityPropertyMappingInfo for each EntityPropertyMappingAttribute on it 
        /// Resouce type for which EntityPropertyMappingAttribute discovery is happening
        internal void BuildReflectionEpmInfo(ResourceType currentResourceType) 
        { 
            if (currentResourceType.BaseType != null)
            { 
                this.BuildReflectionEpmInfo(currentResourceType.BaseType);
            }

            foreach (EntityPropertyMappingAttribute epmAttr in currentResourceType.InstanceType.GetCustomAttributes(typeof(EntityPropertyMappingAttribute), currentResourceType.BaseType != null ? false : true)) 
            {
                this.BuildEpmInfo(epmAttr, currentResourceType, false); 
 
                if (this == currentResourceType)
                { 
                    if (!this.PropertyExistsInCurrentType(epmAttr))
                    {
                        this.InheritedEpmInfo.Add(epmAttr);
                    } 
                    else
                    { 
                        this.OwnEpmInfo.Add(epmAttr); 
                    }
                } 
            }
        }

        ///  
        /// Builds the EntityPropertyMappingInfo corresponding to an EntityPropertyMappingAttribute, also builds the delegate to
        /// be invoked in order to retrieve the property provided in the  
        ///  
        /// Source EntityPropertyMappingAttribute
        /// Type that has the attribute applied to it 
        /// Is EF provider being initialized, used for error message formatting
        internal void BuildEpmInfo(EntityPropertyMappingAttribute epmAttr, ResourceType definingType, bool isEFProvider)
        {
            // We don't need to check for null/empty status of the source path because it is already checked 
            // in the constructor for EntityPropertyMappingAttribute
            ParameterExpression rsrcParam = Expression.Parameter(typeof(object), "rsrc"); 
            ParameterExpression providerParam = Expression.Parameter(typeof(DataServiceProviderWrapper), "provider"); 
            ResourceProperty resourceProperty = null;
 
            Expression propValReaderExpr = this.BuildPropertyReader(
                                                        rsrcParam,
                                                        providerParam,
                                                        this, 
                                                        epmAttr.SourcePath.Split('/'),
                                                        0, 
                                                        ref resourceProperty); 
            Delegate dlgPropValReader = Expression.Lambda(propValReaderExpr, rsrcParam, providerParam).Compile();
            this.EpmSourceTree.Add(new EntityPropertyMappingInfo { Attribute = epmAttr, PropValReader = dlgPropValReader, DefiningType = definingType, IsEFProvider = isEFProvider }); 
        }

        /// 
        /// Sets the value  on the  object 
        /// 
        /// Target path segment containing the corresponding attribute information 
        /// Object on which to set property 
        /// Value to be set
        /// Current deserializer 
        internal void SetEpmValue(EpmTargetPathSegment currentSegment, Object currentValue, object propertyValue, EpmContentDeSerializerBase deserializer)
        {
            if (currentSegment.EpmInfo.Attribute.KeepInContent == false)
            { 
                this.SetPropertyValueFromPath(
                        currentSegment.EpmInfo.Attribute.SourcePath.Split('/'), 
                        this, 
                        currentValue,
                        propertyValue, 
                        0,
                        deserializer);
            }
        } 

        ///  
        /// Given a collection of  corresponding to a property access path 
        /// on the  object, sets the  on the property
        ///  
        /// Property access path where each element is a property name
        /// Resource type for which to set the property
        /// Object on which to set property
        /// Value of property 
        /// Index of the current segment being looked at
        /// Current deserializer 
        internal void SetPropertyValueFromPath( 
            String[] segments,
            ResourceType resourceType, 
            object element,
            object propertyValue,
            int currentIndex,
            EpmContentDeSerializerBase deserializer) 
        {
            String currentSegment = segments[currentIndex]; 
 
            ResourceProperty clientProp = resourceType.TryResolvePropertyName(currentSegment);
            ResourceType propertyType; 
            if (clientProp == null && resourceType.IsOpenType == false)
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidPropertyNameSpecified(currentSegment, resourceType.FullName));
            } 

            // If this is a open property OR we do not have to do type conversion for primitive types, 
            // read the type from the payload. 
            if (clientProp == null ||
                (!deserializer.Service.Configuration.EnableTypeConversion && clientProp.ResourceType.ResourceTypeKind == ResourceTypeKind.Primitive)) 
            {
                String foundTypeName = deserializer.PropertiesApplied.MapPropertyToType(String.Join("/", segments, 0, currentIndex + 1));
                if (foundTypeName != null)
                { 
                    propertyType = WebUtil.TryResolveResourceType(deserializer.Service.Provider, foundTypeName);
                    if (propertyType == null) 
                    { 
                        throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidTypeName(foundTypeName));
                    } 

                    if (propertyType.ResourceTypeKind == ResourceTypeKind.EntityType)
                    {
                        throw DataServiceException.CreateBadRequestError( 
                            Strings.PlainXml_EntityTypeNotSupported(propertyType.FullName));
                    } 
                } 
                else
                { 
                    propertyType = ResourceType.PrimitiveStringResourceType;
                }
            }
            else 
            {
                propertyType = clientProp.ResourceType; 
            } 

            object currentValue; 

            // Re-construct the source path to add the newly applied property
            string sourcePath = string.Join("/", segments, 0, currentIndex + 1);
 
            switch (propertyType.ResourceTypeKind)
            { 
                case ResourceTypeKind.ComplexType: 
                    if (!deserializer.PropertiesApplied.Lookup(sourcePath))
                    { 
                        // Complex types are treated as atomic and we never allow merging of properties belonging to
                        // a complex type.  In other words, we either update the whole complex type or not at all,
                        // never just a subset of its properties.  If the complex property has not been applied yet
                        // we create a new instance then apply its property mappings. 
                        currentValue = deserializer.Updatable.CreateResource(null, propertyType.FullName);
                        ResourceType.SetEpmProperty(element, currentSegment, currentValue, sourcePath, deserializer); 
                    } 
                    else
                    { 
                        // We've already created a new instance of the complex property by now, reuse the same instance.
                        currentValue = deserializer.Updatable.GetValue(element, currentSegment);
                        Debug.Assert(currentValue != null, "currentValue != null -- we should never be here if the complex property were null.");
                    } 

                    this.SetPropertyValueFromPath(segments, propertyType, currentValue, propertyValue, ++currentIndex, deserializer); 
                    break; 
                case ResourceTypeKind.EntityType:
                    throw DataServiceException.CreateBadRequestError( 
                        Strings.PlainXml_NavigationPropertyNotSupported(clientProp.Name));
                default:
                    Debug.Assert(
                        propertyType.ResourceTypeKind == ResourceTypeKind.Primitive, 
                        "property.TypeKind == ResourceTypeKind.Primitive -- metadata shouldn't return " + propertyType.ResourceTypeKind);
 
                    currentValue = PlainXmlDeserializer.ConvertValuesForXml(propertyValue, currentSegment, propertyType.InstanceType); 

                    // Do not try to update the property if it is a key property 
                    if (!deserializer.IsUpdateOperation || clientProp == null || !clientProp.IsOfKind(ResourcePropertyKind.Key))
                    {
                        ResourceType.SetEpmProperty(element, currentSegment, currentValue, sourcePath, deserializer);
                    } 

                    break; 
            } 
        }
 
        /// 
        /// Changes the key property to non key property and removes it from the key properties list
        /// 
        internal void RemoveKeyProperties() 
        {
            Debug.Assert(!this.isReadOnly, "The resource type cannot be sealed - RemoveKeyProperties"); 
            ReadOnlyCollection key = this.KeyProperties; 

            Debug.Assert(key.Count == 1, "Key Properties count must be zero"); 
            Debug.Assert(this.BaseType == null, "BaseType must be null");
            Debug.Assert(key[0].IsOfKind(ResourcePropertyKind.Key), "must be key property");

            ResourceProperty property = key[0]; 
            property.Kind = property.Kind ^ ResourcePropertyKind.Key;
        } 
 
        /// Tries to find the property for the specified name.
        /// Name of property to resolve. 
        /// Resolved property; possibly null.
        internal ResourceProperty TryResolvePropertyName(string propertyName)
        {
            // In case of empty property name this will return null, which means propery is not found 
            return this.Properties.FirstOrDefault(p => p.Name == propertyName);
        } 
 
        /// Tries to find the property declared on this type for the specified name.
        /// Name of property to resolve. 
        /// Resolved property; possibly null.
        internal ResourceProperty TryResolvePropertiesDeclaredOnThisTypeByName(string propertyName)
        {
            // In case of empty property name this will return null, which means propery is not found 
            return this.PropertiesDeclaredOnThisType.FirstOrDefault(p => p.Name == propertyName);
        } 
 
        /// 
        /// Checks if the given type is assignable to this type. In other words, if this type 
        /// is a subtype of the given type or not.
        /// 
        /// resource type to check.
        /// true, if the given type is assignable to this type. Otherwise returns false. 
        internal bool IsAssignableFrom(ResourceType superType)
        { 
            while (superType != null) 
            {
                if (superType == this) 
                {
                    return true;
                }
 
                superType = superType.BaseType;
            } 
 
            return false;
        } 

        /// 
        /// Gets the property info for the resource property
        ///  
        /// Resource property instance to get the property info
        /// Returns the propertyinfo object for the specified resource property. 
        /// The method searchies this type as well as all its base types for the property. 
        internal PropertyInfo GetPropertyInfo(ResourceProperty resourceProperty)
        { 
            Debug.Assert(resourceProperty != null, "resourceProperty != null");
            Debug.Assert(resourceProperty.CanReflectOnInstanceTypeProperty, "resourceProperty.CanReflectOnInstanceTypeProperty");

            PropertyInfo propertyInfo = null; 
            ResourceType resourceType = this;
            while (propertyInfo == null && resourceType != null) 
            { 
                propertyInfo = resourceType.GetPropertyInfoDecaredOnThisType(resourceProperty);
                resourceType = resourceType.BaseType; 
            }

            Debug.Assert(propertyInfo != null, "propertyInfo != null");
            return propertyInfo; 
        }
 
        /// Sets the value of the property. 
        /// The object whose property needs to be set.
        /// new value for the property. 
        /// metadata for the property to be set.
        internal void SetValue(object instance, object propertyValue, ResourceProperty resourceProperty)
        {
            Debug.Assert(instance != null, "instance != null"); 
            Debug.Assert(resourceProperty != null, "resourceProperty != null");
 
            MethodInfo setMethod = this.GetPropertyInfo(resourceProperty).GetSetMethod(); 
            if (setMethod == null)
            { 
                throw DataServiceException.CreateBadRequestError(Strings.BadRequest_PropertyValueCannotBeSet(resourceProperty.Name));
            }

            try 
            {
                setMethod.Invoke(instance, new object[] { propertyValue }); 
            } 
            catch (TargetInvocationException exception)
            { 
                ErrorHandler.HandleTargetInvocationException(exception);
                throw;
            }
            catch (ArgumentException exception) 
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequest_ErrorInSettingPropertyValue(resourceProperty.Name), exception); 
            } 
        }
 
        /// 
        /// Return the list of properties declared by this resource type. This method gives a chance to lazy load the properties
        /// of a resource type, instead of loading them upfront. This property will be called once and only once, whenever
        /// ResourceType.Properties or ResourceType.PropertiesDeclaredOnThisType property is accessed. 
        /// 
        /// the list of properties declared on this type. 
        protected virtual IEnumerable LoadPropertiesDeclaredOnThisType() 
        {
            return new ResourceProperty[0]; 
        }

        /// 
        /// Compares two resource property instances, sorting them so keys are first, 
        /// and are alphabetically ordered in case-insensitive ordinal order.
        ///  
        /// First property to compare. 
        /// Second property to compare.
        ///  
        /// Less than zero if a sorts before b; zero if equal; greater than zero if a sorts
        /// after b.
        /// 
        private static int ResourcePropertyComparison(ResourceProperty a, ResourceProperty b) 
        {
            return StringComparer.OrdinalIgnoreCase.Compare(a.Name, b.Name); 
        } 

        ///  
        /// Sets a mapped property value and mark its source path as applied
        /// 
        /// Object on which to set the property
        /// Name of the property 
        /// Value of the property
        /// Source mapping path for the property to be set 
        /// Current deserializer 
        private static void SetEpmProperty(object element, string propertyName, object propertyValue, string sourcePath, EpmContentDeSerializerBase deserializer)
        { 
            deserializer.Updatable.SetValue(element, propertyName, propertyValue);
            deserializer.PropertiesApplied.AddAppliedProperty(sourcePath, false);
        }
 
        /// 
        /// Initializes all properties for the resource type, to be used by Properties getter. 
        ///  
        /// Collection of properties exposed by this resource type.
        private ReadOnlyCollection InitializeProperties() 
        {
            if (this.allProperties == null)
            {
                ReadOnlyCollection readOnlyAllProps; 
                List allProps = new List();
                if (this.BaseType != null) 
                { 
                    allProps.AddRange(this.BaseType.Properties);
                } 

                allProps.AddRange(this.PropertiesDeclaredOnThisType);
                readOnlyAllProps = new ReadOnlyCollection(allProps);
 
                if (!this.isReadOnly)
                { 
                    return readOnlyAllProps; 
                }
 
                this.allProperties = readOnlyAllProps;
            }

            Debug.Assert(this.isReadOnly, "Propeties - at this point, the resource type must be readonly"); 
            return this.allProperties;
        } 
 
        /// 
        /// Validate the given  and adds it to the list of properties for this type 
        /// 
        /// property which needs to be added.
        private void AddPropertyInternal(ResourceProperty property)
        { 
            if (this.propertiesDeclaredOnThisType == null)
            { 
                this.propertiesDeclaredOnThisType = new List(); 
            }
 
            foreach (ResourceProperty resourceProperty in this.propertiesDeclaredOnThisType)
            {
                if (resourceProperty.Name == property.Name)
                { 
                    throw new InvalidOperationException(Strings.ResourceType_PropertyWithSameNameAlreadyExists(resourceProperty.Name, this.FullName));
                } 
            } 

            if (property.IsOfKind(ResourcePropertyKind.Key)) 
            {
                if (this.baseType != null)
                {
                    throw new InvalidOperationException(Strings.ResourceType_NoKeysInDerivedTypes); 
                }
 
                if (this.ResourceTypeKind != ResourceTypeKind.EntityType) 
                {
                    throw new InvalidOperationException(Strings.ResourceType_KeyPropertiesOnlyOnEntityTypes); 
                }

                Debug.Assert(property.TypeKind == ResourceTypeKind.Primitive, "This check must have been done in ResourceProperty.ValidatePropertyParameters method");
                Debug.Assert(!property.IsOfKind(ResourcePropertyKind.ETag), "This check must have been done in ResourceProperty.ValidatePropertyParameters method"); 
                Debug.Assert(property.IsOfKind(ResourcePropertyKind.Primitive), "This check must have been done in ResourceProperty.ValidatePropertyParameters method");
            } 
 
            if (property.IsOfKind(ResourcePropertyKind.ETag))
            { 
                if (this.ResourceTypeKind != ResourceTypeKind.EntityType)
                {
                    throw new InvalidOperationException(Strings.ResourceType_ETagPropertiesOnlyOnEntityTypes);
                } 
#if DEBUG
 
                Debug.Assert(property.TypeKind == ResourceTypeKind.Primitive, "This check must have been done in ResourceProperty.ValidatePropertyParameters method"); 
                Debug.Assert(property.IsOfKind(ResourcePropertyKind.Primitive), "This check must have been done in ResourceProperty.ValidatePropertyParameters method");
                Debug.Assert(!property.IsOfKind(ResourcePropertyKind.Key), "This check must have been done in ResourceProperty.ValidatePropertyParameters method"); 
#endif
            }

            this.propertiesDeclaredOnThisType.Add(property); 
        }
 
        ///  
        /// Gets the property info for the resource property declared on this type
        ///  
        /// Resource property instance to get the property info
        /// Returns the propertyinfo object for the specified resource property.
        private PropertyInfo GetPropertyInfoDecaredOnThisType(ResourceProperty resourceProperty)
        { 
            Debug.Assert(resourceProperty != null, "resourceProperty != null");
            Debug.Assert(resourceProperty.CanReflectOnInstanceTypeProperty, "resourceProperty.CanReflectOnInstanceTypeProperty"); 
 
            if (this.propertyInfosDeclaredOnThisType == null)
            { 
                this.propertyInfosDeclaredOnThisType = new Dictionary(ReferenceEqualityComparer.Instance);
            }

            PropertyInfo propertyInfo; 
            if (!this.propertyInfosDeclaredOnThisType.TryGetValue(resourceProperty, out propertyInfo))
            { 
                BindingFlags bindingFlags = WebUtil.PublicInstanceBindingFlags; 
                propertyInfo = this.InstanceType.GetProperty(resourceProperty.Name, bindingFlags);
                if (propertyInfo == null) 
                {
                    throw new DataServiceException(500, Strings.BadProvider_UnableToGetPropertyInfo(this.FullName, resourceProperty.Name));
                }
 
                this.propertyInfosDeclaredOnThisType.Add(resourceProperty, propertyInfo);
            } 
 
            Debug.Assert(propertyInfo != null, "propertyInfo != null");
            return propertyInfo; 
        }

        /// Given a resource type, builds the EntityPropertyMappingInfo for each of the dynamic entity property mapping attribute
        /// Resouce type for which EntityPropertyMappingAttribute discovery is happening 
        private void BuildDynamicEpmInfo(ResourceType currentResourceType)
        { 
            if (currentResourceType.BaseType != null) 
            {
                this.BuildDynamicEpmInfo(currentResourceType.BaseType); 
            }

            if (currentResourceType.HasEntityPropertyMappings)
            { 
                foreach (EntityPropertyMappingAttribute epmAttr in currentResourceType.AllEpmInfo.ToList())
                { 
                    this.BuildEpmInfo(epmAttr, currentResourceType, false); 

                    if (this == currentResourceType) 
                    {
                        if (!this.PropertyExistsInCurrentType(epmAttr))
                        {
                            this.InheritedEpmInfo.Add(epmAttr); 
                            this.OwnEpmInfo.Remove(epmAttr);
                        } 
                        else 
                        {
                            Debug.Assert(this.OwnEpmInfo.SingleOrDefault(attr => Object.ReferenceEquals(epmAttr, attr)) != null, "Own epmInfo should already have the given instance"); 
                        }
                    }
                }
            } 
        }
 
        ///  
        /// Given a source property path in segmented form, creates the correponding delegate that reads the
        /// property value from the resource type instance 
        /// 
        /// Generated expression tree
        /// Parameter expression for provider wrapper
        /// Resource type whose property is to be read 
        /// Collection of property names used for resource type property lookup
        /// Index of current property name in  
        /// Property representing the final property in the path. 
        /// Expression tree which results in access to property value
        private Expression BuildPropertyReader(Expression expr, Expression providerParam, ResourceType rsrcType, String[] srcPathSegments, int currentSegment, ref ResourceProperty rsrcProp) 
        {
            if (currentSegment == srcPathSegments.Length)
            {
                return Expression.Convert(expr, WebUtil.GetTypeAllowingNull(expr.Type)); 
            }
 
            String srcPathPart = srcPathSegments[currentSegment]; 

            rsrcProp = rsrcType != null ? rsrcType.TryResolvePropertyName(srcPathPart) : null; 

            // o.Prop
            Expression objectDotProp;
 
            // IProjectedResult.GetProjectedPropertyValue
            Expression projectedResultGetProp; 
 
            if (rsrcProp != null)
            { 
                // If this is the last part of the path, then it has to be a primitive type otherwise should be a complex type
                if (!rsrcProp.IsOfKind(currentSegment == srcPathSegments.Length - 1 ? ResourcePropertyKind.Primitive : ResourcePropertyKind.ComplexType))
                {
                    throw new InvalidOperationException(Strings.EpmSourceTree_EndsWithNonPrimitiveType(srcPathPart)); 
                }
 
                // object IProjectedResult.GetProjectedPropertyValue(string) 
                projectedResultGetProp = Expression.Call(
                    Expression.Convert(expr, typeof(IProjectedResult)), 
                    ResourceType.IProjectedResultGetProjectedPropertyValueMethodInfo,
                    Expression.Constant(rsrcProp.Name));

                Type nullableResourcePropertyType = WebUtil.GetTypeAllowingNull(rsrcProp.Type); 

                projectedResultGetProp = Expression.Condition( 
                                            Expression.Equal(projectedResultGetProp, Expression.Constant(DBNull.Value)), 
                                            Expression.Constant(null, nullableResourcePropertyType),
                                            Expression.Convert(projectedResultGetProp, nullableResourcePropertyType)); 

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

                objectDotProp = Expression.Call( 
                                    providerParam,
                                    ResourceType.GetPropertyValueMethodInfo, 
                                    expr, 
                                    Expression.Constant(rsrcProp),
                                    Expression.Constant(rsrcType)); 

                objectDotProp = Expression.Convert(objectDotProp, WebUtil.GetTypeAllowingNull(rsrcProp.Type));
            }
            else 
            {
                if (rsrcType == null || rsrcType.IsOpenType) 
                { 
                    // object IProjectedResult.GetProjectedPropertyValue(string)
                    projectedResultGetProp = Expression.Call( 
                        Expression.Convert(expr, typeof(IProjectedResult)),
                        ResourceType.IProjectedResultGetProjectedPropertyValueMethodInfo,
                        Expression.Constant(srcPathPart));
 
                    projectedResultGetProp = Expression.Condition(
                                                Expression.Equal(projectedResultGetProp, Expression.Constant(DBNull.Value)), 
                                                Expression.Constant(null, typeof(object)), 
                                                projectedResultGetProp);
 
                    // object WebUtil.GetNamedPropertyValue(object, string, provider)
                    objectDotProp = Expression.Call(
                                        null, /* instance */
                                        WebUtil.GetNamedPropertyValueMethodInfo, 
                                        expr,
                                        Expression.Constant(srcPathPart), 
                                        providerParam); 
                }
                else 
                {
                    throw new InvalidOperationException(Strings.EpmSourceTree_InaccessiblePropertyOnType(srcPathPart, rsrcType.Name));
                }
            } 

            Expression propertyAccess; 
 
            // IProjectedResult can occur only on the first level, as we don't allow projections into nav. properties
            //   or complex types. 
            // If it so happens that the source is a value type, it can't be IProjectedResult anyway.
            if (currentSegment == 0 && !expr.Type.IsValueType)
            {
                if (!WebUtil.TypeAllowsNull(objectDotProp.Type)) 
                {
                    objectDotProp = Expression.Convert(objectDotProp, WebUtil.GetTypeAllowingNull(objectDotProp.Type)); 
                } 

                // if (o is IProjectedResult) then o.GetProjectedPropertyValue(); else o.Prop; 
                propertyAccess = Expression.Condition(
                    Expression.TypeIs(expr, typeof(IProjectedResult)),
                    projectedResultGetProp,
                    objectDotProp); 
            }
            else 
            { 
                propertyAccess = objectDotProp;
            } 

            Expression recursiveExpr = this.BuildPropertyReader(
                                            propertyAccess,
                                            providerParam, 
                                            rsrcProp != null ? rsrcProp.ResourceType : null,
                                            srcPathSegments, 
                                            ++currentSegment, 
                                            ref rsrcProp);
 
            // o == null
            BinaryExpression objectIsNull = Expression.Equal(expr, Expression.Constant(null));

            ConstantExpression nullableNull = Expression.Constant( 
                            null,
                            WebUtil.GetTypeAllowingNull(recursiveExpr.Type)); 
 
            // if (o == null) then null; else o.Prop;
            return Expression.Condition(objectIsNull, nullableNull, recursiveExpr); 
        }

        /// 
        /// Does given property in the attribute exist in this type or one of it's base types 
        /// 
        /// Attribute which has PropertyName 
        /// true if property exists in current type, false otherwise 
        private bool PropertyExistsInCurrentType(EntityPropertyMappingAttribute epmAttr)
        { 
            int indexOfSeparator = epmAttr.SourcePath.IndexOf('/');
            String propertyToLookFor = indexOfSeparator == -1 ? epmAttr.SourcePath : epmAttr.SourcePath.Substring(0, indexOfSeparator);
            return this.PropertiesDeclaredOnThisType.Any(p => p.Name == propertyToLookFor);
        } 

        ///  
        /// Checks if the resource type is sealed. If not, it throws an InvalidOperationException. 
        /// 
        private void ThrowIfSealed() 
        {
            if (this.isReadOnly)
            {
                throw new InvalidOperationException(Strings.ResourceType_Sealed(this.FullName)); 
            }
        } 
 
        /// 
        /// Calls the virtual LoadPropertiesDeclaredOnThisType method, if its not already called and then 
        /// adds the properties returned by the method to the list of properties for this type.
        /// 
        private void GetPropertiesDeclaredOnThisType()
        { 
            // We just call the virtual LoadPropertiesDeclaredOnThisType method only once. If it hasn't been called yet,
            // then call the method and update the state to reflect that. 
            if (!this.isLoadPropertiesMethodCalled) 
            {
                foreach (ResourceProperty p in this.LoadPropertiesDeclaredOnThisType()) 
                {
                    this.AddPropertyInternal(p);

                    // if this type is already set to readonly, make sure that new properties returned by the virtual method 
                    // are also set to readonly
                    if (this.IsReadOnly) 
                    { 
                        p.SetReadOnly();
                    } 
                }

                this.isLoadPropertiesMethodCalled = true;
            } 
        }
 
        ///  
        /// This method is called only when the Properties property is called and the type is already set to read-only.
        /// This method validates all the properties w.r.t to the base type and calls SetReadOnly on all the properties. 
        /// 
        private void ValidateType()
        {
            Debug.Assert(this.isLoadPropertiesMethodCalled && this.IsReadOnly, "This method must be invoked only if LoadPropertiesDeclaredOnThisType has been called and the type is set to ReadOnly"); 

            if (this.BaseType != null) 
            { 
                // make sure that there are no properties with the same name. Properties with duplicate name within the type
                // is already checked in AddProperty method 
                foreach (ResourceProperty rp in this.BaseType.Properties)
                {
                    if (this.propertiesDeclaredOnThisType.Where(p => p.Name == rp.Name).FirstOrDefault() != null)
                    { 
                        throw new InvalidOperationException(Strings.ResourceType_PropertyWithSameNameAlreadyExists(rp.Name, this.FullName));
                    } 
                } 
            }
            else if (this.ResourceTypeKind == ResourceTypeKind.EntityType) 
            {
                if (this.propertiesDeclaredOnThisType.Where(p => p.IsOfKind(ResourcePropertyKind.Key)).FirstOrDefault() == null)
                {
                    throw new InvalidOperationException(Strings.ResourceType_MissingKeyPropertiesForEntity(this.FullName)); 
                }
            } 
 
            // set all the properties to readonly
            foreach (ResourceProperty p in this.propertiesDeclaredOnThisType) 
            {
                p.SetReadOnly();

                // Note that we cache the propertyinfo objects for each CLR properties in the ResourceType class 
                // rather than the ResourceProperty class because the same ResourceProperty instance can be added
                // to multiple ResourceType instances. 
                if (p.CanReflectOnInstanceTypeProperty) 
                {
                    this.GetPropertyInfoDecaredOnThisType(p); 
                }
            }

            // Resolve EpmInfos now that everything in the type hierarchy is readonly 
            try
            { 
                if (this.EpmInfoInitialized == false) 
                {
                    this.BuildDynamicEpmInfo(this); 
                    this.EpmInfoInitialized = true;
                }
            }
            catch 
            {
                // If an exception was thrown from this.BuildDynamicEpmInfo(this) method 
                // EpmSourceTree and EpmTargetTree may be only half constructed and need to be reset. 
                if (this.HasEntityPropertyMappings && !this.EpmInfoInitialized)
                { 
                    this.epmInfo.Reset();
                }

                throw; 
            }
        } 
 
        #endregion Methods.
 
        #region EpmInfoPerResourceType

        /// Holder of Epm related data structure per resource type
        private sealed class EpmInfoPerResourceType 
        {
            /// EpmSourceTree per  
            private EpmSourceTree epmSourceTree; 

            /// EpmTargetTree per  
            private EpmTargetTree epmTargetTree;

            /// Inherited EpmInfo
            private List inheritedEpmInfo; 

            /// Own EpmInfo 
            private List ownEpmInfo; 

            /// Property for obtaining EpmSourceTree for a type 
            internal EpmSourceTree EpmSourceTree
            {
                get
                { 
                    if (this.epmSourceTree == null)
                    { 
                        this.epmSourceTree = new EpmSourceTree(this.EpmTargetTree); 
                    }
 
                    return this.epmSourceTree;
                }
            }
 
            /// Property for obtaining EpmTargetTree for a type
            internal EpmTargetTree EpmTargetTree 
            { 
                get
                { 
                    if (this.epmTargetTree == null)
                    {
                        this.epmTargetTree = new EpmTargetTree();
                    } 

                    return this.epmTargetTree; 
                } 
            }
 
            /// Inherited EpmInfo
            internal List InheritedEpmInfo
            {
                get 
                {
                    if (this.inheritedEpmInfo == null) 
                    { 
                        this.inheritedEpmInfo = new List();
                    } 

                    return this.inheritedEpmInfo;
                }
            } 

            /// Own EpmInfo 
            internal List OwnEpmInfo 
            {
                get 
                {
                    if (this.ownEpmInfo == null)
                    {
                        this.ownEpmInfo = new List(); 
                    }
 
                    return this.ownEpmInfo; 
                }
            } 

            /// 
            /// Removes all data created internally by ResourceType. This is needed when building epm
            /// info fails since the trees may be left in undefined state (i.e. half constructed) and 
            /// if inherited EPM attributes exist duplicates will be added.
            ///  
            internal void Reset() 
            {
                this.epmTargetTree = null; 
                this.epmSourceTree = null;
                this.inheritedEpmInfo = null;
            }
        } 

        #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