@Override
    public void valueChanged(@NotNull TreeSelectionEvent e) {
      if (myTreeModel == null) {
        return;
      }

      TreePath path = myBlockTree.getSelectionModel().getSelectionPath();
      if (path == null) return;
      DefaultMutableTreeNode component = (DefaultMutableTreeNode)path.getLastPathComponent();
      if (component == null) return;
      Object item = component.getUserObject();

      if (!(item instanceof BlockTreeNode descriptor)) return;

      int blockStart = descriptor.getBlock().getTextRange().getStartOffset();
      PsiFile file = myRootElement.getContainingFile();
      PsiElement currentPsiEl = InjectedLanguageUtil.findElementAtNoCommit(file, blockStart);
      if (currentPsiEl == null) currentPsiEl = file;
      int blockLength = descriptor.getBlock().getTextRange().getLength();
      while (currentPsiEl.getParent() != null &&
             currentPsiEl.getTextRange().getStartOffset() == blockStart &&
             currentPsiEl.getTextLength() != blockLength) {
        currentPsiEl = currentPsiEl.getParent();
      }
      BlockTreeNode rootBlockNode = (BlockTreeNode)getRoot().getUserObject();
      int baseOffset = 0;
      if (rootBlockNode != null) {
        baseOffset = rootBlockNode.getBlock().getTextRange().getStartOffset();
      }

      TextRange range = descriptor.getBlock().getTextRange();
      range = range.shiftRight(-baseOffset);
      myUpdater.updatePsiTree(currentPsiEl, myBlockTree.hasFocus() ? range : null);
    }
@Override
    public void valueChanged(@NotNull TreeSelectionEvent e)