private static void InitRoots(YamlyProjectAssemblies assemblies)
        {
            if (_roots != null)
            {
                return;
            }

            var gen = new ProxyCodeGenerator
            {
                TargetAssemblies = assemblies.All.Except(assemblies.IgnoreAssemblies).ToArray()
            };

            _roots = new List <RootDefinition>();
            foreach (var r in gen.GetRootDefinitions().ToList())
            {
                if (r.Assembly == assemblies.MainRuntimeAssembly ||
                    r.Assembly == assemblies.MainEditorAssembly)
                {
                    Debug.LogWarning($"Config root {r.Root.FullName} is defined in assembly {r.Assembly.FullName}. This is not supported - please put it into separate assembly with AssemblyDefinition or manually.");
                    continue;
                }

                _roots.Add(r);
            }

            var groups = _roots.SelectMany(r => r.Attributes)
                         .Select(a => a.Group)
                         .ToList();

            foreach (var group in groups.Distinct())
            {
                if (groups.Count(g => g == group) > 1)
                {
                    var roots = _roots.Where(r => r.Contains(group));

                    var log = new StringBuilder();
                    log.AppendFormat("Group name \"{0}\" is declared multiple times. This is not supported.", group).AppendLine();
                    log.AppendLine("Declarations found in these types:");
                    foreach (var root in roots)
                    {
                        log.AppendFormat("{0} ({1})", root.Root.Name, root.Root.AssemblyQualifiedName).AppendLine();
                    }

                    log.AppendLine("These group will be ignored until duplication is fixed.");

                    Debug.LogError(log);
                }
            }
        }
        private static void BuildAssembly(YamlyProjectAssemblies assemblies, bool debug = false)
        {
            var outputAssetsPath = CodeGenerationUtility.GetProxyAssemblyOutputPath(assemblies.ProxyAssembly);

            if (Settings.VerboseLogs)
            {
                Debug.Log($"Build proxy assembly at path {outputAssetsPath}");
            }

            var assetPathsToReimport = new List <string>(2);

            var outputSystemPath = Application.dataPath.Replace("Assets", outputAssetsPath);
            var assemblyBuilder  = new ProxyAssemblyBuilder
            {
                TargetAssemblies        = assemblies.TargetAssemblies,
                IgnoreAssemblies        = assemblies.IgnoreAssemblies,
                OutputAssembly          = outputSystemPath,
                TreatWarningsAsErrors   = true,
                IncludeDebugInformation = debug
            }.Build();

            if (assemblyBuilder.CompilerResults.Errors.Count != 0)
            {
                Debug.LogError($"Proxy assembly builder have {assemblyBuilder.CompilerResults.Errors.Count} errors!");
                foreach (var error in assemblyBuilder.CompilerResults.Errors)
                {
                    Debug.LogError(error);
                }

                return;
            }

            if (Settings.VerboseLogs)
            {
                Debug.Log("Proxy assembly builder have no errors.");
            }

            assetPathsToReimport.Add(outputAssetsPath);

            if (assemblies.ProxyAssembly != null)
            {
                outputSystemPath = CodeGenerationUtility.GetUtilityAssemblySystemPath();
                outputAssetsPath = outputSystemPath.ToAssetsPath();

                if (Settings.VerboseLogs)
                {
                    Debug.Log($"Build utility assembly at path {outputAssetsPath}");
                }

                var groups         = _roots.SelectMany(r => r.Attributes).Select(a => a.Group).Distinct().ToArray();
                var utilityBuilder = new UtilityAssemblyBuilder(groups)
                {
                    OutputAssembly  = outputSystemPath,
                    TargetNamespace = "Yamly.UnityEditor.Utility"
                }.Build();

                if (utilityBuilder.CompilerResults.Errors.Count != 0)
                {
                    Debug.LogError($"Utility assembly builder have {utilityBuilder.CompilerResults.Errors.Count} errors!");
                    foreach (var error in utilityBuilder.CompilerResults.Errors)
                    {
                        Debug.LogError(error);
                    }

                    return;
                }

                if (Settings.VerboseLogs)
                {
                    Debug.Log("Utility assembly builder have no errors.");
                }

                assetPathsToReimport.Add(utilityBuilder.OutputAssembly.ToAssetsPath());
            }
            else
            {
                if (Settings.VerboseLogs)
                {
                    Debug.Log("Delay building utility assembly until proxy assembly imported.");
                }

                YamlyEditorPrefs.IsAssemblyBuildPending = true;
            }

            try
            {
                AssetDatabase.StartAssetEditing();
                foreach (var assetPath in assetPathsToReimport)
                {
                    AssetDatabase.ImportAsset(assetPath);
                }
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }

            AssetDatabase.StopAssetEditing();
            AssetDatabase.Refresh(ImportAssetOptions.Default);
        }