func CommonGroupAttr(a []attr.Interface, g Group) Group {
	if c, ok := g.(Collection); ok {
		return commonCollectionTrackAttr(a, c)
	}
	return commonGroupTrackAttr(a, g)
}
CommonGroupAttr recurses through the Group and assigns fields on all sub groups
which are common amoungst their children (Groups or Tracks).  If there is no common
field, then the associated Field value is not set.
package index
import "tchaik.com/index/attr"
type subColFlds struct {
	Collection
	flds map[string]interface{}
}
func (scf subColFlds) Field(f string) interface{} {
	if x, ok := scf.flds[f]; ok {
		return x
	}
	return scf.Collection.Field(f)
}
type subGrpFlds struct {
	Group
	tracks []Track
	flds   map[string]interface{}
}
func (sgf subGrpFlds) Tracks() []Track {
	if sgf.tracks != nil {
		return sgf.tracks
	}
	return sgf.Group.Tracks()
}
func (sgf subGrpFlds) Field(field string) interface{} {
	if x, ok := sgf.flds[field]; ok {
		return x
	}
	return sgf.Group.Field(field)
}
func SumGroupIntAttr(field string, g Group) Group {
	if c, ok := g.(Collection); ok {
		return sumCollectionIntAttr(field, c)
	}
	return sumGroupIntAttr(field, g)
}
func sumCollectionIntAttr(field string, c Collection) Collection {
	nc := subCol{
		Collection: c,
		grps:       make(map[Key]Group, len(c.Keys())),
		flds:       make(map[string]interface{}),
	}
	var total int
	for _, k := range c.Keys() {
		g := c.Get(k)
		g = SumGroupIntAttr(field, g)
		total += g.Field(field).(int)
		nc.grps[k] = g
	}
	nc.flds = map[string]interface{}{
		field: total,
	}
	return nc
}
func sumGroupIntAttr(field string, g Group) Group {
	ng := subGrpFlds{
		Group: g,
		flds:  map[string]interface{}{},
	}
	var total int
	for _, t := range g.Tracks() {
		total += t.GetInt(field)
	}
	ng.flds[field] = total
	return ng
}