private static void GenerateScript <TAttributeGroup, TPropertyAttribute>(string scriptName, string templateName, string entryFormat)
            where TPropertyAttribute : IAttribute
        {
            string[] templateAssets = AssetDatabase.FindAssets(templateName);
            if (templateAssets.Length == 0)
            {
                return;
            }

            string templateGUID         = templateAssets[0];
            string templateRelativePath = AssetDatabase.GUIDToAssetPath(templateGUID);
            string templateFullPath     = (Application.dataPath.Replace("Assets", string.Empty) + templateRelativePath).Replace("/", "\\");
            string templateFormat       = IOUtility.ReadFromFile(templateFullPath);

            StringBuilder entriesBuilder = new StringBuilder();
            List <Type>   subTypes       = GetAllSubTypes(typeof(TAttributeGroup));

            foreach (var subType in subTypes)
            {
                IAttribute[] attributes =
                    (IAttribute[])subType.GetCustomAttributes(typeof(TPropertyAttribute), true);

                if (attributes.Length > 0)
                {
                    entriesBuilder.AppendFormat(entryFormat, attributes[0].TargetAttributeType.Name, subType.Name);
                }
            }

            string scriptContent = templateFormat
                                   .Replace(CLASS_NAME_PLACEHOLDER, scriptName)
                                   .Replace(ENTRIES_PLACEHOLDER, entriesBuilder.ToString());

            string scriptPath = GENERATED_CODE_TARGET_FOLDER + scriptName + ".cs";

            IOUtility.WriteToFile(scriptPath, Regex.Replace(scriptContent, @"\r\n|\n\r|\r|\n", Environment.NewLine));
        }