@Override
    public int compare(PsiVariable o1, PsiVariable o2) {

      if (o1 instanceof PsiParameter && ((PsiParameter) o1).isVarArgs()) return 1;
      if (o2 instanceof PsiParameter && ((PsiParameter) o2).isVarArgs()) return -1;

      if (o1 instanceof PsiField && o2 instanceof PsiField) {
        return o1.getTextOffset() - o2.getTextOffset();
      }
      if (o1 instanceof PsiParameter && o2 instanceof PsiParameter) {
        return myParameterList.getParameterIndex((PsiParameter) o1)
            - myParameterList.getParameterIndex((PsiParameter) o2);
      }

      if (o1 instanceof PsiField && o2 instanceof PsiParameter) {
        final PsiField field =
            FieldFromParameterUtils.getParameterAssignedToField((PsiParameter) o2);
        if (field == null) return 1;
        return o1.getTextOffset() - field.getTextOffset();
      }
      if (o1 instanceof PsiParameter && o2 instanceof PsiField) {
        final PsiField field =
            FieldFromParameterUtils.getParameterAssignedToField((PsiParameter) o1);
        if (field == null) return -1;
        return field.getTextOffset() - o2.getTextOffset();
      }

      return 0;
    }
  private static boolean addParameterToConstructor(
      final Project project,
      final PsiFile file,
      final Editor editor,
      final PsiMethod constructor,
      final PsiField[] fields)
      throws IncorrectOperationException {
    final PsiParameterList parameterList = constructor.getParameterList();
    final PsiParameter[] parameters = parameterList.getParameters();
    ParameterInfoImpl[] newParamInfos = new ParameterInfoImpl[parameters.length + fields.length];
    final List<PsiVariable> params = new ArrayList<PsiVariable>(Arrays.asList(parameters));
    Collections.addAll(params, fields);
    Collections.sort(params, new FieldParameterComparator(parameterList));

    int i = 0;
    final HashMap<PsiField, String> usedFields = new HashMap<PsiField, String>();
    for (PsiVariable param : params) {
      final PsiType paramType = param.getType();
      if (param instanceof PsiParameter) {
        newParamInfos[i++] =
            new ParameterInfoImpl(
                parameterList.getParameterIndex((PsiParameter) param),
                param.getName(),
                paramType,
                param.getName());
      } else {
        final String uniqueParameterName = getUniqueParameterName(parameters, param, usedFields);
        usedFields.put((PsiField) param, uniqueParameterName);
        newParamInfos[i++] =
            new ParameterInfoImpl(-1, uniqueParameterName, paramType, uniqueParameterName);
      }
    }
    final SmartPointerManager manager = SmartPointerManager.getInstance(project);
    final SmartPsiElementPointer constructorPointer =
        manager.createSmartPsiElementPointer(constructor);

    final PsiMethod fromText =
        JavaPsiFacade.getElementFactory(project)
            .createMethodFromText(createDummyMethod(constructor, newParamInfos), constructor);
    final PsiClass containingClass = constructor.getContainingClass();
    if (containingClass == null) return false;
    final int minUsagesNumber =
        containingClass.findMethodsBySignature(fromText, false).length > 0 ? 0 : 1;
    final List<ParameterInfoImpl> parameterInfos =
        ChangeMethodSignatureFromUsageFix.performChange(
            project, editor, file, constructor, minUsagesNumber, newParamInfos, true, true);

    final ParameterInfoImpl[] resultParams =
        parameterInfos != null
            ? parameterInfos.toArray(new ParameterInfoImpl[parameterInfos.size()])
            : newParamInfos;
    return ApplicationManager.getApplication()
        .runWriteAction(
            new Computable<Boolean>() {
              @Override
              public Boolean compute() {
                return doCreate(
                    project, editor, parameters, constructorPointer, resultParams, usedFields);
              }
            });
  }
  public void inlineElement(
      final Project project, final Editor editor, final PsiElement psiElement) {
    final PsiParameter psiParameter = (PsiParameter) psiElement;
    final PsiParameterList parameterList = (PsiParameterList) psiParameter.getParent();
    if (!(parameterList.getParent() instanceof PsiMethod)) {
      return;
    }
    final int index = parameterList.getParameterIndex(psiParameter);
    final PsiMethod method = (PsiMethod) parameterList.getParent();

    String errorMessage = getCannotInlineMessage(psiParameter, method);
    if (errorMessage != null) {
      CommonRefactoringUtil.showErrorHint(
          project,
          editor,
          errorMessage,
          RefactoringBundle.message("inline.parameter.refactoring"),
          null);
      return;
    }

    final Ref<PsiExpression> refInitializer = new Ref<PsiExpression>();
    final Ref<PsiExpression> refConstantInitializer = new Ref<PsiExpression>();
    final Ref<PsiCallExpression> refMethodCall = new Ref<PsiCallExpression>();
    final List<PsiReference> occurrences =
        Collections.synchronizedList(new ArrayList<PsiReference>());
    final Collection<PsiFile> containingFiles = Collections.synchronizedSet(new HashSet<PsiFile>());
    containingFiles.add(psiParameter.getContainingFile());
    boolean result =
        ReferencesSearch.search(method)
            .forEach(
                new Processor<PsiReference>() {
                  public boolean process(final PsiReference psiReference) {
                    PsiElement element = psiReference.getElement();
                    final PsiElement parent = element.getParent();
                    if (parent instanceof PsiCallExpression) {
                      final PsiCallExpression methodCall = (PsiCallExpression) parent;
                      occurrences.add(psiReference);
                      containingFiles.add(element.getContainingFile());
                      final PsiExpression[] expressions =
                          methodCall.getArgumentList().getExpressions();
                      if (expressions.length <= index) return false;
                      PsiExpression argument = expressions[index];
                      if (!refInitializer.isNull()) {
                        return argument != null
                            && PsiEquivalenceUtil.areElementsEquivalent(
                                refInitializer.get(), argument)
                            && PsiEquivalenceUtil.areElementsEquivalent(
                                refMethodCall.get(), methodCall);
                      }
                      if (InlineToAnonymousConstructorProcessor.isConstant(argument)
                          || getReferencedFinalField(argument) != null) {
                        if (refConstantInitializer.isNull()) {
                          refConstantInitializer.set(argument);
                        } else if (!isSameConstant(argument, refConstantInitializer.get())) {
                          return false;
                        }
                      } else if (!isRecursiveReferencedParameter(argument, psiParameter)) {
                        if (!refConstantInitializer.isNull()) return false;
                        refInitializer.set(argument);
                        refMethodCall.set(methodCall);
                      }
                    }
                    return true;
                  }
                });
    final int offset = editor.getCaretModel().getOffset();
    final PsiElement refExpr = psiElement.getContainingFile().findElementAt(offset);
    final PsiCodeBlock codeBlock = PsiTreeUtil.getParentOfType(refExpr, PsiCodeBlock.class);
    if (codeBlock != null) {
      final PsiElement[] defs = DefUseUtil.getDefs(codeBlock, psiParameter, refExpr);
      if (defs.length == 1) {
        final PsiElement def = defs[0];
        if (def instanceof PsiReferenceExpression
            && PsiUtil.isOnAssignmentLeftHand((PsiExpression) def)) {
          final PsiExpression rExpr = ((PsiAssignmentExpression) def.getParent()).getRExpression();
          if (rExpr != null) {
            final PsiElement[] refs = DefUseUtil.getRefs(codeBlock, psiParameter, refExpr);

            if (InlineLocalHandler.checkRefsInAugmentedAssignmentOrUnaryModified(refs, def)
                == null) {
              new WriteCommandAction(project) {
                @Override
                protected void run(Result result) throws Throwable {
                  for (final PsiElement ref : refs) {
                    InlineUtil.inlineVariable(
                        psiParameter, rExpr, (PsiJavaCodeReferenceElement) ref);
                  }
                  def.getParent().delete();
                }
              }.execute();
              return;
            }
          }
        }
      }
    }
    if (occurrences.isEmpty()) {
      CommonRefactoringUtil.showErrorHint(
          project,
          editor,
          "Method has no usages",
          RefactoringBundle.message("inline.parameter.refactoring"),
          null);
      return;
    }
    if (!result) {
      CommonRefactoringUtil.showErrorHint(
          project,
          editor,
          "Cannot find constant initializer for parameter",
          RefactoringBundle.message("inline.parameter.refactoring"),
          null);
      return;
    }
    if (!refInitializer.isNull()) {
      if (ApplicationManager.getApplication().isUnitTestMode()) {
        final InlineParameterExpressionProcessor processor =
            new InlineParameterExpressionProcessor(
                refMethodCall.get(),
                method,
                psiParameter,
                refInitializer.get(),
                method
                    .getProject()
                    .getUserData(InlineParameterExpressionProcessor.CREATE_LOCAL_FOR_TESTS));
        processor.run();
      } else {
        final boolean createLocal = ReferencesSearch.search(psiParameter).findAll().size() > 1;
        InlineParameterDialog dlg =
            new InlineParameterDialog(
                refMethodCall.get(), method, psiParameter, refInitializer.get(), createLocal);
        dlg.show();
      }
      return;
    }
    if (refConstantInitializer.isNull()) {
      CommonRefactoringUtil.showErrorHint(
          project,
          editor,
          "Cannot find constant initializer for parameter",
          RefactoringBundle.message("inline.parameter.refactoring"),
          null);
      return;
    }

    final Ref<Boolean> isNotConstantAccessible = new Ref<Boolean>();
    final PsiExpression constantExpression = refConstantInitializer.get();
    constantExpression.accept(
        new JavaRecursiveElementVisitor() {
          @Override
          public void visitReferenceExpression(PsiReferenceExpression expression) {
            super.visitReferenceExpression(expression);
            final PsiElement resolved = expression.resolve();
            if (resolved instanceof PsiMember
                && !PsiUtil.isAccessible((PsiMember) resolved, method, null)) {
              isNotConstantAccessible.set(Boolean.TRUE);
            }
          }
        });
    if (!isNotConstantAccessible.isNull() && isNotConstantAccessible.get()) {
      CommonRefactoringUtil.showErrorHint(
          project,
          editor,
          "Constant initializer is not accessible in method body",
          RefactoringBundle.message("inline.parameter.refactoring"),
          null);
      return;
    }

    for (PsiReference psiReference : ReferencesSearch.search(psiParameter)) {
      final PsiElement element = psiReference.getElement();
      if (element instanceof PsiExpression
          && PsiUtil.isAccessedForWriting((PsiExpression) element)) {
        CommonRefactoringUtil.showErrorHint(
            project,
            editor,
            "Inline parameter which has write usages is not supported",
            RefactoringBundle.message("inline.parameter.refactoring"),
            null);
        return;
      }
    }

    if (!ApplicationManager.getApplication().isUnitTestMode()) {
      String occurencesString = RefactoringBundle.message("occurences.string", occurrences.size());
      String question =
          RefactoringBundle.message(
                  "inline.parameter.confirmation",
                  psiParameter.getName(),
                  constantExpression.getText())
              + " "
              + occurencesString;
      RefactoringMessageDialog dialog =
          new RefactoringMessageDialog(
              REFACTORING_NAME,
              question,
              HelpID.INLINE_VARIABLE,
              "OptionPane.questionIcon",
              true,
              project);
      dialog.show();
      if (!dialog.isOK()) {
        return;
      }
    }

    final RefactoringEventData data = new RefactoringEventData();
    data.addElement(psiElement.copy());
    project
        .getMessageBus()
        .syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC)
        .refactoringStarted(REFACTORING_ID, data);

    SameParameterValueInspection.InlineParameterValueFix.inlineSameParameterValue(
        method, psiParameter, constantExpression);

    project
        .getMessageBus()
        .syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC)
        .refactoringDone(REFACTORING_ID, null);
  }