public void OnIdle()
        {
            if (!isDirty)
            {
                return;
            }
            if (null != onFileChanged)
            {
                HierarchyEventArgs args = new HierarchyEventArgs(fileId.ItemID, fileName);
                args.TextBuffer = buffer;
                // Enqueue a Library Request
                //onFileChanged(fileId.Hierarchy, args);
            }

            isDirty = false;
        }
        public int OnItemDeleted(uint itemid)
        {
            Debug.WriteLine("--> OnItemDeleted");
            // Notify that the item is deleted only if it is a PRG file.
            string name = getItemName(itemid);

            //if (! IsPrgFile(itemid, out name))
            //{
            //    return VSConstants.S_OK;
            //}
            if (null != onItemDeleted)
            {
                HierarchyEventArgs args = new HierarchyEventArgs(itemid, name);
                onItemDeleted(hierarchy, args);
            }
            return(VSConstants.S_OK);
        }
        public int OnItemAdded(uint itemidParent, uint itemidSiblingPrev, uint itemidAdded)
        {
            // Check if the item is a PRG file.
            Debug.WriteLine("--> OnItemAdded");
            string name = getItemName(itemidAdded);

            // if (!IsPrgFile(itemidAdded, out name))
            //{
            //    return VSConstants.S_OK;
            //}

            // This item is a PRG file, so we can notify that it is added to the hierarchy.
            if (null != onItemAdded)
            {
                HierarchyEventArgs args = new HierarchyEventArgs(itemidAdded, name);
                onItemAdded(hierarchy, args);
            }
            return(VSConstants.S_OK);
        }
        /// <summary>
        /// Do a recursive walk on the hierarchy to find all the PRG files in it.
        /// It will generate an event for every file found.
        /// </summary>
        private void InternalScanHierarchy(uint itemId)
        {
            uint currentItem = itemId;

            while (VSConstants.VSITEMID_NIL != currentItem)
            {
                // If this item is a PRG file, then send the add item event.
                string itemName = getItemName(itemId);
                // IsPrgFile(currentItem, out itemName);
                if ((null != onItemAdded) && !string.IsNullOrEmpty(itemName))
                {
                    HierarchyEventArgs args = new HierarchyEventArgs(currentItem, itemName);
                    onItemAdded(hierarchy, args);
                }

                // NOTE: At the moment we skip the nested hierarchies, so here  we look for the
                // children of this node.
                // Before looking at the children we have to make sure that the enumeration has not
                // side effects to avoid unexpected behavior.
                bool   canScanSubitems = true;
                int    hr            = 0;
                object propertyValue = null;
                ThreadHelper.JoinableTaskFactory.Run(async delegate
                {
                    await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
                    hr = hierarchy.GetProperty(currentItem, (int)__VSHPROPID.VSHPROPID_HasEnumerationSideEffects, out propertyValue);
                });

                if (VSConstants.S_OK == hr && propertyValue is bool ok)
                {
                    canScanSubitems = !ok;
                }
                // If it is allow to look at the sub-items of the current one, lets do it.
                if (canScanSubitems)
                {
                    object child = null;
                    ThreadHelper.JoinableTaskFactory.Run(async delegate
                    {
                        await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
                        hr = hierarchy.GetProperty(currentItem, (int)__VSHPROPID.VSHPROPID_FirstChild, out child);
                    });
                    if (VSConstants.S_OK == hr)
                    {
                        // There is a sub-item, call this same function on it.
                        InternalScanHierarchy(GetItemId(child));
                    }
                }

                // Move the current item to its first visible sibling.
                object sibling = null;
                ThreadHelper.JoinableTaskFactory.Run(async delegate
                {
                    await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
                    if (hierarchy != null)
                    {
                        hr = hierarchy.GetProperty(currentItem, (int)__VSHPROPID.VSHPROPID_NextSibling, out sibling);
                    }
                });
                if (VSConstants.S_OK != hr)
                {
                    currentItem = VSConstants.VSITEMID_NIL;
                }
                else
                {
                    currentItem = GetItemId(sibling);
                }
            }
        }