static Pair<JPanel, CheckboxTree> createPopupContextPanel(final Runnable onChange, final TemplateContext context) {
    JPanel panel = new JPanel(new BorderLayout());

    MultiMap<TemplateContextType, TemplateContextType> hierarchy = MultiMap.createLinked();
    for (TemplateContextType type : TemplateManagerImpl.getAllContextTypes()) {
      hierarchy.putValue(type.getBaseContextType(), type);
    }

    final CheckedTreeNode root = new CheckedTreeNode(Pair.create(null, "Hi"));
    final CheckboxTree checkboxTree = new CheckboxTree(new CheckboxTree.CheckboxTreeCellRenderer() {
      @Override
      public void customizeRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
        final Object o = ((DefaultMutableTreeNode)value).getUserObject();
        if (o instanceof Pair) {
          getTextRenderer().append((String)((Pair<?, ?>)o).second);
        }
      }
    }, root) {
      @Override
      protected void onNodeStateChanged(CheckedTreeNode node) {
        final TemplateContextType type = (TemplateContextType)((Pair<?, ?>)node.getUserObject()).first;
        if (type != null) {
          boolean enabled = node.isChecked();
          context.setEnabled(type, enabled);
          for (TemplateContextType inheritor : hierarchy.get(type)) {
            if (context.getOwnValue(inheritor) == null) {
              context.setEnabled(inheritor, !enabled);
            }
          }
        }
        onChange.run();
      }
    };

    for (TemplateContextType type : sortContexts(hierarchy.get(null))) {
      addContextNode(hierarchy, root, type, context);
    }

    ((DefaultTreeModel)checkboxTree.getModel()).nodeStructureChanged(root);

    TreeUtil.treeNodeTraverser(root).traverse(TreeTraversal.POST_ORDER_DFS).consumeEach(_node -> {
      final CheckedTreeNode node = (CheckedTreeNode)_node;
      if (node.isChecked()) {
        final TreeNode[] path = node.getPath();
        if (path != null) {
          checkboxTree.expandPath(new TreePath(path).getParentPath());
        }
      }
    });
    TreeUtil.expand(checkboxTree, 2);

    panel.add(ScrollPaneFactory.createScrollPane(checkboxTree));
    final Dimension size = checkboxTree.getPreferredSize();
    panel.setPreferredSize(new Dimension(size.width + 30, Math.min(size.height + 10, 500)));

    return Pair.create(panel, checkboxTree);
  }
static Pair<JPanel, CheckboxTree> createPopupContextPanel(final Runnable onChange, final TemplateContext context)