private static void replaceReferences(
     List<PsiReferenceExpression> references, PsiElement newExpression)
     throws IncorrectOperationException {
   for (PsiReferenceExpression reference : references) {
     reference.replace(newExpression);
   }
 }
 private static void retargetReferences(
     final PsiElementFactory elementFactory,
     final String localName,
     final Set<PsiReference> refs)
     throws IncorrectOperationException {
   final PsiReferenceExpression refExpr =
       (PsiReferenceExpression) elementFactory.createExpressionFromText(localName, null);
   for (PsiReference ref : refs) {
     if (ref instanceof PsiReferenceExpression) {
       ((PsiReferenceExpression) ref).replace(refExpr);
     }
   }
 }
 public static PsiReferenceExpression qualifyReference(
     PsiReferenceExpression referenceExpression,
     final PsiMember member,
     @Nullable final PsiClass qualifyingClass)
     throws IncorrectOperationException {
   PsiManager manager = referenceExpression.getManager();
   PsiMethodCallExpression methodCallExpression =
       PsiTreeUtil.getParentOfType(referenceExpression, PsiMethodCallExpression.class, true);
   while ((methodCallExpression) != null) {
     if (HighlightUtil.isSuperOrThisMethodCall(methodCallExpression)) {
       return referenceExpression;
     }
     methodCallExpression =
         PsiTreeUtil.getParentOfType(methodCallExpression, PsiMethodCallExpression.class, true);
   }
   PsiReferenceExpression expressionFromText;
   final PsiElementFactory factory =
       JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
   if (qualifyingClass == null) {
     PsiClass parentClass = PsiTreeUtil.getParentOfType(referenceExpression, PsiClass.class);
     final PsiClass containingClass = member.getContainingClass();
     if (parentClass != null
         && !InheritanceUtil.isInheritorOrSelf(parentClass, containingClass, true)) {
       while (parentClass != null
           && !InheritanceUtil.isInheritorOrSelf(parentClass, containingClass, true)) {
         parentClass = PsiTreeUtil.getParentOfType(parentClass, PsiClass.class, true);
       }
       LOG.assertTrue(parentClass != null);
       expressionFromText =
           (PsiReferenceExpression)
               factory.createExpressionFromText("A.this." + member.getName(), null);
       ((PsiThisExpression) expressionFromText.getQualifierExpression())
           .getQualifier()
           .replace(factory.createClassReferenceElement(parentClass));
     } else {
       expressionFromText =
           (PsiReferenceExpression)
               factory.createExpressionFromText("this." + member.getName(), null);
     }
   } else {
     expressionFromText =
         (PsiReferenceExpression) factory.createExpressionFromText("A." + member.getName(), null);
     expressionFromText.setQualifierExpression(factory.createReferenceExpression(qualifyingClass));
   }
   CodeStyleManager codeStyleManager = manager.getCodeStyleManager();
   expressionFromText = (PsiReferenceExpression) codeStyleManager.reformat(expressionFromText);
   return (PsiReferenceExpression) referenceExpression.replace(expressionFromText);
 }
 @Override
 public void invoke(
     @NotNull Project project,
     @NotNull PsiFile file,
     @Nullable("is null when called from inspection") Editor editor,
     @NotNull PsiElement startElement,
     @NotNull PsiElement endElement) {
   PsiReferenceExpression place = (PsiReferenceExpression) startElement;
   String qualifier = null;
   final PsiExpression qualifierExpression = place.getQualifierExpression();
   if (qualifierExpression != null) {
     qualifier = qualifierExpression.getText();
   }
   PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
   PsiMethodCallExpression callExpression;
   final String call = (qualifier != null ? qualifier + "." : "") + myMethodName;
   if (!myIsSetter) {
     callExpression =
         (PsiMethodCallExpression) elementFactory.createExpressionFromText(call + "()", null);
     callExpression =
         (PsiMethodCallExpression) CodeStyleManager.getInstance(project).reformat(callExpression);
     place.replace(callExpression);
   } else {
     PsiElement parent = PsiTreeUtil.skipParentsOfType(place, PsiParenthesizedExpression.class);
     if (parent instanceof PsiAssignmentExpression) {
       final PsiExpression rExpression = ((PsiAssignmentExpression) parent).getRExpression();
       final String argList = rExpression != null ? rExpression.getText() : "";
       callExpression =
           (PsiMethodCallExpression)
               elementFactory.createExpressionFromText(call + "(" + argList + ")", null);
       callExpression =
           (PsiMethodCallExpression)
               CodeStyleManager.getInstance(project).reformat(callExpression);
       parent.replace(callExpression);
     }
   }
 }
  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);
    }
  }
  public boolean processUsage(
      @NotNull EncapsulateFieldUsageInfo usage,
      @NotNull EncapsulateFieldsDescriptor descriptor,
      PsiMethod setter,
      PsiMethod getter) {
    final PsiElement element = usage.getElement();
    if (!(element instanceof PsiReferenceExpression)) return false;

    final FieldDescriptor fieldDescriptor = usage.getFieldDescriptor();
    PsiField field = fieldDescriptor.getField();
    boolean processGet = descriptor.isToEncapsulateGet();
    boolean processSet =
        descriptor.isToEncapsulateSet() && !field.hasModifierProperty(PsiModifier.FINAL);
    if (!processGet && !processSet) return true;
    PsiElementFactory factory =
        JavaPsiFacade.getInstance(descriptor.getTargetClass().getProject()).getElementFactory();

    try {
      final PsiReferenceExpression expr = (PsiReferenceExpression) element;
      final PsiElement parent = expr.getParent();
      if (parent instanceof PsiAssignmentExpression
          && expr.equals(((PsiAssignmentExpression) parent).getLExpression())) {
        PsiAssignmentExpression assignment = (PsiAssignmentExpression) parent;
        if (assignment.getRExpression() == null) return true;
        PsiJavaToken opSign = assignment.getOperationSign();
        IElementType opType = opSign.getTokenType();
        if (opType == JavaTokenType.EQ) {
          {
            if (!processSet) return true;
            final PsiExpression setterArgument = assignment.getRExpression();

            PsiMethodCallExpression methodCall =
                createSetterCall(
                    fieldDescriptor, setterArgument, expr, descriptor.getTargetClass(), setter);

            if (methodCall != null) {
              assignment.replace(methodCall);
            }
            // TODO: check if value is used!!!
          }
        } else if (opType == JavaTokenType.ASTERISKEQ
            || opType == JavaTokenType.DIVEQ
            || opType == JavaTokenType.PERCEQ
            || opType == JavaTokenType.PLUSEQ
            || opType == JavaTokenType.MINUSEQ
            || opType == JavaTokenType.LTLTEQ
            || opType == JavaTokenType.GTGTEQ
            || opType == JavaTokenType.GTGTGTEQ
            || opType == JavaTokenType.ANDEQ
            || opType == JavaTokenType.OREQ
            || opType == JavaTokenType.XOREQ) {
          {
            // Q: side effects of qualifier??!

            String opName = opSign.getText();
            LOG.assertTrue(StringUtil.endsWithChar(opName, '='));
            opName = opName.substring(0, opName.length() - 1);

            PsiExpression getExpr = expr;
            if (processGet) {
              final PsiMethodCallExpression getterCall =
                  createGetterCall(fieldDescriptor, expr, descriptor.getTargetClass(), getter);
              if (getterCall != null) {
                getExpr = getterCall;
              }
            }

            @NonNls String text = "a" + opName + "b";
            PsiBinaryExpression binExpr =
                (PsiBinaryExpression) factory.createExpressionFromText(text, expr);
            binExpr.getLOperand().replace(getExpr);
            binExpr.getROperand().replace(assignment.getRExpression());

            PsiExpression setExpr;
            if (processSet) {
              setExpr =
                  createSetterCall(
                      fieldDescriptor, binExpr, expr, descriptor.getTargetClass(), setter);
            } else {
              text = "a = b";
              PsiAssignmentExpression assignment1 =
                  (PsiAssignmentExpression) factory.createExpressionFromText(text, null);
              assignment1.getLExpression().replace(expr);
              assignment1.getRExpression().replace(binExpr);
              setExpr = assignment1;
            }

            assignment.replace(setExpr);
            // TODO: check if value is used!!!
          }
        }
      } else if (RefactoringUtil.isPlusPlusOrMinusMinus(parent)) {
        IElementType sign;
        if (parent instanceof PsiPrefixExpression) {
          sign = ((PsiPrefixExpression) parent).getOperationTokenType();
        } else {
          sign = ((PsiPostfixExpression) parent).getOperationTokenType();
        }

        PsiExpression getExpr = expr;
        if (processGet) {
          final PsiMethodCallExpression getterCall =
              createGetterCall(fieldDescriptor, expr, descriptor.getTargetClass(), getter);
          if (getterCall != null) {
            getExpr = getterCall;
          }
        }

        @NonNls String text;
        if (sign == JavaTokenType.PLUSPLUS) {
          text = "a+1";
        } else {
          text = "a-1";
        }
        PsiBinaryExpression binExpr =
            (PsiBinaryExpression) factory.createExpressionFromText(text, null);
        binExpr.getLOperand().replace(getExpr);

        PsiExpression setExpr;
        if (processSet) {
          setExpr =
              createSetterCall(fieldDescriptor, binExpr, expr, descriptor.getTargetClass(), setter);
        } else {
          text = "a = b";
          PsiAssignmentExpression assignment =
              (PsiAssignmentExpression) factory.createExpressionFromText(text, null);
          assignment.getLExpression().replace(expr);
          assignment.getRExpression().replace(binExpr);
          setExpr = assignment;
        }
        parent.replace(setExpr);
      } else {
        if (!processGet) return true;
        PsiMethodCallExpression methodCall =
            createGetterCall(fieldDescriptor, expr, descriptor.getTargetClass(), getter);

        if (methodCall != null) {
          expr.replace(methodCall);
        }
      }
    } catch (IncorrectOperationException e) {
      LOG.error(e);
    }
    return true;
  }