private void addOutputVariableFieldsWithGetters() throws IncorrectOperationException {
    final Map<String, String> var2FieldNames = new HashMap<>();
    final PsiVariable[] outputVariables = myExtractProcessor.getOutputVariables();
    for (int i = 0; i < outputVariables.length; i++) {
      final PsiVariable var = outputVariables[i];
      final PsiField outputField = myOutputFields[i];
      final String name = getPureName(var);
      final PsiField field;
      if (outputField != null) {
        var2FieldNames.put(var.getName(), outputField.getName());
        myInnerClass.add(outputField);
        field = outputField;
      } else {
        field = PropertyUtilBase.findPropertyField(myInnerClass, name, false);
      }
      LOG.assertTrue(field != null, "i:" + i + "; output variables: " + Arrays.toString(outputVariables) + "; parameters: " + Arrays.toString(getMethod().getParameterList().getParameters()) + "; output field: " + outputField );
      myInnerClass.add(GenerateMembersUtil.generateGetterPrototype(field));
    }

    final PsiCodeBlock body = getMethod().getBody();
    LOG.assertTrue(body != null);
    final LinkedHashSet<PsiLocalVariable> vars = new LinkedHashSet<>();
    final Map<PsiElement, PsiElement> replacementMap = new LinkedHashMap<>();
    final List<PsiReturnStatement> returnStatements = new ArrayList<>();
    body.accept(new JavaRecursiveElementWalkingVisitor() {
      @Override
      public void visitReturnStatement(@NotNull PsiReturnStatement statement) {
        returnStatements.add(statement);
      }

      @Override
      public void visitClass(@NotNull PsiClass aClass) {}

      @Override
      public void visitLambdaExpression(@NotNull PsiLambdaExpression expression) {}
    });
    if (myExtractProcessor.generatesConditionalExit()) {
      for (int i = 0; i < returnStatements.size() - 1; i++) {
        final PsiReturnStatement condition = returnStatements.get(i);
        final PsiElement container = condition.getParent();
        LOG.assertTrue(myResultFieldName != null);
        final PsiStatement resultStmt = myElementFactory.createStatementFromText(myResultFieldName + " = true;", container);
        if (!CommonJavaRefactoringUtil.isLoopOrIf(container)) {
          container.addBefore(resultStmt, condition);
        } else {
          CommonJavaRefactoringUtil.putStatementInLoopBody(resultStmt, container, condition);
        }
      }

      LOG.assertTrue(!returnStatements.isEmpty());
      final PsiReturnStatement returnStatement = returnStatements.get(returnStatements.size() - 1);
      final PsiElement container = returnStatement.getParent();
      LOG.assertTrue(myResultFieldName != null);
      final PsiStatement resultStmt = myElementFactory.createStatementFromText(myResultFieldName + " = false;", container);
      if (!CommonJavaRefactoringUtil.isLoopOrIf(container)) {
        container.addBefore(resultStmt, returnStatement);
      } else {
        CommonJavaRefactoringUtil.putStatementInLoopBody(resultStmt, container, returnStatement);
      }
    }
    body.accept(new JavaRecursiveElementWalkingVisitor() {
      @Override
      public void visitReturnStatement(final @NotNull PsiReturnStatement statement) {
        super.visitReturnStatement(statement);
        try {
          PsiStatement returnThisStatement = myElementFactory.createStatementFromText("return this;", statement);
          returnThisStatement.putCopyableUserData(GENERATED_RETURN, true);
          replacementMap.put(statement, returnThisStatement);
        }
        catch (IncorrectOperationException e) {
          LOG.error(e);
        }
      }

      @Override
      public void visitClass(@NotNull PsiClass aClass) {}

      @Override
      public void visitLambdaExpression(@NotNull PsiLambdaExpression expression) {}

      @Override
      public void visitDeclarationStatement(final @NotNull PsiDeclarationStatement statement) {
        super.visitDeclarationStatement(statement);
        final PsiElement[] declaredElements = statement.getDeclaredElements();//todo
        for (PsiElement declaredElement : declaredElements) {
          if (declaredElement instanceof PsiVariable) {
            for (PsiVariable variable : outputVariables) {
              PsiVariable var = (PsiVariable)declaredElement;
              if (Comparing.strEqual(var.getName(), variable.getName())) {
                replacementMap.put(var, var.getInitializer());
              }
            }
          }
        }
      }

      @Override
      public void visitParameter(@NotNull PsiParameter parameter) {
        super.visitParameter(parameter);
        final PsiElement declarationScope = parameter.getDeclarationScope();
        for (PsiVariable variable : outputVariables) {
          if (Comparing.strEqual(variable.getName(), parameter.getName())) {
            replacementMap.put(parameter, myElementFactory.createStatementFromText(myInnerClassName + ".this." + var2FieldNames.get(variable.getName()) + " = " + parameter.getName() + ";", declarationScope));
          }
        }
      }

      @Override
      public void visitReferenceExpression(final @NotNull PsiReferenceExpression expression) {
        super.visitReferenceExpression(expression);
        final PsiElement resolved = expression.resolve();
        if (resolved instanceof PsiLocalVariable) {
          final String var = ((PsiLocalVariable)resolved).getName();
          for (PsiVariable variable : outputVariables) {
            if (Comparing.strEqual(variable.getName(), var)) {
              vars.add((PsiLocalVariable)resolved);
              break;
            }
          }
        }
      }
    });

    for (PsiLocalVariable var : vars) {
      final String fieldName = var2FieldNames.get(var.getName());
      for (PsiReference reference : ReferencesSearch.search(var, var.getUseScope())) {
        reference.handleElementRename(fieldName);
      }
    }

    Map<PsiStatement, PsiForeachStatement> blocksToReplace = new LinkedHashMap<>();
    for (PsiElement statement : replacementMap.keySet()) {
      final PsiElement replacement = replacementMap.get(statement);
      if (replacement != null) {
        if (statement instanceof PsiParameter) {
          PsiCodeBlock codeBlock = null;
          final PsiElement declarationScope = ((PsiParameter)statement).getDeclarationScope();
          if (declarationScope instanceof PsiForeachStatement) {
            final PsiStatement loopBody = ((PsiForeachStatement)declarationScope).getBody();
            if (loopBody instanceof PsiBlockStatement) {
              codeBlock = ((PsiBlockStatement)loopBody).getCodeBlock();
            }
            else {
              blocksToReplace.put((PsiStatement)replacement, (PsiForeachStatement)declarationScope);
            }
          }
          else if (declarationScope instanceof PsiCatchSection){
            codeBlock = ((PsiCatchSection)declarationScope).getCatchBlock();
          }
          if (codeBlock != null) {
            codeBlock.addBefore(replacement, codeBlock.getFirstBodyElement());
          }
        }
        else if (statement instanceof PsiLocalVariable variable) {
          variable.normalizeDeclaration();
          final PsiExpression initializer = variable.getInitializer();
          LOG.assertTrue(initializer != null);
          final PsiStatement assignmentStatement = myElementFactory.createStatementFromText(var2FieldNames.get(variable.getName()) + " = " + initializer.getText() + ";", statement);
          final PsiDeclarationStatement declaration = PsiTreeUtil.getParentOfType(statement, PsiDeclarationStatement.class);
          LOG.assertTrue(declaration != null);
          declaration.replace(assignmentStatement);
        }
        else {
          if (statement instanceof PsiReturnStatement) {
            final PsiExpression returnValue = ((PsiReturnStatement)statement).getReturnValue();
            if (!(returnValue instanceof PsiReferenceExpression || returnValue == null || returnValue instanceof PsiLiteralExpression)) {
              statement.getParent()
                .addBefore(myElementFactory.createStatementFromText(returnValue.getText() + ";", returnValue), statement);
            }
          }
          statement.replace(replacement);
        }
      } else {
        statement.delete();
      }
    }

    for (PsiStatement statement : blocksToReplace.keySet()) {
      CommonJavaRefactoringUtil.putStatementInLoopBody(statement, blocksToReplace.get(statement), null);
    }

    myChangeReturnType = true;
  }
private void addOutputVariableFieldsWithGetters()