public int exec() throws IOException {
        int exitValue = 0;
        List<String> argl = new ArrayList<String>();
        argl.add(executable.toString());
        for (Object a : args) {
            if (a != null) {
                if (a.getClass() == String.class) {
                    argl.add(a.toString());
                } else if (a.getClass() == String[].class) {
                    for (String s : (String[]) a) {
                        if (s != null && !s.isEmpty()) {
                            argl.add(s);
                        }
                    }
                }
            }
        }

        pb.command(argl);
        if (Main.logger.isLoggable(Level.INFO)) {
            Main.logger.info(pb.command().toString());
        }

        Process process = pb.start();
        CountDownLatch latch = new CountDownLatch(2);

//        Thread in_ = new Thread(new Handler(stdin,
//                new OutputStreamWriter(process.getOutputStream()), latch));
        Thread out_ = new Thread(new Handler(new BufferedReader(
                new InputStreamReader(process.getInputStream())), stdout, latch));
        Thread err_ = new Thread(new Handler(new BufferedReader(
                new InputStreamReader(process.getErrorStream())), stderr, latch));

        out_.start();
        err_.start();
//        in_.start();

        try {
            latch.await();
            exitValue = process.waitFor();
        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
        } finally {
            process.getInputStream().close();
            process.getOutputStream().close();
            process.getErrorStream().close();
            process.destroy();
        }
        return exitValue;
    }