private void RefreshExplorer(Transactions transactions)
        {
            txnTreeView.Nodes.Clear();

            var rootTreeNode = CategoryNode.CreateTreeNode(null, new TreeNodeData()
            {
                Text = "All"
            });

            txnTreeView.Nodes.Add(rootTreeNode);

            RefreshNode(rootTreeNode, transactions);

            rootTreeNode.Expand();

            if (txnTreeView.SelectedNode == null)
            {
                txnTreeView.SelectedNode = rootTreeNode.Nodes.Cast <TreeNode>().FirstOrDefault()
                                           .IfNotNull(yearNode => yearNode.Nodes.Cast <TreeNode>().FirstOrDefault());
            }
        }
        private static void RefreshNode(TreeNode treeNode, Transactions allTransactions, IEnumerable <Transaction> parentTransactions = null)
        {
            var isExpanded   = treeNode.IsExpanded;
            var treeNodeData = (TreeNodeData)treeNode.Tag;

            if (treeNodeData.YearFilter == null)
            {
                var yearGroups = allTransactions.TopLevelTransactions.GroupBy(t => t.CorrectedTransactionDate.Year).OrderByDescending(g => g.Key);
                foreach (var yearGroup in yearGroups)
                {
                    var yearTreeNode = CategoryNode.CreateTreeNode(treeNode,
                                                                   new TreeNodeData()
                    {
                        Text = yearGroup.Key.ToStringCurrentCulture(), YearFilter = yearGroup.Key
                    });
                    RefreshNode(yearTreeNode, allTransactions, yearGroup.Select(t => t));

                    yearTreeNode.Expand();
                }
            }
            else if (treeNodeData.MonthFilter == null)
            {
                var year = treeNodeData.YearFilter.Value;
                parentTransactions = parentTransactions ?? allTransactions.TopLevelTransactions.Where(t => t.CorrectedTransactionDate.Year == year);
                var monthGroups = parentTransactions.GroupBy(t => t.CorrectedTransactionDate.Month).OrderByDescending(g => g.Key);
                foreach (var monthGroup in monthGroups)
                {
                    var monthTreeNode = CategoryNode.CreateTreeNode(treeNode, new TreeNodeData()
                    {
                        Text        = GetMonthDisplayName(monthGroup.Key),
                        YearFilter  = year,
                        MonthFilter = monthGroup.Key
                    });
                    RefreshNode(monthTreeNode, allTransactions, monthGroup.Select(t => t));
                }
            }
            else
            {
                var year  = treeNodeData.YearFilter.Value;
                var month = treeNodeData.MonthFilter.Value;

                parentTransactions = parentTransactions ?? allTransactions.TopLevelTransactions.Where(t => t.CorrectedTransactionDate.Year == year)
                                     .Where(t => t.CorrectedTransactionDate.Month == month);

                var categoryPathsAndSum = parentTransactions
                                          .GroupBy(t => t.DisplayCategoryPathOrNameCocatenated)
                                          .Select(tg => Tuple.Create(tg.First().DisplayCategoryPathOrName, tg.Sum(t => t.Amount), tg.Count()))
                                          .OrderByDescending(tp => tp.Item2);

                var rootCategoryNode = new CategoryNode(null);

                foreach (var categoryPathAndSum in categoryPathsAndSum)
                {
                    rootCategoryNode.Merge(categoryPathAndSum.Item1, categoryPathAndSum.Item2, categoryPathAndSum.Item3);
                }

                rootCategoryNode.BuildTreeViewNodes(treeNode, year, month);
            }

            if (isExpanded)
            {
                treeNode.Expand();
            }
        }