/**
  * Organized the Applications of "d" into a leveled data structure based on their dependance among
  * each other
  *
  * @return exactly the same Application instances in a leveled data structure
  */
 private final List<Set<Rule.Match>> getTopology(List<Rule.Match> l) {
   List<Set<Occurrence>> levels = new ArrayList<Set<Occurrence>>();
   Occurrence initialWord = new Occurrence();
   initialWord.setSymbol(l.get(0).rule.getLeftHandSide().get(0));
   initialWord.setSource(null);
   initialWord.setPosition(0);
   ensureCapacity(1, levels);
   levels.get(0).add(initialWord);
   List<Occurrence> currentWord = new ArrayList<Occurrence>();
   currentWord.add(initialWord);
   for (int i = 0; i < l.size(); i++) {
     Rule.Match a = l.get(i);
     List<Occurrence> depSeq = dependingSubsequence(currentWord, a);
     List<Occurrence> newWord = apply(currentWord, a);
     List<Occurrence> prodSeq = producedSubsequence(newWord, a);
     int myLevel = getMaxLevel(depSeq, levels) + 1;
     ensureCapacity(myLevel + 1, levels);
     Set<Occurrence> myLevelSet = levels.get(myLevel);
     myLevelSet.addAll(prodSeq);
     currentWord = newWord;
   }
   List<Set<Rule.Match>> result = new ArrayList<Set<Rule.Match>>();
   for (Set<Occurrence> level : levels) {
     Set<Rule.Match> set = new HashSet<Rule.Match>();
     result.add(set);
     for (Occurrence o : level) {
       set.add(o.getSource());
     }
   }
   return result;
 }