protected override void MergeContextMenu(ShellFolder folder, IReadOnlyList <ShellItem> items, ShellMenu existingMenu, ShellMenu appendMenu)
        {
            // because we don't rely on file system, we won't have the "new" menu automatically set for us
            // so we must build one, from the standard one
            // fortunately, there is a helper for that
            appendMenu.AddInvokeItemHandler(OnShellMenuItemInvoke);
            appendMenu.MergeNewMenu();

            // once the new menu has been merged, remember what Id corresponds to what type of item and use that in the OnShellMenuItemInvoke method
        }
        protected override void MergeContextMenu(ShellFolder folder, IReadOnlyList <ShellItem> items, ShellMenu existingMenu, ShellMenu appendMenu)
        {
            if (folder == null)
            {
                throw new ArgumentNullException(nameof(folder));
            }

            if (items == null)
            {
                throw new ArgumentNullException(nameof(items));
            }

            if (appendMenu == null)
            {
                throw new ArgumentNullException(nameof(appendMenu));
            }

            appendMenu.AddInvokeItemHandler(OnShellMenuItemInvoke);
            if (items.Count == 1 && !items[0].IsFolder)
            {
                // only for one non-folder item
                var modifyItem = new ShellMenuItem(appendMenu, "Modify...");
                modifyItem.Tag       = MenuCommand.Modify;
                modifyItem.IsDefault = true;
                appendMenu.Items.Add(modifyItem);
            }
            else
            {
                if (existingMenu.Items.FirstOrDefault(i => i.Text == "New") == null)
                {
                    var newItem = new ShellMenuItem(appendMenu, "New");
                    appendMenu.Items.Add(newItem);

                    newItem.Items.Add(new ShellMenuItem(appendMenu, "Key")
                    {
                        Tag = MenuCommand.NewKey
                    });
                    newItem.Items.Add(new ShellMenuSeparatorItem());
                    newItem.Items.Add(new ShellMenuItem(appendMenu, "String Value")
                    {
                        Tag = MenuCommand.NewValueString
                    });
                    newItem.Items.Add(new ShellMenuItem(appendMenu, "Binary Value")
                    {
                        Tag = MenuCommand.NewValueBinary
                    });
                    newItem.Items.Add(new ShellMenuItem(appendMenu, "DWORD (32-bit) Value")
                    {
                        Tag = MenuCommand.NewValueDWord
                    });
                    newItem.Items.Add(new ShellMenuItem(appendMenu, "QWORD (64-bit) Value")
                    {
                        Tag = MenuCommand.NewValueQWord
                    });
                    newItem.Items.Add(new ShellMenuItem(appendMenu, "Multi-String Value")
                    {
                        Tag = MenuCommand.NewValueMultiString
                    });
                    newItem.Items.Add(new ShellMenuItem(appendMenu, "Expandable String Value")
                    {
                        Tag = MenuCommand.NewValueExpandString
                    });
                }
            }

            if (items.Count > 0)
            {
                // add the "Send To" menu
                appendMenu.Items.Add(new ShellMenuSendToItem());
            }
        }