private static PsiReferenceExpression decodeReferenceExpression(@NotNull PsiReferenceExpression refExpr,
                                                                  PsiExpression thisAccessExpr,
                                                                  PsiClass thisClass) throws IncorrectOperationException {
    PsiManager manager = refExpr.getManager();
    PsiElementFactory factory = JavaPsiFacade.getElementFactory(manager.getProject());

    PsiExpression qualifier = refExpr.getQualifierExpression();
    if (qualifier == null){
      PsiMember refMember = refExpr.getCopyableUserData(REF_MEMBER_KEY);
      refExpr.putCopyableUserData(REF_MEMBER_KEY, null);

      if (refMember != null && refMember.isValid()){
        PsiClass containingClass = refMember.getContainingClass();
        if (containingClass != null && containingClass.isValid() && refMember.hasModifierProperty(PsiModifier.STATIC)){
          PsiElement refElement = refExpr.resolve();
          if (!manager.areElementsEquivalent(refMember, refElement)){
            final PsiClass currentClass = PsiTreeUtil.getParentOfType(refExpr, PsiClass.class);
            if (currentClass == null || !InheritanceUtil.isInheritorOrSelf(currentClass, containingClass, true)) {
              refExpr.setQualifierExpression(factory.createReferenceExpression(containingClass));
            }
          }
        }
        else {
          final PsiClass realParentClass = refExpr.getCopyableUserData(REF_MEMBER_THIS_CLASS_KEY);
          refExpr.putCopyableUserData(REF_MEMBER_THIS_CLASS_KEY, null);
          if (thisAccessExpr != null && thisClass != null && realParentClass != null &&
              InheritanceUtil.isInheritorOrSelf(thisClass, realParentClass, true)) {
            boolean needQualifier = true;
            PsiElement refElement = refExpr.resolve();
            if (refMember.equals(refElement) ||
                (refElement instanceof PsiMethod && refMember instanceof PsiMethod &&
                 MethodSignatureUtil.isSuperMethod((PsiMethod)refMember, (PsiMethod)refElement))) {
              if (thisAccessExpr instanceof PsiThisExpression && ((PsiThisExpression)thisAccessExpr).getQualifier() == null) {
                //Trivial qualifier
                needQualifier = false;
              }
              else {
                final PsiClass currentClass = findThisClass(refExpr, refMember);
                if (thisAccessExpr instanceof PsiThisExpression){
                  PsiJavaCodeReferenceElement thisQualifier = ((PsiThisExpression)thisAccessExpr).getQualifier();
                  PsiClass thisExprClass = thisQualifier != null
                                           ? (PsiClass)thisQualifier.resolve()
                                           : RefactoringChangeUtil.getThisClass(refExpr);
                  if (thisExprClass != null && (thisExprClass.equals(currentClass) || thisExprClass.isInheritor(realParentClass, true))){ // qualifier is not necessary
                    needQualifier = false;
                  }
                }
              }
            }

            if (needQualifier){
              refExpr.setQualifierExpression(thisAccessExpr);
            }
          }
          else if (thisClass != null && realParentClass != null && PsiTreeUtil.isAncestor(realParentClass, thisClass, true)) {
            PsiElement refElement = refExpr.resolve();
            if (refElement != null && !manager.areElementsEquivalent(refMember, refElement)) {
              refExpr = RefactoringChangeUtil.qualifyReference(refExpr, refMember, null);
            }
          }
        }
      }
      else {
        PsiClass refClass = refExpr.getCopyableUserData(REF_CLASS_KEY);
        refExpr.putCopyableUserData(REF_CLASS_KEY, null);
        if (refClass != null && refClass.isValid()){
          refExpr = (PsiReferenceExpression)refExpr.bindToElement(refClass);
        }
      }
    }
    else{
      Boolean couldRemove = refExpr.getCopyableUserData(CAN_REMOVE_QUALIFIER_KEY);
      refExpr.putCopyableUserData(CAN_REMOVE_QUALIFIER_KEY, null);

      if (couldRemove == Boolean.FALSE && canRemoveQualifier(refExpr)){
        PsiReferenceExpression newRefExpr = (PsiReferenceExpression)factory.createExpressionFromText(
          refExpr.getReferenceName(), null);
        refExpr = (PsiReferenceExpression)refExpr.replace(newRefExpr);
      }
    }
    return refExpr;
  }
private static PsiReferenceExpression decodeReferenceExpression(@NotNull PsiReferenceExpression refExpr,
                                                                  PsiExpression thisAccessExpr,
                                                                  PsiClass thisClass)