/**
  * Add this module to the sorted list. If current is the 'root' of a loop, then all elements of
  * that loops are added before.
  */
 private void addToSortList(List sortedList) {
   for (Iterator it = loopElements.iterator(); it.hasNext(); ) {
     ModuleInSort moduleInLoop = (ModuleInSort) it.next();
     moduleInLoop.addToSortList(sortedList);
   }
   if (!this.isSorted()) {
     sortedList.add(module);
     this.isSorted = true;
   }
 }
 /**
  * If current module has already been added to list, returns, Otherwise invokes
  * sortModuleDescriptorsHelp for all dependencies contained within set of moduleDescriptors. Then
  * finally adds self to list of sorted.<br>
  * When a loop is detected by a recursive call, the moduleDescriptors are not added immediately
  * added to the sorted list. They are added as loop dependencies of the root, and will be added to
  * the sorted list only when the root itself will be added.
  *
  * @param current Current module to add to sorted list.
  * @throws CircularDependencyException
  */
 private void sortModuleDescriptorsHelp(ModuleInSort current, ModuleInSort caller)
     throws CircularDependencyException {
   // if already sorted return
   if (current.isProcessed()) {
     return;
   }
   if (current.checkLoop(caller, circularDepStrategy)) {
     return;
   }
   DependencyDescriptor[] descriptors = current.getDependencies();
   Message.debug(
       "Sort dependencies of : "
           + current.toString()
           + " / Number of dependencies = "
           + descriptors.length);
   current.setCaller(caller);
   for (int i = 0; i < descriptors.length; i++) {
     ModuleInSort child = moduleDescriptors.getModuleDescriptorDependency(descriptors[i]);
     if (child != null) {
       sortModuleDescriptorsHelp(child, current);
     }
   }
   current.endOfCall();
   Message.debug("Sort done for : " + current.toString());
   current.addToSortedListIfRequired(sorted);
 }
 /**
  * Check if a adding this element as a dependency of caller will introduce a circular dependency.
  * If it is, all the elements of the loop are flaged as 'loopIntermediateElement', and the
  * loopElements of this module (which is the root of the loop) is updated. The depStrategy is
  * invoked on order to report a correct circular loop message.
  *
  * @param futurCaller
  * @param depStrategy
  * @return true if a loop is detected.
  */
 public boolean checkLoop(ModuleInSort futurCaller, CircularDependencyStrategy depStrategy) {
   if (caller != null) {
     LinkedList elemOfLoop = new LinkedList();
     elemOfLoop.add(this.module.getModuleRevisionId());
     for (ModuleInSort stackEl = futurCaller; stackEl != this; stackEl = stackEl.caller) {
       elemOfLoop.add(stackEl.module.getModuleRevisionId());
       stackEl.isLoopIntermediateElement = true;
       loopElements.add(stackEl);
     }
     elemOfLoop.add(this.module.getModuleRevisionId());
     ModuleRevisionId[] mrids =
         (ModuleRevisionId[]) elemOfLoop.toArray(new ModuleRevisionId[elemOfLoop.size()]);
     depStrategy.handleCircularDependency(mrids);
     return true;
   } else {
     return false;
   }
 }