public static byte[] exec(final String cmd, final String[] args,
      final byte[] in, final File dir) throws IOException,
      InterruptedException {

    final StringBuilder sb = new StringBuilder();
    if (cmd.contains(" ")) {
      sb.append('"' + cmd + '"');
    } else {
      sb.append(cmd);
    }
    for (final String arg : args) {
      sb.append(' ' + arg);
    }

    final Process proc = Runtime.getRuntime().exec(sb.toString(), null, dir);

    final OutputStream stdin = proc.getOutputStream();
    if (in != null) {
      stdin.write(in);
    }
    stdin.close();

    // handle streams
    final byte[] out = readFully(proc.getInputStream());
    final byte[] err = readFully(proc.getErrorStream());

    if (proc.waitFor() != 0) throw new IOException(cmd + " didn't return normally:\n"
        + new String(out) + "\n\n" + new String(err));

    return out;
  }