diff --git a/GUI/src/main/java/cz/fidentis/analyst/core/OutputWindow.java b/GUI/src/main/java/cz/fidentis/analyst/core/OutputWindow.java
deleted file mode 100644
index e1c99d343179384ddb8863c7cbe6e82a8d325c54..0000000000000000000000000000000000000000
--- a/GUI/src/main/java/cz/fidentis/analyst/core/OutputWindow.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package cz.fidentis.analyst.core;
-
-import cz.fidentis.analyst.Logger;
-import java.awt.BorderLayout;
-import java.util.List;
-import javax.swing.JScrollPane;
-import javax.swing.JTextArea;
-import javax.swing.SwingWorker;
-import org.openide.windows.TopComponent;
-import org.openide.windows.WindowManager;
-
-/**
- * Wrapper of the default Java Netbeans Platform output window.
- * This wrapper runs in the worker thread, reads messages logged through 
- * the {@link cz.fidentis.analyst.Logger} and displays them in the output window.
- * 
- * The {@code OutputWindow} is currently executed from 
- * the {@link cz.fidentis.analyst.core.ProjectTopComp}, which is always presented.
- * 
- * @author Radek Oslejsek
- */
-public class OutputWindow extends SwingWorker<String, String> {
-
-    private static JTextArea textArea; 
-    
-    /**
-     * Constructor.
-     */
-    public OutputWindow() {
-        TopComponent outputWin = WindowManager.getDefault().findTopComponent("output");
-        textArea = new JTextArea();
-        JScrollPane sp = new JScrollPane(textArea);
-        outputWin.add(sp, BorderLayout.CENTER);
-    }
-
-    /**
-     * Reads messages of the {@code Logger} in the background and re-sends them
-     * the {@link #process(java.util.List)} method.
-     * 
-     * @return Complete text displayed in the output window.
-     * @throws Exception 
-     */
-    @Override
-    protected String doInBackground() throws Exception {
-        String line = Logger.reader().readLine();
-        while (line != null) {
-            publish(line);
-            line = Logger.reader().readLine();
-        }
-        return textArea.getText();
-    }
-    
-    /**
-     * Takes text lines process by the {@link #doInBackground()} method and
-     * adds them to the output window.
-     * 
-     * @param chunks process lines
-     */
-    @Override
-    protected void process(List<String> chunks) {
-        StringBuilder sb = new StringBuilder();
-        sb.append(textArea.getText());
-        chunks.forEach(str -> {
-            sb.append(str + System.lineSeparator());
-        });
-        textArea.setText(sb.toString());
-    }
-        
-}
diff --git a/GUI/src/main/java/cz/fidentis/analyst/core/OutputWindowThread.java b/GUI/src/main/java/cz/fidentis/analyst/core/OutputWindowThread.java
new file mode 100644
index 0000000000000000000000000000000000000000..eed010d254a336665068dd03be5664c673c6fc0e
--- /dev/null
+++ b/GUI/src/main/java/cz/fidentis/analyst/core/OutputWindowThread.java
@@ -0,0 +1,122 @@
+package cz.fidentis.analyst.core;
+
+import cz.fidentis.analyst.Logger;
+import java.awt.BorderLayout;
+import java.io.IOException;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import org.openide.util.Exceptions;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
+
+/**
+ * Wrapper of the default Java Netbeans Platform output window.
+ * This singleton runs in the background, reads messages logged through 
+ * the {@link cz.fidentis.analyst.Logger} and displays them in the output window.
+ * 
+ * This singleton is currently executed from 
+ * the {@link cz.fidentis.analyst.core.ProjectTopComp}, which is always presented
+ * in the FIDENTIS application.
+ *
+ * @author Radek Oslejsek
+ */
+public class OutputWindowThread extends Thread {
+    
+    private JTextArea textArea; 
+    
+    private static OutputWindowThread instance;
+    
+    protected OutputWindowThread() {
+        TopComponent outputWin = WindowManager.getDefault().findTopComponent("output");
+        textArea = new JTextArea();
+        JScrollPane sp = new JScrollPane(textArea);
+        outputWin.add(sp, BorderLayout.CENTER);
+    }
+    
+    /**
+     * Starts the redirection of messages logged via the {@link cz.fidentis.analyst.Logger}
+     * into the output window.
+     * 
+     * @return {@code false} if the singleton/thread is already executed, 
+     * {@code true} otherwise.
+     */
+    public static boolean execute() {
+        if (instance != null) {
+            return false;
+        }
+        instance = new OutputWindowThread();
+        instance.start(); // executes the run() method
+        Logger.redirectToPipe();
+        return true;
+    }
+    
+    /**
+     * Stops the redirection of messages logged via the {@link cz.fidentis.analyst.Logger}
+     * into the output window.
+     * 
+     * @param err If {@code true} then the logged messages are redirected to the system error output.
+     *            Otherwise, the system standard output is used.
+     * @return {@code false} if the singleton/thread is already stopped, 
+     *         {@code true} otherwise.
+     */
+    public static boolean stopExecution(boolean err) {
+        if (instance == null) {
+            return false;
+        }
+        if (err) {
+            Logger.redirectToStdErr();
+        } else {
+            Logger.redirectToStdOut();
+        }
+        instance = null;
+        return true;
+    }
+    
+    /**
+     * Stops the redirection of messages logged via the {@link cz.fidentis.analyst.Logger}
+     * into the output window. The messages are redirected into the system standard output.
+     * 
+     * @return {@code false} if the singleton/thread is already stopped, 
+     *         {@code true} otherwise.
+     */
+    public static boolean stopExecution() {
+        return stopExecution(false);
+    }
+    
+    @Override
+    public void run() {
+        int errorCounter = 0;
+        
+        while (true) {
+            try {
+                String line = Logger.read();
+                if (line != null) {
+                    StringBuilder sb = new StringBuilder();
+                    sb.append(textArea.getText())
+                            .append(line)
+                            .append(System.lineSeparator());
+                    textArea.setText(sb.toString());
+                    textArea.setCaretPosition(textArea.getDocument().getLength());
+                    errorCounter = 0;
+                } else {
+                    //System.out.println("No datain the message pipe");
+                    fallAsleep(2000);
+                }
+            } catch (IOException ex) {
+                if (errorCounter < 8) {
+                    errorCounter++;
+                }
+                System.out.println("IOException: " + ex);
+                fallAsleep(errorCounter * 1000);                
+            } 
+        }
+    }
+    
+    protected void fallAsleep(int mil) {
+        try {
+            sleep(mil);
+        } catch (InterruptedException ex) {
+            Exceptions.printStackTrace(ex);
+        }
+    }
+}
diff --git a/GUI/src/main/java/cz/fidentis/analyst/core/ProjectTopComp.java b/GUI/src/main/java/cz/fidentis/analyst/core/ProjectTopComp.java
index 0c74a3e5b0fbb7f8e1ad8055e5ad448ac4d9c9b8..a5850328d862d6644115f06c9833b44af20f57c1 100644
--- a/GUI/src/main/java/cz/fidentis/analyst/core/ProjectTopComp.java
+++ b/GUI/src/main/java/cz/fidentis/analyst/core/ProjectTopComp.java
@@ -81,9 +81,9 @@ public final class ProjectTopComp extends TopComponent {
         putClientProperty(TopComponent.PROP_DRAGGING_DISABLED, Boolean.TRUE);
         putClientProperty(TopComponent.PROP_UNDOCKING_DISABLED, Boolean.TRUE);
         
-        // Execute OutputWindow in the worker thread so that messages
-        // logged via Logger are displayed in the output window
-        (new OutputWindow()).execute();
+        // Execute infinite OutputWindowThread that redirects messages logged
+        // via Logger into the standard output window
+        OutputWindowThread.execute();
     }
 
     /**
diff --git a/GUI/src/main/java/cz/fidentis/analyst/registration/RegistrationAction.java b/GUI/src/main/java/cz/fidentis/analyst/registration/RegistrationAction.java
index b39d4a10e3850e7ee8f1deea4468bc989015f65e..ce879fb9f36d5a21491b8856024ff93d73d620bd 100644
--- a/GUI/src/main/java/cz/fidentis/analyst/registration/RegistrationAction.java
+++ b/GUI/src/main/java/cz/fidentis/analyst/registration/RegistrationAction.java
@@ -306,8 +306,6 @@ public class RegistrationAction extends ControlPanelAction {
      * otherwise set color to default
      */
     private void calculateFeaturePoints() {
-        Logger.print("Calculation of feature points");
-        
         if (getPrimaryDrawableFace() == null) { // scene not yet initiated
             return;
         }
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/Logger.java b/MeshModel/src/main/java/cz/fidentis/analyst/Logger.java
index a4220075a64f248ed587e61e75134ae6e520db04..df629174b7161e8e55cf82dc2621b5528d485331 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/Logger.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/Logger.java
@@ -14,16 +14,17 @@ import java.util.logging.Level;
  * A logging class that can be used from anywhere to display debugging or other
  * messages.
  * <p>
- * Messages are printed into the standard output unless the {@link #reader()} 
- * method is called. Then the messages are redirected to the returned {@code BufferedReader}.
+ * Messages are printed into the system standard output by default. But can be also
+ * redirected to system error output or into the pipe.
  * </p>
  * <p>
- * The implementation supposes that the caller of the {@link #reader()} method 
- * (or other object} will read the messages from the {@code BufferedReader} forever. 
- * Otherwise, the program can freeze due to the full buffer.
+ * If the messages are redirected into pipe, then <b>a consumer has to be running 
+ * concurrently</b> and reading the data through the {@link #read()} method.
+ * <b>Otherwise, the program can freeze due to the full buffer!</b>
  * </p>
  * <p>
- * FIDENTIS application automatically redirects logged messages to the output window.
+ * FIDENTIS application automatically redirects logged messages to the output window 
+ * via the {@code OutputWindowThread}. 
  * </p>
  * <p>
  * <b>Usage:</b>
@@ -39,6 +40,8 @@ import java.util.logging.Level;
  */
 public final class Logger {
     
+    private static final int PIPE_SIZE = 10240; // default is 1024
+    
     private static PrintStream out = System.out;
     private static BufferedReader in;
     
@@ -48,21 +51,53 @@ public final class Logger {
     }
     
     /**
-     * Redirects logs from standard output to the {@code BufferedReader}.
+     * Redirects messages into a pipe. 
+     * <b>A consumer has to be running concurrently</b> and reading the messages
+     * through the {@link #read()} method.
+     * Otherwise, the program can freeze due to the full buffer!
+     */
+    public static synchronized void redirectToPipe() {
+        if (in != null) {
+            return;
+        }
+        
+        PipedOutputStream pOut = new PipedOutputStream();
+        out = new PrintStream(pOut);
+        try {
+            in = new BufferedReader(new InputStreamReader(new PipedInputStream(pOut, PIPE_SIZE)));
+        } catch (IOException ex) {
+            java.util.logging.Logger.getLogger(Logger.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+    
+    /**
+     * Redirects messages into the system standard output.
+     */
+    public static synchronized void redirectToStdOut() {
+        out = System.out;
+        in = null;
+    }
+    
+    /**
+     * Redirects messages into the system error output.
+     */
+    public static synchronized void redirectToStdErr() {
+        out = System.err;
+        in = null;
+    }
+    
+    /**
+     * Returns an event message. If the logger is redirected to standard or error output,
+     * then {@code null} is returned. Also, if the is no message, {@code null} is returned.
      * 
-     * @return {@code BufferedReader} to which the logs are redirected.
+     * @return Event message or {@code null}
+     * @throws IOException on error in reading the message buffer.
      */
-    public static BufferedReader reader() {
-        if (in == null) {
-            PipedOutputStream pOut = new PipedOutputStream();
-            out = new PrintStream(pOut);
-            try {
-                in = new BufferedReader(new InputStreamReader(new PipedInputStream(pOut)));
-            } catch (IOException ex) {
-                java.util.logging.Logger.getLogger(Logger.class.getName()).log(Level.SEVERE, null, ex);
-            }
+    public static String read() throws IOException {
+        if (in == null/* || !in.ready()*/) {
+            return null;
         }
-        return in;
+        return in.readLine();
     }
     
     /**
@@ -76,6 +111,7 @@ public final class Logger {
                 + " [duration unknown]: "
                 + msg.trim();
         out.println(outMsg);
+        out.flush();
     }
 
     /**
@@ -112,8 +148,9 @@ public final class Logger {
                         duration.toMillisPart())
                 + "]: "
                 + msg.trim();
-        
+    
         out.println(outMsg);
+        out.flush();
     }
     
 }