private static void processCallerMethod(
      JavaChangeInfo changeInfo,
      PsiMethod caller,
      PsiMethod baseMethod,
      boolean toInsertParams,
      boolean toInsertThrows)
      throws IncorrectOperationException {
    LOG.assertTrue(toInsertParams || toInsertThrows);
    if (toInsertParams) {
      List<PsiParameter> newParameters = new ArrayList<PsiParameter>();
      ContainerUtil.addAll(newParameters, caller.getParameterList().getParameters());
      final JavaParameterInfo[] primaryNewParms = changeInfo.getNewParameters();
      PsiSubstitutor substitutor =
          baseMethod == null
              ? PsiSubstitutor.EMPTY
              : ChangeSignatureProcessor.calculateSubstitutor(caller, baseMethod);
      for (JavaParameterInfo info : primaryNewParms) {
        if (info.getOldIndex() < 0)
          newParameters.add(createNewParameter(changeInfo, info, substitutor));
      }
      PsiParameter[] arrayed = newParameters.toArray(new PsiParameter[newParameters.size()]);
      boolean[] toRemoveParm = new boolean[arrayed.length];
      Arrays.fill(toRemoveParm, false);
      resolveParameterVsFieldsConflicts(arrayed, caller, caller.getParameterList(), toRemoveParm);
    }

    if (toInsertThrows) {
      List<PsiJavaCodeReferenceElement> newThrowns = new ArrayList<PsiJavaCodeReferenceElement>();
      final PsiReferenceList throwsList = caller.getThrowsList();
      ContainerUtil.addAll(newThrowns, throwsList.getReferenceElements());
      final ThrownExceptionInfo[] primaryNewExns = changeInfo.getNewExceptions();
      for (ThrownExceptionInfo thrownExceptionInfo : primaryNewExns) {
        if (thrownExceptionInfo.getOldIndex() < 0) {
          final PsiClassType type =
              (PsiClassType) thrownExceptionInfo.createType(caller, caller.getManager());
          final PsiJavaCodeReferenceElement ref =
              JavaPsiFacade.getInstance(caller.getProject())
                  .getElementFactory()
                  .createReferenceElementByType(type);
          newThrowns.add(ref);
        }
      }
      PsiJavaCodeReferenceElement[] arrayed =
          newThrowns.toArray(new PsiJavaCodeReferenceElement[newThrowns.size()]);
      boolean[] toRemoveParm = new boolean[arrayed.length];
      Arrays.fill(toRemoveParm, false);
      ChangeSignatureUtil.synchronizeList(
          throwsList, Arrays.asList(arrayed), ThrowsList.INSTANCE, toRemoveParm);
    }
  }
 private static void fixJavadocsForChangedMethod(
     PsiMethod method, JavaChangeInfo changeInfo, int newParamsLength)
     throws IncorrectOperationException {
   final PsiParameter[] parameters = method.getParameterList().getParameters();
   final JavaParameterInfo[] newParms = changeInfo.getNewParameters();
   LOG.assertTrue(parameters.length <= newParamsLength);
   final Set<PsiParameter> newParameters = new HashSet<PsiParameter>();
   final String[] oldParameterNames = changeInfo.getOldParameterNames();
   for (int i = 0; i < newParamsLength; i++) {
     JavaParameterInfo newParm = newParms[i];
     if (newParm.getOldIndex() < 0
         || !newParm.getName().equals(oldParameterNames[newParm.getOldIndex()])) {
       newParameters.add(parameters[i]);
     }
   }
   RefactoringUtil.fixJavadocsForParams(method, newParameters);
 }
 private static void addDelegateArguments(
     JavaChangeInfo changeInfo, PsiElementFactory factory, final PsiCallExpression callExpression)
     throws IncorrectOperationException {
   final JavaParameterInfo[] newParms = changeInfo.getNewParameters();
   final String[] oldParameterNames = changeInfo.getOldParameterNames();
   for (int i = 0; i < newParms.length; i++) {
     JavaParameterInfo newParm = newParms[i];
     final PsiExpression actualArg;
     if (newParm.getOldIndex() >= 0) {
       actualArg =
           factory.createExpressionFromText(
               oldParameterNames[newParm.getOldIndex()], callExpression);
     } else {
       actualArg = changeInfo.getValue(i, callExpression);
     }
     JavaCodeStyleManager.getInstance(callExpression.getProject())
         .shortenClassReferences(callExpression.getArgumentList().add(actualArg));
   }
 }
    private void addMethodConflicts(MultiMap<PsiElement, String> conflicts) {
      String newMethodName = myChangeInfo.getNewName();
      if (!(myChangeInfo instanceof JavaChangeInfo)) {
        return;
      }
      try {
        PsiMethod prototype;
        final PsiMethod method = myChangeInfo.getMethod();
        if (!StdLanguages.JAVA.equals(method.getLanguage())) return;
        PsiManager manager = method.getManager();
        PsiElementFactory factory =
            JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
        final CanonicalTypes.Type returnType = myChangeInfo.getNewReturnType();
        if (returnType != null) {
          prototype = factory.createMethod(newMethodName, returnType.getType(method, manager));
        } else {
          prototype = factory.createConstructor();
          prototype.setName(newMethodName);
        }
        JavaParameterInfo[] parameters = myChangeInfo.getNewParameters();

        for (JavaParameterInfo info : parameters) {
          PsiType parameterType = info.createType(method, manager);
          if (parameterType == null) {
            parameterType =
                JavaPsiFacade.getElementFactory(method.getProject())
                    .createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, method);
          }
          PsiParameter param = factory.createParameter(info.getName(), parameterType);
          prototype.getParameterList().add(param);
        }

        ConflictsUtil.checkMethodConflicts(
            method.getContainingClass(), method, prototype, conflicts);
      } catch (IncorrectOperationException e) {
        LOG.error(e);
      }
    }
  private void findParametersUsage(
      final PsiMethod method, ArrayList<UsageInfo> result, PsiMethod[] overriders) {
    if (JavaLanguage.INSTANCE.equals(myChangeInfo.getLanguage())) {
      PsiParameter[] parameters = method.getParameterList().getParameters();
      for (ParameterInfo info : myChangeInfo.getNewParameters()) {
        if (info.getOldIndex() >= 0) {
          PsiParameter parameter = parameters[info.getOldIndex()];
          if (!info.getName().equals(parameter.getName())) {
            addParameterUsages(parameter, result, info);

            for (PsiMethod overrider : overriders) {
              PsiParameter parameter1 =
                  overrider.getParameterList().getParameters()[info.getOldIndex()];
              if (parameter1 != null
                  && Comparing.strEqual(parameter.getName(), parameter1.getName())) {
                addParameterUsages(parameter1, result, info);
              }
            }
          }
        }
      }
    }
  }
  private static void processPrimaryMethod(
      JavaChangeInfo changeInfo, PsiMethod method, PsiMethod baseMethod, boolean isOriginal)
      throws IncorrectOperationException {
    PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory();

    if (changeInfo.isVisibilityChanged()) {
      PsiModifierList modifierList = method.getModifierList();
      final String highestVisibility =
          isOriginal
              ? changeInfo.getNewVisibility()
              : VisibilityUtil.getHighestVisibility(
                  changeInfo.getNewVisibility(),
                  VisibilityUtil.getVisibilityModifier(modifierList));
      VisibilityUtil.setVisibility(modifierList, highestVisibility);
    }

    if (changeInfo.isNameChanged()) {
      String newName =
          baseMethod == null
              ? changeInfo.getNewName()
              : RefactoringUtil.suggestNewOverriderName(
                  method.getName(), baseMethod.getName(), changeInfo.getNewName());

      if (newName != null && !newName.equals(method.getName())) {
        final PsiIdentifier nameId = method.getNameIdentifier();
        assert nameId != null;
        nameId.replace(
            JavaPsiFacade.getInstance(method.getProject())
                .getElementFactory()
                .createIdentifier(newName));
      }
    }

    final PsiSubstitutor substitutor =
        baseMethod == null
            ? PsiSubstitutor.EMPTY
            : ChangeSignatureProcessor.calculateSubstitutor(method, baseMethod);

    if (changeInfo.isReturnTypeChanged()) {
      PsiType newTypeElement =
          changeInfo
              .getNewReturnType()
              .getType(changeInfo.getMethod().getParameterList(), method.getManager());
      final PsiType returnType = substitutor.substitute(newTypeElement);
      // don't modify return type for non-Java overriders (EJB)
      if (method.getName().equals(changeInfo.getNewName())) {
        final PsiTypeElement typeElement = method.getReturnTypeElement();
        if (typeElement != null) {
          typeElement.replace(factory.createTypeElement(returnType));
        }
      }
    }

    PsiParameterList list = method.getParameterList();
    PsiParameter[] parameters = list.getParameters();

    final JavaParameterInfo[] parameterInfos = changeInfo.getNewParameters();
    final int delta =
        baseMethod != null
            ? baseMethod.getParameterList().getParametersCount()
                - method.getParameterList().getParametersCount()
            : 0;
    PsiParameter[] newParms = new PsiParameter[Math.max(parameterInfos.length - delta, 0)];
    final String[] oldParameterNames = changeInfo.getOldParameterNames();
    final String[] oldParameterTypes = changeInfo.getOldParameterTypes();
    for (int i = 0; i < newParms.length; i++) {
      JavaParameterInfo info = parameterInfos[i];
      int index = info.getOldIndex();
      if (index >= 0) {
        PsiParameter parameter = parameters[index];
        newParms[i] = parameter;

        String oldName = oldParameterNames[index];
        if (!oldName.equals(info.getName()) && oldName.equals(parameter.getName())) {
          PsiIdentifier newIdentifier = factory.createIdentifier(info.getName());
          parameter.getNameIdentifier().replace(newIdentifier);
        }

        String oldType = oldParameterTypes[index];
        if (!oldType.equals(info.getTypeText())) {
          parameter.normalizeDeclaration();
          PsiType newType =
              substitutor.substitute(
                  info.createType(changeInfo.getMethod().getParameterList(), method.getManager()));

          parameter.getTypeElement().replace(factory.createTypeElement(newType));
        }
      } else {
        newParms[i] = createNewParameter(changeInfo, info, substitutor);
      }
    }

    resolveParameterVsFieldsConflicts(newParms, method, list, changeInfo.toRemoveParm());
    fixJavadocsForChangedMethod(method, changeInfo, newParms.length);
    if (changeInfo.isExceptionSetOrOrderChanged()) {
      final PsiClassType[] newExceptions = getPrimaryChangedExceptionInfo(changeInfo);
      fixPrimaryThrowsLists(method, newExceptions);
    }
  }
  // This methods works equally well for primary usages as well as for propagated callers' usages
  private static void fixActualArgumentsList(
      PsiExpressionList list,
      JavaChangeInfo changeInfo,
      boolean toInsertDefaultValue,
      PsiSubstitutor substitutor)
      throws IncorrectOperationException {
    final PsiElementFactory factory =
        JavaPsiFacade.getInstance(list.getProject()).getElementFactory();
    if (changeInfo.isParameterSetOrOrderChanged()) {
      if (changeInfo instanceof JavaChangeInfoImpl
          && ((JavaChangeInfoImpl) changeInfo).isPropagationEnabled) {
        final ParameterInfoImpl[] createdParmsInfo =
            ((JavaChangeInfoImpl) changeInfo).getCreatedParmsInfoWithoutVarargs();
        for (ParameterInfoImpl info : createdParmsInfo) {
          PsiExpression newArg;
          if (toInsertDefaultValue) {
            newArg = createDefaultValue(changeInfo, factory, info, list);
          } else {
            newArg = factory.createExpressionFromText(info.getName(), list);
          }
          JavaCodeStyleManager.getInstance(list.getProject())
              .shortenClassReferences(list.add(newArg));
        }
      } else {
        final PsiExpression[] args = list.getExpressions();
        final int nonVarargCount = getNonVarargCount(changeInfo, args);
        final int varargCount = args.length - nonVarargCount;
        if (varargCount < 0) return;
        PsiExpression[] newVarargInitializers = null;

        final int newArgsLength;
        final int newNonVarargCount;
        final JavaParameterInfo[] newParms = changeInfo.getNewParameters();
        if (changeInfo.isArrayToVarargs()) {
          newNonVarargCount = newParms.length - 1;
          final JavaParameterInfo lastNewParm = newParms[newParms.length - 1];
          final PsiExpression arrayToConvert = args[lastNewParm.getOldIndex()];
          if (arrayToConvert instanceof PsiNewExpression) {
            final PsiNewExpression expression = (PsiNewExpression) arrayToConvert;
            final PsiArrayInitializerExpression arrayInitializer = expression.getArrayInitializer();
            if (arrayInitializer != null) {
              newVarargInitializers = arrayInitializer.getInitializers();
            }
          }
          newArgsLength =
              newVarargInitializers == null
                  ? newParms.length
                  : newNonVarargCount + newVarargInitializers.length;
        } else if (changeInfo.isRetainsVarargs()) {
          newNonVarargCount = newParms.length - 1;
          newArgsLength = newNonVarargCount + varargCount;
        } else if (changeInfo.isObtainsVarags()) {
          newNonVarargCount = newParms.length - 1;
          newArgsLength = newNonVarargCount;
        } else {
          newNonVarargCount = newParms.length;
          newArgsLength = newParms.length;
        }

        String[] oldVarargs = null;
        if (changeInfo.wasVararg() && !changeInfo.isRetainsVarargs()) {
          oldVarargs = new String[varargCount];
          for (int i = nonVarargCount; i < args.length; i++) {
            oldVarargs[i - nonVarargCount] = args[i].getText();
          }
        }

        final PsiExpression[] newArgs = new PsiExpression[newArgsLength];
        for (int i = 0; i < newNonVarargCount; i++) {
          if (newParms[i].getOldIndex() == nonVarargCount && oldVarargs != null) {
            PsiType type = newParms[i].createType(changeInfo.getMethod(), list.getManager());
            if (type instanceof PsiArrayType) {
              type = substitutor.substitute(type);
              type = TypeConversionUtil.erasure(type);
              String typeText = type.getCanonicalText();
              if (type instanceof PsiEllipsisType) {
                typeText = typeText.replace("...", "[]");
              }
              String text = "new " + typeText + "{" + StringUtil.join(oldVarargs, ",") + "}";
              newArgs[i] = factory.createExpressionFromText(text, changeInfo.getMethod());
              continue;
            }
          }
          newArgs[i] =
              createActualArgument(changeInfo, list, newParms[i], toInsertDefaultValue, args);
        }
        if (changeInfo.isArrayToVarargs()) {
          if (newVarargInitializers == null) {
            newArgs[newNonVarargCount] =
                createActualArgument(
                    changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args);
          } else {
            System.arraycopy(
                newVarargInitializers, 0, newArgs, newNonVarargCount, newVarargInitializers.length);
          }
        } else {
          final int newVarargCount = newArgsLength - newNonVarargCount;
          LOG.assertTrue(newVarargCount == 0 || newVarargCount == varargCount);
          for (int i = newNonVarargCount; i < newArgsLength; i++) {
            final int oldIndex = newParms[newNonVarargCount].getOldIndex();
            if (oldIndex >= 0 && oldIndex != nonVarargCount) {
              newArgs[i] =
                  createActualArgument(
                      changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args);
            } else {
              System.arraycopy(args, nonVarargCount, newArgs, newNonVarargCount, newVarargCount);
              break;
            }
          }
        }
        ChangeSignatureUtil.synchronizeList(
            list, Arrays.asList(newArgs), ExpressionList.INSTANCE, changeInfo.toRemoveParm());
      }
    }
  }
  private void detectLocalsCollisionsInMethod(
      final PsiMethod method, final ArrayList<UsageInfo> result, boolean isOriginal) {
    if (!JavaLanguage.INSTANCE.equals(method.getLanguage())) return;

    final PsiParameter[] parameters = method.getParameterList().getParameters();
    final Set<PsiParameter> deletedOrRenamedParameters = new HashSet<PsiParameter>();
    if (isOriginal) {
      ContainerUtil.addAll(deletedOrRenamedParameters, parameters);
      for (ParameterInfo parameterInfo : myChangeInfo.getNewParameters()) {
        if (parameterInfo.getOldIndex() >= 0 && parameterInfo.getOldIndex() < parameters.length) {
          final PsiParameter parameter = parameters[parameterInfo.getOldIndex()];
          if (parameterInfo.getName().equals(parameter.getName())) {
            deletedOrRenamedParameters.remove(parameter);
          }
        }
      }
    }

    for (ParameterInfo parameterInfo : myChangeInfo.getNewParameters()) {
      final int oldParameterIndex = parameterInfo.getOldIndex();
      final String newName = parameterInfo.getName();
      if (oldParameterIndex >= 0) {
        if (isOriginal
            && oldParameterIndex < parameters.length
            && !newName.equals(myChangeInfo.getOldParameterNames()[oldParameterIndex])) {
          // Name changes take place only in primary method when name was actually changed
          final PsiParameter parameter = parameters[oldParameterIndex];
          if (!newName.equals(parameter.getName())) {
            JavaUnresolvableLocalCollisionDetector.visitLocalsCollisions(
                parameter,
                newName,
                method.getBody(),
                null,
                new JavaUnresolvableLocalCollisionDetector.CollidingVariableVisitor() {
                  public void visitCollidingElement(final PsiVariable collidingVariable) {
                    if (!deletedOrRenamedParameters.contains(collidingVariable)) {
                      result.add(
                          new RenamedParameterCollidesWithLocalUsageInfo(
                              parameter, collidingVariable, method));
                    }
                  }
                });
          }
        }
      } else {
        JavaUnresolvableLocalCollisionDetector.visitLocalsCollisions(
            method,
            newName,
            method.getBody(),
            null,
            new JavaUnresolvableLocalCollisionDetector.CollidingVariableVisitor() {
              public void visitCollidingElement(PsiVariable collidingVariable) {
                if (!deletedOrRenamedParameters.contains(collidingVariable)) {
                  result.add(
                      new NewParameterCollidesWithLocalUsageInfo(
                          collidingVariable, collidingVariable, method));
                }
              }
            });
      }
    }
  }
  private static void processMethodUsage(
      PsiElement element,
      JavaChangeInfo changeInfo,
      boolean toChangeArguments,
      boolean toCatchExceptions,
      GrClosureSignatureUtil.ArgInfo<PsiElement>[] map,
      PsiSubstitutor substitutor) {
    if (map == null) return;
    if (changeInfo.isNameChanged()) {
      if (element instanceof GrReferenceElement) {
        element = ((GrReferenceElement) element).handleElementRename(changeInfo.getNewName());
      }
    }
    if (toChangeArguments) {
      JavaParameterInfo[] parameters = changeInfo.getNewParameters();
      GrArgumentList argumentList = PsiUtil.getArgumentsList(element);
      GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(element.getProject());
      if (argumentList == null) {
        if (element instanceof GrEnumConstant) {
          argumentList = factory.createArgumentList();
          argumentList = (GrArgumentList) element.add(argumentList);
        } else {
          return;
        }
      }
      Set<PsiElement> argsToDelete = new HashSet<PsiElement>(map.length * 2);
      for (GrClosureSignatureUtil.ArgInfo<PsiElement> argInfo : map) {
        argsToDelete.addAll(argInfo.args);
      }

      for (JavaParameterInfo parameter : parameters) {
        int index = parameter.getOldIndex();
        if (index >= 0) {
          argsToDelete.removeAll(map[index].args);
        }
      }

      for (PsiElement arg : argsToDelete) {
        arg.delete();
      }

      boolean skipOptionals = false;
      PsiElement anchor = null; // PsiTreeUtil.getChildOfAnyType(argumentList, GrExpression.class,
      // GrNamedArgument.class);
      for (int i = 0; i < parameters.length; i++) {
        JavaParameterInfo parameter = parameters[i];
        int index = parameter.getOldIndex();
        if (index >= 0) {
          GrClosureSignatureUtil.ArgInfo<PsiElement> argInfo = map[index];
          List<PsiElement> arguments = argInfo.args;
          if (argInfo.isMultiArg) { // arguments for Map and varArg
            if ((i != 0
                    || !(!arguments.isEmpty()
                        && arguments.iterator().next() instanceof GrNamedArgument))
                && (i != parameters.length - 1 || !parameter.isVarargType())) {
              final PsiType type =
                  parameter.createType(
                      changeInfo.getMethod().getParameterList(), argumentList.getManager());
              final GrExpression arg =
                  GroovyRefactoringUtil.generateArgFromMultiArg(
                      substitutor, arguments, type, element.getProject());
              for (PsiElement argument : arguments) {
                argument.delete();
              }
              anchor = argumentList.addAfter(arg, anchor);
              JavaCodeStyleManager.getInstance(anchor.getProject()).shortenClassReferences(anchor);
            }
          } else { // arguments for simple parameters
            if (arguments.size() == 1) { // arg exists
              PsiElement arg = arguments.iterator().next();
              if (i == parameters.length - 1 && parameter.isVarargType()) {
                if (arg instanceof GrSafeCastExpression) {
                  PsiElement expr = ((GrSafeCastExpression) arg).getOperand();
                  if (expr instanceof GrListOrMap && !((GrListOrMap) expr).isMap()) {
                    final PsiElement copy = expr.copy();
                    PsiElement[] newVarargs = ((GrListOrMap) copy).getInitializers();
                    for (PsiElement vararg : newVarargs) {
                      anchor = argumentList.addAfter(vararg, anchor);
                    }
                    arg.delete();
                    continue;
                  }
                }
              }

              PsiElement curArg = getNextOfType(argumentList, anchor, GrExpression.class);
              if (curArg == arg) {
                anchor = arg;
              } else {
                final PsiElement copy = arg.copy();
                anchor = argumentList.addAfter(copy, anchor);
                arg.delete();
              }
            } else { // arg is skipped. Parameter is optional
              skipOptionals = true;
            }
          }
        } else {
          if (skipOptionals && isParameterOptional(parameter)) continue;

          if (forceOptional(parameter)) {
            skipOptionals = true;
            continue;
          }
          try {

            GrExpression value = createDefaultValue(factory, changeInfo, parameter, argumentList);
            if (i > 0 && (value == null || anchor == null)) {
              PsiElement comma =
                  Factory.createSingleLeafElement(
                          GroovyTokenTypes.mCOMMA,
                          ",",
                          0,
                          1,
                          SharedImplUtil.findCharTableByTree(argumentList.getNode()),
                          argumentList.getManager())
                      .getPsi();
              if (anchor == null) anchor = argumentList.getLeftParen();

              anchor = argumentList.addAfter(comma, anchor);
            }
            if (value != null) {
              anchor = argumentList.addAfter(value, anchor);
            }
          } catch (IncorrectOperationException e) {
            LOG.error(e.getMessage());
          }
        }
      }

      GrCall call = GroovyRefactoringUtil.getCallExpressionByMethodReference(element);
      if (argumentList.getText().trim().isEmpty()
          && (call == null || !PsiImplUtil.hasClosureArguments(call))) {
        argumentList = argumentList.replaceWithArgumentList(factory.createArgumentList());
      }
      CodeStyleManager.getInstance(argumentList.getProject()).reformat(argumentList);
    }

    if (toCatchExceptions) {
      final ThrownExceptionInfo[] exceptionInfos = changeInfo.getNewExceptions();
      PsiClassType[] exceptions = getExceptions(exceptionInfos, element, element.getManager());
      fixExceptions(element, exceptions);
    }
  }
  private static boolean processPrimaryMethodInner(
      JavaChangeInfo changeInfo, GrMethod method, @Nullable PsiMethod baseMethod) {
    if (changeInfo.isNameChanged()) {
      String newName =
          baseMethod == null
              ? changeInfo.getNewName()
              : RefactoringUtil.suggestNewOverriderName(
                  method.getName(), baseMethod.getName(), changeInfo.getNewName());
      if (newName != null && !newName.equals(method.getName())) {
        method.setName(changeInfo.getNewName());
      }
    }

    final GrModifierList modifierList = method.getModifierList();
    if (changeInfo.isVisibilityChanged()) {
      modifierList.setModifierProperty(changeInfo.getNewVisibility(), true);
    }

    PsiSubstitutor substitutor =
        baseMethod != null ? calculateSubstitutor(method, baseMethod) : PsiSubstitutor.EMPTY;

    final PsiMethod context = changeInfo.getMethod();
    GrTypeElement oldReturnTypeElement = method.getReturnTypeElementGroovy();
    if (changeInfo.isReturnTypeChanged()) {
      CanonicalTypes.Type newReturnType = changeInfo.getNewReturnType();
      if (newReturnType == null) {
        if (oldReturnTypeElement != null) {
          oldReturnTypeElement.delete();
          if (modifierList.getModifiers().length == 0) {
            modifierList.setModifierProperty(GrModifier.DEF, true);
          }
        }
      } else {
        PsiType type = newReturnType.getType(context, method.getManager());
        GrReferenceAdjuster.shortenAllReferencesIn(
            method.setReturnType(substitutor.substitute(type)));
        if (oldReturnTypeElement == null) {
          modifierList.setModifierProperty(GrModifier.DEF, false);
        }
      }
    }

    JavaParameterInfo[] newParameters = changeInfo.getNewParameters();
    final GrParameterList parameterList = method.getParameterList();
    GrParameter[] oldParameters = parameterList.getParameters();
    final PsiParameter[] oldBaseParams =
        baseMethod != null ? baseMethod.getParameterList().getParameters() : null;

    Set<GrParameter> toRemove = new HashSet<GrParameter>(oldParameters.length);
    ContainerUtil.addAll(toRemove, oldParameters);

    GrParameter anchor = null;
    final GrDocComment docComment = method.getDocComment();
    final GrDocTag[] tags = docComment == null ? null : docComment.getTags();

    for (JavaParameterInfo newParameter : newParameters) {
      // if old parameter name differs from base method parameter name we don't change it
      final String newName;
      final int oldIndex = newParameter.getOldIndex();
      if (oldIndex >= 0 && oldBaseParams != null) {
        final String oldName = oldParameters[oldIndex].getName();
        if (oldName.equals(oldBaseParams[oldIndex].getName())) {
          newName = newParameter.getName();
        } else {
          newName = oldName;
        }
      } else {
        newName = newParameter.getName();
      }

      final GrParameter oldParameter = oldIndex >= 0 ? oldParameters[oldIndex] : null;

      if (docComment != null && oldParameter != null) {
        final String oldName = oldParameter.getName();
        for (GrDocTag tag : tags) {
          if ("@param".equals(tag.getName())) {
            final GrDocParameterReference parameterReference = tag.getDocParameterReference();
            if (parameterReference != null && oldName.equals(parameterReference.getText())) {
              parameterReference.handleElementRename(newName);
            }
          }
        }
      }

      GrParameter grParameter =
          createNewParameter(substitutor, context, parameterList, newParameter, newName);
      if (oldParameter != null) {
        grParameter.getModifierList().replace(oldParameter.getModifierList());
      }

      if ("def".equals(newParameter.getTypeText())) {
        grParameter.getModifierList().setModifierProperty(GrModifier.DEF, true);
      } else if (StringUtil.isEmpty(newParameter.getTypeText())) {
        grParameter.getModifierList().setModifierProperty(GrModifier.DEF, false);
      }

      anchor = (GrParameter) parameterList.addAfter(grParameter, anchor);
    }

    for (GrParameter oldParameter : toRemove) {
      oldParameter.delete();
    }
    JavaCodeStyleManager.getInstance(parameterList.getProject())
        .shortenClassReferences(parameterList);
    CodeStyleManager.getInstance(parameterList.getProject()).reformat(parameterList);

    if (changeInfo.isExceptionSetOrOrderChanged()) {
      final ThrownExceptionInfo[] infos = changeInfo.getNewExceptions();
      PsiClassType[] exceptionTypes = new PsiClassType[infos.length];
      for (int i = 0; i < infos.length; i++) {
        ThrownExceptionInfo info = infos[i];
        exceptionTypes[i] = (PsiClassType) info.createType(method, method.getManager());
      }

      PsiReferenceList thrownList =
          GroovyPsiElementFactory.getInstance(method.getProject()).createThrownList(exceptionTypes);
      thrownList = (PsiReferenceList) method.getThrowsList().replace(thrownList);
      JavaCodeStyleManager.getInstance(thrownList.getProject()).shortenClassReferences(thrownList);
      CodeStyleManager.getInstance(method.getProject()).reformat(method.getThrowsList());
    }
    return true;
  }