public static void Expose( CoherentFoldout[] foldouts )
	{
		GUILayoutOption[] emptyOptions = new GUILayoutOption[0];
		
		if(!m_LogoTexture)
		{
			m_LogoTexture = EditorGUIUtility.FindTexture("Coherent_UI_inspector");
		}
		if(!m_SupportTexture)
		{
			m_SupportTexture = EditorGUIUtility.FindTexture("Coherent_UI_support");
		}
		if(!m_DocsTexture)
		{
			m_DocsTexture = EditorGUIUtility.FindTexture("Coherent_UI_docs");
		}
		EditorGUILayout.BeginVertical( GUILayout.Height(32) );
		EditorGUILayout.BeginHorizontal( emptyOptions );
		var labelStyle = new GUIStyle();
		labelStyle.fixedHeight = 32;
		labelStyle.fixedWidth = 163;
		if(m_LogoTexture) {
			EditorGUILayout.LabelField(new GUIContent("", m_LogoTexture), labelStyle, emptyOptions);
		}
		
		if(m_DocsTexture && GUILayout.Button(m_DocsTexture)){
			Application.OpenURL("http://coherent-labs.com/Documentation/unity/");
		}
		if(m_SupportTexture && GUILayout.Button(m_SupportTexture)){
			Application.OpenURL("http://coherent-labs.com/developer/");
		}
		
		EditorGUILayout.EndHorizontal();
		EditorGUILayout.EndVertical();
		
		EditorGUILayout.BeginVertical( emptyOptions );				
		foreach (CoherentFoldout fold in foldouts)
		{
			if(fold == null)
				continue;
			bool hasPropertiesToShow = false;
			foreach ( CoherentPropertyField field in fold.Fields )
			{
				if(!Application.isPlaying || !field.IsStatic) {
					hasPropertiesToShow = true;
					break;
				}
			}
			if(!hasPropertiesToShow)
				continue;
						
			fold.Show = EditorGUILayout.Foldout(fold.Show, new GUIContent(fold.Name, fold.Tooltip));

			if(fold.Show) {
				foreach ( CoherentPropertyField field in fold.Fields )
				{
					if(Application.isPlaying && field.IsStatic) {
						continue;						
					}
					
					var realType = field.RealType;
						
					EditorGUILayout.BeginHorizontal( emptyOptions );
					GUIContent content = new GUIContent(field.Name);
					if(field.Tooltip.Length > 0)
					{
						content.tooltip = field.Tooltip;
					}
					
					switch ( field.Type )
					{
					case SerializedPropertyType.Integer:
							field.SetValue( EditorGUILayout.IntField( content, (int)field.GetValue(), emptyOptions ) ); 
						break;
					 
					case SerializedPropertyType.Float:
							field.SetValue( EditorGUILayout.FloatField( content, (float)field.GetValue(), emptyOptions ) );
						break;
		 
					case SerializedPropertyType.Boolean:
							field.SetValue( EditorGUILayout.Toggle( content, (bool)field.GetValue(), emptyOptions ) );
						break;
		 
					case SerializedPropertyType.String:
							field.SetValue( EditorGUILayout.TextField( content, (String)field.GetValue(), emptyOptions ) );
						break;
		 
					case SerializedPropertyType.Vector2:
							field.SetValue( EditorGUILayout.Vector2Field( field.Name, (Vector2)field.GetValue(), emptyOptions ) );
						break;
		 
					case SerializedPropertyType.Vector3:
							field.SetValue( EditorGUILayout.Vector3Field( field.Name, (Vector3)field.GetValue(), emptyOptions ) );
						break;
		  
					case SerializedPropertyType.Enum:
							field.SetValue(EditorGUILayout.EnumPopup( content, (Enum)field.GetValue(), emptyOptions));
						break;
					case SerializedPropertyType.ObjectReference:
							field.SetValue(EditorGUILayout.ObjectField( content.text, (UnityEngine.Object)field.GetValue(), realType, true, emptyOptions));
						break;
		 
					default:
		 
						break;
		 
					}

					EditorGUILayout.EndHorizontal();	 
				}
			}
		}
		EditorGUILayout.EndVertical();
	}
    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);
    }
	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;
	}