public override void OnInspectorGUI()
    {
        DataPrototype data = (DataPrototype)serializedObject.targetObject;

        foreach (var property in data.GetProperties())
        {
            DrawPropertyUserInput(property, data);
        }

        target.SetDirtyIfGUIChanged();
    }
    private static void DrawPropertyUserInput(DataPrototype.Property property, DataPrototype data)
    {
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.PrefixLabel(property.Name);

        if (DoesInputFieldExistForProperty(property))
        {
            QueryPropertyUserInput(property, data);
        }

        EditorGUILayout.EndHorizontal();
    }
    private static void QueryPropertyUserInput(DataPrototype.Property property, DataPrototype data)
    {
        var input = GetUnityEditorPropertyInputFieldValue(property);

        if (property.DelegatesToPrototype)
        {
            property.ProtoProperty = GetProtoPropertyUserInput(property, data);
        }
        else
        {
            property.Value = input;
        }

        property.DelegatesToPrototype = GetPrototypeDelegationUserInput(property);
    }
    private static DataPrototype.Property GetProtoPropertyUserInput(DataPrototype.Property property, DataPrototype data)
    {
        GUI.enabled = property.DelegatesToPrototype;

        var currentProtoPropertyOwner = property.ProtoProperty == null ? null : property.ProtoProperty.Owner;
        var protoPropertyOwner        = (DataPrototype)EditorGUILayout.ObjectField(currentProtoPropertyOwner, data.GetType(), true);

        if (protoPropertyOwner != null)
        {
            return(protoPropertyOwner.GetProperty(property.Name));
        }

        return(null);
    }