         _delegate.lookup_tool = { return BuildSystem.toSystem($0!).lookupTool($1!) }
         _delegate.had_command_failure = { BuildSystem.toSystem($0!).hadCommandFailure() }
         _delegate.handle_diagnostic = { BuildSystem.toSystem($0!).handleDiagnostic($1, String(cString: $2!), Int($3), Int($4), String(cString: $5!)) }
-        _delegate.command_status_changed = { BuildSystem.toSystem($0!).commandStatusChanged(Command($1), $2) }
-        _delegate.command_preparing = { BuildSystem.toSystem($0!).commandPreparing(Command($1)) }
-        _delegate.command_started = { BuildSystem.toSystem($0!).commandStarted(Command($1)) }
-        _delegate.should_command_start = { BuildSystem.toSystem($0!).shouldCommandStart(Command($1)) }
-        _delegate.command_finished = { BuildSystem.toSystem($0!).commandFinished(Command($1), $2) }
-        _delegate.command_had_error = { BuildSystem.toSystem($0!).commandHadError(Command($1), $2!) }
-        _delegate.command_had_note = { BuildSystem.toSystem($0!).commandHadNote(Command($1), $2!) }
-        _delegate.command_had_warning = { BuildSystem.toSystem($0!).commandHadWarning(Command($1), $2!) }
+        _delegate.command_status_changed = { BuildSystem.toSystem($0!).commandStatusChanged(Command(handle: $1), $2) }
+        _delegate.command_preparing = { BuildSystem.toSystem($0!).commandPreparing(Command(handle: $1)) }
+        _delegate.command_started = { BuildSystem.toSystem($0!).commandStarted(Command(handle: $1)) }
+        _delegate.should_command_start = { BuildSystem.toSystem($0!).shouldCommandStart(Command(handle: $1)) }
+        _delegate.command_finished = { BuildSystem.toSystem($0!).commandFinished(Command(handle: $1), $2) }
+        _delegate.command_had_error = { BuildSystem.toSystem($0!).commandHadError(Command(handle: $1), $2!) }
+        _delegate.command_had_note = { BuildSystem.toSystem($0!).commandHadNote(Command(handle: $1), $2!) }
+        _delegate.command_had_warning = { BuildSystem.toSystem($0!).commandHadWarning(Command(handle: $1), $2!) }
         _delegate.command_cannot_build_output_due_to_missing_inputs = {
             let inputsPtr = $3!
             let inputs = (0..<Int($4)).map { BuildKey(key: inputsPtr[$0]) }
-            BuildSystem.toSystem($0!).commandCannotBuildOutputDueToMissingInputs(Command($1), BuildKey(key: $2!.pointee), inputs)
+            BuildSystem.toSystem($0!).commandCannotBuildOutputDueToMissingInputs(Command(handle: $1), BuildKey(key: $2!.pointee), inputs)
         }
         _delegate.cannot_build_node_due_to_multiple_producers = {
             let commandsPtr = $2!
-            let commands = (0..<Int($3)).map { Command(commandsPtr[$0]) }
+            let commands = (0..<Int($3)).map { Command(handle: commandsPtr[$0]) }
             BuildSystem.toSystem($0!).cannotBuildNodeDueToMultipleProducers(BuildKey(key: $1!.pointee), commands)
         }
-        _delegate.command_process_started = { BuildSystem.toSystem($0!).commandProcessStarted(Command($1), ProcessHandle($2!)) }
-        _delegate.command_process_had_error = { BuildSystem.toSystem($0!).commandProcessHadError(Command($1), ProcessHandle($2!), $3!) }
-        _delegate.command_process_had_output = { BuildSystem.toSystem($0!).commandProcessHadOutput(Command($1), ProcessHandle($2!), $3!) }
-        _delegate.command_process_finished = { BuildSystem.toSystem($0!).commandProcessFinished(Command($1), ProcessHandle($2!), CommandExtendedResult($3!)) }
+        _delegate.command_process_started = { BuildSystem.toSystem($0!).commandProcessStarted(Command(handle: $1), ProcessHandle($2!)) }
+        _delegate.command_process_had_error = { BuildSystem.toSystem($0!).commandProcessHadError(Command(handle: $1), ProcessHandle($2!), $3!) }
+        _delegate.command_process_had_output = { BuildSystem.toSystem($0!).commandProcessHadOutput(Command(handle: $1), ProcessHandle($2!), $3!) }
+        _delegate.command_process_finished = { BuildSystem.toSystem($0!).commandProcessFinished(Command(handle: $1), ProcessHandle($2!), CommandExtendedResult($3!)) }
         _delegate.cycle_detected = {
             var rules = [BuildKey]()
             UnsafeBufferPointer(start: $1, count: Int($2)).forEach {


/// Handle for a command as invoked by the low-level BuildSystem.
public struct Command: Hashable, CustomStringConvertible, CustomDebugStringConvertible {
    fileprivate let handle: OpaquePointer?

    fileprivate init(_ handle: OpaquePointer?) {
        self.handle = handle
    }

    /// The command name.
    //
    // FIXME: We shouldn't need to expose this to use for mapping purposes, we should be able to use something more efficient.
    public var name: String {
        var data = llb_data_t()
        withUnsafeMutablePointer(to: &data) { (ptr: UnsafeMutablePointer<llb_data_t>) in
            llb_buildsystem_command_get_name(handle, ptr)
        }
        return stringFromData(data)
    }

    /// Whether the default status reporting shows status for the command.
    public var shouldShowStatus: Bool {
        return llb_buildsystem_command_should_show_status(handle)
    }

    /// The description provided by the command.
    public var description: String {
        let name = llb_buildsystem_command_get_description(handle)!
        defer { free(name) }

        return String(cString: name)
    }

    /// The verbose description provided by the command.
    public var verboseDescription: String {
        let name = llb_buildsystem_command_get_verbose_description(handle)!
        defer { free(name) }

        return String(cString: name)
    }

    /// The debug description provides the verbose description.

        _delegate.execute_command = { return BuildSystem.toCommandWrapper($0!).executeCommand($1!, $2!, $3!, $4!) }

        // Create the low-level command.
        wrapper._command = Command(handle: llb_buildsystem_external_command_create(name, _delegate))

        return wrapper._command.handle
    }
