private void DrawMember(SerializedProperty property, ref int index, ParameterData parameter)
        {
            var label = this.labels[index];

            switch (parameter.returnType)
            {
            case ObjectType.Boolean:
            case ObjectType.Int32:
            case ObjectType.Int64:
            case ObjectType.Single:
            case ObjectType.Double:
            case ObjectType.String:
            case ObjectType.LayerMask:
            case ObjectType.Color:
            case ObjectType.AnimationCurve:
                EditorGUILayout.PropertyField(property, label, false);
                break;

            case ObjectType.UInt64:
                var   oldString   = property.stringValue;
                var   ulongString = EditorGUILayout.TextField(label, property.stringValue);
                ulong ulongVal;

                if (!ulong.TryParse(ulongString, out ulongVal))
                {
                    ulongString = oldString;
                }

                if (string.IsNullOrEmpty(ulongString))
                {
                    ulongString = "0";
                }

                property.stringValue = ulongString;
                break;

            case ObjectType.Byte:
                property.intValue = EditorFields.ByteField(label, (byte)property.intValue);
                break;

            case ObjectType.SByte:
                property.intValue = EditorFields.SByteField(label, (sbyte)property.intValue);
                break;

            case ObjectType.Char:
                property.intValue = EditorFields.CharField(label, (char)property.intValue);
                break;

            case ObjectType.Int16:
                property.intValue = EditorFields.ShortField(label, (short)property.intValue);
                break;

            case ObjectType.UInt16:
                property.intValue = EditorFields.UShortField(label, (ushort)property.intValue);
                break;

            case ObjectType.UInt32:
                property.longValue = EditorFields.UIntField(label, (uint)property.longValue);
                break;

            case ObjectType.Enum:
            {
                var  typeOf         = Type.GetType(parameter.assemblyQualifiedName);
                var  flagsAttribute = typeOf.GetCustomAttributes(typeof(FlagsAttribute), false);
                Enum enumValue;

                if (flagsAttribute != null && flagsAttribute.Length >= 1)
                {
                    enumValue = EditorGUILayout.EnumMaskPopup(label, (Enum)Enum.ToObject(typeOf, property.longValue));
                }
                else
                {
                    enumValue = EditorGUILayout.EnumPopup(label, (Enum)Enum.ToObject(typeOf, property.longValue));
                }

                try
                {
                    property.longValue = (int)Enum.ToObject(typeOf, enumValue);
                }
                catch
                {
                    property.longValue = (long)Enum.ToObject(typeOf, enumValue);
                }
            }
            break;

            case ObjectType.Vector2:
                property.vector2Value = EditorGUILayout.Vector2Field(label, property.vector2Value);
                break;

            case ObjectType.Vector3:
                property.vector3Value = EditorGUILayout.Vector3Field(label, property.vector3Value);
                break;

            case ObjectType.Vector4:
                property.vector4Value = EditorGUILayout.Vector4Field(label, property.vector4Value);
                break;

            case ObjectType.Bounds:
                property.boundsValue = EditorGUILayout.BoundsField(label, property.boundsValue);
                break;

            case ObjectType.Rect:
                property.rectValue = EditorGUILayout.RectField(label, property.rectValue);
                break;

            case ObjectType.Quaternion:
                property.quaternionValue = EditorFields.QuaternionField(label, property.quaternionValue);
                break;

            case ObjectType.UnityObject:
            {
                var typeOf = Type.GetType(parameter.assemblyQualifiedName);
                property.objectReferenceValue = EditorGUILayout.ObjectField(label, property.objectReferenceValue, typeOf, true);
            }
            break;

            case ObjectType.Matrix4x4:
            {
                var matrix = property.stringValue.ToObject <Matrix4x4>();
                matrix = EditorFields.Matrix4x4Field(label, matrix);
                property.stringValue = matrix.ToJson();
            }
            break;

            case ObjectType.SerializableType:
            case ObjectType.Array:
            case ObjectType.List:
            {
                var typeOf = Type.GetType(parameter.assemblyQualifiedName);

                if (this.cloneObjects[index] == null)
                {
                    var cloneObjectType = CreateCloneObjectType("CloneObject", FakeObjectFields.Value, typeOf);
                    this.cloneObjects[index]         = CreateInstance(cloneObjectType);
                    this.cloneValueFieldInfos[index] = cloneObjectType.GetField(FakeObjectFields.Value,
                                                                                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                }

                var cloneObject         = this.cloneObjects[index];
                var cloneValueFieldInfo = this.cloneValueFieldInfos[index];

                var data = property.stringValue.ToObject(typeOf);

                if (data == null)
                {
                    if (parameter.returnType == ObjectType.Array)
                    {
                        data = Activator.CreateInstance(typeOf, 0);
                    }
                    else
                    {
                        data = Activator.CreateInstance(typeOf);
                    }
                }

                cloneValueFieldInfo.SetValue(cloneObject, data);

                if (this.serializedCloneObjects[index] == null)
                {
                    this.serializedCloneObjects[index]    = new SerializedObject(cloneObject);
                    this.serializedCloneProperties[index] = this.serializedCloneObjects[index].FindProperty(FakeObjectFields.Value);
                }

                var serializedCloneObject   = this.serializedCloneObjects[index];
                var serializedCloneProperty = this.serializedCloneProperties[index];

                EditorGUI.BeginChangeCheck();

                serializedCloneObject.Update();
                EditorGUILayout.PropertyField(serializedCloneProperty, label, true);

                if (EditorGUI.EndChangeCheck())
                {
                    serializedCloneObject.ApplyModifiedPropertiesWithoutUndo();
                    data = cloneValueFieldInfo.GetValue(cloneObject);

                    property.stringValue = data.ToJson(typeOf);
                }
            }
            break;
            }
        }
        private void DrawMember(SerializedProperty property)
        {
            switch (this.type)
            {
            case ObjectType.Bounds:
                property.boundsValue = EditorGUILayout.BoundsField(this.infos.memberData.guiLabel, property.boundsValue);
                break;

            case ObjectType.Rect:
                property.rectValue = EditorGUILayout.RectField(this.infos.memberData.guiLabel, property.rectValue);
                break;

            case ObjectType.Matrix4x4:
            {
                var matrix = property.stringValue.ToObject <Matrix4x4>();
                matrix = EditorFields.Matrix4x4Field(this.infos.memberData.guiLabel, matrix);
                property.stringValue = matrix.ToJson();
            }
            break;

            case ObjectType.SerializableType:
            case ObjectType.Array:
            case ObjectType.List:
            {
                if (this.cloneObject == null)
                {
                    var cloneObjectType = CreateCloneObjectType("CloneObject", FakeObjectFields.Value, this.typeOf);
                    this.cloneObject         = CreateInstance(cloneObjectType);
                    this.cloneValueFieldInfo = cloneObjectType.GetField(FakeObjectFields.Value,
                                                                        BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                }

                var data = property.stringValue.ToObject(this.typeOf);

                if (data == null)
                {
                    if (this.type == ObjectType.Array)
                    {
                        data = Activator.CreateInstance(this.typeOf, 0);
                    }
                    else
                    {
                        data = Activator.CreateInstance(this.typeOf);
                    }
                }

                this.cloneValueFieldInfo.SetValue(this.cloneObject, data);

                if (this.serializedCloneObject == null)
                {
                    this.serializedCloneObject   = new SerializedObject(this.cloneObject);
                    this.serializedCloneProperty = this.serializedCloneObject.FindProperty(FakeObjectFields.Value);
                }

                EditorGUI.BeginChangeCheck();

                this.serializedCloneObject.Update();
                EditorGUILayout.PropertyField(this.serializedCloneProperty, this.infos.memberData.guiLabel, true);

                if (EditorGUI.EndChangeCheck())
                {
                    this.serializedCloneObject.ApplyModifiedPropertiesWithoutUndo();
                    data = this.cloneValueFieldInfo.GetValue(this.cloneObject);

                    property.stringValue = data.ToJson(this.typeOf);
                }
            }
            break;
            }
        }
        private void DrawValue(Rect rect, MemberInfos infos, string name, string assemblyQualifiedName, ObjectType objectType, string typeName, SerializedProperty valueProperty, SerializedObject serializedObject)
        {
            var fieldProp = valueProperty.GetPropertyOfType(objectType);

            if (fieldProp == null)
            {
                return;
            }

            var typeProperty         = valueProperty.FindPropertyRelative(ValueFields.Type);
            var fullTypeNameProperty = valueProperty.FindPropertyRelative(ValueFields.FullTypeName);

            typeProperty.intValue            = (int)objectType;
            fullTypeNameProperty.stringValue = assemblyQualifiedName;
            serializedObject.ApplyModifiedProperties();

            switch (objectType)
            {
            case ObjectType.Bounds:
            case ObjectType.Rect:
            case ObjectType.Matrix4x4:
            case ObjectType.SerializableType:
            case ObjectType.Array:
            case ObjectType.List:
                if (GUI.Button(rect, WIZARD))
                {
                    var wizard = ScriptableWizard.DisplayWizard <PropertyWizard>(string.Empty, "Save");
                    wizard.infos              = infos;
                    wizard.type               = objectType;
                    wizard.typeOf             = Type.GetType(assemblyQualifiedName);
                    wizard.serializedProperty = fieldProp;
                    wizard.path               = fieldProp.propertyPath;
                    wizard.onClose            = OnPropertyWizardClose;
                }
                return;
            }

            var label = new GUIContent(typeName);

            switch (objectType)
            {
            case ObjectType.Boolean:
            case ObjectType.Int32:
            case ObjectType.Int64:
            case ObjectType.Single:
            case ObjectType.Double:
            case ObjectType.String:
                EditorGUI.PropertyField(rect, fieldProp, label, false);
                serializedObject.ApplyModifiedProperties();
                break;

            case ObjectType.UInt64:
                var   oldValue    = fieldProp.stringValue;
                var   ulongString = EditorGUI.TextField(rect, label, fieldProp.stringValue);
                ulong ulongVal;

                if (!ulong.TryParse(ulongString, out ulongVal))
                {
                    ulongString = oldValue;
                }

                if (string.IsNullOrEmpty(ulongString))
                {
                    ulongString = "0";
                }

                fieldProp.stringValue = ulongString;
                serializedObject.ApplyModifiedProperties();
                break;

            case ObjectType.LayerMask:
            case ObjectType.Color:
            case ObjectType.AnimationCurve:
                EditorGUI.PropertyField(rect, fieldProp, GUIContent.none, false);
                serializedObject.ApplyModifiedProperties();
                break;

            case ObjectType.Byte:
                fieldProp.intValue = EditorFields.ByteField(rect, label, (byte)fieldProp.intValue);
                serializedObject.ApplyModifiedProperties();
                break;

            case ObjectType.SByte:
                fieldProp.intValue = EditorFields.SByteField(rect, label, (sbyte)fieldProp.intValue);
                serializedObject.ApplyModifiedProperties();
                break;

            case ObjectType.Char:
                fieldProp.intValue = EditorFields.CharField(rect, label, (char)fieldProp.intValue);
                serializedObject.ApplyModifiedProperties();
                break;

            case ObjectType.Int16:
                fieldProp.intValue = EditorFields.ShortField(rect, label, (short)fieldProp.intValue);
                serializedObject.ApplyModifiedProperties();
                break;

            case ObjectType.UInt16:
                fieldProp.intValue = EditorFields.UShortField(rect, label, (ushort)fieldProp.intValue);
                serializedObject.ApplyModifiedProperties();
                break;

            case ObjectType.UInt32:
                fieldProp.longValue = EditorFields.UIntField(rect, label, (uint)fieldProp.longValue);
                serializedObject.ApplyModifiedProperties();
                break;

            case ObjectType.Enum:
            {
                var  typeOf         = Type.GetType(assemblyQualifiedName);
                var  flagsAttribute = typeOf.GetCustomAttributes(typeof(FlagsAttribute), false);
                Enum enumValue;

                if (flagsAttribute != null && flagsAttribute.Length >= 1)
                {
                    enumValue = EditorGUI.EnumMaskPopup(rect, GUIContent.none, (Enum)Enum.ToObject(typeOf, fieldProp.longValue));
                }
                else
                {
                    enumValue = EditorGUI.EnumPopup(rect, (Enum)Enum.ToObject(typeOf, fieldProp.longValue));
                }

                try
                {
                    fieldProp.longValue = (int)Enum.ToObject(typeOf, enumValue);
                    serializedObject.ApplyModifiedProperties();
                }
                catch
                {
                    fieldProp.longValue = (long)Enum.ToObject(typeOf, enumValue);
                    serializedObject.ApplyModifiedProperties();
                }
            }
            break;

            case ObjectType.Vector2:
                fieldProp.vector2Value = EditorGUI.Vector2Field(rect, GUIContent.none, fieldProp.vector2Value);
                serializedObject.ApplyModifiedProperties();
                break;

            case ObjectType.Vector3:
                fieldProp.vector3Value = EditorGUI.Vector3Field(rect, GUIContent.none, fieldProp.vector3Value);
                serializedObject.ApplyModifiedProperties();
                break;

            case ObjectType.Vector4:
                fieldProp.vector4Value = EditorGUI.Vector4Field(rect, GUIContent.none, fieldProp.vector4Value);
                serializedObject.ApplyModifiedProperties();
                break;

            case ObjectType.Quaternion:
                fieldProp.quaternionValue = EditorFields.QuaternionField(rect, GUIContent.none, fieldProp.quaternionValue);
                serializedObject.ApplyModifiedProperties();
                break;

            case ObjectType.UnityObject:
            {
                var typeOf = Type.GetType(assemblyQualifiedName);
                fieldProp.objectReferenceValue = EditorGUI.ObjectField(rect, GUIContent.none, fieldProp.objectReferenceValue, typeOf, true);
                serializedObject.ApplyModifiedProperties();
            }
            break;
            }
        }