code: func collectPrincipals(principal *m.MSPPrincipal, mspVersion MSPVersion) ([]*m.MSPPrincipal, error) {
  	switch principal.PrincipalClassification {
  	case m.MSPPrincipal_COMBINED:
  		// Combined principals are not supported in MSP v1.0 or v1.1
  		if mspVersion <= MSPv1_1 {
  			return nil, errors.Errorf("invalid principal type %d", int32(principal.PrincipalClassification))
  		}
  		// Principal is a combination of multiple principals.
  		principals := &m.CombinedPrincipal{}
  		err := proto.Unmarshal(principal.Principal, principals)
  		if err != nil {
  			return nil, errors.Wrap(err, "could not unmarshal CombinedPrincipal from principal")
  		}
  		// Return an error if there are no principals in the combined principal.
  		if len(principals.Principals) == 0 {
  			return nil, errors.New("No principals in CombinedPrincipal")
  		}
  		// Recursively call msp.collectPrincipals for all combined principals.
  		// There is no limit for the levels of nesting for the combined principals.
  		var principalsSlice []*m.MSPPrincipal
  		for _, cp := range principals.Principals {
  			internalSlice, err := collectPrincipals(cp, mspVersion)
  			if err != nil {
  				return nil, err
  			}
  			principalsSlice = append(principalsSlice, internalSlice...)
  		}
  		// All the combined principals have been collected into principalsSlice
  		return principalsSlice, nil
  	default:
  		return []*m.MSPPrincipal{principal}, nil
  	}
  }
docs: // collectPrincipals collects principals from combined principals into a single MSPPrincipal slice.