public static CoherentPropertyField[] GetProperties(System.Object obj)
    {
        List <CoherentPropertyField> fields = new List <CoherentPropertyField>();

        PropertyInfo[] infos = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

        foreach (PropertyInfo info in infos)
        {
            if (!(info.CanRead && info.CanWrite))
            {
                continue;
            }

            object[] attributes = info.GetCustomAttributes(true);

            bool isExposed = false;

            foreach (object o in attributes)
            {
                var t = o.GetType();
                if (t == typeof(CoherentExposePropertyAttribute)
                                        #if UNITY_STANDALONE
                    || t == typeof(CoherentExposePropertyStandaloneAttribute)
                                        #elif UNITY_IPHONE || UNITY_ANDROID
                    || t == typeof(CoherentExposePropertyiOSAttribute)
                                        #endif
                    )
                {
                    isExposed = true;
                    break;
                }
            }

            if (!isExposed)
            {
                continue;
            }

            SerializedPropertyType type = SerializedPropertyType.Integer;

            if (CoherentPropertyField.GetPropertyType(info, out type))
            {
                CoherentPropertyField field = new CoherentPropertyField(obj, info, type);
                fields.Add(field);
            }
        }

        return(fields.ToArray());
    }
    public static CoherentFoldout[] GetProperties(System.Object obj)
    {
        CoherentFoldout[] foldouts = new CoherentFoldout[(int)CoherentExposePropertyInfo.FoldoutType.Count];

        PropertyInfo[] infos = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

        foreach (PropertyInfo info in infos)
        {
            if (!(info.CanRead && info.CanWrite))
            {
                continue;
            }

            object[] attributes = info.GetCustomAttributes(true);

            bool   isExposed     = false;
            object infoAttribute = null;

            foreach (object o in attributes)
            {
                var t = o.GetType();
                if (t == typeof(CoherentExposePropertyAttribute)
                                        #if UNITY_STANDALONE
                    || t == typeof(CoherentExposePropertyStandaloneAttribute)
                                        #elif UNITY_IPHONE || UNITY_ANDROID
                    || t == typeof(CoherentExposePropertyiOSAttribute)
                                        #endif
                    )
                {
                    infoAttribute = o;
                    isExposed     = true;
                    break;
                }
            }

            if (!isExposed)
            {
                continue;
            }

            SerializedPropertyType type = SerializedPropertyType.Integer;

            if (CoherentPropertyField.GetPropertyType(info, out type))
            {
                CoherentPropertyField field = new CoherentPropertyField(obj, info, type, infoAttribute);

                var category = CoherentExposePropertyInfo.FoldoutType.General;
                var attr     = infoAttribute as CoherentExposePropertyInfo;
                if (attr != null)
                {
                    category = attr.Category;
                }

                if (foldouts[(int)category] == null)
                {
                    foldouts[(int)category] = new CoherentFoldout(category);
                }
                foldouts[(int)category].AddField(field);
            }
        }

        return(foldouts);
    }