/// <summary>
    /// Gets the fields and properties.
    /// </summary>
    /// <returns>The fields and properties.</returns>
    /// <param name="type">Type.</param>
    public static List <GUIClassField> GetFieldsAndProperties(Type type, object instance = null)
    {
        List <GUIClassField> gFields = new List <GUIClassField>();

        var fields = GetFields(type);

        if (null != fields && fields.Length > 0)
        {
            gFields.AddRange(GUIClassField.GetClassFields(type, fields, instance));
        }

        var properties = GetProperties(type);

        if (null != properties && properties.Length > 0)
        {
            gFields.AddRange(GUIClassField.GetClassFields(type, properties, instance));
        }

        return(gFields);
    }
    /// <summary>
    /// Raises the GU event.
    /// </summary>
    public void OnGUI()
    {
        var assembly = GetAssembly();

        // --------------
        // POPULATE TYPES
        // --------------
        var types = GetTypes(assembly);

        string[] typeNames = null;
        if (null == types || types.Length == 0)
        {
            typeNames  = new string[] { NO_TYPES_FOUND };
            _TypeIndex = 0;
        }
        else
        {
            typeNames = types.Select(t => t.FullName).ToArray();
        }

        using (var gTypeSelection = new JuneHorizontalSection()) {
            EditorGUILayout.LabelField("Type", GUILayout.MaxWidth(50), GUILayout.ExpandWidth(false));
            _TypeIndex   = EditorGUILayout.Popup(_TypeIndex, typeNames, STYLE_TYPE);
            _IS_FILTERED = EditorGUILayout.ToggleLeft("Filter Types", _IS_FILTERED, GUILayout.MaxWidth(140f), GUILayout.ExpandWidth(false));
        }

        // -----------------
        // SET SELECTED TYPE
        // -----------------
        Type selectedType = null;

        if (null != types && _TypeIndex >= 0 && _TypeIndex < types.Length)
        {
            selectedType = types[_TypeIndex];
            //Debug.Log("Selected - " + selectedType.Name);
            //Debug.Log("Selected Methods - " + selectedType.GetMethods().Where(m => m.IsPublic && m.IsStatic).Count());
        }

        // ------------------------------
        // POPULATE SELECTED TYPE FIELDS
        // ------------------------------
        var fields = GetFieldsAndProperties(selectedType);

        string[] fieldNames = null;
        if (null == fields || fields.Count == 0)
        {
            fieldNames  = new string[] { NO_STATIC_VARIABLES };
            _FieldIndex = 0;
        }
        else
        {
            try {
                fieldNames = fields.Select(f => _FULL_FIELD_NAME ? f.FullName : f.Name).ToArray();
            }
            catch (Exception ex) {
                Debug.Log(ex);
            }
        }

        using (var gVarSelection = new JuneHorizontalSection()) {
            EditorGUILayout.LabelField("Variables", GUILayout.MaxWidth(50), GUILayout.ExpandWidth(false));
            _FieldIndex      = EditorGUILayout.Popup(_FieldIndex, fieldNames, GUILayout.ExpandWidth(true));
            _FULL_FIELD_NAME = EditorGUILayout.ToggleLeft("Full Variable Signature", _FULL_FIELD_NAME, GUILayout.MaxWidth(140f), GUILayout.ExpandWidth(false));
        }

        if (null == fields || _FieldIndex >= fields.Count)
        {
            _FieldIndex = 0;
        }

        // -------------------
        // SET SELECTED FIELD
        // -------------------
        GUIClassField selectedField = null;

        if (null != fields && _FieldIndex >= 0 && _FieldIndex < fields.Count)
        {
            selectedField = fields[_FieldIndex];
        }

        using (var gAddObject = new JuneHorizontalSection()) {
            if (GUILayout.Button("Add"))
            {
                if (null != selectedField && false == _WatchObjects.Contains(selectedField))
                {
                    _WatchObjects.Add(selectedField);
                }
            }
        }

        EditorGUILayout.Separator();

        var normalColor = GUI.color;

        GUI.color = Color.yellow;
        using (var gHeader = new JuneHorizontalSection()) {
            EditorGUILayout.LabelField("Name");
            EditorGUILayout.LabelField("Value");
            EditorGUILayout.LabelField("Type");
            if (GUILayout.Button("Refresh", GUILayout.Width(CLOSE_BUTTON_WIDTH + 15)))
            {
                _WatchObjects.ForEach(o => o.Refresh());
            }
            if (GUILayout.Button("Clear", GUILayout.Width(CLOSE_BUTTON_WIDTH)))
            {
                _WatchObjects.Clear();
            }
        }
        GUI.color = normalColor;

        EditorGUILayout.Separator();

        if (null != _WatchObjects && _WatchObjects.Count > 0)
        {
            using (var gScrollView = new JuneScrollView(ref _ScrollPosition)) {
                try {
                    for (int i = 0; i < _WatchObjects.Count; i++)
                    {
                        var item = _WatchObjects[i];
                        using (var gObj = new JuneVerticalSection()) {
                            item.RenderField();
                        }
                    }
                }
                catch (Exception ex) {
                    Debug.Log(ex);
                }
            }
        }

        // -------------------------
        // DISPLAY METHOD PARAMETERS
        // -------------------------

        /*
         * var parameters = GetParameters(selectedMethod);
         * EditorGUILayout.BeginVertical();
         * {
         *
         *      EditorGUILayout.HelpBox(GetMethodStr(selectedMethod), MessageType.None);
         *
         *      EditorGUILayout.Separator();
         *
         *      if (null != parameters && parameters.Length > 0) {
         *
         *              if (null == paramValues || paramValues.Length != parameters.Length) {
         *                      paramValues = new object[parameters.Length];
         *              }
         *
         *              for (int i = 0; i < parameters.Length; i++) {
         *                      EditorGUILayout.BeginHorizontal();
         *                      {
         *                              PopulateField(ref paramValues[i], parameters[i]);
         *                      }
         *                      EditorGUILayout.EndHorizontal();
         *              }
         *      }
         *      else {
         *              EditorGUILayout.LabelField("No parameters.");
         *      }
         *
         *      if (GUILayout.Button("Invoke")) {
         *              try {
         *                      //if(null == Dispatcher.Instance) {
         *                      Dispatcher.Initialize();
         *                      //}
         *
         *                      Result = selectedMethod.Invoke(null, paramValues);
         *                      //Result = "Invoked";
         *                      //EditorCoroutine.start(Util.ExecuteGetCommand("http://yahoo.com", www => {
         *                      //	Debug.Log("[CALLBACK] " + www.ToString());
         *                      //	EditorUtility.DisplayDialog("Callback", www.text, "ok");
         *                      //}));
         *              }
         *              catch (Exception ex) {
         *                      Result = ex.ToString();
         *              }
         *      }
         *      EditorGUILayout.Separator();
         *      EditorGUILayout.LabelField("Result");
         *      EditorGUILayout.TextArea((null == Result) ? "<NULL>" : Result.ToString(), GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
         * }
         * EditorGUILayout.EndVertical();
         */
    }