private static int runProcess(String[] cmd, String[] environment,
                                  InputStream in, OutputStream out,
                                  OutputStream err)
        throws IOException
    {
        Process p;
        if (environment == null) {
            p = Runtime.getRuntime().exec(cmd);
        } else {
            p = Runtime.getRuntime().exec(cmd, environment);
        }

        try {
            PipeThread inThread = null;
            if (in != null) {
                inThread = new PipeThread(false, in, p.getOutputStream());
                inThread.start();
            } else {
                p.getOutputStream().close();
            }

            PipeThread outThread = null;
            if (out != null) {
                outThread = new PipeThread(true, p.getInputStream(), out);
                outThread.start();
            } else {
                p.getInputStream().close();
            }

            PipeThread errThread = null;
            if (err != null) {
                errThread = new PipeThread(true, p.getErrorStream(), err);
                errThread.start();
            } else {
                p.getErrorStream().close();
            }

            // wait for process completion
            for (;;) {
                try {
                    p.waitFor();
                    if (outThread != null) {
                        outThread.join();
                    }
                    if (inThread != null) {
                        inThread.join();
                    }
                    if (errThread != null) {
                        errThread.join();
                    }
                    break;
                } catch (InterruptedException ignore) {
                }
            }

            return p.exitValue();
        } finally {
            p.destroy();
        }
    }