public static Dictionary <string, TreeItem> PopulatePropertyTree(
            IEnumerable <PropertyConfig> properties, ObservableCollection <TreeItem> treeItems,
            bool isInstalled, Action <TreeItem, PropertyConfig> OnCreate = null)
        {
            Dictionary <string, TreeItem> dict = new Dictionary <string, TreeItem>();

            // Build tree based on property names
            foreach (var p in properties)
            {
                var treeItem = AddTreeItem(dict, treeItems, p);
                OnCreate?.Invoke(treeItem, p);
            }

            // Populating installed tree - do some surgery on the system properties
            if (isInstalled)
            {
                List <TreeItem> roots = new List <TreeItem>(treeItems);
                treeItems.Clear();
                List <TreeItem> lastRoots = new List <TreeItem>();

                // Wire trees to tree controls, tweaking the structure as we go
                TreeItem propGroup = null;
                foreach (TreeItem root in
                         roots)
                {
                    if (root.Name == "System")
                    {
                        lastRoots.Insert(0, root);

                        // Move property groups from root to their own subtree
                        propGroup = root.Children.Where(x => x.Name == "PropGroup").FirstOrDefault();
                        if (propGroup != null)
                        {
                            root.RemoveChild(propGroup);
                            lastRoots.Add(propGroup);
                        }

                        // Move properties with names of the form System.* to their own subtree
                        var systemProps = new TreeItem("System.*");
                        lastRoots.Insert(0, systemProps);

                        foreach (var ti in root.Children.Where(x => x.Children.Count == 0).ToList())
                        {
                            root.RemoveChild(ti);
                            systemProps.AddChild(ti);
                        }
                    }
                    else if (root.Name == "Microsoft")
                    {
                        lastRoots.Insert(0, root);
                    }
                    else
                    {
                        treeItems.Add(root);
                    }
                }

                foreach (var ti in lastRoots)
                {
                    treeItems.Add(ti);
                }
            }
            else
            {
                // Fully expand the saved tree
                ExpandTree(treeItems);
            }

            return(dict);
        }