private @NotNull List<TemplateGroupItem> fillGroupTemplateMap(@NotNull WizardContext context) {
    List<ModuleBuilder> builders = ModuleBuilder.getAllBuilders();
    Map<String, TemplatesGroup> groupMap = new HashMap<>();
    for (ModuleBuilder builder : builders) {
      try {
        BuilderBasedTemplate template = new BuilderBasedTemplate(builder);
        if (builder.isTemplate()) {
          TemplatesGroup group = groupMap.get(builder.getGroupName());
          if (group == null) {
            group = new TemplatesGroup(builder);
          }
          myTemplatesMap.putValue(group, template);
        }
        else {
          TemplatesGroup group = new TemplatesGroup(builder);
          groupMap.put(group.getName(), group);
          myTemplatesMap.put(group, new ArrayList<>());
        }
      }
      catch (Throwable e) {
        LOG.error(e);
      }
    }

    myTemplatesMap.putAllValues(getTemplatesMap(context));

    for (ProjectCategory category : CATEGORY_EP.getExtensionList()) {
      TemplatesGroup group = new TemplatesGroup(category);
      ModuleBuilder builder = group.getModuleBuilder();
      if (builder == null || builder.isAvailable()) {
        myTemplatesMap.remove(group);
        myTemplatesMap.put(group, new ArrayList<>());
      }
    }

    if (context.isCreatingNewProject()) {
      MultiMap<String, ProjectTemplate> localTemplates = loadLocalTemplates();
      for (TemplatesGroup group : myTemplatesMap.keySet()) {
        myTemplatesMap.putValues(group, localTemplates.get(group.getId()));
      }
    }

    List<TemplatesGroup> groups = new ArrayList<>(myTemplatesMap.keySet());

    // sorting by module type popularity
    final MultiMap<ModuleType, TemplatesGroup> moduleTypes = new MultiMap<>();
    for (TemplatesGroup group : groups) {
      ModuleType type = getModuleType(group);
      moduleTypes.putValue(type, group);
    }
    groups.sort((o1, o2) -> {
      int i = o2.getWeight() - o1.getWeight();
      if (i != 0) return i;
      int i1 = moduleTypes.get(getModuleType(o2)).size() - moduleTypes.get(getModuleType(o1)).size();
      if (i1 != 0) return i1;
      return o1.compareTo(o2);
    });

    Set<String> groupNames = ContainerUtil.map2Set(groups, TemplatesGroup::getParentGroup);

    // move subgroups
    MultiMap<String, TemplatesGroup> subGroups = new MultiMap<>();
    for (ListIterator<TemplatesGroup> iterator = groups.listIterator(); iterator.hasNext(); ) {
      TemplatesGroup group = iterator.next();
      String parentGroup = group.getParentGroup();
      if (parentGroup != null && groupNames.contains(parentGroup) && !group.getName().equals(parentGroup) && groupMap.containsKey(parentGroup)) {
        subGroups.putValue(parentGroup, group);
        iterator.remove();
      }
    }
    for (ListIterator<TemplatesGroup> iterator = groups.listIterator(); iterator.hasNext(); ) {
      TemplatesGroup group = iterator.next();
      for (TemplatesGroup subGroup : subGroups.get(group.getName())) {
        iterator.add(subGroup);
      }
    }

    // remove Static Web group in IDEA Community if no specific templates found (IDEA-120593)
    if (PlatformUtils.isIdeaCommunity()) {
      for (ListIterator<TemplatesGroup> iterator = groups.listIterator(); iterator.hasNext(); ) {
        TemplatesGroup group = iterator.next();
        if (WebModuleTypeBase.WEB_MODULE.equals(group.getId()) && myTemplatesMap.get(group).isEmpty()) {
          iterator.remove();
          break;
        }
      }
    }

    return ContainerUtil.map(groups, it -> new TemplateGroupItem(it));
  }
private @NotNull List<TemplateGroupItem> fillGroupTemplateMap(@NotNull WizardContext context)