private void LifestyleQualitiesOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
        {
            if (notifyCollectionChangedEventArgs.Action == NotifyCollectionChangedAction.Reset)
            {
                ResetLifestyleQualitiesTree();
                return;
            }
            if (notifyCollectionChangedEventArgs.Action == NotifyCollectionChangedAction.Move)
            {
                return;
            }

            TreeNode nodPositiveQualityRoot = treLifestyleQualities.FindNode("Node_SelectAdvancedLifestyle_PositiveQualities", false);
            TreeNode nodNegativeQualityRoot = treLifestyleQualities.FindNode("Node_SelectAdvancedLifestyle_NegativeQualities", false);
            TreeNode nodEntertainmentsRoot  = treLifestyleQualities.FindNode("Node_SelectAdvancedLifestyle_Entertainments", false);

            switch (notifyCollectionChangedEventArgs.Action)
            {
            case NotifyCollectionChangedAction.Add:
            {
                foreach (LifestyleQuality objQuality in notifyCollectionChangedEventArgs.NewItems)
                {
                    AddToTree(objQuality);
                }
                break;
            }

            case NotifyCollectionChangedAction.Remove:
            {
                foreach (LifestyleQuality objQuality in notifyCollectionChangedEventArgs.OldItems)
                {
                    TreeNode objNode = treLifestyleQualities.FindNodeByTag(objQuality);
                    if (objNode != null)
                    {
                        TreeNode objParent = objNode.Parent;
                        objNode.Remove();
                        if (objParent.Level == 0 && objParent.Nodes.Count == 0)
                        {
                            objParent.Remove();
                        }
                    }
                }
                break;
            }

            case NotifyCollectionChangedAction.Replace:
            {
                List <TreeNode> lstOldParents = new List <TreeNode>();
                foreach (LifestyleQuality objQuality in notifyCollectionChangedEventArgs.OldItems)
                {
                    TreeNode objNode = treLifestyleQualities.FindNodeByTag(objQuality);
                    if (objNode != null)
                    {
                        if (objNode.Parent != null)
                        {
                            lstOldParents.Add(objNode.Parent);
                        }
                        objNode.Remove();
                    }
                }
                foreach (LifestyleQuality objQuality in notifyCollectionChangedEventArgs.NewItems)
                {
                    AddToTree(objQuality);
                }
                foreach (TreeNode objOldParent in lstOldParents)
                {
                    if (objOldParent.Level == 0 && objOldParent.Nodes.Count == 0)
                    {
                        objOldParent.Remove();
                    }
                }
                break;
            }
            }

            void AddToTree(LifestyleQuality objQuality)
            {
                TreeNode objNode = objQuality.CreateTreeNode();

                if (objNode == null)
                {
                    return;
                }
                TreeNode objParentNode;

                switch (objQuality.Type)
                {
                case QualityType.Positive:
                    if (nodPositiveQualityRoot == null)
                    {
                        nodPositiveQualityRoot = new TreeNode
                        {
                            Tag  = "Node_SelectAdvancedLifestyle_PositiveQualities",
                            Text = LanguageManager.GetString("Node_SelectAdvancedLifestyle_PositiveQualities")
                        };
                        treLifestyleQualities.Nodes.Insert(0, nodPositiveQualityRoot);
                        nodPositiveQualityRoot.Expand();
                    }
                    objParentNode = nodPositiveQualityRoot;
                    break;

                case QualityType.Negative:
                    if (nodNegativeQualityRoot == null)
                    {
                        nodNegativeQualityRoot = new TreeNode
                        {
                            Tag  = "Node_SelectAdvancedLifestyle_NegativeQualities",
                            Text = LanguageManager.GetString("Node_SelectAdvancedLifestyle_NegativeQualities")
                        };
                        treLifestyleQualities.Nodes.Insert(nodPositiveQualityRoot == null ? 0 : 1, nodNegativeQualityRoot);
                        nodNegativeQualityRoot.Expand();
                    }
                    objParentNode = nodNegativeQualityRoot;
                    break;

                default:
                    if (nodEntertainmentsRoot == null)
                    {
                        nodEntertainmentsRoot = new TreeNode
                        {
                            Tag  = "Node_SelectAdvancedLifestyle_Entertainments",
                            Text = LanguageManager.GetString("Node_SelectAdvancedLifestyle_Entertainments")
                        };
                        treLifestyleQualities.Nodes.Insert((nodPositiveQualityRoot == null ? 0 : 1) + (nodNegativeQualityRoot == null ? 0 : 1), nodEntertainmentsRoot);
                        nodEntertainmentsRoot.Expand();
                    }
                    objParentNode = nodEntertainmentsRoot;
                    break;
                }

                TreeNodeCollection lstParentNodeChildren = objParentNode.Nodes;
                int intNodesCount  = lstParentNodeChildren.Count;
                int intTargetIndex = 0;

                for (; intTargetIndex < intNodesCount; ++intTargetIndex)
                {
                    if (CompareTreeNodes.CompareText(lstParentNodeChildren[intTargetIndex], objNode) >= 0)
                    {
                        break;
                    }
                }

                lstParentNodeChildren.Insert(intTargetIndex, objNode);
                treLifestyleQualities.SelectedNode = objNode;
            }
        }
        private void FreeGridsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
        {
            if (notifyCollectionChangedEventArgs.Action == NotifyCollectionChangedAction.Reset)
            {
                ResetLifestyleQualitiesTree();
                return;
            }
            if (notifyCollectionChangedEventArgs.Action == NotifyCollectionChangedAction.Move)
            {
                return;
            }

            TreeNode nodFreeGridsRoot = treLifestyleQualities.FindNode("Node_SelectAdvancedLifestyle_FreeMatrixGrids", false);

            switch (notifyCollectionChangedEventArgs.Action)
            {
            case NotifyCollectionChangedAction.Add:
            {
                foreach (LifestyleQuality objFreeGrid in notifyCollectionChangedEventArgs.NewItems)
                {
                    TreeNode objNode = objFreeGrid.CreateTreeNode();
                    if (objNode == null)
                    {
                        return;
                    }
                    if (nodFreeGridsRoot == null)
                    {
                        nodFreeGridsRoot = new TreeNode
                        {
                            Tag  = "Node_SelectAdvancedLifestyle_FreeMatrixGrids",
                            Text = LanguageManager.GetString("Node_SelectAdvancedLifestyle_FreeMatrixGrids")
                        };
                        treLifestyleQualities.Nodes.Add(nodFreeGridsRoot);
                        nodFreeGridsRoot.Expand();
                    }

                    TreeNodeCollection lstParentNodeChildren = nodFreeGridsRoot.Nodes;
                    int intNodesCount  = lstParentNodeChildren.Count;
                    int intTargetIndex = 0;
                    for (; intTargetIndex < intNodesCount; ++intTargetIndex)
                    {
                        if (CompareTreeNodes.CompareText(lstParentNodeChildren[intTargetIndex], objNode) >= 0)
                        {
                            break;
                        }
                    }

                    lstParentNodeChildren.Insert(intTargetIndex, objNode);
                    treLifestyleQualities.SelectedNode = objNode;
                }
                break;
            }

            case NotifyCollectionChangedAction.Remove:
            {
                foreach (LifestyleQuality objFreeGrid in notifyCollectionChangedEventArgs.OldItems)
                {
                    TreeNode objNode = treLifestyleQualities.FindNodeByTag(objFreeGrid);
                    if (objNode != null)
                    {
                        TreeNode objParent = objNode.Parent;
                        objNode.Remove();
                        if (objParent.Level == 0 && objParent.Nodes.Count == 0)
                        {
                            objParent.Remove();
                        }
                    }
                }
                break;
            }

            case NotifyCollectionChangedAction.Replace:
            {
                List <TreeNode> lstOldParents = new List <TreeNode>();
                foreach (LifestyleQuality objFreeGrid in notifyCollectionChangedEventArgs.OldItems)
                {
                    TreeNode objNode = treLifestyleQualities.FindNodeByTag(objFreeGrid);
                    if (objNode != null)
                    {
                        if (objNode.Parent != null)
                        {
                            lstOldParents.Add(objNode.Parent);
                        }
                        objNode.Remove();
                    }
                }
                foreach (LifestyleQuality objFreeGrid in notifyCollectionChangedEventArgs.NewItems)
                {
                    TreeNode objNode = objFreeGrid.CreateTreeNode();
                    if (objNode == null)
                    {
                        return;
                    }
                    if (nodFreeGridsRoot == null)
                    {
                        nodFreeGridsRoot = new TreeNode
                        {
                            Tag  = "Node_SelectAdvancedLifestyle_FreeMatrixGrids",
                            Text = LanguageManager.GetString("Node_SelectAdvancedLifestyle_FreeMatrixGrids")
                        };
                        treLifestyleQualities.Nodes.Add(nodFreeGridsRoot);
                        nodFreeGridsRoot.Expand();
                    }

                    TreeNodeCollection lstParentNodeChildren = nodFreeGridsRoot.Nodes;
                    int intNodesCount  = lstParentNodeChildren.Count;
                    int intTargetIndex = 0;
                    for (; intTargetIndex < intNodesCount; ++intTargetIndex)
                    {
                        if (CompareTreeNodes.CompareText(lstParentNodeChildren[intTargetIndex], objNode) >= 0)
                        {
                            break;
                        }
                    }

                    lstParentNodeChildren.Insert(intTargetIndex, objNode);
                    treLifestyleQualities.SelectedNode = objNode;
                }
                foreach (TreeNode objOldParent in lstOldParents)
                {
                    if (objOldParent.Level == 0 && objOldParent.Nodes.Count == 0)
                    {
                        objOldParent.Remove();
                    }
                }
                break;
            }
            }
        }
        private async void LifestyleQualitiesOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
            case NotifyCollectionChangedAction.Move:
                return;

            case NotifyCollectionChangedAction.Reset:
                await ResetLifestyleQualitiesTree();

                return;

            default:
            {
                TreeNode nodPositiveQualityRoot
                    = await treLifestyleQualities.DoThreadSafeFuncAsync(x => x.FindNode("Node_SelectAdvancedLifestyle_PositiveQualities", false));

                TreeNode nodNegativeQualityRoot
                    = await treLifestyleQualities.DoThreadSafeFuncAsync(x => x.FindNode("Node_SelectAdvancedLifestyle_NegativeQualities", false));

                TreeNode nodEntertainmentsRoot
                    = await treLifestyleQualities.DoThreadSafeFuncAsync(x => x.FindNode("Node_SelectAdvancedLifestyle_Entertainments", false));

                TreeNode nodFreeGridsRoot =
                    await treLifestyleQualities.DoThreadSafeFuncAsync(x => x.FindNode("Node_SelectAdvancedLifestyle_FreeMatrixGrids", false));

                switch (e.Action)
                {
                case NotifyCollectionChangedAction.Add:
                {
                    foreach (LifestyleQuality objQuality in e.NewItems)
                    {
                        await AddToTree(objQuality);
                    }

                    break;
                }

                case NotifyCollectionChangedAction.Remove:
                {
                    foreach (LifestyleQuality objQuality in e.OldItems)
                    {
                        await treLifestyleQualities.DoThreadSafeAsync(x =>
                                {
                                    TreeNode objNode = x.FindNodeByTag(objQuality);
                                    if (objNode != null)
                                    {
                                        TreeNode objParent = objNode.Parent;
                                        objNode.Remove();
                                        if (objParent.Level == 0 && objParent.Nodes.Count == 0)
                                        {
                                            objParent.Remove();
                                        }
                                    }
                                });
                    }

                    break;
                }

                case NotifyCollectionChangedAction.Replace:
                {
                    List <TreeNode> lstOldParents = new List <TreeNode>(e.OldItems.Count);
                    foreach (LifestyleQuality objQuality in e.OldItems)
                    {
                        await treLifestyleQualities.DoThreadSafeAsync(x =>
                                {
                                    TreeNode objNode = x.FindNodeByTag(objQuality);
                                    if (objNode != null)
                                    {
                                        if (objNode.Parent != null)
                                        {
                                            lstOldParents.Add(objNode.Parent);
                                        }
                                        objNode.Remove();
                                    }
                                });
                    }

                    foreach (LifestyleQuality objQuality in e.NewItems)
                    {
                        await AddToTree(objQuality);
                    }

                    if (lstOldParents.Count > 0)
                    {
                        await treLifestyleQualities.DoThreadSafeAsync(() =>
                                {
                                    foreach (TreeNode objOldParent in lstOldParents)
                                    {
                                        if (objOldParent.Level == 0 && objOldParent.Nodes.Count == 0)
                                        {
                                            objOldParent.Remove();
                                        }
                                    }
                                });
                    }

                    break;
                }
                }

                break;

                async ValueTask AddToTree(LifestyleQuality objQuality)
                {
                    TreeNode objNode = objQuality.CreateTreeNode();

                    if (objNode == null)
                    {
                        return;
                    }
                    TreeNode objParentNode;

                    if (objQuality.IsFreeGrid)
                    {
                        if (nodFreeGridsRoot == null)
                        {
                            nodFreeGridsRoot = new TreeNode
                            {
                                Tag  = "Node_SelectAdvancedLifestyle_FreeMatrixGrids",
                                Text = await LanguageManager.GetStringAsync("Node_SelectAdvancedLifestyle_FreeMatrixGrids")
                            };
                            // ReSharper disable once AssignNullToNotNullAttribute
                            await treLifestyleQualities.DoThreadSafeAsync(x =>
                                {
                                    x.Nodes.Insert(
                                        (nodPositiveQualityRoot == null ? 0 : 1)
                                        + (nodNegativeQualityRoot == null ? 0 : 1)
                                        // ReSharper disable once AssignNullToNotNullAttribute
                                        + (nodEntertainmentsRoot == null ? 0 : 1), nodFreeGridsRoot);
                                    nodFreeGridsRoot.Expand();
                                });
                        }
                        objParentNode = nodFreeGridsRoot;
                    }
                    else
                    {
                        switch (objQuality.Type)
                        {
                        case QualityType.Positive:
                            if (nodPositiveQualityRoot == null)
                            {
                                nodPositiveQualityRoot = new TreeNode
                                {
                                    Tag  = "Node_SelectAdvancedLifestyle_PositiveQualities",
                                    Text = await LanguageManager.GetStringAsync(
                                        "Node_SelectAdvancedLifestyle_PositiveQualities")
                                };
                                // ReSharper disable once AssignNullToNotNullAttribute
                                await treLifestyleQualities.DoThreadSafeAsync(x =>
                                    {
                                        x.Nodes.Insert(0,
                                                       nodPositiveQualityRoot);
                                        nodPositiveQualityRoot.Expand();
                                    });
                            }

                            objParentNode = nodPositiveQualityRoot;
                            break;

                        case QualityType.Negative:
                            if (nodNegativeQualityRoot == null)
                            {
                                nodNegativeQualityRoot = new TreeNode
                                {
                                    Tag  = "Node_SelectAdvancedLifestyle_NegativeQualities",
                                    Text = await LanguageManager.GetStringAsync(
                                        "Node_SelectAdvancedLifestyle_NegativeQualities")
                                };
                                // ReSharper disable once AssignNullToNotNullAttribute
                                await treLifestyleQualities.DoThreadSafeAsync(x =>
                                    {
                                        x.Nodes.Insert(nodPositiveQualityRoot == null ? 0 : 1,
                                                       nodNegativeQualityRoot);
                                        nodNegativeQualityRoot.Expand();
                                    });
                            }

                            objParentNode = nodNegativeQualityRoot;
                            break;

                        default:
                            if (nodEntertainmentsRoot == null)
                            {
                                nodEntertainmentsRoot = new TreeNode
                                {
                                    Tag  = "Node_SelectAdvancedLifestyle_Entertainments",
                                    Text = await LanguageManager.GetStringAsync(
                                        "Node_SelectAdvancedLifestyle_Entertainments")
                                };
                                await treLifestyleQualities.DoThreadSafeAsync(x =>
                                    {
                                        x.Nodes.Insert(
                                            (nodPositiveQualityRoot == null ? 0 : 1)
                                            // ReSharper disable once AssignNullToNotNullAttribute
                                            + (nodNegativeQualityRoot == null ? 0 : 1), nodEntertainmentsRoot);
                                        nodEntertainmentsRoot.Expand();
                                    });
                            }

                            objParentNode = nodEntertainmentsRoot;
                            break;
                        }
                    }

                    await treLifestyleQualities.DoThreadSafeAsync(x =>
                        {
                            if (objParentNode == null)
                            {
                                return;
                            }
                            TreeNodeCollection lstParentNodeChildren = objParentNode.Nodes;
                            int intNodesCount  = lstParentNodeChildren.Count;
                            int intTargetIndex = 0;
                            for (; intTargetIndex < intNodesCount; ++intTargetIndex)
                            {
                                if (CompareTreeNodes.CompareText(lstParentNodeChildren[intTargetIndex], objNode) >= 0)
                                {
                                    break;
                                }
                            }

                            lstParentNodeChildren.Insert(intTargetIndex, objNode);
                            x.SelectedNode = objNode;
                        });
                }
            }
            }
        }