public object InheritedCollections(
            ResourceProfileData profileData,
            ResourceClassBase resource,
            TemplateContext templateContext)
        {
            if (resource.IsDescriptorEntity())
            {
                return(ResourceRenderer.DoRenderProperty);
            }

            string ns = profileData.GetProfileNamespace(resource);

            var activeResource = profileData.GetProfileActiveResource(resource);

            return(activeResource.IsDerived && activeResource.Collections.Any()
                ? new
            {
                Inherited =
                    activeResource.Collections
                    .Where(x => x.IsInherited)
                    .OrderBy(x => x.PropertyName)
                    .Select(
                        x => new
                {
                    BaseEntity =
                        $"{resource.Entity.BaseEntity.Name}.{resource.Entity.BaseEntity.SchemaProperCaseName()}",
                    BaseEntityInterfaceName = $"I{resource.Entity.BaseEntity.Name}",
                    ItemTypeNamespacePrefix = GetContextualNamespacePrefix(x.ItemType),
                    ItemType = x.ItemType.Name,
                    Collection = x.ItemType.PluralName,
                    PropertyName = x.PropertyName,
                    JsonPropertyName =
                        x.IsDerivedEntityATypeEntity()
                                            ? x.Association.OtherEntity.PluralName.ToCamelCase()
                                            : x.JsonPropertyName,
                    PropertyFieldName = x.ItemType.PluralName.ToCamelCase(),
                    ParentName = x.ParentFullName.Name,
                    PropertyNamespace = ns,
                    ResourceName = resource.Name,
                    Standard =
                        profileData.IsIncluded(resource, x) &&
                        !profileData.IsFilteredCollection(resource, x),
                    Null = !profileData.IsIncluded(resource, x),
                    Filtered = profileData.IsIncluded(resource, x) &&
                               profileData.IsFilteredCollection(
                        resource,
                        x)
                })
                    .ToList()
            }
                : ResourceRenderer.DoNotRenderProperty);
        }
        public object CreatePutPostRequestValidator(
            ResourceProfileData profileData,
            ResourceClassBase resource,
            TemplateContext templateContext)
        {
            var resourceChildItem = resource as ResourceChildItem;

            return(new PutPostRequestValidator
            {
                EntityName = resource.Name,
                Collections = resource.Collections
                              // TODO: Remove this filter with dynamic profiles
                              .Where(collection => !profileData.HasProfile || profileData.IsIncluded(resource, collection))
                              .Select(
                    collection => new PutPostRequestValidatorCollectionProperty
                {
                    PropertyName = collection.PropertyName,
                    PropertyFieldNamePrefix = collection.PropertyName.ToCamelCase(),
                    ItemTypeName = collection.ItemType.Name,
                    Namespace = collection.ParentFullName.Name != resource.Name
                                ? string.Format(
                        "{0}.{1}.{2}",
                        collection.ParentFullName.Name,
                        profileData.HasProfile ? resource.SchemaProperCaseName : resource.Entity.BaseEntity.SchemaProperCaseName(),
                        profileData.ProfilePropertyNamespaceSection)
                                : ResourceRenderer.DoNotRenderProperty
                }),
                HasProfileItemFilterValidations = profileData.HasProfile &&
                                                  profileData.IsWritable &&
                                                  profileData.HasFilteredCollection() &&
                                                  GetItemFilterValidations().Any(),
                ProfileItemFilterValidations = GetItemFilterValidations(),
                KeyUnificationValidations = new KeyUnificationValidation
                {
                    ResourceClassName = resource.Name,
                    ParentResourceClassName = resourceChildItem?.Parent.Name,
                    UnifiedProperties = resource.AllProperties
                                        // TODO: Remove this filter with dynamic profiles
                                        .Where(rp => !profileData.HasProfile || profileData.IsIncluded(resource, rp))
                                        .Where(rp => rp.IsUnified())
                                        .Select(rp => new UnifiedProperty
                    {
                        UnifiedPropertyName = rp.PropertyName,
                        UnifiedJsonPropertyName = rp.JsonPropertyName,
                        UnifiedCSharpPropertyType = rp.PropertyType.ToCSharp(),
                        UnifiedPropertyIsFromParent = rp.EntityProperty.IncomingAssociations
                                                      .Any(a => a.IsNavigable),
                        UnifiedPropertyParentPath = resourceChildItem != null && resourceChildItem.IsResourceExtension
                                ? string.Join(
                            string.Empty,
                            resourceChildItem.GetLineage().TakeWhile(l => !l.IsResourceExtension)
                            .Select(l => "." + l.Name))
                                : null,
                        References = rp.EntityProperty.IncomingAssociations
                                     .Where(a => !a.IsNavigable && rp.Parent.ReferenceByName.ContainsKey(a.Name + "Reference"))
                                     .Select(a => new
                        {
                            Reference = rp.Parent.ReferenceByName[a.Name + "Reference"],
                            OtherEntityPropertyName = a.PropertyMappings.Where(pm => pm.ThisProperty.Equals(rp.EntityProperty)).Select(pm => pm.OtherProperty.PropertyName).Single(),
                        })
                                     // TODO: Remove this filter with dynamic profiles
                                     .Where(x => !profileData.HasProfile || profileData.IsIncluded(resource, x.Reference))
                                     .Select(x => new
                        {
                            Reference = x.Reference,
                            ReferenceProperty =
                                (x.Reference.ReferenceTypeProperties
                                 .SingleOrDefault(rtp => rtp.EntityProperty.PropertyName == x.OtherEntityPropertyName)
                                 // Deal with the special case of the re-pointing of the identifying property from USI to UniqueId in Person entities
                                 ?? x.Reference.ReferenceTypeProperties
                                 .Single(rtp => rtp.EntityProperty.PropertyName ==
                                         EdFi.Ods.Common.Specifications.UniqueIdSpecification.GetUniqueIdPropertyName(x.OtherEntityPropertyName)))
                        })
                                     .Select(x => new UnifiedReferenceProperty
                        {
                            ReferenceName = x.Reference.PropertyName,
                            ReferenceJsonName = x.Reference.JsonPropertyName,
                            ReferencePropertyName = x.ReferenceProperty.PropertyName,
                            ReferenceJsonPropertyName = x.ReferenceProperty.JsonPropertyName
                        })
                    })
                }
            });

            IEnumerable <ItemFilterValidation> GetItemFilterValidations()
            {
                return(resource.Collections
                       .Where(x => profileData.IsFilteredCollection(resource, x))
                       .OrderBy(x => x.PropertyName)
                       .SelectMany(
                           x => profileData.GetFilteredCollection(resource, x)
                           .ValueFilters
                           .Select(
                               y => new ItemFilterValidation
                {
                    PropertyName = x.PropertyName,
                    ValidatorName = x.ItemType.Name,
                    ValidatorPropertyName = y.PropertyName,
                    PropertyFieldName = x.ItemType.Name.ToCamelCase(),
                    Filters = string.Join(", ", y.Values.Select(s => string.Format("'{0}'", s))),
                    ProfileName = profileData.ProfileName
                })));
            }
        }