code: func endorsersByGroup(criteria *peerMembershipCriteria) map[string]*discovery.Peers {
  	satGraph := criteria.satGraph
  	idOfMembers := criteria.idOfMembers
  	chanMemberById := criteria.chanMemberById
  	includedGroups := criteria.possibleLayouts.groupsSet()
  
  	res := make(map[string]*discovery.Peers)
  	// Map endorsers to their corresponding groups.
  	// Iterate the principals, and put the peers into each group that corresponds with a principal vertex
  	for grp, principalVertex := range satGraph.principalVertices {
  		if _, exists := includedGroups[grp]; !exists {
  			// If the current group is not found in any layout, skip the corresponding principal
  			continue
  		}
  		peerList := &discovery.Peers{}
  		res[grp] = peerList
  		for _, peerVertex := range principalVertex.Neighbors() {
  			member := peerVertex.Data.(NetworkMember)
  			peerList.Peers = append(peerList.Peers, &discovery.Peer{
  				Identity:       idOfMembers.identityByPKIID(member.PKIid),
  				StateInfo:      chanMemberById[string(member.PKIid)].Envelope,
  				MembershipInfo: member.Envelope,
  			})
  		}
  	}
  	return res
  }
docs: // endorsersByGroup computes a map from groups to peers.
  // Each group included, is found in some layout, which means
  // that there is some principal combination that includes the corresponding
  // group.
  // This means that if a group isn't included in the result, there is no
  // principal combination (that includes the principal corresponding to the group),
  // such that there are enough peers to satisfy the principal combination.