code: public static List<String> topologicalSort(List<String> moduleNames, String rfsAbsPath)
      throws CmsConfigurationException {
  
          List<String> modules = new ArrayList<String>(moduleNames);
          List<String> retList = new ArrayList<String>();
          Map<String, List<String>> moduleDependencies = buildDepsForModulelist(moduleNames, rfsAbsPath, true);
          boolean finished = false;
          while (!finished) {
              finished = true;
              Iterator<String> itMods = modules.iterator();
              while (itMods.hasNext()) {
                  String moduleName = itMods.next();
                  List<String> deps = moduleDependencies.get(moduleName);
                  if ((deps == null) || deps.isEmpty()) {
                      retList.add(moduleName);
                      Iterator<List<String>> itDeps = moduleDependencies.values().iterator();
                      while (itDeps.hasNext()) {
                          List<String> dependencies = itDeps.next();
                          dependencies.remove(moduleName);
                      }
                      finished = false;
                      itMods.remove();
                  }
              }
          }
          if (!modules.isEmpty()) {
              throw new CmsIllegalStateException(
                  Messages.get().container(Messages.ERR_MODULE_DEPENDENCY_CYCLE_1, modules.toString()));
          }
          Collections.reverse(retList);
          return retList;
      }
docs: Sorts a given list of module names by dependencies,
  so that the resulting list can be imported in that given order,
  that means modules without dependencies first.<p>
  
  The module dependencies are get from the installed modules or
  from the module manifest.xml files found in the given FRS path.<p>
  
  @param moduleNames a list of module names
  @param rfsAbsPath a RFS absolute path to search for modules, or <code>null</code> to use the installed modules
  
  @return a sorted list of module names
  
  @throws CmsConfigurationException if something goes wrong