public static int executeProgram(String[] cmd, File workingDir, StreamMonitor inputStream, StreamMonitor errStream) {
		logger.trace("Executing '"+explode(cmd)+"' with working dir '"+workingDir.getAbsolutePath()+"'.");
		
		int exitVal;
		try {
			Runtime rt = Runtime.getRuntime();
			Process proc = rt.exec(cmd, null, workingDir);
			// consume the err stream and stdout stream from the process
			Thread inputStreamThread;
			if (inputStream != null) {
				inputStream.setStream(proc.getInputStream());
				inputStreamThread = new Thread(inputStream);
			}
			else {
				inputStreamThread = new StreamGobbler(proc.getInputStream(), StreamType.STDOUT); // the input stream is the STDOUT from the program being executed
			}
			inputStreamThread.start();
			
			Thread errStreamThread;
			if (errStream != null) {
				errStream.setStream(proc.getErrorStream());
				errStreamThread = new Thread(errStream);
			}
			else {
				errStreamThread = new StreamGobbler(proc.getErrorStream(), StreamType.ERR);
			}
			errStreamThread.start();
			
			// wait make sure stream threads have finished collecting output
			inputStreamThread.join();
			errStreamThread.join();
			exitVal = proc.waitFor();
		
		} catch (IOException e) {
			throw(new RuntimeException("Error trying to execute program."));
		} catch (InterruptedException e) {
			throw(new RuntimeException("InterruptException occured. This shouldn't happen."));
		}
		return exitVal;
	}