code: func computeLayouts(principalsSets []policies.PrincipalSet, principalGroups principalGroupMapper, satGraph *principalPeerGraph) []*discovery.Layout {
  	var layouts []*discovery.Layout
  	// principalsSets is a collection of combinations of principals,
  	// such that each combination (given enough peers) satisfies the endorsement policy.
  	for _, principalSet := range principalsSets {
  		layout := &discovery.Layout{
  			QuantitiesByGroup: make(map[string]uint32),
  		}
  		// Since principalsSet has repetitions, we first
  		// compute a mapping from the principal to repetitions in the set.
  		for principal, plurality := range principalSet.UniqueSet() {
  			key := principalKey{
  				cls:       int32(principal.PrincipalClassification),
  				principal: string(principal.Principal),
  			}
  			// We map the principal to a group, which is an alias for the principal.
  			layout.QuantitiesByGroup[principalGroups.group(key)] = uint32(plurality)
  		}
  		// Check that the layout can be satisfied with the current known peers
  		// This is done by iterating the current layout, and ensuring that
  		// each principal vertex is connected to at least <plurality> peer vertices.
  		if isLayoutSatisfied(layout.QuantitiesByGroup, satGraph) {
  			// If so, then add the layout to the layouts, since we have enough peers to satisfy the
  			// principal combination
  			layouts = append(layouts, layout)
  		}
  	}
  	return layouts
  }
docs: // computeLayouts computes all possible principal combinations
  // that can be used to satisfy the endorsement policy, given a graph
  // of available peers that maps each peer to a principal it satisfies.
  // Each such a combination is called a layout, because it maps
  // a group (alias for a principal) to a threshold of peers that need to endorse,
  // and that satisfy the corresponding principal.