/**
 * END USER LICENSE AGREEMENT (“EULA”)
 *
 * READ THIS AGREEMENT CAREFULLY (date: 9/13/2011):
 * http://www.akiban.com/licensing/20110913
 *
 * BY INSTALLING OR USING ALL OR ANY PORTION OF THE SOFTWARE, YOU ARE ACCEPTING
 * ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. YOU AGREE THAT THIS
 * AGREEMENT IS ENFORCEABLE LIKE ANY WRITTEN AGREEMENT SIGNED BY YOU.
 *
 * IF YOU HAVE PAID A LICENSE FEE FOR USE OF THE SOFTWARE AND DO NOT AGREE TO
 * THESE TERMS, YOU MAY RETURN THE SOFTWARE FOR A FULL REFUND PROVIDED YOU (A) DO
 * NOT USE THE SOFTWARE AND (B) RETURN THE SOFTWARE WITHIN THIRTY (30) DAYS OF
 * YOUR INITIAL PURCHASE.
 *
 * IF YOU WISH TO USE THE SOFTWARE AS AN EMPLOYEE, CONTRACTOR, OR AGENT OF A
 * CORPORATION, PARTNERSHIP OR SIMILAR ENTITY, THEN YOU MUST BE AUTHORIZED TO SIGN
 * FOR AND BIND THE ENTITY IN ORDER TO ACCEPT THE TERMS OF THIS AGREEMENT. THE
 * LICENSES GRANTED UNDER THIS AGREEMENT ARE EXPRESSLY CONDITIONED UPON ACCEPTANCE
 * BY SUCH AUTHORIZED PERSONNEL.
 *
 * IF YOU HAVE ENTERED INTO A SEPARATE WRITTEN LICENSE AGREEMENT WITH AKIBAN FOR
 * USE OF THE SOFTWARE, THE TERMS AND CONDITIONS OF SUCH OTHER AGREEMENT SHALL
 * PREVAIL OVER ANY CONFLICTING TERMS OR CONDITIONS IN THIS AGREEMENT.
 */

package com.akiban.server.service.ui;

import com.akiban.server.service.Service;
import com.akiban.server.service.ServiceManager;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import java.io.PrintStream;

import com.google.inject.Inject;

public class SwingConsoleServiceImpl implements SwingConsoleService, Service<SwingConsoleService> 
{
    private final ServiceManager serviceManager;
    private final PrintStream origOut = System.out;
    private SwingConsole console;

    @Inject
    public SwingConsoleServiceImpl(ServiceManager serviceManager) {
        this.serviceManager = serviceManager;
    }

    @Override
    public final void start() {
        if (console == null) {
            console = new SwingConsole(serviceManager);
            System.setOut(console.openPrintStream(true));
            System.out.flush(); // Pick up output from before started.
        }
        show();
    }

    @Override
    public final void stop() {
        // If we stop while starting, that means some other service has problems.
        // Let the user see them before removing the console.
        switch (serviceManager.getState()) {
        case STARTING:
            return;
        }
        final JFrame console = this.console;
        this.console = null;
        System.setOut(origOut);
        if (console != null) {
            SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        console.dispose();
                    }
                });
        }
    }
    
    @Override
    public void crash() {
        stop();
    }

    @Override
    public SwingConsoleService cast() {
        return this;
    }

    @Override
    public Class<SwingConsoleService> castClass() {
        return SwingConsoleService.class;
    }

    @Override
    public void show() {
        setVisible(true);
    }

    @Override
    public void hide() {
        setVisible(true);
    }
    
    private void setVisible(final boolean visible) {
        final JFrame console = this.console;
        if (console != null) {
            SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        console.setVisible(visible);
                    }
                });
        }
        else
            throw new IllegalStateException("No frame to show / hide.");
    }

    @Override
    public PrintStream getPrintStream() {
        return console.getPrintStream();
    }

}

@@ -1728,16 +1728,69 @@
 m.out;%0D%0A
+    private final PrintStream origErr = System.err;%0D%0A
     priv
@@ -1816,16 +1816,16 @@
 nsole;%0D%0A
-
 %0D%0A    @I
@@ -2105,30 +2105,33 @@
         
-System.setOut(
+PrintStream ps = 
 console.
@@ -2151,17 +2151,16 @@
 am(true)
-)
 ;%0D%0A     
@@ -2173,19 +2173,75 @@
  System.
-out
+setOut(ps);%0D%0A            System.setErr(ps);%0D%0A            ps
 .flush()
@@ -2690,16 +2690,16 @@
  null;%0D%0A
-
         
@@ -2719,24 +2719,57 @@
 (origOut);%0D%0A
+        System.setErr(origErr);%0D%0A
         if (

Set error too, in case of fatal error.