func (c *Checker) Info() []CheckerInfo {
	checkers := make([]CheckerInfo, 0, len(c.checkers))
	for _, c := range c.checkers {
		checkers = append(checkers, c)
	}
	sort.Sort(checkerInfoByName(checkers))
	return checkers
}
Info returns information on all the registered checkers, sorted by namespace
and then name.
package checkers
import (
	"fmt"
	"sort"
	"strings"
	"golang.org/x/net/context"
	"gopkg.in/errgo.v1"
)
const StdNamespace = "std"
const (
	CondDeclared   = "declared"
	CondTimeBefore = "time-before"
	CondError      = "error"
)
const (
	CondNeedDeclared = "need-declared"
)
type Func func(ctx context.Context, cond, arg string) error
type CheckerInfo struct {
	Check Func
	Prefix string
	Name string
	Namespace string
}
var allCheckers = map[string]Func{
	CondTimeBefore: checkTimeBefore,
	CondDeclared:   checkDeclared,
	CondError:      checkError,
}
func NewEmpty(ns *Namespace) *Checker {
	if ns == nil {
		ns = NewNamespace(nil)
	}
	return &Checker{
		namespace: ns,
		checkers:  make(map[string]CheckerInfo),
	}
}
func RegisterStd(c *Checker) {
	c.namespace.Register(StdNamespace, "")
	for cond, check := range allCheckers {
		c.Register(cond, StdNamespace, check)
	}
}
func New(ns *Namespace) *Checker {
	c := NewEmpty(ns)
	RegisterStd(c)
	return c
}
type Checker struct {
	namespace *Namespace
	checkers  map[string]CheckerInfo
}
func (c *Checker) Register(cond, uri string, check Func) {
	if check == nil {
		panic(fmt.Errorf("nil check function registered for namespace %q when registering condition %q", uri, cond))
	}
	prefix, ok := c.namespace.Resolve(uri)
	if !ok {
		panic(fmt.Errorf("no prefix registered for namespace %q when registering condition %q", uri, cond))
	}
	if prefix == "" && strings.Contains(cond, ":") {
		panic(fmt.Errorf("caveat condition %q in namespace %q contains a colon but its prefix is empty", cond, uri))
	}
	fullCond := ConditionWithPrefix(prefix, cond)
	if info, ok := c.checkers[fullCond]; ok {
		panic(fmt.Errorf("checker for %q (namespace %q) already registered in namespace %q", fullCond, uri, info.Namespace))
	}
	c.checkers[fullCond] = CheckerInfo{
		Check:     check,
		Namespace: uri,
		Name:      cond,
		Prefix:    prefix,
	}
}