     }
 }
 
-extension Package {
-    private func sourceRoot() throws -> AbsolutePath {
+/// Helper for constructing a package following the convention system.
+private struct PackageBuilder {
+    /// The package being constructed.
+    let package: Package
+
+    /// The package manifest.
+    var manifest: Manifest {
+        return package.manifest
+    }
+
+    /// The path of the package.
+    var path: AbsolutePath {
+        return package.path
+    }
+
+    // MARK: Utility Predicates
+    
+    func isValidSource(_ path: AbsolutePath) -> Bool {
+        return isValidSource(path, validExtensions: SupportedLanguageExtension.validExtensions)
+    }
+    
+    func isValidSource(_ path: AbsolutePath, validExtensions: Set<String>) -> Bool {
+        if path.basename.hasPrefix(".") { return false }
+        if path == manifest.path { return false }
+        if excludedPaths.contains(path) { return false }
+        if !path.asString.isFile { return false }
+        guard let ext = path.asString.fileExt else { return false }
+        return validExtensions.contains(ext)
+    }
+    
+    func shouldConsiderDirectory(_ path: AbsolutePath) -> Bool {
+        let base = path.basename.lowercased()
+        if base == "tests" { return false }
+        if base == "include" { return false }
+        if base.hasSuffix(".xcodeproj") { return false }
+        if base.hasSuffix(".playground") { return false }
+        if base.hasPrefix(".") { return false }  // eg .git
+        if excludedPaths.contains(path) { return false }
+        if path == packagesDirectory { return false }
+        if !path.asString.isDirectory { return false }
+        return true
+    }
+
+    var packagesDirectory: AbsolutePath {
+        return path.appending("Packages")
+    }
+
+    var excludedPaths: [AbsolutePath] {
+        return manifest.package.exclude.map { path.appending(RelativePath($0)) }
+    }
+    
+    var pkgConfigPath: RelativePath? {
+        guard let pkgConfig = manifest.package.pkgConfig else { return nil }
+        return RelativePath(pkgConfig)
+    }
+    
+    func sourceRoot() throws -> AbsolutePath {
         let viableRoots = walk(path, recursively: false).filter { entry in
             switch entry.basename.lowercased() {
             case "sources", "source", "src", "srcs":

    // it makes sense.
    public static func createUsingConventions(manifest: Manifest, includingTestModules: Bool) throws -> Package {
        let package = Package(manifest: manifest)
        package.modules = try package.modules()
        if includingTestModules {
            package.testModules = try package.testModules(modules: package.modules)
        } else {
            package.testModules = []
        }
        package.products = try package.products(package.modules, testModules: package.testModules)
        return package
    }
}

        let moduleMapPath = path.appending("module.modulemap")
        if moduleMapPath.asString.isFile {
            let sources = Sources(paths: [moduleMapPath], root: path)
            return [try CModule(name: package.name, sources: sources, path: path, pkgConfig: pkgConfigPath, providers: manifest.package.providers)]
        }

        if manifest.package.exclude.contains(".") {
