// load list of files of the selected torrent
        private async Task LoadTorrentFilesList()
        {
            ToggleLoadingPanels(true);
            Globals.SelectedTorrentFiles.Clear();
            TorrentFileListTreeView.Nodes.Clear();

            // prepare torrent file paths for TorrentFileListTreeView display
            List <string> torrentPaths = new List <string>();

            foreach (TransmissionTorrentFiles torrentFile in Globals.SelectedTorrent.Torrent.Files)
            {
                FriendlyTorrentFileInfo friendlyTorrentFileInfo = new FriendlyTorrentFileInfo(torrentFile, Globals.SelectedTorrent.Torrent);
                torrentPaths.Add(item: friendlyTorrentFileInfo.InitialPath);
            }

            // populate TorrentFileListTreeView
            foreach (TreeNode node in GenerateTorrentFilesTreeViewItems(torrentPaths).Nodes)
            {
                node.Checked = true;
                TorrentFileListTreeView.Nodes.Add(node);
            }

            // update UI state
            TorrentFileListTreeView.BeginUpdate();
            rootNode         = TorrentFileListTreeView.GetNodeAt(0, 0);
            rootNode.Checked = true;
            rootNode.Expand();
            TorrentFileListTreeView.EndUpdate();
            await TorrentFileListTreeView.UpdateCounters();

            ToggleLoadingPanels(false);
        }
        // invert currently selected files in file tab
        // unused, function works but introduces buggy UI checked state which causes confusion
        private async void InverseButtonClick(object sender, EventArgs e)
        {
            TorrentFileListTreeView.BeginUpdate();
            InvertFileSelection(rootNode);
            await TorrentFileListTreeView.UpdateCounters();

            TorrentFileListTreeView.EndUpdate();
        }
        // deselect all files in file tab, update UI state
        private async void DeselectAllButtonClick(object sender, EventArgs e)
        {
            TorrentFileListTreeView.BeginUpdate();
            ToggleFilesSelectState(rootNode, false);
            await TorrentFileListTreeView.UpdateCounters();

            TorrentFileListTreeView.EndUpdate();
        }
        // expand all folder nodes in files list
        private async void ExpandAllButtonClick(object sender, EventArgs e)
        {
            ToggleLoadingPanels(true);
            TorrentFileListTreeView.BeginUpdate();
            await Task.Run(() =>
            {
                BeginInvoke((Action)(() => { rootNode.ExpandAll(); }));
            });

            TorrentFileListTreeView.EndUpdate();
            ToggleLoadingPanels(false);
        }
        // collapse all folder nodes in files list
        private async void CollapseAllButtonClick(object sender, EventArgs e)
        {
            ToggleLoadingPanels(true);
            TorrentFileListTreeView.BeginUpdate();
            await Task.Run(() =>
            {
                BeginInvoke((Action)(() =>
                {
                    foreach (var node in TorrentFileListTreeView.GetAllNodes(rootNode.Nodes))
                    {
                        node.Collapse();
                    }
                }));
            });

            TorrentFileListTreeView.EndUpdate();
            ToggleLoadingPanels(false);
        }