static PsiElement[] getOccurrences(GrIntroduceParameterSettings settings) {
    final GrParametersOwner scope = settings.getToReplaceIn();

    final GrExpression expression = settings.getExpression();
    if (expression != null) {
      final PsiElement expr = PsiUtil.skipParentheses(expression, false);
      if (expr == null) return PsiElement.EMPTY_ARRAY;

      final PsiElement[] occurrences = GroovyRefactoringUtil.getExpressionOccurrences(expr, scope);
      if (occurrences == null || occurrences.length == 0) {
        throw new GrRefactoringError(GroovyRefactoringBundle.message("no.occurrences.found"));
      }
      return occurrences;
    } else {
      final GrVariable var = settings.getVar();
      LOG.assertTrue(var != null);
      final List<PsiElement> list = Collections.synchronizedList(new ArrayList<PsiElement>());
      ReferencesSearch.search(var, new LocalSearchScope(scope))
          .forEach(
              new Processor<PsiReference>() {
                @Override
                public boolean process(PsiReference psiReference) {
                  final PsiElement element = psiReference.getElement();
                  if (element != null) {
                    list.add(element);
                  }
                  return true;
                }
              });
      return list.toArray(new PsiElement[list.size()]);
    }
  }
 @NotNull
 @Override
 public PsiType getForcedType() {
   final PsiType selectedType = mySettings.getSelectedType();
   if (selectedType != null) return selectedType;
   final PsiManager manager = PsiManager.getInstance(myProject);
   final GlobalSearchScope resolveScope = mySettings.getToReplaceIn().getResolveScope();
   return PsiType.getJavaLangObject(manager, resolveScope);
 }
 private static void removeParametersFromCall(
     GrMethodCallExpression methodCall, GrIntroduceParameterSettings settings) {
   final GroovyResolveResult resolveResult = methodCall.advancedResolve();
   final PsiElement resolved = resolveResult.getElement();
   LOG.assertTrue(resolved instanceof PsiMethod);
   final GrClosureSignature signature =
       GrClosureSignatureUtil.createSignature(
           (PsiMethod) resolved, resolveResult.getSubstitutor());
   final GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos =
       GrClosureSignatureUtil.mapParametersToArguments(signature, methodCall);
   LOG.assertTrue(argInfos != null);
   settings
       .parametersToRemove()
       .forEach(
           new TIntProcedure() {
             @Override
             public boolean execute(int value) {
               final List<PsiElement> args = argInfos[value].args;
               for (PsiElement arg : args) {
                 arg.delete();
               }
               return true;
             }
           });
 }
  @NotNull
  @Override
  protected UsageInfo[] findUsages() {
    ArrayList<UsageInfo> result = new ArrayList<UsageInfo>();

    final PsiMethod toSearchFor = ((PsiMethod) mySettings.getToSearchFor());

    if (!mySettings.generateDelegate()) {
      Collection<PsiReference> refs =
          MethodReferencesSearch.search(
                  toSearchFor, GlobalSearchScope.projectScope(myProject), true)
              .findAll();

      for (PsiReference ref1 : refs) {
        PsiElement ref = ref1.getElement();
        if (ref instanceof PsiMethod && ((PsiMethod) ref).isConstructor()) {
          DefaultConstructorImplicitUsageInfo implicitUsageInfo =
              new DefaultConstructorImplicitUsageInfo(
                  (PsiMethod) ref, ((PsiMethod) ref).getContainingClass(), toSearchFor);
          result.add(implicitUsageInfo);
        } else if (ref instanceof PsiClass) {
          result.add(new NoConstructorClassUsageInfo((PsiClass) ref));
        } else if (!PsiTreeUtil.isAncestor(mySettings.getToReplaceIn(), ref, false)) {
          result.add(new ExternalUsageInfo(ref));
        } else {
          result.add(new ChangedMethodCallInfo(ref));
        }
      }
    }

    if (mySettings.replaceAllOccurrences()) {
      PsiElement[] exprs = GroovyIntroduceParameterUtil.getOccurrences(mySettings);
      for (PsiElement expr : exprs) {
        result.add(new InternalUsageInfo(expr));
      }
    } else {
      if (mySettings.getExpression() != null) {
        result.add(new InternalUsageInfo(mySettings.getExpression()));
      }
    }

    Collection<PsiMethod> overridingMethods =
        OverridingMethodsSearch.search(toSearchFor, true).findAll();

    for (PsiMethod overridingMethod : overridingMethods) {
      result.add(new UsageInfo(overridingMethod));
    }

    final UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]);
    return UsageViewUtil.removeDuplicatedUsages(usageInfos);
  }
  @Override
  protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
    UsageInfo[] usagesIn = refUsages.get();
    MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();

    if (!mySettings.generateDelegate()) {
      GroovyIntroduceParameterUtil.detectAccessibilityConflicts(
          mySettings.getExpression(),
          usagesIn,
          conflicts,
          mySettings.replaceFieldsWithGetters()
              != IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE,
          myProject);
    }

    final GrMethod toReplaceIn = (GrMethod) mySettings.getToReplaceIn();
    if (mySettings.getExpression() != null
        && !toReplaceIn.hasModifierProperty(PsiModifier.PRIVATE)) {
      final AnySupers anySupers = new AnySupers();
      mySettings.getExpression().accept(anySupers);
      if (anySupers.containsSupers()) {
        for (UsageInfo usageInfo : usagesIn) {
          if (!(usageInfo.getElement() instanceof PsiMethod)
              && !(usageInfo instanceof InternalUsageInfo)) {
            if (!PsiTreeUtil.isAncestor(
                toReplaceIn.getContainingClass(), usageInfo.getElement(), false)) {
              conflicts.putValue(
                  mySettings.getExpression(),
                  RefactoringBundle.message(
                      "parameter.initializer.contains.0.but.not.all.calls.to.method.are.in.its.class",
                      CommonRefactoringUtil.htmlEmphasize(PsiKeyword.SUPER)));
              break;
            }
          }
        }
      }
    }

    for (IntroduceParameterMethodUsagesProcessor processor :
        IntroduceParameterMethodUsagesProcessor.EP_NAME.getExtensions()) {
      processor.findConflicts(this, refUsages.get(), conflicts);
    }

    return showConflicts(conflicts, usagesIn);
  }
  public GrIntroduceParameterProcessor(GrIntroduceParameterSettings settings) {
    super(settings.getProject());
    this.mySettings = settings;

    LOG.assertTrue(mySettings.getToReplaceIn() instanceof GrMethod);
    LOG.assertTrue(mySettings.getToSearchFor() instanceof PsiMethod);

    final StringPartInfo stringPartInfo = mySettings.getStringPartInfo();
    final GrExpression expression =
        stringPartInfo != null
            ? GrIntroduceHandlerBase.generateExpressionFromStringPart(
                stringPartInfo, settings.getProject())
            : mySettings.getExpression();
    myParameterInitializer = new GrExpressionWrapper(expression);
  }
  public static void processChangedMethodCall(
      PsiElement element, GrIntroduceParameterSettings settings, Project project) {
    if (!(element.getParent() instanceof GrMethodCallExpression)) {
      LOG.error(element.getParent());
      return;
    }

    GrMethodCallExpression methodCall = (GrMethodCallExpression) element.getParent();

    GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project);
    final String name = settings.getName();
    LOG.assertTrue(name != null);
    GrExpression expression = factory.createExpressionFromText(name, null);
    final GrArgumentList argList = methodCall.getArgumentList();
    final PsiElement[] exprs = argList.getAllArguments();

    if (exprs.length > 0) {
      argList.addAfter(expression, exprs[exprs.length - 1]);
    } else {
      argList.add(expression);
    }

    removeParametersFromCall(methodCall, settings);
  }
 @Override
 public boolean isDeclareFinal() {
   return mySettings.declareFinal();
 }
 @Override
 protected String getCommandName() {
   return RefactoringBundle.message(
       "introduce.parameter.command",
       DescriptiveNameUtil.getDescriptiveName(mySettings.getToReplaceIn()));
 }
 @NotNull
 @Override
 public TIntArrayList getParametersToRemove() {
   return mySettings.parametersToRemove();
 }
 @Override
 public boolean isGenerateDelegate() {
   return mySettings.generateDelegate();
 }
 @NotNull
 @Override
 public Project getProject() {
   return mySettings.getProject();
 }
  @Override
  protected void performRefactoring(UsageInfo[] usages) {
    GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);

    PsiType initializerType = mySettings.getSelectedType();

    // Changing external occurrences (the tricky part)

    IntroduceParameterUtil.processUsages(usages, this);

    final GrMethod toReplaceIn = (GrMethod) mySettings.getToReplaceIn();
    final PsiMethod toSearchFor = (PsiMethod) mySettings.getToSearchFor();

    final boolean methodsToProcessAreDifferent = toReplaceIn != toSearchFor;
    if (mySettings.generateDelegate()) {
      GroovyIntroduceParameterUtil.generateDelegate(toReplaceIn, myParameterInitializer, myProject);
      if (methodsToProcessAreDifferent) {
        final GrMethod method =
            GroovyIntroduceParameterUtil.generateDelegate(
                toSearchFor, myParameterInitializer, myProject);
        final PsiClass containingClass = method.getContainingClass();
        if (containingClass != null && containingClass.isInterface()) {
          final GrOpenBlock block = method.getBlock();
          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 == null || initializerType.isValid());

    final FieldConflictsResolver fieldConflictsResolver =
        new FieldConflictsResolver(mySettings.getName(), toReplaceIn.getBlock());
    IntroduceParameterUtil.changeMethodSignatureAndResolveFieldConflicts(
        new UsageInfo(toReplaceIn), usages, this);
    if (methodsToProcessAreDifferent) {
      IntroduceParameterUtil.changeMethodSignatureAndResolveFieldConflicts(
          new UsageInfo(toSearchFor), usages, this);
    }

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

        GroovyIntroduceParameterUtil.processChangedMethodCall(element, mySettings, myProject);
      } else if (usage instanceof InternalUsageInfo) {
        PsiElement element = usage.getElement();
        if (element == null) continue;
        GrExpression newExpr = factory.createExpressionFromText(mySettings.getName());
        if (element instanceof GrExpression) {
          ((GrExpression) element).replaceWithExpression(newExpr, true);
        } else {
          element.replace(newExpr);
        }
      }
    }

    final StringPartInfo stringPartInfo = mySettings.getStringPartInfo();
    if (stringPartInfo != null) {
      final GrExpression expr =
          GrIntroduceHandlerBase.processLiteral(
              mySettings.getName(), mySettings.getStringPartInfo(), mySettings.getProject());
      final Editor editor = PsiUtilBase.findEditor(expr);
      if (editor != null) {
        editor.getSelectionModel().removeSelection();
        editor.getCaretModel().moveToOffset(expr.getTextRange().getEndOffset());
      }
    }

    final GrVariable var = mySettings.getVar();
    if (var != null && mySettings.removeLocalVariable()) {
      var.delete();
    }
    fieldConflictsResolver.fix();
  }
 @Override
 public int getReplaceFieldsWithGetters() {
   return mySettings.replaceFieldsWithGetters();
 }
 @NotNull
 @Override
 public String getParameterName() {
   return mySettings.getName();
 }
 @NotNull
 @Override
 public PsiMethod getMethodToSearchFor() {
   return (PsiMethod) mySettings.getToSearchFor();
 }
 @Override
 public PsiMethod getMethodToReplaceIn() {
   return (PsiMethod) mySettings.getToReplaceIn();
 }