private static HashSet <string> GetSkipAssemblies(string skipAssemblyFile, string sourceAssembliesFolder, string[] rootFilter)
        {
            skipAssemblyFile ??= string.Empty;
            var skipAssemblies = new string[] { };

            if (File.Exists(skipAssemblyFile))
            {
                skipAssemblies = File.ReadAllLines(skipAssemblyFile)
                                 .Where(line => !string.IsNullOrWhiteSpace(skipAssemblyFile))
                                 .ToArray();
            }
            else
            {
                skipAssemblies = skipAssemblyFile.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            }

            var assemblyMap = FindConflictsProgram.GetAllAssembliesV2(sourceAssembliesFolder, rootFilter);

            // TODO: enhance search
            var allAssemblies = assemblyMap.SelectMany(a => a.Value.GetReferencedAssemblies().Select(x => x.Name)).ToList();

            allAssemblies.AddRange(assemblyMap.Keys);
            var skipAssemblyMap = skipAssemblies
                                  .SelectMany(skipAssemblyName => allAssemblies.Where(a => a.StartsWith(skipAssemblyName, StringComparison.OrdinalIgnoreCase)))
                                  .OrderBy(x => x)
                                  .ToHashSet(StringComparer.OrdinalIgnoreCase);

            var dependenciesOfSkipAssemblies = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
            var processQueue = new Queue <string>(skipAssemblyMap);

            while (processQueue.Count != 0)
            {
                var assemblyName = processQueue.Dequeue();
                if (!dependenciesOfSkipAssemblies.Contains(assemblyName) &&
                    assemblyMap.ContainsKey(assemblyName))
                {
                    dependenciesOfSkipAssemblies.Add(assemblyName);
                    var refs = assemblyMap[assemblyName].GetReferencedAssemblies();
                    foreach (var refAssembly in refs)
                    {
                        processQueue.Enqueue(refAssembly.Name);
                    }
                }
            }

            var assembliesRefByMap = FindConflictsProgram.GetAssembliesRefByMap(sourceAssembliesFolder, rootFilter);

            bool changedOnce;

            do
            {
                changedOnce = false;
                foreach (var assemblyName in dependenciesOfSkipAssemblies.ToList())
                {
                    if (assembliesRefByMap.ContainsKey(assemblyName))
                    {
                        var assemblyInfo = assembliesRefByMap[assemblyName];
                        var validRefs    = assemblyInfo
                                           .Select(x => x.GetName().Name)
                                           .Where(x => !skipAssemblyMap.Contains(x))
                                           .ToList();

                        if (validRefs.Count == 0)
                        {
                            skipAssemblyMap.Add(assemblyName);
                            dependenciesOfSkipAssemblies.Remove(assemblyName);
                            changedOnce = true;
                        }
                    }
                }
            }while (changedOnce);

            return(skipAssemblyMap.OrderBy(x => x).ToHashSet(StringComparer.OrdinalIgnoreCase));
        }