func tryConvert(convertor runtime.ObjectConvertor, object runtime.Object, versions ...string) (runtime.Object, error) {
	var last error
	for _, version := range versions {
		if len(version) == 0 {
			return object, nil
		}
		obj, err := convertor.ConvertToVersion(object, version)
		if err != nil {
			last = err
			continue
		}
		return obj, nil
	}
	return nil, last
}
tryConvert attempts to convert the given object to the provided versions in order. This function assumes
the object is in internal version.
package resource
import (
	"fmt"
	"reflect"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/meta"
	"k8s.io/kubernetes/pkg/api/unversioned"
	"k8s.io/kubernetes/pkg/apimachinery/registered"
	"k8s.io/kubernetes/pkg/runtime"
	utilerrors "k8s.io/kubernetes/pkg/util/errors"
	"k8s.io/kubernetes/pkg/util/sets"
	"k8s.io/kubernetes/pkg/watch"
)
type ErrMatchFunc func(error) bool
type Result struct {
	err     error
	visitor Visitor
	sources  []Visitor
	singular bool
	ignoreErrors []utilerrors.Matcher
	info []*Info
}
func (r *Result) IgnoreErrors(fns ...ErrMatchFunc) *Result {
	for _, fn := range fns {
		r.ignoreErrors = append(r.ignoreErrors, utilerrors.Matcher(fn))
	}
	return r
}
func (r *Result) Err() error {
	return r.err
}
func (r *Result) Visit(fn VisitorFunc) error {
	if r.err != nil {
		return r.err
	}
	err := r.visitor.Visit(fn)
	return utilerrors.FilterOut(err, r.ignoreErrors...)
}
func (r *Result) IntoSingular(b *bool) *Result {
	*b = r.singular
	return r
}
func (r *Result) Infos() ([]*Info, error) {
	if r.err != nil {
		return nil, r.err
	}
	if r.info != nil {
		return r.info, nil
	}
	infos := []*Info{}
	err := r.visitor.Visit(func(info *Info, err error) error {
		if err != nil {
			return err
		}
		infos = append(infos, info)
		return nil
	})
	err = utilerrors.FilterOut(err, r.ignoreErrors...)
	r.info, r.err = infos, err
	return infos, err
}
func (r *Result) Object() (runtime.Object, error) {
	infos, err := r.Infos()
	if err != nil {
		return nil, err
	}
	versions := sets.String{}
	objects := []runtime.Object{}
	for _, info := range infos {
		if info.Object != nil {
			objects = append(objects, info.Object)
			versions.Insert(info.ResourceVersion)
		}
	}
	if len(objects) == 1 {
		if r.singular {
			return objects[0], nil
		}
		if meta.IsListType(objects[0]) {
			return objects[0], nil
		}
	}
	version := ""
	if len(versions) == 1 {
		version = versions.List()[0]
	}
	return &api.List{
		ListMeta: unversioned.ListMeta{
			ResourceVersion: version,
		},
		Items: objects,
	}, err
}
func (r *Result) ResourceMapping() (*meta.RESTMapping, error) {
	if r.err != nil {
		return nil, r.err
	}
	mappings := map[string]*meta.RESTMapping{}
	for i := range r.sources {
		m, ok := r.sources[i].(ResourceMapping)
		if !ok {
			return nil, fmt.Errorf("a resource mapping could not be loaded from %v", reflect.TypeOf(r.sources[i]))
		}
		mapping := m.ResourceMapping()
		mappings[mapping.Resource] = mapping
	}
	if len(mappings) != 1 {
		return nil, fmt.Errorf("expected only a single resource type")
	}
	for _, mapping := range mappings {
		return mapping, nil
	}
	return nil, nil
}
func (r *Result) Watch(resourceVersion string) (watch.Interface, error) {
	if r.err != nil {
		return nil, r.err
	}
	if len(r.sources) != 1 {
		return nil, fmt.Errorf("you may only watch a single resource or type of resource at a time")
	}
	w, ok := r.sources[0].(Watchable)
	if !ok {
		info, err := r.Infos()
		if err != nil {
			return nil, err
		}
		if len(info) != 1 {
			return nil, fmt.Errorf("watch is only supported on individual resources and resource collections - %d resources were found", len(info))
		}
		return info[0].Watch(resourceVersion)
	}
	return w.Watch(resourceVersion)
}
func AsVersionedObject(infos []*Info, forceList bool, version string, encoder runtime.Encoder) (runtime.Object, error) {
	objects, err := AsVersionedObjects(infos, version, encoder)
	if err != nil {
		return nil, err
	}
	var object runtime.Object
	if len(objects) == 1 && !forceList {
		object = objects[0]
	} else {
		object = &api.List{Items: objects}
		converted, err := tryConvert(api.Scheme, object, version, registered.GroupOrDie(api.GroupName).GroupVersion.Version)
		if err != nil {
			return nil, err
		}
		object = converted
	}
	return object, nil
}
func AsVersionedObjects(infos []*Info, version string, encoder runtime.Encoder) ([]runtime.Object, error) {
	objects := []runtime.Object{}
	for _, info := range infos {
		if info.Object == nil {
			continue
		}
		if len(version) > 0 {
			if _, err := api.Scheme.ObjectKind(info.Object); runtime.IsNotRegisteredError(err) {
				data, err := runtime.Encode(encoder, info.Object)
				if err != nil {
					return nil, err
				}
				objects = append(objects, &runtime.Unknown{RawJSON: data})
				continue
			}
		}
		converted, err := tryConvert(info.Mapping.ObjectConvertor, info.Object, version, info.Mapping.GroupVersionKind.GroupVersion().String())
		if err != nil {
			return nil, err
		}
		objects = append(objects, converted)
	}
	return objects, nil
}