func (app *Application) SetMessageOutput(out MessageOutput) MessageOutput {
	var prev MessageOutput
	app.mutex.Lock()
	{
		prev = app.messageOutput
		app.messageOutput = out
	}
	app.mutex.Unlock()
	return prev
}
Replaces the MessageOutput, and returns the previous MessageOutput
package spectrum
import (
	"fmt"
	"os"
	"os/signal"
	"runtime"
	"sync"
	"time"
)
type Application struct {
	exitApp       chan byte  
	HasTerminated chan byte  
	eventLoops []*EventLoop
	terminationInProgress bool
	terminated            bool
	mutex sync.Mutex
	messageOutput MessageOutput
	Verbose         bool
	VerboseShutdown bool
	CreationTime time.Time  
}
func NewApplication() *Application {
	app := &Application{
		exitApp:       make(chan byte),
		HasTerminated: make(chan byte),
		eventLoops:    make([]*EventLoop, 0, 8),
		CreationTime:  time.Now(),
		messageOutput: &stdoutMessageOutput{},
	}
	go appGoroutine(app)
	return app
}
func appGoroutine(app *Application) {
	<-app.exitApp
	var startTime time.Time
	if app.Verbose {
		startTime = time.Now()
	}
	for {
		app.mutex.Lock()
		eventLoops := app.eventLoops
		app.eventLoops = make([]*EventLoop, 0, 8)
		app.mutex.Unlock()
		for _, e := range eventLoops {
			if app.VerboseShutdown {
				app.PrintfMsg("sending pause message to %s", e.Name)
			}
			e.Pause <- 0
			<-e.Pause
			if app.VerboseShutdown {
				app.PrintfMsg("%s is now paused", e.Name)
			}
		}
		for _, e := range eventLoops {
			if app.VerboseShutdown {
				app.PrintfMsg("sending terminate message to %s", e.Name)
			}
			e.Terminate <- 0
			<-e.Terminate
			if app.VerboseShutdown {
				app.PrintfMsg("%s has terminated", e.Name)
			}
		}
		app.mutex.Lock()
		if len(app.eventLoops) == 0 {
			app.mutex.Unlock()
			break
		} else {
			app.mutex.Unlock()
		}
	}
	if app.Verbose {
		endTime := time.Now()
		app.PrintfMsg("application shutdown completed after %s", endTime.Sub(startTime))
		app.PrintfMsg("application has terminated")
	}
	close(app.HasTerminated)
	app.mutex.Lock()
	app.terminationInProgress = false
	app.terminated = true
	app.mutex.Unlock()
}
func (app *Application) addEventLoop(e *EventLoop) bool {
	app.mutex.Lock()
	if app.terminated {
		app.mutex.Unlock()
		return false
	}
	app.eventLoops = append(app.eventLoops, e)
	app.mutex.Unlock()
	return true
}
func (app *Application) RequestExit() {
	app.mutex.Lock()
	{
		if app.terminationInProgress || app.terminated {
			app.mutex.Unlock()
			return
		}
		app.terminationInProgress = true
	}
	app.mutex.Unlock()
	close(app.exitApp)
}
func (app *Application) TerminationInProgress() bool {
	app.mutex.Lock()
	a := app.terminationInProgress
	app.mutex.Unlock()
	return a
}
func (app *Application) Terminated() bool {
	app.mutex.Lock()
	a := app.terminated
	app.mutex.Unlock()
	return a
}
func (app *Application) GetMessageOutput() MessageOutput {
	return app.messageOutput
}