private void doMoveClass(PsiSubstitutor substitutor, GrMemberInfo info) {
    GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject);
    GrTypeDefinition aClass = (GrTypeDefinition) info.getMember();
    if (Boolean.FALSE.equals(info.getOverrides())) {
      final GrReferenceList sourceReferenceList = info.getSourceReferenceList();
      LOG.assertTrue(sourceReferenceList != null);
      GrCodeReferenceElement ref =
          mySourceClass.equals(sourceReferenceList.getParent())
              ? removeFromReferenceList(sourceReferenceList, aClass)
              : findReferenceToClass(sourceReferenceList, aClass);
      if (ref != null && !myTargetSuperClass.isInheritor(aClass, false)) {
        replaceMovedMemberTypeParameters(
            ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
        GrReferenceList referenceList;
        if (myTargetSuperClass.isInterface()) {
          referenceList = myTargetSuperClass.getExtendsClause();
          if (referenceList == null) {
            GrExtendsClause newClause =
                GroovyPsiElementFactory.getInstance(myProject).createExtendsClause();
            PsiElement anchor =
                myTargetSuperClass.getTypeParameterList() != null
                    ? myTargetSuperClass.getTypeParameterList()
                    : myTargetSuperClass.getNameIdentifierGroovy();
            referenceList = (GrReferenceList) myTargetSuperClass.addAfter(newClause, anchor);
            addSpacesAround(referenceList);
          }
        } else {
          referenceList = myTargetSuperClass.getImplementsClause();

          if (referenceList == null) {
            GrImplementsClause newClause =
                GroovyPsiElementFactory.getInstance(myProject).createImplementsClause();
            PsiElement anchor =
                myTargetSuperClass.getExtendsClause() != null
                    ? myTargetSuperClass.getExtendsClause()
                    : myTargetSuperClass.getTypeParameterList() != null
                        ? myTargetSuperClass.getTypeParameterList()
                        : myTargetSuperClass.getNameIdentifierGroovy();
            referenceList = (GrReferenceList) myTargetSuperClass.addAfter(newClause, anchor);
            addSpacesAround(referenceList);
          }
        }

        assert referenceList != null;
        referenceList.add(ref);
      }
    } else {
      replaceMovedMemberTypeParameters(
          aClass, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
      // fixReferencesToStatic(aClass, movedMembers);
      PsiMember movedElement = (PsiMember) myTargetSuperClass.addAfter(aClass, null);
      // movedElement = (PsiMember)CodeStyleManager.getInstance(myProject).reformat(movedElement);
      myMembersAfterMove.add(movedElement);
      deleteMemberWithDocComment(aClass);
    }
  }
  @NotNull
  @Override
  protected UsageInfo[] findUsages() {
    final List<UsageInfo> result = new ArrayList<UsageInfo>();
    for (GrMemberInfo info : myMembersToMove) {
      final PsiMember member = info.getMember();
      if (member.hasModifierProperty(PsiModifier.STATIC)) {
        for (PsiReference reference : ReferencesSearch.search(member)) {
          result.add(new UsageInfo(reference));
        }
      }
    }

    return DefaultGroovyMethods.asType(result, UsageInfo[].class);
  }
  public void setCorrectVisibility(final HashSet<PsiMember> movedMembers, GrMemberInfo info) {
    PsiModifierListOwner modifierListOwner = info.getMember();
    if (myTargetSuperClass.isInterface()) {
      PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PUBLIC, true);
    } else if (modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE)) {
      if (info.isToAbstract()
          || willBeUsedInSubclass(
              modifierListOwner, movedMembers, myTargetSuperClass, mySourceClass)) {
        PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PROTECTED, true);
      }

      if (modifierListOwner instanceof GrTypeDefinition) {
        ((GrTypeDefinition) modifierListOwner)
            .accept(
                new GroovyRecursiveElementVisitor() {
                  @Override
                  public void visitMethod(GrMethod method) {
                    check(method);
                  }

                  @Override
                  public void visitField(GrField field) {
                    check(field);
                  }

                  @Override
                  public void visitTypeDefinition(GrTypeDefinition typeDefinition) {
                    check(typeDefinition);
                    super.visitTypeDefinition(typeDefinition);
                  }

                  private void check(PsiMember member) {
                    if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
                      if (willBeUsedInSubclass(
                          member, movedMembers, myTargetSuperClass, mySourceClass)) {
                        PsiUtil.setModifierProperty(member, PsiModifier.PROTECTED, true);
                      }
                    }
                  }
                });
      }
    }
  }
 private void doMoveField(PsiSubstitutor substitutor, GrMemberInfo info) {
   GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject);
   GrField field = (GrField) info.getMember();
   field.normalizeDeclaration();
   replaceMovedMemberTypeParameters(
       field, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
   // fixReferencesToStatic(field, movedMembers);
   if (myTargetSuperClass.isInterface()) {
     PsiUtil.setModifierProperty(field, PsiModifier.PUBLIC, true);
   }
   final PsiMember movedElement = (PsiMember) myTargetSuperClass.add(field);
   myMembersAfterMove.add(movedElement);
   deleteMemberWithDocComment(field);
 }
  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);
    }
  }