public function exec($command, array $arguments = [], array $okCodes = [0], $workingDir = null)
    {
        $command = $this->makeAbsolute($command);

        $escapedCommand = escapeshellcmd($command) . ' ' . implode(' ', array_map('escapeshellarg', $arguments));

        $originalWorkingDir = getcwd();
        chdir($workingDir ?: $originalWorkingDir);
        exec($escapedCommand, $output, $return);
        chdir($originalWorkingDir);

        if (!in_array($return, $okCodes)) {
            $message = sprintf(
                'Command "%s" exited with non zero exit code %s: %s',
                $escapedCommand,
                $return,
                implode(PHP_EOL, $output)
            );
            throw new \Exception($message);
        }

        return implode(PHP_EOL, $output);
    }