private static boolean canBePrivate(
      PsiMethod method,
      Collection<PsiReference> references,
      Collection<? extends PsiElement> deleted,
      final PsiElement[] allElementsToDelete) {
    final PsiClass containingClass = method.getContainingClass();
    if (containingClass == null) {
      return false;
    }

    PsiManager manager = method.getManager();
    final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject());
    final PsiElementFactory factory = facade.getElementFactory();
    final PsiModifierList privateModifierList;
    try {
      final PsiMethod newMethod = factory.createMethod("x3", PsiType.VOID);
      privateModifierList = newMethod.getModifierList();
      privateModifierList.setModifierProperty(PsiModifier.PRIVATE, true);
    } catch (IncorrectOperationException e) {
      LOG.assertTrue(false);
      return false;
    }
    for (PsiReference reference : references) {
      final PsiElement element = reference.getElement();
      if (!isInside(element, allElementsToDelete)
          && !isInside(element, deleted)
          && !facade
              .getResolveHelper()
              .isAccessible(method, privateModifierList, element, null, null)) {
        return false;
      }
    }
    return true;
  }
    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
      if (!CodeInsightUtilBase.preparePsiElementForWrite(descriptor.getPsiElement())) return;
      final PsiMethod psiMethod =
          PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiMethod.class);
      if (psiMethod != null) {
        final ArrayList<PsiElement> psiParameters = new ArrayList<PsiElement>();
        final RefElement refMethod = myManager != null ? myManager.getReference(psiMethod) : null;
        if (refMethod != null) {
          for (final RefParameter refParameter : getUnusedParameters((RefMethod) refMethod)) {
            psiParameters.add(refParameter.getElement());
          }
        } else {
          final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
          for (PsiParameter parameter : parameters) {
            if (Comparing.strEqual(parameter.getName(), myHint)) {
              psiParameters.add(parameter);
              break;
            }
          }
        }
        final PsiModificationTracker tracker = psiMethod.getManager().getModificationTracker();
        final long startModificationCount = tracker.getModificationCount();

        removeUnusedParameterViaChangeSignature(psiMethod, psiParameters);
        if (refMethod != null && startModificationCount != tracker.getModificationCount()) {
          myProcessor.ignoreElement(refMethod);
        }
      }
    }
  @NotNull
  private static Set<PsiClassType> filterInProjectExceptions(
      @Nullable PsiMethod targetMethod, @NotNull List<PsiClassType> unhandledExceptions) {
    if (targetMethod == null) return Collections.emptySet();

    Set<PsiClassType> result = new HashSet<PsiClassType>();

    if (targetMethod.getManager().isInProject(targetMethod)) {
      PsiMethod[] superMethods = targetMethod.findSuperMethods();
      for (PsiMethod superMethod : superMethods) {
        Set<PsiClassType> classTypes = filterInProjectExceptions(superMethod, unhandledExceptions);
        result.addAll(classTypes);
      }

      if (superMethods.length == 0) {
        result.addAll(unhandledExceptions);
      }
    } else {
      PsiClassType[] referencedTypes = targetMethod.getThrowsList().getReferencedTypes();
      for (PsiClassType referencedType : referencedTypes) {
        PsiClass psiClass = referencedType.resolve();
        if (psiClass == null) continue;
        for (PsiClassType exception : unhandledExceptions) {
          if (referencedType.isAssignableFrom(exception)) result.add(exception);
        }
      }
    }

    return result;
  }
  private void findUsagesForMethod(PsiMethod method, List<FixableUsageInfo> usages) {
    final PsiManager psiManager = method.getManager();
    final Project project = psiManager.getProject();
    final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
    final Iterable<PsiReference> calls = ReferencesSearch.search(method, scope);
    for (PsiReference reference : calls) {
      final PsiElement referenceElement = reference.getElement();
      final PsiElement parent = referenceElement.getParent();
      if (parent instanceof PsiMethodCallExpression) {
        final PsiMethodCallExpression call = (PsiMethodCallExpression) parent;
        if (isInMovedElement(call)) {
          continue;
        }
        final PsiReferenceExpression methodExpression = call.getMethodExpression();
        final PsiExpression qualifier = methodExpression.getQualifierExpression();
        if (qualifier == null || qualifier instanceof PsiThisExpression) {
          usages.add(new ReplaceThisCallWithDelegateCall(call, delegateFieldName));
        }
        delegationRequired = true;
      }
    }

    if (!delegationRequired && MethodInheritanceUtils.hasSiblingMethods(method)) {
      delegationRequired = true;
    }

    if (delegationRequired) {
      usages.add(new MakeMethodDelegate(method, delegateFieldName));
    } else {
      usages.add(new RemoveMethod(method));
    }
  }
 private static PsiSubstitutor calculateSubstitutor(
     PsiMethod derivedMethod, PsiMethod baseMethod) {
   PsiSubstitutor substitutor;
   if (derivedMethod.getManager().areElementsEquivalent(derivedMethod, baseMethod)) {
     substitutor = PsiSubstitutor.EMPTY;
   } else {
     final PsiClass baseClass = baseMethod.getContainingClass();
     final PsiClass derivedClass = derivedMethod.getContainingClass();
     if (baseClass != null
         && derivedClass != null
         && InheritanceUtil.isInheritorOrSelf(derivedClass, baseClass, true)) {
       final PsiSubstitutor superClassSubstitutor =
           TypeConversionUtil.getSuperClassSubstitutor(
               baseClass, derivedClass, PsiSubstitutor.EMPTY);
       final MethodSignature superMethodSignature = baseMethod.getSignature(superClassSubstitutor);
       final MethodSignature methodSignature = derivedMethod.getSignature(PsiSubstitutor.EMPTY);
       final PsiSubstitutor superMethodSubstitutor =
           MethodSignatureUtil.getSuperMethodSignatureSubstitutor(
               methodSignature, superMethodSignature);
       substitutor =
           superMethodSubstitutor != null ? superMethodSubstitutor : superClassSubstitutor;
     } else {
       substitutor = PsiSubstitutor.EMPTY;
     }
   }
   return substitutor;
 }
  private void findUsagesForStaticMethod(PsiMethod method, List<FixableUsageInfo> usages) {
    final PsiManager psiManager = method.getManager();
    final Project project = psiManager.getProject();
    final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
    final Iterable<PsiReference> calls = ReferencesSearch.search(method, scope);
    final String fullyQualifiedName = getQualifiedName();
    for (PsiReference reference : calls) {
      final PsiElement referenceElement = reference.getElement();

      final PsiElement parent = referenceElement.getParent();
      if (parent instanceof PsiMethodCallExpression) {
        final PsiMethodCallExpression call = (PsiMethodCallExpression) parent;
        if (!isInMovedElement(call)) {
          usages.add(new RetargetStaticMethodCall(call, fullyQualifiedName));
        }
      } else if (parent instanceof PsiImportStaticStatement) {
        final PsiJavaCodeReferenceElement importReference =
            ((PsiImportStaticStatement) parent).getImportReference();
        if (importReference != null) {
          final PsiElement qualifier = importReference.getQualifier();
          if (qualifier instanceof PsiJavaCodeReferenceElement) {
            usages.add(
                new ReplaceClassReference(
                    (PsiJavaCodeReferenceElement) qualifier, fullyQualifiedName));
          }
        }
      }
    }
    usages.add(new RemoveMethod(method));
  }
 @Override
 public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
   return myMethod != null
       && myMethod.isValid()
       && myMethod.getBody() == null
       && myMethod.getContainingClass() != null
       && myMethod.getManager().isInProject(myMethod);
 }
 private static PsiClassType[] getPrimaryChangedExceptionInfo(JavaChangeInfo changeInfo)
     throws IncorrectOperationException {
   final ThrownExceptionInfo[] newExceptionInfos = changeInfo.getNewExceptions();
   PsiClassType[] newExceptions = new PsiClassType[newExceptionInfos.length];
   final PsiMethod method = changeInfo.getMethod();
   for (int i = 0; i < newExceptions.length; i++) {
     newExceptions[i] =
         (PsiClassType)
             newExceptionInfos[i].createType(
                 method, method.getManager()); // context really does not matter here
   }
   return newExceptions;
 }
  @NotNull
  protected UsageInfo[] findUsages() {
    final PsiManager manager = myMethod.getManager();
    final GlobalSearchScope searchScope = GlobalSearchScope.allScope(manager.getProject());
    final List<UsageInfo> usages = new ArrayList<UsageInfo>();
    for (PsiReference ref : ReferencesSearch.search(myMethod, searchScope, false)) {
      final PsiElement element = ref.getElement();
      if (element instanceof PsiReferenceExpression) {
        boolean isInternal = PsiTreeUtil.isAncestor(myMethod, element, true);
        usages.add(new MethodCallUsageInfo((PsiReferenceExpression) element, isInternal));
      } else if (element instanceof PsiDocTagValue) {
        usages.add(new JavadocUsageInfo(((PsiDocTagValue) element)));
      } else {
        throw new UnknownReferenceTypeException(element.getLanguage());
      }
    }

    if (myTargetClass.isInterface()) {
      addInheritorUsages(myTargetClass, searchScope, usages);
    }

    final PsiCodeBlock body = myMethod.getBody();
    if (body != null) {
      body.accept(
          new JavaRecursiveElementWalkingVisitor() {
            @Override
            public void visitNewExpression(PsiNewExpression expression) {
              if (MoveInstanceMembersUtil.getClassReferencedByThis(expression) != null) {
                usages.add(new InternalUsageInfo(expression));
              }
              super.visitNewExpression(expression);
            }

            @Override
            public void visitReferenceExpression(PsiReferenceExpression expression) {
              if (MoveInstanceMembersUtil.getClassReferencedByThis(expression) != null) {
                usages.add(new InternalUsageInfo(expression));
              } else if (!expression.isQualified()) {
                final PsiElement resolved = expression.resolve();
                if (myTargetVariable.equals(resolved)) {
                  usages.add(new InternalUsageInfo(expression));
                }
              }

              super.visitReferenceExpression(expression);
            }
          });
    }

    return usages.toArray(new UsageInfo[usages.size()]);
  }
  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);
    }
  }
Exemple #11
0
  @Override
  public boolean isAvailable(
      @NotNull Project project,
      @NotNull PsiFile file,
      @NotNull PsiElement startElement,
      @NotNull PsiElement endElement) {
    final PsiMethod myMethod = (PsiMethod) startElement;

    PsiType myReturnType = myReturnTypePointer.getType();
    return myMethod.isValid()
        && myMethod.getManager().isInProject(myMethod)
        && myReturnType != null
        && myReturnType.isValid()
        && !TypeConversionUtil.isNullType(myReturnType)
        && myMethod.getReturnType() != null
        && !Comparing.equal(myReturnType, myMethod.getReturnType());
  }
    private boolean shouldFixSuper(PsiMethod method) {
      for (PsiMember element : myMembersAfterMove) {
        if (element instanceof PsiMethod) {
          PsiMethod member = (PsiMethod) element;
          // if there is such member among moved members, super qualifier
          // should not be removed
          final PsiManager manager = method.getManager();
          if (manager.areElementsEquivalent(
                  member.getContainingClass(), method.getContainingClass())
              && MethodSignatureUtil.areSignaturesEqual(member, method)) {
            return false;
          }
        }
      }

      final PsiMethod methodFromSuper = myTargetSuperClass.findMethodBySignature(method, false);
      return methodFromSuper == null;
    }
  @Override
  public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
    int offset = editor.getCaretModel().getOffset();
    final PsiMethod method = findMethod(file, offset);

    if (method == null || !method.isValid()) return false;
    setText(getIntentionName(method));

    if (!method.getManager().isInProject(method)) return false;

    PsiClass containingClass = method.getContainingClass();
    if (containingClass == null) return false;
    final boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT);
    if (isAbstract
        || !method.hasModifierProperty(PsiModifier.PRIVATE)
            && !method.hasModifierProperty(PsiModifier.STATIC)) {
      if (!isAbstract && !isOnIdentifier(file, offset)) return false;
      MyElementProcessor processor = new MyElementProcessor(method);
      if (containingClass.isEnum()) {
        for (PsiField field : containingClass.getFields()) {
          if (field instanceof PsiEnumConstant) {
            final PsiEnumConstantInitializer initializingClass =
                ((PsiEnumConstant) field).getInitializingClass();
            if (initializingClass == null) {
              processor.myHasMissingImplementations = true;
            } else {
              if (!processor.execute(initializingClass)) {
                break;
              }
            }
          }
        }
      }
      ClassInheritorsSearch.search(containingClass, false)
          .forEach(new PsiElementProcessorAdapter<PsiClass>(processor));
      return isAvailable(processor);
    }

    return false;
  }
  private void reportNullableArgumentsPassedToNonAnnotated(
      DataFlowInstructionVisitor visitor, ProblemsHolder holder, Set<PsiElement> reportedAnchors) {
    for (PsiElement expr :
        visitor.getProblems(NullabilityProblem.passingNullableArgumentToNonAnnotatedParameter)) {
      if (reportedAnchors.contains(expr)) continue;

      final String text =
          isNullLiteralExpression(expr)
              ? "Passing <code>null</code> argument to non annotated parameter"
              : "Argument <code>#ref</code> #loc might be null but passed to non annotated parameter";
      LocalQuickFix[] fixes =
          createNPEFixes((PsiExpression) expr, (PsiExpression) expr, holder.isOnTheFly());
      final PsiElement parent = expr.getParent();
      if (parent instanceof PsiExpressionList) {
        final int idx = ArrayUtilRt.find(((PsiExpressionList) parent).getExpressions(), expr);
        if (idx > -1) {
          final PsiElement gParent = parent.getParent();
          if (gParent instanceof PsiCallExpression) {
            final PsiMethod psiMethod = ((PsiCallExpression) gParent).resolveMethod();
            if (psiMethod != null
                && psiMethod.getManager().isInProject(psiMethod)
                && AnnotationUtil.isAnnotatingApplicable(psiMethod)) {
              final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
              if (idx < parameters.length) {
                final AddNullableAnnotationFix addNullableAnnotationFix =
                    new AddNullableAnnotationFix(parameters[idx]);
                fixes =
                    fixes == null
                        ? new LocalQuickFix[] {addNullableAnnotationFix}
                        : ArrayUtil.append(fixes, addNullableAnnotationFix);
                holder.registerProblem(expr, text, fixes);
                reportedAnchors.add(expr);
              }
            }
          }
        }
      }
    }
  }
  private static void fixPrimaryThrowsLists(PsiMethod method, PsiClassType[] newExceptions)
      throws IncorrectOperationException {
    PsiElementFactory elementFactory =
        JavaPsiFacade.getInstance(method.getProject()).getElementFactory();
    PsiJavaCodeReferenceElement[] refs = new PsiJavaCodeReferenceElement[newExceptions.length];
    for (int i = 0; i < refs.length; i++) {
      refs[i] = elementFactory.createReferenceElementByType(newExceptions[i]);
    }
    PsiReferenceList throwsList = elementFactory.createReferenceList(refs);

    PsiReferenceList methodThrowsList =
        (PsiReferenceList) method.getThrowsList().replace(throwsList);
    methodThrowsList =
        (PsiReferenceList)
            JavaCodeStyleManager.getInstance(method.getProject())
                .shortenClassReferences(methodThrowsList);
    CodeStyleManager.getInstance(method.getManager().getProject())
        .reformatRange(
            method,
            method.getParameterList().getTextRange().getEndOffset(),
            methodThrowsList.getTextRange().getEndOffset());
  }
    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);
      }
    }
  public void checkPrimitiveVarargs(
      @NotNull List<CandidateInfo> conflicts, final int argumentsCount) {
    if (JavaVersionService.getInstance().isAtLeast(myArgumentsList, JavaSdkVersion.JDK_1_7)) return;
    CandidateInfo objectVararg = null;
    for (CandidateInfo conflict : conflicts) {
      ProgressManager.checkCanceled();
      final PsiMethod method = (PsiMethod) conflict.getElement();
      final int parametersCount = method.getParameterList().getParametersCount();
      if (method.isVarArgs() && parametersCount - 1 == argumentsCount) {
        final PsiType type =
            method.getParameterList().getParameters()[parametersCount - 1].getType();
        final PsiType componentType = ((PsiArrayType) type).getComponentType();
        final PsiClassType classType =
            PsiType.getJavaLangObject(
                method.getManager(), GlobalSearchScope.allScope(method.getProject()));
        if (Comparing.equal(componentType, classType)) {
          objectVararg = conflict;
        }
      }
    }

    if (objectVararg != null) {
      for (CandidateInfo conflict : conflicts) {
        ProgressManager.checkCanceled();
        PsiMethod method = (PsiMethod) conflict.getElement();
        if (method != objectVararg && method.isVarArgs()) {
          final int paramsCount = method.getParameterList().getParametersCount();
          final PsiType type = method.getParameterList().getParameters()[paramsCount - 1].getType();
          final PsiType componentType = ((PsiArrayType) type).getComponentType();
          if (argumentsCount == paramsCount - 1 && componentType instanceof PsiPrimitiveType) {
            conflicts.remove(objectVararg);
            break;
          }
        }
      }
    }
  }
  public static boolean isMethodEquivalentTo(@NotNull PsiMethod method1, PsiElement another) {
    if (method1 == another) return true;
    if (!(another instanceof PsiMethod)) return false;
    PsiMethod method2 = (PsiMethod) another;
    if (!another.isValid()) return false;
    if (!method1.getName().equals(method2.getName())) return false;
    PsiClass aClass1 = method1.getContainingClass();
    PsiClass aClass2 = method2.getContainingClass();
    PsiManager manager = method1.getManager();
    if (!(aClass1 != null && aClass2 != null && manager.areElementsEquivalent(aClass1, aClass2)))
      return false;

    PsiParameter[] parameters1 = method1.getParameterList().getParameters();
    PsiParameter[] parameters2 = method2.getParameterList().getParameters();
    if (parameters1.length != parameters2.length) return false;
    for (int i = 0; i < parameters1.length; i++) {
      PsiParameter parameter1 = parameters1[i];
      PsiParameter parameter2 = parameters2[i];
      PsiType type1 = parameter1.getType();
      PsiType type2 = parameter2.getType();
      if (!compareParamTypes(manager, type1, type2)) return false;
    }
    return true;
  }
  private void correctMethodCall(
      final PsiMethodCallExpression expression, final boolean isInternalCall) {
    try {
      final PsiManager manager = myMethod.getManager();
      PsiReferenceExpression methodExpression = expression.getMethodExpression();
      if (!methodExpression.isReferenceTo(myMethod)) return;
      final PsiExpression oldQualifier = methodExpression.getQualifierExpression();
      PsiExpression newQualifier = null;
      final PsiClass classReferencedByThis =
          MoveInstanceMembersUtil.getClassReferencedByThis(methodExpression);
      if (myTargetVariable instanceof PsiParameter) {
        final int index =
            myMethod.getParameterList().getParameterIndex((PsiParameter) myTargetVariable);
        final PsiExpression[] arguments = expression.getArgumentList().getExpressions();
        if (index < arguments.length) {
          newQualifier = (PsiExpression) arguments[index].copy();
          arguments[index].delete();
        }
      } else {
        VisibilityUtil.escalateVisibility((PsiField) myTargetVariable, expression);
        String newQualifierName = myTargetVariable.getName();
        if (myTargetVariable instanceof PsiField && oldQualifier != null) {
          final PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(oldQualifier.getType());
          if (aClass == ((PsiField) myTargetVariable).getContainingClass()) {
            newQualifierName = oldQualifier.getText() + "." + newQualifierName;
          }
        }
        newQualifier =
            JavaPsiFacade.getInstance(manager.getProject())
                .getElementFactory()
                .createExpressionFromText(newQualifierName, null);
      }

      PsiExpression newArgument = null;

      if (classReferencedByThis != null) {
        @NonNls String thisArgumentText = null;
        if (manager.areElementsEquivalent(myMethod.getContainingClass(), classReferencedByThis)) {
          if (myOldClassParameterNames.containsKey(myMethod.getContainingClass())) {
            thisArgumentText = "this";
          }
        } else {
          thisArgumentText = classReferencedByThis.getName() + ".this";
        }

        if (thisArgumentText != null) {
          newArgument =
              JavaPsiFacade.getInstance(manager.getProject())
                  .getElementFactory()
                  .createExpressionFromText(thisArgumentText, null);
        }
      } else {
        if (!isInternalCall && oldQualifier != null) {
          final PsiType type = oldQualifier.getType();
          if (type instanceof PsiClassType) {
            final PsiClass resolved = ((PsiClassType) type).resolve();
            if (resolved != null && getParameterNameToCreate(resolved) != null) {
              newArgument =
                  replaceRefsToTargetVariable(
                      oldQualifier); // replace is needed in case old qualifier is e.g. the same as
                                     // field as target variable
            }
          }
        }
      }

      if (newArgument != null) {
        expression.getArgumentList().add(newArgument);
      }

      if (newQualifier != null) {
        if (newQualifier instanceof PsiThisExpression
            && ((PsiThisExpression) newQualifier).getQualifier() == null) {
          // Remove now redundant 'this' qualifier
          if (oldQualifier != null) oldQualifier.delete();
        } else {
          final PsiReferenceExpression refExpr =
              (PsiReferenceExpression)
                  JavaPsiFacade.getInstance(manager.getProject())
                      .getElementFactory()
                      .createExpressionFromText("q." + myMethod.getName(), null);
          refExpr.getQualifierExpression().replace(newQualifier);
          methodExpression.replace(refExpr);
        }
      }
    } catch (IncorrectOperationException e) {
      LOG.error(e);
    }
  }
  private PsiClass buildClass() {
    if (existingClass != null) {
      return existingClass;
    }
    final ParameterObjectBuilder beanClassBuilder = new ParameterObjectBuilder();
    beanClassBuilder.setVisibility(myCreateInnerClass ? PsiModifier.PRIVATE : PsiModifier.PUBLIC);
    beanClassBuilder.setProject(myProject);
    beanClassBuilder.setTypeArguments(typeParams);
    beanClassBuilder.setClassName(className);
    beanClassBuilder.setPackageName(packageName);
    for (ParameterChunk parameterChunk : parameters) {
      final VariableData parameter = parameterChunk.parameter;
      final boolean setterRequired = paramsNeedingSetters.contains(parameter.variable);
      beanClassBuilder.addField(
          (PsiParameter) parameter.variable, parameter.name, parameter.type, setterRequired);
    }
    final String classString = beanClassBuilder.buildBeanClass();

    try {
      final PsiFileFactory factory = PsiFileFactory.getInstance(method.getProject());
      final PsiJavaFile newFile =
          (PsiJavaFile)
              factory.createFileFromText(className + ".java", JavaFileType.INSTANCE, classString);
      if (myCreateInnerClass) {
        final PsiClass containingClass = method.getContainingClass();
        final PsiClass[] classes = newFile.getClasses();
        assert classes.length > 0 : classString;
        final PsiClass innerClass = (PsiClass) containingClass.add(classes[0]);
        PsiUtil.setModifierProperty(innerClass, PsiModifier.STATIC, true);
        return (PsiClass)
            JavaCodeStyleManager.getInstance(newFile.getProject())
                .shortenClassReferences(innerClass);
      } else {
        final PsiFile containingFile = method.getContainingFile();
        final PsiDirectory containingDirectory = containingFile.getContainingDirectory();
        final PsiDirectory directory;
        if (myMoveDestination != null) {
          directory = myMoveDestination.getTargetDirectory(containingDirectory);
        } else {
          final Module module = ModuleUtil.findModuleForPsiElement(containingFile);
          directory =
              PackageUtil.findOrCreateDirectoryForPackage(
                  module, packageName, containingDirectory, true, true);
        }

        if (directory != null) {

          final CodeStyleManager codeStyleManager =
              CodeStyleManager.getInstance(method.getManager().getProject());
          final PsiElement shortenedFile =
              JavaCodeStyleManager.getInstance(newFile.getProject())
                  .shortenClassReferences(newFile);
          final PsiElement reformattedFile = codeStyleManager.reformat(shortenedFile);
          return ((PsiJavaFile) directory.add(reformattedFile)).getClasses()[0];
        }
      }
    } catch (IncorrectOperationException e) {
      logger.info(e);
    }
    return null;
  }
  private PsiMethod createMethodToAdd() {
    ChangeContextUtil.encodeContextInfo(myMethod, true);
    try {
      final PsiManager manager = myMethod.getManager();
      final PsiElementFactory factory =
          JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();

      // correct internal references
      final PsiCodeBlock body = myMethod.getBody();
      if (body != null) {
        final Map<PsiElement, PsiElement> replaceMap = new HashMap<PsiElement, PsiElement>();
        body.accept(
            new JavaRecursiveElementVisitor() {
              @Override
              public void visitThisExpression(PsiThisExpression expression) {
                final PsiClass classReferencedByThis =
                    MoveInstanceMembersUtil.getClassReferencedByThis(expression);
                if (classReferencedByThis != null
                    && !PsiTreeUtil.isAncestor(myMethod, classReferencedByThis, false)) {
                  final PsiElementFactory factory =
                      JavaPsiFacade.getInstance(myProject).getElementFactory();
                  String paramName = getParameterNameToCreate(classReferencedByThis);
                  try {
                    final PsiExpression refExpression =
                        factory.createExpressionFromText(paramName, null);
                    replaceMap.put(expression, refExpression);
                  } catch (IncorrectOperationException e) {
                    LOG.error(e);
                  }
                }
              }

              @Override
              public void visitReferenceExpression(PsiReferenceExpression expression) {
                try {
                  final PsiExpression qualifier = expression.getQualifierExpression();
                  final PsiElement resolved = expression.resolve();
                  if (qualifier instanceof PsiReferenceExpression
                      && ((PsiReferenceExpression) qualifier).isReferenceTo(myTargetVariable)) {
                    if (resolved instanceof PsiField) {
                      for (PsiParameter parameter : myMethod.getParameterList().getParameters()) {
                        if (Comparing.strEqual(
                            parameter.getName(), ((PsiField) resolved).getName())) {
                          qualifier.replace(factory.createExpressionFromText("this", null));
                          return;
                        }
                      }
                    }
                    // Target is a field, replace target.m -> m
                    qualifier.delete();
                    return;
                  }
                  if (myTargetVariable.equals(resolved)) {
                    PsiThisExpression thisExpression =
                        RefactoringChangeUtil.createThisExpression(
                            manager,
                            PsiTreeUtil.isAncestor(
                                    myMethod,
                                    PsiTreeUtil.getParentOfType(expression, PsiClass.class),
                                    true)
                                ? myTargetClass
                                : null);
                    replaceMap.put(expression, thisExpression);
                    return;
                  } else if (myMethod.equals(resolved)) {
                  } else {
                    PsiClass classReferencedByThis =
                        MoveInstanceMembersUtil.getClassReferencedByThis(expression);
                    if (classReferencedByThis != null) {
                      final String paramName = getParameterNameToCreate(classReferencedByThis);
                      if (paramName != null) {
                        PsiReferenceExpression newQualifier =
                            (PsiReferenceExpression)
                                factory.createExpressionFromText(paramName, null);
                        expression.setQualifierExpression(newQualifier);
                        return;
                      }
                    }
                  }
                  super.visitReferenceExpression(expression);
                } catch (IncorrectOperationException e) {
                  LOG.error(e);
                }
              }

              @Override
              public void visitNewExpression(PsiNewExpression expression) {
                try {
                  final PsiExpression qualifier = expression.getQualifier();
                  if (qualifier instanceof PsiReferenceExpression
                      && ((PsiReferenceExpression) qualifier).isReferenceTo(myTargetVariable)) {
                    // Target is a field, replace target.new A() -> new A()
                    qualifier.delete();
                  } else {
                    final PsiClass classReferencedByThis =
                        MoveInstanceMembersUtil.getClassReferencedByThis(expression);
                    if (classReferencedByThis != null) {
                      if (qualifier != null) qualifier.delete();
                      final String paramName = getParameterNameToCreate(classReferencedByThis);
                      final PsiExpression newExpression =
                          factory.createExpressionFromText(
                              paramName + "." + expression.getText(), null);
                      replaceMap.put(expression, newExpression);
                    }
                  }
                  super.visitNewExpression(expression);
                } catch (IncorrectOperationException e) {
                  LOG.error(e);
                }
              }

              @Override
              public void visitMethodCallExpression(PsiMethodCallExpression expression) {
                correctMethodCall(expression, true);
                super.visitMethodCallExpression(expression);
              }
            });
        for (PsiElement element : replaceMap.keySet()) {
          final PsiElement replacement = replaceMap.get(element);
          element.replace(replacement);
        }
      }

      final PsiMethod methodCopy = getPatternMethod();

      final List<PsiParameter> newParameters =
          Arrays.asList(methodCopy.getParameterList().getParameters());
      RefactoringUtil.fixJavadocsForParams(methodCopy, new HashSet<PsiParameter>(newParameters));
      return methodCopy;
    } catch (IncorrectOperationException e) {
      LOG.error(e);
      return myMethod;
    }
  }
  private static PsiMethod generateDelegateMethod(
      PsiMethod method,
      PsiClass superClass,
      PsiSubstitutor substitutor,
      boolean keepParameterAnnotations) {
    final LightMethodBuilder builder =
        new LightMethodBuilder(
            superClass.getManager(), GroovyFileType.GROOVY_LANGUAGE, method.getName());
    builder.setContainingClass(superClass);
    builder.setMethodReturnType(substitutor.substitute(method.getReturnType()));
    builder.setNavigationElement(method);
    builder.addModifier(PsiModifier.PUBLIC);

    final PsiTypeParameter[] typeParameters = method.getTypeParameters();

    final PsiClass containingClass = method.getContainingClass();
    boolean isRaw =
        containingClass != null && PsiUtil.isRawSubstitutor(containingClass, substitutor);
    if (isRaw) {
      substitutor =
          JavaPsiFacade.getInstance(method.getProject())
              .getElementFactory()
              .createRawSubstitutor(substitutor, typeParameters);
    }

    if (!isRaw) {
      for (PsiTypeParameter typeParameter : typeParameters) {
        builder.addTypeParameter(typeParameter);
      }
    }

    final PsiParameter[] originalParameters = method.getParameterList().getParameters();

    for (int i = 0; i < originalParameters.length; i++) {
      PsiParameter originalParameter = originalParameters[i];
      PsiType type;
      if (isRaw) {
        type = TypeConversionUtil.erasure(substitutor.substitute(originalParameter.getType()));
      } else {
        type = substitutor.substitute(originalParameter.getType());
      }
      if (type == null) {
        type = PsiType.getJavaLangObject(superClass.getManager(), superClass.getResolveScope());
      }
      final LightParameter lightParameter =
          new LightParameter(
              StringUtil.notNullize(originalParameter.getName(), "p" + i),
              type,
              builder,
              JavaLanguage.INSTANCE);
      if (keepParameterAnnotations) {
        final PsiCompositeModifierList delegatingModifierList =
            new PsiCompositeModifierList(
                method.getManager(),
                Collections.singletonList(originalParameter.getModifierList()));
        lightParameter.setModifierList(delegatingModifierList);
      }
      builder.addParameter(lightParameter);
    }
    builder.setBaseIcon(JetgroovyIcons.Groovy.Method);

    return new DelegatedMethod(builder, method);
  }
  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);
    }
  }