class ExecPipe {

    public AsynchronousExecResult exec() throws IOException {
        PipedInputStream inputStream = null;
        PipedOutputStream outputStream = null;

        for (int i = 0; i < builders.size(); i++) {
            ExecBuilder builder = builders.get(i);

            // if this is not the first process, set the stdin
            if (i != 0) {
                builder.stdIn(inputStream);
            }

            // if this is not the last process, set the stdout
            if (i != builders.size() - 1) {
                outputStream = new PipedOutputStream();
                builder.stdOutAndErr(outputStream, null);
                inputStream = new PipedInputStream(outputStream);
            }
        }

        AsynchronousExecResult lastAsyncResult = null;
        for (ExecBuilder builder : builders) {
            lastAsyncResult = builder.asyncExec();
        }

        return lastAsyncResult;
    }

    public  ExecPipe(final ExecBuilder... execBuilders);
    public  ExecPipe(final List<ExecBuilder> execBuilders);

}