public String timeoutShellCommandWithWatchdog(final String[] cmd, final String[] restartTimerKeywords, final int timeout, final boolean logLevel2, Target shell) {
                StringBuilder sb = new StringBuilder();
                try {
                    ProcessBuilder p = new ProcessBuilder(cmd);
                    p = p.redirectErrorStream(true);
                    final Process process = p.start();
                    final TimeoutLogger tl = new TimeoutLogger(logLevel2, process, restartTimerKeywords, timeout);
                    Thread processMonitor = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                tl.processRunning.waitFor();
                                tl.watchDogTimer.stop();
                                tl.isRunning.set(false);
                                Lib.log.appendLog("Process Monitor done.");
                                synchronized (tl.processRunning) {
                                    tl.processRunning.notifyAll();
                                }
                            } catch (InterruptedException ex) {
                                Logger.getLogger(Target.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                    });
                    processMonitor.setName("Monitoring Process Exit Status from " + cmd[0]);
                    Thread reader = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            BufferedInputStream STDOUT = new BufferedInputStream(tl.processRunning.getInputStream());
                            Lib.log.appendLog("Instantiating reader process");
                            try {
                                while (tl.isRunning.get() && !tl.timedOut.get()) {
                                    if (STDOUT.available() > 0) {
                                        char read = (char) STDOUT.read();
                                        tl.log(read);
                                    }
                                }
                                tl.watchDogTimer.stop();
                                Thread.sleep(100);
                                while (STDOUT.available() > 0) {
                                    char read = (char) STDOUT.read();
                                    tl.log(read);
                                }
                                tl.isLogging.set(false);
                                synchronized (tl.processRunning) {
                                    tl.processRunning.notifyAll();
                                }
                            } catch (IOException | InterruptedException ex) {
                                Logger.getLogger(Target.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                    });
                    reader.setName("Reading and monitoring output from " + cmd[0]);
                    reader.start();
                    tl.watchDogTimer.start();
                    processMonitor.start();
                    synchronized (tl.processRunning) {
                        tl.processRunning.wait();
                    }
                    if (tl.isLogging.get()) {
                        synchronized (tl.processRunning) {
                            tl.processRunning.wait();
                        }
                    }
                    String retvalue = tl.get();
                    if (tl.timedOut.get()) {
                        retvalue = "Timeout!!! " + retvalue;
                        process.destroy();
                    }
                    return retvalue;
                } catch (IOException | InterruptedException ex) {
                    Logger.getLogger(Target.class.getName()).log(Level.SEVERE, null, ex);
                }
                return "";
            }