protected List <MappedProperty> GetPropertiesHierarchy(Type rootType, Type propertyType, List <string> parentPropertyNames)
        {
            List <MappedProperty> list = new List <MappedProperty>();

            BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance;

            PropertyInfo[]      allEntityProperties = propertyType.GetProperties(bindingFlags);
            List <PropertyInfo> mappedProperties    = allEntityProperties.Where(
                p =>
            {
                Type underlined = Nullable.GetUnderlyingType(p.PropertyType);
                Type property   = underlined ?? p.PropertyType;
                return(property.IsValueType == true ||
                       property.IsPrimitive ||
                       property == typeof(string));
            })
                                                      .ToList();

            foreach (PropertyInfo supportedProp in mappedProperties)
            {
                List <string> namesHierarchy = parentPropertyNames.ToList();
                namesHierarchy.Add(supportedProp.Name);

                string efDefaultName = ReflectionUtility.ConcatenateEfPropertyName(namesHierarchy);
                string efMappedName  = DbContextExtensions.GetColumnName(_context, rootType, efDefaultName);
                list.Add(new MappedProperty
                {
                    PropertyInfo  = supportedProp,
                    EfDefaultName = efDefaultName,
                    EfMappedName  = efMappedName
                });
            }

            List <PropertyInfo> complexProperties = allEntityProperties.Where(
                p => p.PropertyType != typeof(string) &&
                p.PropertyType.IsClass)
                                                    .ToList();

            //Exclude navigation properties
            //ICollection properties are excluded already as interfaces and not classes.
            //Here we exclude virtual properties that are not ICollection, by checking if they are virtual.
            complexProperties = complexProperties
                                .Where(x => x.GetAccessors()[0].IsVirtual == false)
                                .ToList();

            foreach (PropertyInfo complexProp in complexProperties)
            {
                List <string> namesHierarchy = parentPropertyNames.ToList();
                namesHierarchy.Add(complexProp.Name);

                List <MappedProperty> childProperties = GetPropertiesHierarchy(rootType, complexProp.PropertyType, namesHierarchy);
                if (childProperties.Count > 0)
                {
                    list.Add(new MappedProperty
                    {
                        PropertyInfo    = complexProp,
                        ChildProperties = childProperties
                    });
                }
            }

            return(list);
        }