public override UTVisibilityDecision IsVisible(System.Reflection.FieldInfo fieldInfo)
    {
        if (fieldInfo.Name == "gameObject" || fieldInfo.Name == "property")
        {
            return(base.IsVisible(fieldInfo));
        }

        // only expression field if the type is not clear
        var self = (UTSetComponentPropertyAction)target;

        if (self.property.UseExpression || !self.property.Value.FullyDefined)
        {
            if (fieldInfo.Name == "objectPropertyValue")
            {
                return(UTVisibilityDecision.Visible);
            }
            return(UTVisibilityDecision.Invisible);
        }

        // only expression field if the property is not valid anymore
        var propertyPath = UTComponentScanner.FindPropertyPath(self.property.Value.Type, self.property.Value.FieldPath);

        if (propertyPath == null)
        {
            if (fieldInfo.Name == "objectPropertyValue")
            {
                return(UTVisibilityDecision.Visible);
            }
            return(UTVisibilityDecision.Invisible);
        }

        Type   propertyType = UTInternalCall.GetMemberType(propertyPath[propertyPath.Length - 1]);
        string expectedPropertyFieldName = "objectPropertyValue";

        if (typeof(string).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "stringPropertyValue";
        }
        else if (typeof(bool).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "boolPropertyValue";
        }
        else if (typeof(int).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "intPropertyValue";
        }
        else if (typeof(float).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "floatPropertyValue";
        }
        else if (typeof(Texture).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "texturePropertyValue";
        }
        else if (typeof(Vector3).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "vector3PropertyValue";
        }
        else if (typeof(Vector2).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "vector2PropertyValue";
        }
        else if (typeof(Rect).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "rectPropertyValue";
        }
        else if (typeof(Quaternion).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "quaternionPropertyValue";
        }
        else if (typeof(Material).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "materialPropertyValue";
        }
        else if (typeof(Color).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "colorPropertyValue";
        }
        else if (typeof(GameObject).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "gameObjectPropertyValue";
        }
        else if (typeof(UObject).IsAssignableFrom(propertyType))
        {
            expectedPropertyFieldName = "unityObjectPropertyValue";
        }

        if (fieldInfo.Name == expectedPropertyFieldName)
        {
            return(UTVisibilityDecision.Visible);
        }

        return(UTVisibilityDecision.Invisible);
    }
    public override IEnumerator Execute(UTContext context)
    {
        var theGameObject = gameObject.EvaluateIn(context);

        if (theGameObject == null)
        {
            throw new UTFailBuildException("You must specify the game object htat holds the component.", this);
        }

        var theProperty = property.EvaluateIn(context);

        if (theProperty == null || !theProperty.FullyDefined)
        {
            throw new UTFailBuildException("You must specify the component type and its property you want to change.", this);
        }

        var propertyPath = UTComponentScanner.FindPropertyPath(theProperty.Type, theProperty.FieldPath);

        if (propertyPath == null)
        {
            throw new UTFailBuildException("The component type or the property path is no longer valid.", this);
        }

        var theComponent = theGameObject.GetComponent(theProperty.Type);

        if (theComponent == null)
        {
            // nothing to do
            if (UTPreferences.DebugMode)
            {
                Debug.Log("Component " + theProperty.Type.Name + " not found at game object " + theGameObject, this);
            }
        }
        else
        {
            Type   propertyType = UTInternalCall.GetMemberType(propertyPath[propertyPath.Length - 1]);
            object propertyValue;
            if (typeof(string).IsAssignableFrom(propertyType))
            {
                propertyValue = stringPropertyValue.EvaluateIn(context);
            }
            else if (typeof(bool).IsAssignableFrom(propertyType))
            {
                propertyValue = boolPropertyValue.EvaluateIn(context);
            }
            else if (typeof(int).IsAssignableFrom(propertyType))
            {
                propertyValue = intPropertyValue.EvaluateIn(context);
            }
            else if (typeof(float).IsAssignableFrom(propertyType))
            {
                propertyValue = floatPropertyValue.EvaluateIn(context);
            }
            else if (typeof(Texture).IsAssignableFrom(propertyType))
            {
                propertyValue = texturePropertyValue.EvaluateIn(context);
            }
            else if (typeof(Vector3).IsAssignableFrom(propertyType))
            {
                propertyValue = vector3PropertyValue.EvaluateIn(context);
            }
            else if (typeof(Vector2).IsAssignableFrom(propertyType))
            {
                propertyValue = vector2PropertyValue.EvaluateIn(context);
            }
            else if (typeof(Rect).IsAssignableFrom(propertyType))
            {
                propertyValue = rectPropertyValue.EvaluateIn(context);
            }
            else if (typeof(Quaternion).IsAssignableFrom(propertyType))
            {
                propertyValue = quaternionPropertyValue.EvaluateIn(context);
            }
            else if (typeof(Material).IsAssignableFrom(propertyType))
            {
                propertyValue = materialPropertyValue.EvaluateIn(context);
            }
            else if (typeof(Color).IsAssignableFrom(propertyType))
            {
                propertyValue = colorPropertyValue.EvaluateIn(context);
            }
            else if (typeof(GameObject).IsAssignableFrom(propertyType))
            {
                propertyValue = gameObjectPropertyValue.EvaluateIn(context);
            }
            else if (typeof(UObject).IsAssignableFrom(propertyType))
            {
                propertyValue = unityObjectPropertyValue.EvaluateIn(context);
            }
            else
            {
                propertyValue = objectPropertyValue.EvaluateIn(context);
            }

            // TODO: we need a lot more validation here.
            // e.g. is the value assignable?

            // Tested with Vector3 -> BoxCollider:center
            // and float -> BoxCollider:center.y
            UTInternalCall.SetMemberValue(theComponent, propertyPath, propertyValue);
        }
        yield return("");
    }