func processTagDiff(client *tags.RestClient, d *schema.ResourceData, obj object.Reference) error {
	log.Printf("[DEBUG] Processing tags for object %q", obj.Reference().Value)
	old, new := d.GetChange(vSphereTagAttributeKey)
	tdp := &tagDiffProcessor{
		client:    client,
		subject:   obj,
		oldTagIDs: structure.SliceInterfacesToStrings(old.(*schema.Set).List()),
		newTagIDs: structure.SliceInterfacesToStrings(new.(*schema.Set).List()),
	}
	if err := tdp.processDetachOperations(); err != nil {
		return fmt.Errorf("error detaching tags to object ID %q: %s", obj.Reference().Value, err)
	}
	if err := tdp.processAttachOperations(); err != nil {
		return fmt.Errorf("error attaching tags to object ID %q: %s", obj.Reference().Value, err)
	}
	return nil
}
func processTagDiff(client *tags.RestClient, d *schema.ResourceData, obj object.Reference) error {
	log.Printf("[DEBUG] Processing tags for object %q", obj.Reference().Value)
	old, new := d.GetChange(vSphereTagAttributeKey)
	tdp := &tagDiffProcessor{
		client:    client,
		subject:   obj,
		oldTagIDs: structure.SliceInterfacesToStrings(old.(*schema.Set).List()),
		newTagIDs: structure.SliceInterfacesToStrings(new.(*schema.Set).List()),
	}
	if err := tdp.processDetachOperations(); err != nil {
		return fmt.Errorf("error detaching tags to object ID %q: %s", obj.Reference().Value, err)
	}
	if err := tdp.processAttachOperations(); err != nil {
		return fmt.Errorf("error attaching tags to object ID %q: %s", obj.Reference().Value, err)
	}
	return nil
}
// processTagDiff wraps the whole tag diffing operation into a nice clean
// function that resources can use.