     }
 }
 
+struct CocoaPodsTool: Tool {
+    let launchPath: String
+
+    init?() {
+        guard let path = launchPathForTool("pod") else { return nil }
+        self.launchPath = path
+    }
+}
+
+struct CarthageTool : Tool {
+    let launchPath: String
+
+    init?() {
+        guard let path = launchPathForTool("carthage") else { return nil }
+        self.launchPath = path
+    }
+}
+
 struct SwiftTool : Tool {
     let launchPath: String
     
     init?() {
-        let which = WhichTool()
-        let result = which.run("swiftc")
-        if result.out.characters.count == 0 { return nil }
-        self.launchPath = result.out
+        guard let path = launchPathForTool("swiftc") else { return nil }
+        self.launchPath = path
     }
 }
 
 struct ApousScriptTool : Tool {
     let launchPath = "./.apousscript"
 }
+
+func launchPathForTool(tool: String) -> String? {
+    let which = WhichTool()
+    let result = which.run(tool)
+    
+    return result.out.characters.count == 0 ? nil : result.out
+}

    /// The name of the tool to be run.
    var launchPath: String { get }
    
    /// `true` when the output of the tool should be printed to `stdout`.
    var printOutput: Bool { get }

    /// Runs the tool and returns result of the execution.
    func run(args: [String]) -> (out: String, err: String, code: Int32)


            err: err.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()),
            code: task.terminationStatus)
    }
}

struct WhichTool : Tool {
    let launchPath = "/usr/bin/which"

    func run(args: [String]) -> (out: String, err: String, code: Int32) {
        let output = NSPipe()
        let error = NSPipe()
        
        // NOTE(owensd): This merges stdout and stderr for now...
        func stream(handle: NSFileHandle) -> String {
            let data = handle.availableData
            let str = NSString(data: data, encoding: NSUTF8StringEncoding) ?? ""
            
            return str as String
        }
        
        var out = ""
        var err = ""
        
        output.fileHandleForReading.readabilityHandler = { out += stream($0) }
        error.fileHandleForReading.readabilityHandler = { err += stream($0) }
        
        let task = NSTask()
        task.launchPath = self.launchPath
