@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 adjustPossibleEmptyTryStatement(PsiTryStatement tryStatement)
     throws IncorrectOperationException {
   PsiCodeBlock tryBlock = tryStatement.getTryBlock();
   if (tryBlock != null) {
     if (tryStatement.getCatchSections().length == 0 && tryStatement.getFinallyBlock() == null) {
       PsiElement firstBodyElement = tryBlock.getFirstBodyElement();
       if (firstBodyElement != null) {
         tryStatement
             .getParent()
             .addRangeAfter(firstBodyElement, tryBlock.getLastBodyElement(), tryStatement);
       }
       tryStatement.delete();
     }
   }
 }
 private static void addSuperCall(
     JavaChangeInfo changeInfo, PsiMethod constructor, PsiMethod callee, final UsageInfo[] usages)
     throws IncorrectOperationException {
   final PsiElementFactory factory = JavaPsiFacade.getElementFactory(constructor.getProject());
   PsiExpressionStatement superCall =
       (PsiExpressionStatement) factory.createStatementFromText("super();", constructor);
   PsiCodeBlock body = constructor.getBody();
   assert body != null;
   PsiStatement[] statements = body.getStatements();
   if (statements.length > 0) {
     superCall = (PsiExpressionStatement) body.addBefore(superCall, statements[0]);
   } else {
     superCall = (PsiExpressionStatement) body.add(superCall);
   }
   PsiMethodCallExpression callExpression = (PsiMethodCallExpression) superCall.getExpression();
   final PsiClass aClass = constructor.getContainingClass();
   final PsiClass baseClass = changeInfo.getMethod().getContainingClass();
   final PsiSubstitutor substitutor =
       TypeConversionUtil.getSuperClassSubstitutor(baseClass, aClass, PsiSubstitutor.EMPTY);
   processMethodUsage(
       callExpression.getMethodExpression(), changeInfo, true, false, callee, substitutor, usages);
 }
  protected void performRefactoring(UsageInfo[] usages) {
    try {
      PsiElementFactory factory =
          JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory();
      PsiType initializerType =
          getInitializerType(myForcedType, myParameterInitializer, myLocalVariable);
      setForcedType(initializerType);

      // Converting myParameterInitializer
      if (myParameterInitializer == null) {
        LOG.assertTrue(myLocalVariable != null);
        myParameterInitializer =
            factory.createExpressionFromText(myLocalVariable.getName(), myLocalVariable);
      } else if (myParameterInitializer instanceof PsiArrayInitializerExpression) {
        final PsiExpression newExprArrayInitializer =
            RefactoringUtil.createNewExpressionFromArrayInitializer(
                (PsiArrayInitializerExpression) myParameterInitializer, initializerType);
        myParameterInitializer =
            (PsiExpression) myParameterInitializer.replace(newExprArrayInitializer);
      }

      myInitializerWrapper = new JavaExpressionWrapper(myParameterInitializer);

      // Changing external occurences (the tricky part)

      IntroduceParameterUtil.processUsages(usages, this);

      if (myGenerateDelegate) {
        generateDelegate(myMethodToReplaceIn);
        if (myMethodToReplaceIn != myMethodToSearchFor) {
          final PsiMethod method = generateDelegate(myMethodToSearchFor);
          if (method.getContainingClass().isInterface()) {
            final PsiCodeBlock block = method.getBody();
            if (block != null) {
              block.delete();
            }
          }
        }
      }

      // Changing signature of initial method
      // (signature of myMethodToReplaceIn will be either changed now or have already been changed)
      LOG.assertTrue(initializerType.isValid());
      final FieldConflictsResolver fieldConflictsResolver =
          new FieldConflictsResolver(myParameterName, myMethodToReplaceIn.getBody());
      IntroduceParameterUtil.changeMethodSignatureAndResolveFieldConflicts(
          new UsageInfo(myMethodToReplaceIn), usages, this);
      if (myMethodToSearchFor != myMethodToReplaceIn) {
        IntroduceParameterUtil.changeMethodSignatureAndResolveFieldConflicts(
            new UsageInfo(myMethodToSearchFor), usages, this);
      }
      ChangeContextUtil.clearContextInfo(myParameterInitializer);

      // Replacing expression occurrences
      for (UsageInfo usage : usages) {
        if (usage instanceof ChangedMethodCallInfo) {
          PsiElement element = usage.getElement();

          processChangedMethodCall(element);
        } else if (usage instanceof InternalUsageInfo) {
          PsiElement element = usage.getElement();
          if (element instanceof PsiExpression) {
            element = RefactoringUtil.outermostParenthesizedExpression((PsiExpression) element);
          }
          if (element != null) {
            if (element.getParent() instanceof PsiExpressionStatement) {
              element.getParent().delete();
            } else {
              PsiExpression newExpr = factory.createExpressionFromText(myParameterName, element);
              IntroduceVariableBase.replace((PsiExpression) element, newExpr, myProject);
            }
          }
        }
      }

      if (myLocalVariable != null && myRemoveLocalVariable) {
        myLocalVariable.normalizeDeclaration();
        myLocalVariable.getParent().delete();
      }
      fieldConflictsResolver.fix();
    } catch (IncorrectOperationException ex) {
      LOG.error(ex);
    }
  }
  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;
    }
  }