public static PsiClass extractSuperClass(final Project project,
                                           final PsiDirectory targetDirectory,
                                           final String superclassName,
                                           final PsiClass subclass,
                                           final MemberInfo[] selectedMemberInfos,
                                           final DocCommentPolicy javaDocPolicy)
    throws IncorrectOperationException {

    project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC)
      .refactoringStarted(REFACTORING_EXTRACT_SUPER_ID, createBeforeData(subclass, selectedMemberInfos));

    final PsiClass superclass = JavaDirectoryService.getInstance().createClass(targetDirectory, superclassName);
    try {
      final PsiModifierList superClassModifierList = superclass.getModifierList();
      assert superClassModifierList != null;
      superClassModifierList.setModifierProperty(PsiModifier.FINAL, false);
      final PsiReferenceList subClassExtends = subclass.getExtendsList();
      if (subClassExtends != null) {
        copyPsiReferenceList(subClassExtends, superclass.getExtendsList());
      }
      else if (subclass instanceof PsiAnonymousClass) {
        PsiJavaCodeReferenceElement classReference = ((PsiAnonymousClass)subclass).getBaseClassReference();
        PsiElement baseClass = classReference.resolve();
        if (baseClass instanceof PsiClass && ((PsiClass)baseClass).isInterface()) {
          superclass.getImplementsList().add(classReference);
        }
        else {
          superclass.getExtendsList().add(classReference);
        }
      }

      // create constructors if neccesary
      PsiMethod[] constructors = getCalledBaseConstructors(subclass);
      if (constructors.length > 0) {
        createConstructorsByPattern(project, superclass, constructors);
      }

      // clear original class' "extends" list
      if (subClassExtends != null) {
        clearPsiReferenceList(subclass.getExtendsList());
      }

      // make original class extend extracted superclass
      PsiJavaCodeReferenceElement ref = createExtendingReference(superclass, subclass, selectedMemberInfos);
      final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);
      if (subClassExtends != null) {
        codeStyleManager.reformat(subclass.getExtendsList().add(ref));
      } else if (subclass instanceof PsiAnonymousClass) {
        codeStyleManager.reformat(((PsiAnonymousClass)subclass).getBaseClassReference().replace(ref));
      }

      PullUpProcessor pullUpHelper = new PullUpProcessor(subclass, superclass, selectedMemberInfos,
                                                   javaDocPolicy
      );

      pullUpHelper.moveMembersToBase();
      pullUpHelper.moveFieldInitializations();

      Collection<MethodSignature> toImplement = OverrideImplementExploreUtil.getMethodSignaturesToImplement(superclass);
      if (!toImplement.isEmpty()) {
        superClassModifierList.setModifierProperty(PsiModifier.ABSTRACT, true);
      }
      return superclass;
    }
    finally {
      project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringDone(REFACTORING_EXTRACT_SUPER_ID, createAfterData(superclass));
    }
  }
public static PsiClass extractSuperClass(final Project project,
                                           final PsiDirectory targetDirectory,
                                           final String superclassName,
                                           final PsiClass subclass,
                                           final MemberInfo[] selectedMemberInfos,
                                           final DocCommentPolicy javaDocPolicy)