@Override
 public void visitReferenceExpression(GrReferenceExpression expression) {
   super.visitReferenceExpression(expression);
   if (expression.getCopyableUserData(SUPER_REF) != null) {
     expression.putCopyableUserData(SUPER_REF, null);
     final GrExpression qualifier = expression.getQualifier();
     if (qualifier instanceof GrReferenceExpression
         && ((GrReferenceExpression) qualifier).isReferenceTo(mySourceClass)) {
       try {
         GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
         GrExpression newExpr =
             factory.createExpressionFromText(myTargetSuperClass.getName() + ".this", null);
         expression.replace(newExpr);
       } catch (IncorrectOperationException e) {
         LOG.error(e);
       }
     }
   } else if (expression.getCopyableUserData(THIS_REF) != null) {
     expression.putCopyableUserData(THIS_REF, null);
     final GrExpression qualifier = expression.getQualifier();
     if (qualifier instanceof GrReferenceExpression
         && ((GrReferenceExpression) qualifier).isReferenceTo(mySourceClass)) {
       try {
         ((GrReferenceExpression) qualifier).bindToElement(myTargetSuperClass);
         GroovyChangeContextUtil.clearContextInfo(qualifier);
       } catch (IncorrectOperationException e) {
         LOG.error(e);
       }
     }
   }
 }
  private void doMoveMethod(PsiSubstitutor substitutor, GrMemberInfo info) {
    GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject);
    GrMethod method = (GrMethod) info.getMember();
    PsiMethod sibling = method;
    PsiMethod anchor = null;
    while (sibling != null) {
      sibling = PsiTreeUtil.getNextSiblingOfType(sibling, PsiMethod.class);
      if (sibling != null) {
        anchor =
            MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived(
                method.getContainingClass(),
                myTargetSuperClass,
                sibling.getSignature(PsiSubstitutor.EMPTY),
                false);
        if (anchor != null) {
          break;
        }
      }
    }

    GrMethod methodCopy = (GrMethod) method.copy();
    if (method.findSuperMethods(myTargetSuperClass).length == 0) {
      deleteOverrideAnnotationIfFound(methodCopy);
    }

    final boolean isOriginalMethodAbstract =
        method.hasModifierProperty(PsiModifier.ABSTRACT)
            || method.hasModifierProperty(PsiModifier.DEFAULT);
    if (myTargetSuperClass.isInterface() || info.isToAbstract()) {
      GroovyChangeContextUtil.clearContextInfo(method);
      RefactoringUtil.makeMethodAbstract(myTargetSuperClass, methodCopy);
      if (myTargetSuperClass.isInterface()) {
        PsiUtil.setModifierProperty(methodCopy, PsiModifier.ABSTRACT, false);
      }
      replaceMovedMemberTypeParameters(
          methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);

      final GrMethod movedElement =
          anchor != null
              ? (GrMethod) myTargetSuperClass.addBefore(methodCopy, anchor)
              : (GrMethod) myTargetSuperClass.add(methodCopy);
      CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(method.getProject());
      if (styleSettings.INSERT_OVERRIDE_ANNOTATION) {
        if (PsiUtil.isLanguageLevel5OrHigher(mySourceClass) && !myTargetSuperClass.isInterface()
            || PsiUtil.isLanguageLevel6OrHigher(mySourceClass)) {
          new AddAnnotationFix(CommonClassNames.JAVA_LANG_OVERRIDE, method)
              .invoke(method.getProject(), null, mySourceClass.getContainingFile());
        }
      }

      GrDocComment oldDoc = method.getDocComment();
      if (oldDoc != null) {
        GrDocCommentUtil.setDocComment(movedElement, oldDoc);
      }

      myDocCommentPolicy.processCopiedJavaDoc(
          methodCopy.getDocComment(), oldDoc, isOriginalMethodAbstract);

      myMembersAfterMove.add(movedElement);
      if (isOriginalMethodAbstract) {
        deleteMemberWithDocComment(method);
      }
    } else {
      if (isOriginalMethodAbstract) {
        PsiUtil.setModifierProperty(myTargetSuperClass, PsiModifier.ABSTRACT, true);
      }

      // fixReferencesToStatic(methodCopy, movedMembers);
      replaceMovedMemberTypeParameters(
          methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
      final PsiMethod superClassMethod =
          myTargetSuperClass.findMethodBySignature(methodCopy, false);
      final GrMethod movedElement;
      if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) {
        movedElement = (GrMethod) superClassMethod.replace(methodCopy);
      } else {
        movedElement =
            anchor != null
                ? (GrMethod) myTargetSuperClass.addBefore(methodCopy, anchor)
                : (GrMethod) myTargetSuperClass.add(methodCopy);
        myMembersAfterMove.add(movedElement);
      }

      GrDocCommentUtil.setDocComment(movedElement, method.getDocComment());

      deleteMemberWithDocComment(method);
    }
  }
  public void moveMembersToBase() throws IncorrectOperationException {
    final HashSet<PsiMember> movedMembers = ContainerUtil.newHashSet();
    myMembersAfterMove = ContainerUtil.newHashSet();

    // build aux sets
    for (GrMemberInfo info : myMembersToMove) {
      movedMembers.add(info.getMember());
    }

    // correct private member visibility
    for (GrMemberInfo info : myMembersToMove) {
      if (info.getMember() instanceof PsiClass && info.getOverrides() != null) continue;
      setCorrectVisibility(movedMembers, info);
      GroovyChangeContextUtil.encodeContextInfo(info.getMember());
      info.getMember().accept(new QualifiedThisSuperSearcher());
      fixReferencesToStatic(info.getMember(), movedMembers);
    }

    final PsiSubstitutor substitutor = upDownSuperClassSubstitutor();

    // do actual move
    for (GrMemberInfo info : myMembersToMove) {
      if (info.getMember() instanceof PsiMethod) {
        doMoveMethod(substitutor, info);
      } else if (info.getMember() instanceof GrField) {
        doMoveField(substitutor, info);
      } else if (info.getMember() instanceof PsiClass) {
        doMoveClass(substitutor, info);
      }
    }

    ExplicitSuperDeleter explicitSuperDeleter = new ExplicitSuperDeleter();
    for (PsiMember member : myMembersAfterMove) {
      ((GrMember) member).accept(explicitSuperDeleter);
    }
    explicitSuperDeleter.fixSupers();

    final QualifiedThisSuperAdjuster qualifiedThisSuperAdjuster = new QualifiedThisSuperAdjuster();
    for (PsiMember member : myMembersAfterMove) {
      ((GrMember) member).accept(qualifiedThisSuperAdjuster);
    }

    for (PsiMember member : myMembersAfterMove) {
      GroovyChangeContextUtil.decodeContextInfo(member, null, null);
    }

    final JavaRefactoringListenerManagerImpl listenerManager =
        (JavaRefactoringListenerManagerImpl) JavaRefactoringListenerManager.getInstance(myProject);
    for (final PsiMember movedMember : myMembersAfterMove) {
      ((GroovyPsiElement) movedMember)
          .accept(
              new GroovyRecursiveElementVisitor() {
                @Override
                public void visitReferenceExpression(GrReferenceExpression referenceExpression) {
                  if (processRef(referenceExpression)) return;
                  super.visitReferenceExpression(referenceExpression);
                }

                @Override
                public void visitCodeReferenceElement(GrCodeReferenceElement refElement) {
                  if (processRef(refElement)) return;
                  super.visitCodeReferenceElement(refElement);
                }

                private boolean processRef(
                    @NotNull GrReferenceElement<? extends GroovyPsiElement> refElement) {
                  final PsiElement qualifier = refElement.getQualifier();
                  if (qualifier != null) {
                    final Boolean preserveQualifier =
                        qualifier.getCopyableUserData(PRESERVE_QUALIFIER);
                    if (preserveQualifier != null && !preserveQualifier) {
                      refElement.setQualifier(null);
                      return true;
                    }
                  }
                  return false;
                }
              });
      listenerManager.fireMemberMoved(mySourceClass, movedMember);
    }
  }