internal EntityTracker(ODataClient oDataClient, object entity)
        {
            Contract.Requires<ArgumentNullException>(oDataClient != null);
            Contract.Requires<ArgumentNullException>(entity != null);

            _oDataClient = oDataClient;
            _entity = entity;
            _entityTypeInfo = oDataClient.GetEntityTypeInfoFor(entity.GetType());

            if (_entityTypeInfo == null)
            {
                throw new ArgumentException("Entity type " + entity.GetType() + " is unknown in the OData Client.");
            }

            _linkCollectionTrackers = new LinkCollectionTracker[_entityTypeInfo.CollectionProperties.Length];
            for (int i = 0; i < _entityTypeInfo.CollectionProperties.Length; ++i)
            {
                PropertyInfo property = _entityTypeInfo.CollectionProperties[i];
                IEnumerable collection = (IEnumerable) property.GetValue(_entity, null);
                if (collection != null)
                {
                    _linkCollectionTrackers[i] = new LinkCollectionTracker(this, property.Name, collection);
                }
            }

            INotifyPropertyChanged inpc = _entity as INotifyPropertyChanged;
            if (inpc != null)
            {
                // Use change tracking for more efficiency (possibly)
                inpc.PropertyChanged += OnPropertyChanged;
            }
        }
        internal EntitySetInfo(IEdmModel edmModel, IEdmEntitySet edmEntitySet, ITypeResolver typeResolver)
        {
            Contract.Assert(edmModel != null);
            Contract.Assert(edmEntitySet != null);
            Contract.Assert(typeResolver != null);

            Name = edmEntitySet.Name;
            ElementType = new EntityTypeInfo(edmModel, edmEntitySet.ElementType, typeResolver);
            var entityTypes = new List<EntityTypeInfo>(3) { ElementType };

            // Create an EntityTypeInfo for any derived types in the model
            foreach (var edmDerivedType in edmModel.FindAllDerivedTypes(edmEntitySet.ElementType).OfType<IEdmEntityType>())
            {
                entityTypes.Add(new EntityTypeInfo(edmModel, edmDerivedType, typeResolver));
            }

            // Connect any derived types with their base class
            for (int i = 1; i < entityTypes.Count; ++i)
            {
                var baseEdmEntityType = entityTypes[i].EdmEntityType.BaseEntityType();
                if (baseEdmEntityType != null)
                {
                    var baseEntityTypeInfo = entityTypes.First(entityTypeInfo => entityTypeInfo.EdmEntityType == baseEdmEntityType);
                    if (baseEntityTypeInfo != null)
                    {
                        entityTypes[i].BaseTypeInfo = baseEntityTypeInfo;
                    }
                }
            }

            EntityTypes = entityTypes;
        }