private static List<RootModelImpl> getSortedChangedModels(
      Collection<ModifiableRootModel> rootModels, ModifiableModuleModel moduleModel) {
    List<RootModelImpl> result = ContainerUtil.newArrayListWithCapacity(rootModels.size());

    for (ModifiableRootModel model : rootModels) {
      RootModelImpl rootModel = (RootModelImpl) model;
      if (rootModel.isChanged()) {
        result.add(rootModel);
      }
    }

    DFSTBuilder<RootModelImpl> builder = createDFSTBuilder(result, moduleModel);
    Collections.sort(result, builder.comparator());

    return result;
  }
 static Comparator<IdeaPluginDescriptor> getPluginDescriptorComparator(
     Map<PluginId, IdeaPluginDescriptorImpl> idToDescriptorMap) {
   final Graph<PluginId> graph = createPluginIdGraph(idToDescriptorMap);
   final DFSTBuilder<PluginId> builder = new DFSTBuilder<PluginId>(graph);
   /*
   if (!builder.isAcyclic()) {
     final Pair<String,String> circularDependency = builder.getCircularDependency();
     throw new Exception("Cyclic dependencies between plugins are not allowed: \"" + circularDependency.getFirst() + "\" and \"" + circularDependency.getSecond() + "");
   }
   */
   final Comparator<PluginId> idComparator = builder.comparator();
   return new Comparator<IdeaPluginDescriptor>() {
     @Override
     public int compare(IdeaPluginDescriptor o1, IdeaPluginDescriptor o2) {
       return idComparator.compare(o1.getPluginId(), o2.getPluginId());
     }
   };
 }
  @Nullable
  private static Pair<List<String>, Boolean> keysOrder(final ResourceBundle resourceBundle) {
    final boolean[] isAlphaSorted = new boolean[] {true};
    final Graph<String> generator =
        GraphGenerator.generate(
            CachingSemiGraph.cache(
                new InboundSemiGraph<String>() {
                  @Override
                  public Collection<String> getNodes() {
                    final Set<String> nodes = new LinkedHashSet<>();
                    for (PropertiesFile propertiesFile : resourceBundle.getPropertiesFiles()) {
                      for (IProperty property : propertiesFile.getProperties()) {
                        final String key = property.getKey();
                        if (key != null) {
                          nodes.add(key);
                        }
                      }
                    }
                    return nodes;
                  }

                  @Override
                  public Iterator<String> getIn(String n) {
                    final Collection<String> siblings = new LinkedHashSet<>();
                    for (PropertiesFile propertiesFile : resourceBundle.getPropertiesFiles()) {
                      for (IProperty property : propertiesFile.findPropertiesByKey(n)) {
                        PsiElement sibling = property.getPsiElement().getNextSibling();
                        while (sibling instanceof PsiWhiteSpace || sibling instanceof PsiComment) {
                          sibling = sibling.getNextSibling();
                        }
                        if (sibling instanceof IProperty) {
                          final String key = ((IProperty) sibling).getKey();
                          if (key != null) {
                            if (isAlphaSorted[0]
                                && String.CASE_INSENSITIVE_ORDER.compare(n, key) > 0) {
                              isAlphaSorted[0] = false;
                            }
                            siblings.add(key);
                          }
                        }
                      }
                    }
                    return siblings.iterator();
                  }
                }));
    DFSTBuilder<String> dfstBuilder = new DFSTBuilder<>(generator);
    final boolean acyclic = dfstBuilder.isAcyclic();
    if (acyclic) {
      if (isAlphaSorted[0]) {
        final List<String> sortedNodes = new ArrayList<>(generator.getNodes());
        Collections.sort(sortedNodes, String.CASE_INSENSITIVE_ORDER);
        return Pair.create(sortedNodes, true);
      } else {
        final List<String> dfsNodes = dfstBuilder.getSortedNodes();
        Collections.reverse(dfsNodes);
        return Pair.create(dfsNodes, false);
      }
    } else {
      return null;
    }
  }