private static IEnumerable <string> EnumerateAllFiles(
            string source,
            string filters,
            List <string> virtualEnvPaths
            )
        {
            var files    = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
            var patterns = filters.Split(';').Concat(new[] { "*.py" }).Select(p => p.Trim()).ToArray();

            var directories = new List <string>()
            {
                source
            };
            var skipDirectories = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            try {
                directories.AddRange(Directory.EnumerateDirectories(source, "*", SearchOption.AllDirectories));
            } catch (UnauthorizedAccessException) {
            }

            foreach (var dir in directories)
            {
                if (UnwindDirectory(dir).Any(skipDirectories.Contains))
                {
                    continue;
                }

                try {
                    if (virtualEnvPaths != null)
                    {
                        var origPrefix = VirtualEnv.GetOrigPrefixPath(dir);
                        if (!string.IsNullOrEmpty(origPrefix))
                        {
                            virtualEnvPaths.Add(dir);
                            skipDirectories.Add(CommonUtils.TrimEndSeparator(dir));
                            continue;
                        }
                    }

                    foreach (var filter in patterns)
                    {
                        files.UnionWith(Directory.EnumerateFiles(dir, filter));
                    }
                } catch (UnauthorizedAccessException) {
                }
            }

            return(files
                   .Where(path => path.StartsWith(source))
                   .Select(path => path.Substring(source.Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar))
                   .Distinct(StringComparer.OrdinalIgnoreCase));
        }