public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
        {
            InspectorDisplayAttribute attr = this.attribute as InspectorDisplayAttribute;
            string fieldName = (attr == null) ? "value" : attr.FieldName;

            float height = base.GetPropertyHeight(property, label);
            SerializedProperty valueProperty = property.FindPropertyRelative(fieldName);

            if (valueProperty == null)
            {
                return(height);
            }

            if (valueProperty.propertyType == SerializedPropertyType.Rect)
            {
                return(height * 2);
            }
            if (valueProperty.propertyType == SerializedPropertyType.Bounds)
            {
                return(height * 3);
            }
            if (valueProperty.propertyType == SerializedPropertyType.String)
            {
                MultilineReactivePropertyAttribute multilineAttr = GetMultilineAttribute();
                if (multilineAttr != null)
                {
                    return(((!EditorGUIUtility.wideMode) ? 16f : 0f) + 16f + (float)((multilineAttr.Lines - 1) * 13));
                }
                ;
            }

            if (valueProperty.isExpanded)
            {
                int         count = 0;
                IEnumerator e     = valueProperty.GetEnumerator();
                while (e.MoveNext())
                {
                    count++;
                }
                return(((height + 4) * count) + 6); // (Line = 20 + Padding) ?
            }

            return(height);
        }
        public override void OnGUI(Rect position, UnityEditor.SerializedProperty property, GUIContent label)
        {
            string fieldName;
            bool   notifyPropertyChanged;

            {
                InspectorDisplayAttribute attr = this.attribute as InspectorDisplayAttribute;
                fieldName             = (attr == null) ? "value" : attr.FieldName;
                notifyPropertyChanged = (attr == null) ? true : attr.NotifyPropertyChanged;
            }

            if (notifyPropertyChanged)
            {
                EditorGUI.BeginChangeCheck();
            }
            SerializedProperty targetSerializedProperty = property.FindPropertyRelative(fieldName);

            if (targetSerializedProperty == null)
            {
                UnityEditor.EditorGUI.LabelField(position, label, new GUIContent()
                {
                    text = "InspectorDisplay can't find target:" + fieldName
                });
                if (notifyPropertyChanged)
                {
                    EditorGUI.EndChangeCheck();
                }
                return;
            }
            else
            {
                EmitPropertyField(position, targetSerializedProperty, label);
            }

            if (notifyPropertyChanged)
            {
                if (EditorGUI.EndChangeCheck())
                {
                    property.serializedObject.ApplyModifiedProperties();                     // deserialize to field

                    string[]           paths             = property.propertyPath.Split('.'); // X.Y.Z...
                    UnityEngine.Object attachedComponent = property.serializedObject.targetObject;

                    object targetProp = (paths.Length == 1)
                        ? fieldInfo.GetValue(attachedComponent)
                        : GetValueRecursive(attachedComponent, 0, paths);
                    if (targetProp == null)
                    {
                        return;
                    }
                    PropertyInfo propInfo      = targetProp.GetType().GetProperty(fieldName, BindingFlags.IgnoreCase | BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                    object       modifiedValue = propInfo.GetValue(targetProp, null); // retrieve new value

                    MethodInfo methodInfo = targetProp.GetType().GetMethod("SetValueAndForceNotify", BindingFlags.IgnoreCase | BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                    if (methodInfo != null)
                    {
                        methodInfo.Invoke(targetProp, new object[] { modifiedValue });
                    }
                }
                else
                {
                    property.serializedObject.ApplyModifiedProperties();
                }
            }
        }