public IEnumerable<string> Resolve(Func<string, bool> predicate) { IEnumerable<string> files = Directory.EnumerateFiles( this.applicationRoot.AppendPath(this.scriptsDirectory), this.scriptFilePattern, SearchOption.AllDirectories); FileInfo[] fileInfos = files.Where(predicate).Select(file => new FileInfo(file.ToLowerInvariant())).ToArray(); var edges = new HashSet<Edge<string>>(); var scripts = new Dictionary<string, string>(); foreach (FileInfo source in fileInfos) { string script = File.ReadAllText(source.FullName); scripts.Add(source.FullName, DependencyRegex.Replace(script, string.Empty)); if (source.Directory != null) { string directory = source.Directory.FullName; Debug.Assert(directory != null, "directory != null"); Match match = DependencyRegex.Match(script); while (match.Success) { string path = match.Groups["path"].Value; string rootPath = path.StartsWith("~") || path.StartsWith("/") ? this.applicationRoot : directory; var target = new FileInfo(rootPath.AppendPath(path)); if (!target.Exists) { throw new InvalidOperationException( string.Format( "The script file \"{0}\" has a reference (\"{1}\") that points to a non-existant file", source.FullName, path)); } edges.Add(new Edge<string>(source.FullName, target.FullName.ToLowerInvariant())); match = match.NextMatch(); } } } IEnumerable<string> sortedEdges; try { sortedEdges = edges.ToAdjacencyGraph<string, Edge<string>>(false).TopologicalSort(); } catch (NonAcyclicGraphException exception) { throw new InvalidOperationException("A script file has a circular dependency", exception); } return sortedEdges.Reverse().Where(scripts.ContainsKey).Select(s => scripts[s]); }