You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: registry.go
    path of file: ./repos/syncthing/lib/nat
    
    the code of the file until where you have to start completion: // Copyright (C) 2015 The Syncthing Authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

package nat

import (
	"context"
	"sync"
	"time"
)

type DiscoverFunc func(ctx context.Context, renewal, timeout time.Duration) []Device

var providers []DiscoverFunc

func Register
    
func discoverAll(ctx context.Context, renewal, timeout time.Duration) map[string]Device {
	wg := &sync.WaitGroup{}
	wg.Add(len(providers))

	c := make(chan Device)
	done := make(chan struct{})

	for _, discoverFunc := range providers {
		go func(f DiscoverFunc) {
			defer wg.Done()
			for _, dev := range f(ctx, renewal, timeout) {
				select {
				case c <- dev:
				case <-ctx.Done():
					return
				}
			}
		}(discoverFunc)
	}

	nats := make(map[string]Device)

	go func() {
		defer close(done)
		for {
			select {
			case dev, ok := <-c:
				if !ok {
					return
				}
				nats[dev.ID()] = dev
			case <-ctx.Done():
				return
			}
		}
	}()

	wg.Wait()
	close(c)
	<-done

	return nats
}