func New(cfg *config.Config) (m *Manager, err error) {
	m = &Manager{
		r:                  eventual2go.NewReactor(),
		connected:          typed_events.NewBoolStreamController(),
		peers:              map[config.UUID]*peer.Peer{},
		arrive:             config.NewUUIDStreamController(),
		leave:              config.NewUUIDStreamController(),
		guaranteedMessages: map[messages.Message]*peer.Peer{},
		messageIn:          connection.NewMessageStreamController(),
		logger:             log.New(cfg.Logger(), fmt.Sprintf("%s MANAGER ", cfg.UUID()), 0),
		shutdown:           eventual2go.NewShutdown(),
		shutdownComplete:   eventual2go.NewCompleter(),
	}

	m.r.React(peerLeave{}, m.peerLeave)
	m.r.React(peerConnected{}, m.peerConnected)
	m.r.OnShutdown(m.onShutdown)

	for _, iface := range cfg.Interfaces() {

		var i *connection.Incoming
		i, err = connection.NewIncoming(iface)
		if err != nil {
			m.logger.Println("ERROR setting up incoming:", err)
			m.Shutdown()
			return
		}
		m.shutdown.Register(i)
		m.messageIn.Join(i.In().Where(filterMessages))

		var t *tracker.Tracker
		t, err = tracker.New(iface, i.Port(), cfg)
		if err != nil {
			m.logger.Println("ERROR setting up tracker:", err)
			m.Shutdown()
			return
		}
		m.tracker = append(m.tracker, t)
		m.shutdown.Register(t)
		m.r.AddStream(peerLeave{}, t.Leave().Stream)

		var d *discoverer.Discoverer
		d = discoverer.New(t.Join(), i, cfg)
		m.r.AddStream(peerConnected{}, d.ConnectedPeers().Stream)
	}

	return
}
func TestShutdown(t *testing.T) {

	sd := &testshutdown{}
	se := &testshutdownerr{}

	s := eventual2go.NewShutdown()

	s.Register(sd)
	s.Register(se)

	errs := s.Do(true)

	if !(sd.data.(bool)) {
		t.Error("wrong data")
	}

	if len(errs) != 1 {
		t.Error("wrong number of errors", len(errs))
	} else {
		if errs[0] != testerr {
			t.Error("wrong error")
		}
	}
}