public static void DrawComponent(bool[] unfoldedComponents, string[] componentMemberSearch, IEntity entity, int index,
                                         IComponent component)
        {
            var componentType = component.GetType();
            var componentName = componentType.Name.RemoveComponentSuffix();

            if (EditorGUILayoutTools.MatchesSearchString(componentName.ToLower(), ComponentNameSearchString.ToLower()))
            {
                var boxStyle = GetColoredBoxStyle(entity, index);

                EditorGUILayout.BeginVertical(boxStyle);

                if (!Attribute.IsDefined(componentType, typeof(DontDrawComponentAttribute)))
                {
                    var memberInfos = componentType.GetPublicMemberInfos();
                    EditorGUILayout.BeginHorizontal();
                    {
                        if (memberInfos.Count == 0)
                        {
                            EditorGUILayout.LabelField(componentName, EditorStyles.boldLabel);
                        }
                        else
                        {
                            unfoldedComponents[index] = EditorGUILayoutTools.Foldout(
                                unfoldedComponents[index],
                                componentName,
                                FoldoutStyle);
                            if (unfoldedComponents[index])
                            {
                                componentMemberSearch[index] = memberInfos.Count > 5
                                                                        ? EditorGUILayoutTools.SearchTextField(componentMemberSearch[index])
                                                                        : string.Empty;
                            }
                        }

                        if (EditorGUILayoutTools.MiniButton("-"))
                        {
                            entity.RemoveComponent(index);
                        }
                    }
                    EditorGUILayout.EndHorizontal();

                    if (unfoldedComponents[index])
                    {
                        var newComponent = entity.CreateComponent(index, componentType);
                        component.CopyPublicMemberValues(newComponent);

                        var changed         = false;
                        var componentDrawer = GetComponentDrawer(componentType);
                        if (componentDrawer != null)
                        {
                            EditorGUI.BeginChangeCheck();
                            {
                                componentDrawer.DrawComponent(newComponent);
                            }
                            changed = EditorGUI.EndChangeCheck();
                        }
                        else
                        {
                            foreach (var info in memberInfos)
                            {
                                if (EditorGUILayoutTools.MatchesSearchString(
                                        info.name.ToLower(),
                                        componentMemberSearch[index].ToLower()))
                                {
                                    var memberValue = info.GetValue(newComponent);
                                    var memberType  = memberValue == null ? info.type : memberValue.GetType();
                                    if (DrawObjectMember(
                                            memberType,
                                            info.name,
                                            memberValue,
                                            newComponent,
                                            info.SetValue))
                                    {
                                        changed = true;
                                    }
                                }
                            }
                        }

                        if (changed)
                        {
                            entity.ReplaceComponent(index, newComponent);
                        }
                        else
                        {
                            entity.GetComponentPool(index).Push(newComponent);
                        }
                    }
                }
                else
                {
                    EditorGUILayout.LabelField(componentName, "[DontDrawComponent]", EditorStyles.boldLabel);
                }

                EditorGUILayoutTools.EndVerticalBox();
            }
        }
        public object DrawAndGetNewValue(Type memberType, string memberName, object value, object target)
        {
            var dictionary = (IDictionary)value;
            var keyType    = memberType.GetGenericArguments()[0];
            var valueType  = memberType.GetGenericArguments()[1];
            var targetType = target.GetType();

            if (!_keySearchTexts.ContainsKey(targetType))
            {
                _keySearchTexts.Add(targetType, string.Empty);
            }

            EditorGUILayout.BeginHorizontal();
            {
                if (dictionary.Count == 0)
                {
                    EditorGUILayout.LabelField(memberName, "empty");
                    _keySearchTexts[targetType] = string.Empty;
                }
                else
                {
                    EditorGUILayout.LabelField(memberName);
                }

                var keyTypeName   = keyType.ToCompilableString().ShortTypeName();
                var valueTypeName = valueType.ToCompilableString().ShortTypeName();
                if (EditorGUILayoutTools.MiniButton("new <" + keyTypeName + ", " + valueTypeName + ">"))
                {
                    if (EntityDrawer.CreateDefault(keyType, out var defaultKey))
                    {
                        if (EntityDrawer.CreateDefault(valueType, out var defaultValue))
                        {
                            dictionary[defaultKey] = defaultValue;
                        }
                    }
                }
            }
            EditorGUILayout.EndHorizontal();

            if (dictionary.Count > 0)
            {
                var indent = EditorGUI.indentLevel;
                EditorGUI.indentLevel = indent + 1;

                if (dictionary.Count > 5)
                {
                    EditorGUILayout.Space();
                    _keySearchTexts[targetType] = EditorGUILayoutTools.SearchTextField(_keySearchTexts[targetType]);
                }

                EditorGUILayout.Space();

                var keys = new ArrayList(dictionary.Keys);
                for (var i = 0; i < keys.Count; i++)
                {
                    var key = keys[i];
                    if (EditorGUILayoutTools.MatchesSearchString(key.ToString().ToLower(), _keySearchTexts[targetType].ToLower()))
                    {
                        EntityDrawer.DrawObjectMember(
                            keyType,
                            "key",
                            key,
                            target,
                            (newComponent, newValue) =>
                        {
                            var tmpValue = dictionary[key];
                            dictionary.Remove(key);
                            if (newValue != null)
                            {
                                dictionary[newValue] = tmpValue;
                            }
                        });

                        EntityDrawer.DrawObjectMember(
                            valueType,
                            "value",
                            dictionary[key],
                            target,
                            (newComponent, newValue) => dictionary[key] = newValue);

                        EditorGUILayout.Space();
                    }
                }

                EditorGUI.indentLevel = indent;
            }

            return(dictionary);
        }