private void ValidateFields(Type validationTest, IEnumerable <FieldInfo> fields, AbstractPluginManager pluginManager)
        {
            ValidationResult result;

            foreach (FieldInfo field in fields)
            {
                AbstractSettingSO fieldInstance = field.GetValue(pluginManager.Profile) as AbstractSettingSO;
                if (fieldInstance == null)
                {
                    AddOrUpdateAsError(field.Name, pluginManager, "Must provide a Setting Scriptable Object");
                    return;
                }

                ResultCollection.Remove(field.Name);

                if (field.FieldType == typeof(GenericSettingSO <>))
                {
                    ValidateGenericSettingField(field, pluginManager, fieldInstance);
                }

                Type type = field.FieldType;
                // Validate the field according to the SO validation setting.
                result = (ValidationResult)type.InvokeMember("Validate",
                                                             BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,
                                                             null, fieldInstance, new object[] { validationTest, pluginManager });

                ResultCollection.AddOrUpdate(result, validationTest.Name);

                IEnumerable <FieldInfo> childFields = field.FieldType.GetFields()
                                                      .Where(childField => childField.FieldType.IsSubclassOf(typeof(AbstractSettingSO)));
                ValidateChildFields(validationTest, pluginManager, childFields, fieldInstance);
            }
        }
        private void ValidateGenericSettingField(FieldInfo field, AbstractPluginManager pluginManager, AbstractSettingSO fieldInstance)
        {
            string className    = ((GenericSettingSO <T>)fieldInstance).valueClassName;
            string accessorName = ((GenericSettingSO <T>)fieldInstance).valueName;

            if ((className != null && className.Length > 0) ||
                (accessorName != null && accessorName.Length > 0))
            {
                IEnumerable <Type> propertyTypes = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
                                                    from candidate in assembly.GetTypes()
                                                    where candidate.Name == className
                                                    select candidate);
                Type propertyType = propertyTypes.FirstOrDefault();

                if (propertyType == null)
                {
                    string msg = "A property accessor is provided but the class identified, `"
                                 + className + "`, cannot be found in the Assembly.";
                    AddOrUpdateAsError(field.Name, pluginManager, msg);
                }
                else
                {
                    PropertyInfo accessorPropertyInfo = propertyType.GetProperty(accessorName);
                    FieldInfo    acessorFieldInfo     = propertyType.GetField(accessorName);
                    if (accessorPropertyInfo == null && acessorFieldInfo == null)
                    {
                        string msg = "A property accessor is provided but the accessor identified, `"
                                     + accessorName + "`, cannot be found in the class specified, `" + className + "`.";
                        AddOrUpdateAsError(field.Name, pluginManager, msg);
                    }
                }
            }
        }