code: func (c *crConverter) ConvertToVersion(in runtime.Object, target runtime.GroupVersioner) (runtime.Object, error) {
  	fromGVK := in.GetObjectKind().GroupVersionKind()
  	toGVK, ok := target.KindForGroupVersionKinds([]schema.GroupVersionKind{fromGVK})
  	if !ok {
  		// TODO: should this be a typed error?
  		return nil, fmt.Errorf("%v is unstructured and is not suitable for converting to %q", fromGVK.String(), target)
  	}
  	if !c.validVersions[toGVK.GroupVersion()] {
  		return nil, fmt.Errorf("request to convert CR to an invalid group/version: %s", toGVK.GroupVersion().String())
  	}
  	// Note that even if the request is for a list, the GV of the request UnstructuredList is what
  	// is expected to convert to. As mentioned in the function's document, it is not expected to
  	// get a v1.List.
  	if !c.validVersions[fromGVK.GroupVersion()] {
  		return nil, fmt.Errorf("request to convert CR from an invalid group/version: %s", fromGVK.GroupVersion().String())
  	}
  	// Check list item's apiVersion
  	if list, ok := in.(*unstructured.UnstructuredList); ok {
  		for i := range list.Items {
  			expectedGV := list.Items[i].GroupVersionKind().GroupVersion()
  			if !c.validVersions[expectedGV] {
  				return nil, fmt.Errorf("request to convert CR list failed, list index %d has invalid group/version: %s", i, expectedGV.String())
  			}
  		}
  	}
  	return c.converter.Convert(in, toGVK.GroupVersion())
  }
docs: // ConvertToVersion converts in object to the given gvk in place and returns the same `in` object.
  // The in object can be a single object or a UnstructuredList. CRD storage implementation creates an
  // UnstructuredList with the request's GV, populates it from storage, then calls conversion to convert
  // the individual items. This function assumes it never gets a v1.List.