public void updateTreeView(string next_change_id = null)
        {
            treeViewStash.Invoke(new Action(() => treeViewStash.Nodes.Clear())); //we call this function from another thread so we have to send this action to the main-thread
            statusStripLabel.GetCurrentParent().Invoke(new Action(() => statusStripLabel.Text = "Fetching Root Object..."));

            Dictionary <string, List <Stash> > dList = new Dictionary <string, List <Stash> >();
            RootObject ro = DataManagement.getRootObject(next_change_id);

            statusStripLabel.GetCurrentParent().Invoke(new Action(() => statusStripLabel.Text = "Updating Tree View..."));
            currentChangeID.GetCurrentParent().Invoke(new Action(() => currentChangeID.Text   = "Next Change ID: " + ro.next_change_id));
            currentChangeID.Tag = ro.next_change_id;

            for (int i = 0; i < ro.stashes.Count; i++)
            {
                if (ro.stashes[i].items.Count == 0) //only add stash tab if it actually contains items
                {
                    continue;
                }
                List <Stash> currentStashes = new List <Stash>();
                if (i != 0)
                {
                    if (ro.stashes[i].accountName == ro.stashes[i - 1].accountName)           //check if previous stash has the same owner
                    {
                        if (dList.TryGetValue(ro.stashes[i].accountName, out currentStashes)) //check if there is already a KeyValuePair for that owner
                        {
                            currentStashes.Add(ro.stashes[i]);                                //add the current stash to the list of stashes
                        }
                        else //create a new KeyValuePair for this owner
                        {
                            currentStashes = new List <Stash>(); //no value returned so currentStashes is null -> create new instance
                            currentStashes.Add(ro.stashes[i]);
                            dList.Add(ro.stashes[i].accountName, currentStashes);
                        }
                    }
                }
                else //first stash so we create a new KeyValuePair
                {
                    currentStashes.Add(ro.stashes[i]);
                    dList.Add(ro.stashes[i].accountName, currentStashes);
                }
            }
            foreach (KeyValuePair <string, List <Stash> > kvp in dList)
            {
                TreeNode tn = new TreeNode(kvp.Key);
                for (int n = 0; n < kvp.Value.Count; n++)
                {
                    TreeNode tb = new TreeNode(n.ToString());
                    tb.Tag = kvp.Value[n];
                    tn.Nodes.Add(tb);
                }
                treeViewStash.Invoke(new Action(() => treeViewStash.Nodes.Add(tn)));
            }
            statusStripLabel.GetCurrentParent().Invoke(new Action(() => statusStripLabel.Text = ""));
        }
        private void treeViewItems_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            Dictionary <string, object> dict = (Dictionary <string, object>)e.Node.Tag;
            object iconUrl;

            dict.TryGetValue("icon", out iconUrl);
            picBox.SizeMode = PictureBoxSizeMode.Zoom;
            if (iconUrl != null)
            {
                picBox.Load(iconUrl.ToString());
                treeViewProperties.Nodes.Clear();
                treeViewProperties.Nodes.AddRange(DataManagement.RecurseTree(dict));
            }
        }