public ShellNode(ShellBrowser browser, ShellNode parentItem, IntPtr pidl, IntPtr shellFolderPtr)
        {
            this.Browser = browser;

            this.ParentItem = parentItem;
            this.shellFolderPtr = shellFolderPtr;
            this.shellFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(shellFolderPtr, typeof(IShellFolder));
            SubFiles = new ShellItemCollection(this);
            SubFolders = new ShellItemCollection(this);

            PIDLRel = new Pidl(pidl, false);

            SetText(this);
            SetPath(this);
            SetAttributesFolder(this);
            SetInfo(this);

            SortFlag = MakeSortFlag(this);
        }
        public void Update(bool updateFiles, bool updateFolders)
        {
            if (Browser.UpdateCondition.ContinueUpdate && (updateFiles || updateFolders) && ShellFolder != null && !disposed)
            {
                lock (Browser)
                {
                    IEnumIDList fileList = null;
                    IEnumIDList folderList = null;
                    IntPtr pidlSubItem;
                    int celtFetched;

                    SHCONT fileFlag = SHCONT.NonFolders | SHCONT.IncludeHidden;

                    SHCONT folderFlag = SHCONT.Folders | SHCONT.IncludeHidden;

                    bool[] fileExists;
                    fileExists = new bool[SubFiles.Count];

                    bool[] folderExists;
                    folderExists = new bool[SubFolders.Count];

                    int index;

                    try
                    {
                        #region Update Files

                        if (Browser.UpdateCondition.ContinueUpdate && updateFiles)
                        {
                            ShellItemCollection add = new ShellItemCollection(this);
                            ShellItemCollection remove = new ShellItemCollection(this);

                            bool fileEnumCompleted = false;

                            #region Add Files

                            if (this.Equals(Browser.DesktopItem) || ParentItem.Equals(Browser.DesktopItem))
                            {
                                if (ShellFolder.EnumObjects(IntPtr.Zero, fileFlag, out fileList) == 0)
                                {
                                    SFGAO attribs = SFGAO.Folder;
                                    while (Browser.UpdateCondition.ContinueUpdate && fileList.Next(1, out pidlSubItem, out celtFetched) == 0 && celtFetched == 1)
                                    {
                                        ShellFolder.GetAttributesOf(1, new IntPtr[] { pidlSubItem }, ref attribs);

                                        if ((attribs & SFGAO.Folder) == 0)
                                        {
                                            if ((index = SubFiles.IndexOf(pidlSubItem)) == -1)
                                            {
                                                ShellNode newItem = new ShellNode(Browser, this, pidlSubItem);

                                                if (!SubFolders.Contains(newItem.Text))
                                                {
                                                    add.Add(newItem);
                                                }
                                            }
                                            else if (index < fileExists.Length)
                                            {
                                                fileExists[index] = true;
                                                Marshal.FreeCoTaskMem(pidlSubItem);
                                            }
                                        }
                                        else
                                        {
                                            Marshal.FreeCoTaskMem(pidlSubItem);
                                        }
                                    }

                                    fileEnumCompleted = true;
                                }
                            }
                            else
                            {
                                if (ShellFolder.EnumObjects(IntPtr.Zero, fileFlag, out fileList) == 0)
                                {
                                    while (Browser.UpdateCondition.ContinueUpdate && fileList.Next(1, out pidlSubItem, out celtFetched) == 0 && celtFetched == 1)
                                    {
                                        if ((index = SubFiles.IndexOf(pidlSubItem)) == -1)
                                        {
                                            add.Add(new ShellNode(Browser, this, pidlSubItem));
                                        }
                                        else if (index < fileExists.Length)
                                        {
                                            fileExists[index] = true;
                                            Marshal.FreeCoTaskMem(pidlSubItem);
                                        }
                                    }

                                    fileEnumCompleted = true;
                                }
                            }

                            #endregion

                            #region Remove Files

                            for (int i = 0; fileEnumCompleted && Browser.UpdateCondition.ContinueUpdate && i < fileExists.Length; i++)
                            {
                                if (!fileExists[i] && SubFiles[i] != null)
                                {
                                    remove.Add(SubFiles[i]);
                                }
                            }

                            #endregion

                            #region Do Events

                            if (fileEnumCompleted && Browser.UpdateCondition.ContinueUpdate)
                            {
                                int newIndex;
                                foreach (ShellNode oldItem in remove)
                                {
                                    if ((newIndex = add.IndexOf(oldItem.Text)) > -1)
                                    {
                                        ShellNode newItem = add[newIndex];
                                        add.Remove(newItem);

                                        oldItem.PIDLRel.Free();
                                        oldItem.PIDLRel = new Pidl(newItem.PIDLRel.Ptr, true);

                                        oldItem.shellFolder = newItem.shellFolder;
                                        oldItem.shellFolderPtr = newItem.shellFolderPtr;

                                        ((IDisposable)newItem).Dispose();

                                        Browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(oldItem, oldItem, ShellItemUpdateType.Updated));
                                    }
                                    else
                                    {
                                        SubFiles.Remove(oldItem);
                                        Browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(oldItem, null, ShellItemUpdateType.Deleted));
                                        ((IDisposable)oldItem).Dispose();
                                    }
                                }

                                foreach (ShellNode newItem in add)
                                {
                                    SubFiles.Add(newItem);
                                    Browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(null, newItem, ShellItemUpdateType.Created));
                                }

                                SubFiles.Capacity = SubFiles.Count;
                                SubFiles.Sort();

                                FilesExpanded = true;
                            }

                            #endregion
                        }

                        #endregion

                        #region Update Folders

                        if (Browser.UpdateCondition.ContinueUpdate && updateFolders)
                        {
                            ShellItemCollection add = new ShellItemCollection(this);
                            ShellItemCollection remove = new ShellItemCollection(this);

                            bool folderEnumCompleted = false;

                            #region Add Folders

                            if (ShellFolder.EnumObjects(IntPtr.Zero, folderFlag, out folderList) == 0)
                            {
                                while (Browser.UpdateCondition.ContinueUpdate && folderList.Next(1, out pidlSubItem, out celtFetched) == 0 && celtFetched == 1)
                                {
                                    if ((index = SubFolders.IndexOf(pidlSubItem)) == -1)
                                    {
                                        IntPtr shellFolderPtr;
                                        if (ShellFolder.BindToObject(pidlSubItem, IntPtr.Zero, ref ShellGuids.IShellFolder, out shellFolderPtr) == 0)
                                        {
                                            add.Add(new ShellNode(Browser, this, pidlSubItem, shellFolderPtr));
                                        }
                                    }
                                    else if (index < folderExists.Length)
                                    {
                                        folderExists[index] = true;
                                        Marshal.FreeCoTaskMem(pidlSubItem);
                                    }
                                }

                                folderEnumCompleted = true;
                            }

                            #endregion

                            #region Remove Folders

                            for (int i = 0; folderEnumCompleted && Browser.UpdateCondition.ContinueUpdate && i < folderExists.Length; i++)
                            {
                                if (!folderExists[i] && SubFolders[i] != null)
                                {
                                    remove.Add(SubFolders[i]);
                                }
                            }

                            #endregion

                            #region Do Events

                            if (folderEnumCompleted && Browser.UpdateCondition.ContinueUpdate)
                            {
                                int newIndex;
                                foreach (ShellNode oldItem in remove)
                                {
                                    if ((newIndex = add.IndexOf(oldItem.Text)) > -1)
                                    {
                                        ShellNode newItem = add[newIndex];
                                        add.Remove(newItem);

                                        oldItem.PIDLRel.Free();
                                        oldItem.PIDLRel = new Pidl(newItem.PIDLRel, true);

                                        Marshal.ReleaseComObject(oldItem.shellFolder);
                                        Marshal.Release(oldItem.shellFolderPtr);

                                        oldItem.shellFolder = newItem.shellFolder;
                                        oldItem.shellFolderPtr = newItem.shellFolderPtr;

                                        newItem.shellFolder = null;
                                        newItem.shellFolderPtr = IntPtr.Zero;
                                        ((IDisposable)newItem).Dispose();

                                        Browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(oldItem, oldItem, ShellItemUpdateType.Updated));
                                    }
                                    else
                                    {
                                        SubFolders.Remove(oldItem);
                                        Browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(oldItem, null, ShellItemUpdateType.Deleted));
                                        ((IDisposable)oldItem).Dispose();
                                    }
                                }

                                foreach (ShellNode newItem in add)
                                {
                                    SubFolders.Add(newItem);

                                    Browser.OnShellItemUpdate(this, new ShellItemUpdateEventArgs(null, newItem, ShellItemUpdateType.Created));
                                }

                                SubFolders.Capacity = SubFolders.Count;
                                SubFolders.Sort();
                                FoldersExpanded = true;
                            }

                            #endregion
                        }

                        #endregion
                    }
                    catch (Exception)
                    {
                    }
                    finally
                    {
                        #region Free

                        if (folderList != null)
                        {
                            Marshal.ReleaseComObject(folderList);
                        }

                        if (fileList != null)
                        {
                            Marshal.ReleaseComObject(fileList);
                        }

                        #endregion
                    }
                }
            }
        }