func (m *Manager) Select(selectors []string) []string {
	m.access.RLock()
	defer m.access.RUnlock()
	tags := make([]string, 0, len(selectors))
	for tag := range m.taggedHandler {
		match := false
		for _, selector := range selectors {
			if strings.HasPrefix(tag, selector) {
				match = true
				break
			}
		}
		if match {
			tags = append(tags, tag)
		}
	}
	return tags
}
Select implements outbound.HandlerSelector.
package outbound
import (
	"context"
	"strings"
	"sync"
	core "github.com/v2fly/v2ray-core/v4"
	"github.com/v2fly/v2ray-core/v4/app/proxyman"
	"github.com/v2fly/v2ray-core/v4/common"
	"github.com/v2fly/v2ray-core/v4/common/errors"
	"github.com/v2fly/v2ray-core/v4/features/outbound"
)
type Manager struct {
	access           sync.RWMutex
	defaultHandler   outbound.Handler
	taggedHandler    map[string]outbound.Handler
	untaggedHandlers []outbound.Handler
	running          bool
}
func New(ctx context.Context, config *proxyman.OutboundConfig) (*Manager, error) {
	m := &Manager{
		taggedHandler: make(map[string]outbound.Handler),
	}
	return m, nil
}
func (m *Manager) Type() interface{} {
	return outbound.ManagerType()
}
func (m *Manager) Start() error {
	m.access.Lock()
	defer m.access.Unlock()
	m.running = true
	for _, h := range m.taggedHandler {
		if err := h.Start(); err != nil {
			return err
		}
	}
	for _, h := range m.untaggedHandlers {
		if err := h.Start(); err != nil {
			return err
		}
	}
	return nil
}
func (m *Manager) Close() error {
	m.access.Lock()
	defer m.access.Unlock()
	m.running = false
	var errs []error
	for _, h := range m.taggedHandler {
		errs = append(errs, h.Close())
	}
	for _, h := range m.untaggedHandlers {
		errs = append(errs, h.Close())
	}
	return errors.Combine(errs...)
}
func (m *Manager) GetDefaultHandler() outbound.Handler {
	m.access.RLock()
	defer m.access.RUnlock()
	if m.defaultHandler == nil {
		return nil
	}
	return m.defaultHandler
}
func (m *Manager) GetHandler(tag string) outbound.Handler {
	m.access.RLock()
	defer m.access.RUnlock()
	if handler, found := m.taggedHandler[tag]; found {
		return handler
	}
	return nil
}
func (m *Manager) AddHandler(ctx context.Context, handler outbound.Handler) error {
	m.access.Lock()
	defer m.access.Unlock()
	if m.defaultHandler == nil {
		m.defaultHandler = handler
	}
	tag := handler.Tag()
	if len(tag) > 0 {
		m.taggedHandler[tag] = handler
	} else {
		m.untaggedHandlers = append(m.untaggedHandlers, handler)
	}
	if m.running {
		return handler.Start()
	}
	return nil
}
func (m *Manager) RemoveHandler(ctx context.Context, tag string) error {
	if tag == "" {
		return common.ErrNoClue
	}
	m.access.Lock()
	defer m.access.Unlock()
	delete(m.taggedHandler, tag)
	if m.defaultHandler != nil && m.defaultHandler.Tag() == tag {
		m.defaultHandler = nil
	}
	return nil
}