private GrImportStatement[] prepare(final Set<GrImportStatement> usedImports,
                                        Set<String> importedClasses,
                                        Set<String> staticallyImportedMembers,
                                        Set<String> implicitlyImported,
                                        Set<String> innerClasses,
                                        Map<String, String> aliased,
                                        final Map<String, String> annotations,
                                        Set<GrImportStatement> unresolvedOnDemandImports) {
      final Project project = myFile.getProject();
      final GroovyCodeStyleSettings settings = GroovyCodeStyleSettings.getInstance(myFile);
      final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project);

      Object2IntMap<String> packageCountMap=new Object2IntOpenHashMap<>();
      Object2IntMap<String> classCountMap=new Object2IntOpenHashMap<>();

      //init packageCountMap
      for (String importedClass : importedClasses) {
        if (implicitlyImported.contains(importedClass) ||
            innerClasses.contains(importedClass) ||
            aliased.containsKey(importedClass) ||
            annotations.containsKey(importedClass)) {
          continue;
        }

        final String packageName = StringUtil.getPackageName(importedClass);

        packageCountMap.mergeInt(packageName, 1, Math::addExact);
      }

      //init classCountMap
      for (String importedMember : staticallyImportedMembers) {
        if (aliased.containsKey(importedMember) || annotations.containsKey(importedMember)) {
          continue;
        }

        classCountMap.mergeInt(StringUtil.getPackageName(importedMember), 1, Math::addExact);
      }

      final Set<String> onDemandImportedSimpleClassNames = new HashSet<>();
      final List<GrImportStatement> result = new ArrayList<>();

      for (Object2IntMap.Entry<String> entry : packageCountMap.object2IntEntrySet()) {
        String s = entry.getKey();
        if (entry.getIntValue() >= settings.CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND || settings.PACKAGES_TO_USE_IMPORT_ON_DEMAND.contains(s)) {
          final GrImportStatement imp = factory.createImportStatementFromText(s, false, true, null);
          String annos = annotations.remove(s + ".*");
          if (annos != null) {
            imp.getAnnotationList().replace(factory.createModifierList(annos));
          }
          result.add(imp);
          final PsiPackage aPackage = JavaPsiFacade.getInstance(myFile.getProject()).findPackage(s);
          if (aPackage != null) {
            for (PsiClass clazz : aPackage.getClasses(myFile.getResolveScope())) {
              onDemandImportedSimpleClassNames.add(clazz.getName());
            }
          }
        }
      }

      for (Object2IntMap.Entry<String> entry : classCountMap.object2IntEntrySet()) {
        if (entry.getIntValue() >= settings.NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND) {
          final GrImportStatement imp = factory.createImportStatementFromText(entry.getKey(), true, true, null);
          String annos = annotations.remove(entry.getKey() + ".*");
          if (annos != null) {
            imp.getAnnotationList().replace(factory.createModifierList(annos));
          }
          result.add(imp);
        }
      }

      List<GrImportStatement> explicated = new ArrayList<>();
      for (String importedClass : importedClasses) {
        final String parentName = StringUtil.getPackageName(importedClass);
        if (!annotations.containsKey(importedClass) && !aliased.containsKey(importedClass)) {
          if (packageCountMap.getInt(parentName) >= settings.CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND ||
              settings.PACKAGES_TO_USE_IMPORT_ON_DEMAND.contains(parentName)) {
            continue;
          }
          if (implicitlyImported.contains(importedClass) &&
              !onDemandImportedSimpleClassNames.contains(StringUtil.getShortName(importedClass))) {
            continue;
          }
        }

        final GrImportStatement imp = factory.createImportStatementFromText(importedClass, false, false, null);
        String annos = annotations.remove(importedClass);
        if (annos != null) {
          imp.getAnnotationList().replace(factory.createModifierList(annos));
        }
        explicated.add(imp);
      }

      for (String importedMember : staticallyImportedMembers) {
        final String className = StringUtil.getPackageName(importedMember);
        if (!annotations.containsKey(importedMember) && !aliased.containsKey(importedMember)) {
          if (classCountMap.getInt(className) >= settings.NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND) continue;
        }
        result.add(factory.createImportStatementFromText(importedMember, true, false, null));
      }

      for (GrImportStatement anImport : usedImports) {
        if (anImport.isAliasedImport() || GroovyImportUtil.isAnnotatedImport(anImport)) {
          if (GroovyImportUtil.isAnnotatedImport(anImport)) {
            annotations.remove(anImport.getImportFqn());
          }

          if (anImport.isStatic()) {
            result.add(anImport);
          }
          else {
            explicated.add(anImport);
          }
        }
      }

      final Comparator<GrImportStatement> comparator = getComparator(settings);
      result.sort(comparator);
      explicated.sort(comparator);

      explicated.addAll(result);

      if (!annotations.isEmpty()) {
        StringBuilder allSkippedAnnotations = new StringBuilder();
        for (String anno : annotations.values()) {
          allSkippedAnnotations.append(anno).append(' ');
        }
        if (explicated.isEmpty()) {
          explicated.add(factory.createImportStatementFromText(CommonClassNames.JAVA_LANG_OBJECT, false, false, null));
        }

        final GrImportStatement first = explicated.get(0);

        allSkippedAnnotations.append(first.getAnnotationList().getText());
        first.getAnnotationList().replace(factory.createModifierList(allSkippedAnnotations));
      }

      explicated.addAll(unresolvedOnDemandImports);

      return explicated.toArray(GrImportStatement.EMPTY_ARRAY);
    }
private GrImportStatement[] prepare(final Set<GrImportStatement> usedImports,
                                        Set<String> importedClasses,
                                        Set<String> staticallyImportedMembers,
                                        Set<String> implicitlyImported,
                                        Set<String> innerClasses,
                                        Map<String, String> aliased,
                                        final Map<String, String> annotations,
                                        Set<GrImportStatement> unresolvedOnDemandImports)