@Override
 protected MemberChooser<ClassMember> createMembersChooser(
     ClassMember[] members,
     boolean allowEmptySelection,
     boolean copyJavadocCheckbox,
     Project project) {
   final MemberChooser<ClassMember> chooser =
       super.createMembersChooser(members, allowEmptySelection, copyJavadocCheckbox, project);
   final List<ClassMember> preselection = preselect(members);
   if (!preselection.isEmpty()) {
     chooser.selectElements(preselection.toArray(new ClassMember[preselection.size()]));
   }
   return chooser;
 }
 @Nullable
 @Override
 protected ClassMember[] chooseMembers(
     ClassMember[] classMembers,
     boolean allowEmptySelection,
     boolean copyJavadocCheckbox,
     Project project,
     @Nullable Editor editor) {
   MemberChooser<ClassMember> chooser =
       new MemberChooser<ClassMember>(classMembers, allowEmptySelection, true, project);
   chooser.setTitle("Select Fields to Generate With Methods");
   chooser.setCopyJavadocVisible(copyJavadocCheckbox);
   chooser.show();
   myToCopyJavaDoc = chooser.isCopyJavadoc();
   List<ClassMember> list = chooser.getSelectedElements();
   return list == null ? null : list.toArray(new ClassMember[list.size()]);
 }
  @NotNull
  public static List<MavenDomDependency> chooseDependencies(
      Collection<MavenDomDependency> candidates, final Project project) {
    List<MavenDomDependency> dependencies = new ArrayList<MavenDomDependency>();

    MavenDomProjectModelMember[] memberCandidates =
        ContainerUtil.map2Array(
            candidates,
            MavenDomProjectModelMember.class,
            dependency -> new MavenDomProjectModelMember(dependency));
    MemberChooser<MavenDomProjectModelMember> chooser =
        new MemberChooser<MavenDomProjectModelMember>(memberCandidates, true, true, project) {
          protected ShowContainersAction getShowContainersAction() {
            return new ShowContainersAction(
                MavenDomBundle.message("chooser.show.project.files"), MavenIcons.MavenProject);
          }

          @NotNull
          @Override
          protected String convertElementText(@NotNull String originalElementText) {
            return originalElementText;
          }

          protected String getAllContainersNodeName() {
            return MavenDomBundle.message("all.dependencies");
          }
        };

    chooser.setTitle(MavenDomBundle.message("dependencies.chooser.title"));
    chooser.setCopyJavadocVisible(false);
    chooser.show();

    if (chooser.getExitCode() == MemberChooser.OK_EXIT_CODE) {
      final MavenDomProjectModelMember[] members =
          chooser.getSelectedElements(new MavenDomProjectModelMember[0]);
      if (members != null) {
        dependencies.addAll(
            ContainerUtil.mapNotNull(
                members, mavenDomProjectModelMember -> mavenDomProjectModelMember.getDependency()));
      }
    }

    return dependencies;
  }
  @Override
  @Nullable
  protected ClassMember[] chooseOriginalMembers(PsiClass aClass, Project project) {
    if (aClass instanceof PsiAnonymousClass) {
      Messages.showMessageDialog(
          project,
          CodeInsightBundle.message("error.attempt.to.generate.constructor.for.anonymous.class"),
          CommonBundle.getErrorTitle(),
          Messages.getErrorIcon());
      return null;
    }

    myCopyJavadoc = false;
    PsiMethod[] baseConstructors = null;
    PsiClass baseClass = aClass.getSuperClass();
    if (baseClass != null) {
      ArrayList<PsiMethod> array = new ArrayList<PsiMethod>();
      for (PsiMethod method : baseClass.getConstructors()) {
        if (JavaPsiFacade.getInstance(method.getProject())
            .getResolveHelper()
            .isAccessible(method, aClass, null)) {
          array.add(method);
        }
      }
      if (!array.isEmpty()) {
        if (array.size() == 1) {
          baseConstructors = new PsiMethod[] {array.get(0)};
        } else {
          final PsiSubstitutor substitutor =
              TypeConversionUtil.getSuperClassSubstitutor(baseClass, aClass, PsiSubstitutor.EMPTY);
          PsiMethodMember[] constructors =
              ContainerUtil.map2Array(
                  array,
                  PsiMethodMember.class,
                  new Function<PsiMethod, PsiMethodMember>() {
                    @Override
                    public PsiMethodMember fun(final PsiMethod s) {
                      return new PsiMethodMember(s, substitutor);
                    }
                  });
          MemberChooser<PsiMethodMember> chooser =
              new MemberChooser<PsiMethodMember>(constructors, false, true, project);
          chooser.setTitle(
              CodeInsightBundle.message("generate.constructor.super.constructor.chooser.title"));
          chooser.show();
          List<PsiMethodMember> elements = chooser.getSelectedElements();
          if (elements == null || elements.isEmpty()) return null;
          baseConstructors = new PsiMethod[elements.size()];
          for (int i = 0; i < elements.size(); i++) {
            final ClassMember member = elements.get(i);
            baseConstructors[i] = ((PsiMethodMember) member).getElement();
          }
          myCopyJavadoc = chooser.isCopyJavadoc();
        }
      }
    }

    ClassMember[] allMembers = getAllOriginalMembers(aClass);
    ClassMember[] members;
    if (allMembers.length == 0) {
      members = ClassMember.EMPTY_ARRAY;
    } else {
      members = chooseMembers(allMembers, true, false, project, null);
      if (members == null) return null;
    }
    if (baseConstructors != null) {
      ArrayList<ClassMember> array = new ArrayList<ClassMember>();
      for (PsiMethod baseConstructor : baseConstructors) {
        array.add(new PsiMethodMember(baseConstructor));
      }
      ContainerUtil.addAll(array, members);
      members = array.toArray(new ClassMember[array.size()]);
    }

    return members;
  }
  @Override
  public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file)
      throws IncorrectOperationException {
    if (!FileModificationService.getInstance().prepareFileForWrite(file)) return;

    PsiMethod[] constructors = myClass.getConstructors();
    if (constructors.length == 0) {
      final AddDefaultConstructorFix defaultConstructorFix = new AddDefaultConstructorFix(myClass);
      ApplicationManager.getApplication()
          .runWriteAction(
              new Runnable() {
                @Override
                public void run() {
                  defaultConstructorFix.invoke(project, editor, file);
                }
              });
      constructors = myClass.getConstructors();
    }
    Arrays.sort(
        constructors,
        new Comparator<PsiMethod>() {
          @Override
          public int compare(PsiMethod c1, PsiMethod c2) {
            final PsiMethod cc1 = RefactoringUtil.getChainedConstructor(c1);
            final PsiMethod cc2 = RefactoringUtil.getChainedConstructor(c2);
            if (cc1 == c2) return 1;
            if (cc2 == c1) return -1;
            if (cc1 == null) {
              return cc2 == null ? 0 : compare(c1, cc2);
            } else {
              return cc2 == null ? compare(cc1, c2) : compare(cc1, cc2);
            }
          }
        });
    final ArrayList<PsiMethod> constrs =
        filterConstructorsIfFieldAlreadyAssigned(constructors, getField());
    if (constrs.size() > 1) {
      final PsiMethodMember[] members = new PsiMethodMember[constrs.size()];
      int i = 0;
      for (PsiMethod constructor : constrs) {
        members[i++] = new PsiMethodMember(constructor);
      }
      final List<PsiMethodMember> elements;
      if (ApplicationManager.getApplication().isUnitTestMode()) {
        elements = Arrays.asList(members);
      } else {
        final MemberChooser<PsiMethodMember> chooser =
            new MemberChooser<PsiMethodMember>(members, false, true, project);
        chooser.setTitle("Choose constructors to add parameter to");
        chooser.show();
        elements = chooser.getSelectedElements();
        if (elements == null) return;
      }

      for (PsiMethodMember member : elements) {
        if (!addParameterToConstructor(
            project, file, editor, member.getElement(), new PsiField[] {getField()})) break;
      }

    } else if (!constrs.isEmpty()) {
      final Collection<SmartPsiElementPointer<PsiField>> fieldsToFix = getFieldsToFix();
      try {
        final PsiMethod constructor = constrs.get(0);
        final LinkedHashSet<PsiField> fields = new LinkedHashSet<PsiField>();
        getFieldsToFix().add(myField);
        for (SmartPsiElementPointer<PsiField> elementPointer : fieldsToFix) {
          final PsiField field = elementPointer.getElement();
          if (field != null
              && isAvailable(field)
              && filterConstructorsIfFieldAlreadyAssigned(new PsiMethod[] {constructor}, field)
                  .contains(constructor)) {
            fields.add(field);
          }
        }
        if (constrs.size() == constructors.length
            && fields.size() > 1
            && !ApplicationManager.getApplication().isUnitTestMode()) {
          PsiFieldMember[] members = new PsiFieldMember[fields.size()];
          int i = 0;
          for (PsiField field : fields) {
            members[i++] = new PsiFieldMember(field);
          }
          MemberChooser<PsiElementClassMember> chooser =
              new MemberChooser<PsiElementClassMember>(members, false, true, project);
          chooser.setTitle("Choose Fields to Generate Constructor Parameters for");
          chooser.show();
          if (chooser.getExitCode() != DialogWrapper.OK_EXIT_CODE) return;
          final List<PsiElementClassMember> selectedElements = chooser.getSelectedElements();
          if (selectedElements == null) return;
          fields.clear();
          for (PsiElementClassMember member : selectedElements) {
            fields.add((PsiField) member.getElement());
          }
        }

        addParameterToConstructor(
            project,
            file,
            editor,
            constructor,
            constrs.size() == constructors.length
                ? fields.toArray(new PsiField[fields.size()])
                : new PsiField[] {getField()});
      } finally {
        fieldsToFix.clear();
      }
    }
  }
  private void proceedWithChoosingMethods(
      Project project,
      PsiFile file,
      final Editor editor,
      List<CppMethodElementNode> candidates,
      boolean override) {
    final MemberChooser<CppMethodElementNode> chooser =
        new MemberChooser<CppMethodElementNode>(
            candidates.toArray(new CppMethodElementNode[candidates.size()]),
            false,
            true,
            project,
            false) {};

    chooser.setTitle("Choose Methods to " + (override ? "Override" : "Implement"));
    chooser.setCopyJavadocVisible(false);
    chooser.show();
    if (chooser.getExitCode() != DialogWrapper.OK_EXIT_CODE) return;
    final List<CppMethodElementNode> selectedElements = chooser.getSelectedElements();
    if (selectedElements == null || selectedElements.size() == 0) return;

    CommandProcessor.getInstance()
        .executeCommand(
            project,
            new Runnable() {
              public void run() {
                ApplicationManager.getApplication()
                    .runWriteAction(
                        new Runnable() {
                          public void run() {
                            Document document = editor.getDocument();
                            int offset = editor.getCaretModel().getOffset();

                            for (CppMethodElementNode c : selectedElements) {
                              String cType = c.getType();
                              String methodText =
                                  "virtual "
                                      + cType
                                      + " "
                                      + c.getText()
                                      + " {\n"
                                      + (!"void".equals(cType) ? "return " : "")
                                      + (c.myIsAbstract
                                          ? ""
                                          : c.getParentName()
                                              + "::"
                                              + c.myName
                                              + "("
                                              + c.myParamNames
                                              + ");")
                                      + "\n"
                                      + "}\n";
                              document.insertString(offset, methodText);
                              offset += methodText.length();
                            }
                          }
                        });
              }
            },
            override ? "Override Methods" : "Implement Methods",
            this);
  }