@Nullable
  private static PsiExpression wrapExpressionWithCodeBlock(PsiElement @NotNull [] copy,
                                                           @NotNull ExtractMethodProcessor originalProcessor) {
    if (copy.length != 1 || !(copy[0] instanceof PsiExpression expression)) return null;

    PsiType type = expression.getType();
    if (type == null || PsiTypes.nullType().equals(type)) return null;

    PsiElement parent = expression.getParent();
    PsiElementFactory factory = JavaPsiFacade.getElementFactory(expression.getProject());
    PsiClass parentClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class);
    if (parentClass == null) return null;

    PsiElement parentClassStart = parentClass.getLBrace();
    if (parentClassStart == null) return null;

    // It's syntactically correct to write "new Object() {void foo(){}}.foo()" - see JLS 15.9.5
    @NonNls String wrapperBodyText = (PsiTypes.voidType().equals(type) ? "" : "return ") + expression.getText() + ";";
    String wrapperClassImmediateCallText = "new " + CommonClassNames.JAVA_LANG_OBJECT + "() { " +
                                           type.getCanonicalText() + " wrapperMethod() {" + wrapperBodyText + "} " +
                                           "}.wrapperMethod()";
    PsiExpression wrapperClassImmediateCall = factory.createExpressionFromText(wrapperClassImmediateCallText, parent);
    wrapperClassImmediateCall = (PsiExpression)expression.replace(wrapperClassImmediateCall);
    PsiMethod method = PsiTreeUtil.findChildOfType(wrapperClassImmediateCall, PsiMethod.class);
    LOG.assertTrue(method != null, "wrapper class method is null");

    PsiCodeBlock body = method.getBody();
    LOG.assertTrue(body != null, "wrapper class method's body is null");

    PsiStatement[] statements = body.getStatements();
    LOG.assertTrue(statements.length == 1, "wrapper class method's body statement count");
    PsiStatement bodyStatement = statements[0];

    Set<PsiVariable> effectivelyLocal = originalProcessor.getEffectivelyLocalVariables();
    for (PsiVariable variable : effectivelyLocal) {
      String name = variable.getName();
      LOG.assertTrue(name != null, "effectively local variable's name is null");
      PsiDeclarationStatement declaration = factory.createVariableDeclarationStatement(name, variable.getType(), null);
      body.addBefore(declaration, bodyStatement);
    }

    PsiExpression wrapped = null;
    if (PsiTypes.voidType().equals(type) && bodyStatement instanceof PsiExpressionStatement) {
      wrapped = ((PsiExpressionStatement)bodyStatement).getExpression();
    }
    else if (bodyStatement instanceof PsiReturnStatement) {
      wrapped = ((PsiReturnStatement)bodyStatement).getReturnValue();
    }
    else {
      LOG.error("Unexpected statement in expression code block " + bodyStatement);
    }
    if (wrapped != null) {
      // this key is not copyable so replace() doesn't preserve it - have to do it here
      wrapped.putUserData(ElementToWorkOn.REPLACE_NON_PHYSICAL, expression.getUserData(ElementToWorkOn.REPLACE_NON_PHYSICAL));
    }
    return wrapped;
  }
@Nullable
  private static PsiExpression wrapExpressionWithCodeBlock(PsiElement @NotNull [] copy,
                                                           @NotNull ExtractMethodProcessor originalProcessor)