code: public Set<MessageDescriptor<? extends M>> getSubtypes() {
  		if (subtypes != null) {
  			return subtypes;
  		}
  
  		Set<MessageDescriptor<? extends M>> list = new HashSet<MessageDescriptor<? extends M>>();
  		for (Provider<MessageDescriptor<? extends M>> provider : subtypeProviders) {
  			MessageDescriptor<? extends M> subtype = provider.get();
  			list.add(subtype);
  		}
  
  		Map<Enum<?>, MessageDescriptor<? extends M>> map = new HashMap<Enum<?>,
  				MessageDescriptor<? extends M>>();
  		for (MessageDescriptor<? extends M> subtype : list) {
  			map.put(subtype.getDiscriminatorValue(), subtype);
  		}
  
  		subtypes = ImmutableCollections.set(list);
  		subtypeMap = ImmutableCollections.map(map);
  		return subtypes;
  	}
docs: Returns this message subtypes (including their subtypes) or an empty set.