@Override
  protected void surroundExpression(@NotNull ActionContext context, @NotNull PsiExpression expr, @NotNull ModPsiUpdater updater) {
    Project project = context.project();
    PsiType[] types =
      DumbService.getInstance(project).computeWithAlternativeResolveEnabled(() -> GuessManager.getInstance(project).guessTypeToCast(expr));
    final boolean parenthesesNeeded = expr instanceof PsiPolyadicExpression ||
                                      expr instanceof PsiConditionalExpression ||
                                      expr instanceof PsiAssignmentExpression;
    String exprText = parenthesesNeeded ? "(" + expr.getText() + ")" : expr.getText();

    RangeMarker rangeMarker = expr.getUserData(ElementToWorkOn.TEXT_RANGE);
    TextRange range = rangeMarker == null ? expr.getTextRange() : rangeMarker.getTextRange();
    PsiFile file = updater.getWritable(context.file()); // cannot use expr.getContainingFile(), as expr could be detached (e.g., part of polyadic)
    Document document = file.getFileDocument();
    document.replaceString(range.getStartOffset(), range.getEndOffset(), "((x)" + exprText + ")");
    PsiDocumentManager.getInstance(project).commitDocument(document);
    PsiTypeCastExpression cast = PsiTreeUtil.getParentOfType(file.findElementAt(range.getStartOffset() + 1), PsiTypeCastExpression.class);
    if (cast == null) return;
    cast = (PsiTypeCastExpression)CodeStyleManager.getInstance(project).reformat(cast);
    updater.moveCaretTo(cast.getParent().getTextRange().getEndOffset());
    PsiTypeElement castType = Objects.requireNonNull(cast.getCastType());
    Set<LookupElement> itemSet = new LinkedHashSet<>();
    for (PsiType type : types) {
      itemSet.add(PsiTypeLookupItem.createLookupItem(type, null));
    }

    String result = types.length > 0 ? types[0].getPresentableText() : "";
    Expression typeExpr = new ConstantNode(result).withLookupItems(itemSet.size() > 1 ? itemSet : Collections.emptySet());
    updater.templateBuilder()
      .field(castType, typeExpr)
      .finishAt(updater.getCaretOffset());
  }
@Override
  protected void surroundExpression(@NotNull ActionContext context, @NotNull PsiExpression expr, @NotNull ModPsiUpdater updater)