func (pm *ManagerImpl) Manager(path []string) (Manager, bool) {
	if len(path) == 0 {
		return pm, true
	}
	m, ok := pm.config.managers[path[0]]
	if !ok {
		return nil, false
	}
	return m.Manager(path[1:])
}
Manager returns the sub-policy manager for a given path and whether it exists
package policies
import (
	"fmt"
	"strings"
	"sync"
	cb "github.com/inklabsfoundation/inkchain/protos/common"
	"github.com/golang/protobuf/proto"
	"github.com/inklabsfoundation/inkchain/common/flogging"
	logging "github.com/op/go-logging"
)
const (
	PathSeparator = "/"
	ChannelPrefix = "Channel"
	ApplicationPrefix = "Application"
	OrdererPrefix = "Orderer"
	ChannelReaders = PathSeparator + ChannelPrefix + PathSeparator + "Readers"
	ChannelWriters = PathSeparator + ChannelPrefix + PathSeparator + "Writers"
	ChannelApplicationReaders = PathSeparator + ChannelPrefix + PathSeparator + ApplicationPrefix + PathSeparator + "Readers"
	ChannelApplicationWriters = PathSeparator + ChannelPrefix + PathSeparator + ApplicationPrefix + PathSeparator + "Writers"
	ChannelApplicationAdmins = PathSeparator + ChannelPrefix + PathSeparator + ApplicationPrefix + PathSeparator + "Admins"
	BlockValidation = PathSeparator + ChannelPrefix + PathSeparator + OrdererPrefix + PathSeparator + "BlockValidation"
)
var logger = flogging.MustGetLogger("policies")
type Policy interface {
	Evaluate(signatureSet []*cb.SignedData) error
}
type Manager interface {
	GetPolicy(id string) (Policy, bool)
	Manager(path []string) (Manager, bool)
	BasePath() string
	PolicyNames() []string
}
type Proposer interface {
	BeginPolicyProposals(tx interface{}, groups []string) ([]Proposer, error)
	ProposePolicy(tx interface{}, name string, policy *cb.ConfigPolicy) (proto.Message, error)
	RollbackProposals(tx interface{})
	CommitProposals(tx interface{})
	PreCommit(tx interface{}) error
}
type Provider interface {
	NewPolicy(data []byte) (Policy, proto.Message, error)
}
type ChannelPolicyManagerGetter interface {
	Manager(channelID string) (Manager, bool)
}
type policyConfig struct {
	policies map[string]Policy
	managers map[string]*ManagerImpl
	imps     []*implicitMetaPolicy
}
type ManagerImpl struct {
	parent        *ManagerImpl
	basePath      string
	fqPrefix      string
	providers     map[int32]Provider
	config        *policyConfig
	pendingConfig map[interface{}]*policyConfig
	pendingLock   sync.RWMutex
	SuppressSanityLogMessages bool
}
func NewManagerImpl(basePath string, providers map[int32]Provider) *ManagerImpl {
	_, ok := providers[int32(cb.Policy_IMPLICIT_META)]
	if ok {
		logger.Panicf("ImplicitMetaPolicy type must be provider by the policy manager")
	}
	return &ManagerImpl{
		basePath:  basePath,
		fqPrefix:  PathSeparator + basePath + PathSeparator,
		providers: providers,
		config: &policyConfig{
			policies: make(map[string]Policy),
			managers: make(map[string]*ManagerImpl),
		},
		pendingConfig: make(map[interface{}]*policyConfig),
	}
}
type rejectPolicy string
func (rp rejectPolicy) Evaluate(signedData []*cb.SignedData) error {
	return fmt.Errorf("No such policy type: %s", rp)
}
func (pm *ManagerImpl) BasePath() string {
	return pm.basePath
}
func (pm *ManagerImpl) PolicyNames() []string {
	policyNames := make([]string, len(pm.config.policies))
	i := 0
	for policyName := range pm.config.policies {
		policyNames[i] = policyName
		i++
	}
	return policyNames
}