private static void startAlgorithm () {
        ArrayList unmatchedFromO1 = AlgorithmUtils.filterClses (_results.getUnmatchedEntriesFromO1 ());
        ArrayList unmatchedFromO2 = AlgorithmUtils.filterClses (_results.getUnmatchedEntriesFromO2 ());

        if (unmatchedFromO1 == null || unmatchedFromO1.isEmpty()) return;


        int i = 0;
        while (!unmatchedFromO1.isEmpty() && i < unmatchedFromO1.size()) {
            Cls nextUnmatchedCls = (Cls)unmatchedFromO1.get(i);
            i++;
            // **** need to deal with multiple images here
            if (_results.getFirstImage(nextUnmatchedCls) == null) // i.e., we haven't found a match for it in
            	findMatch (nextUnmatchedCls, new ArrayList(unmatchedFromO1), new ArrayList(unmatchedFromO2)); // one of the previous iterations of this loop
        }
    }
    private static void findMatch (Cls unmatchedCls, Collection unmatchedInO1, Collection unmatchedInO2) {
     	Collection superclasses = Util.getDirectSuperclasses(unmatchedCls);
        Iterator supers = superclasses.iterator();
        while (supers.hasNext()) {
         	Cls nextSuper = (Cls)supers.next();
            // **** need to deal with multiple images here
            Cls nextSuperImage = (Cls)_results.getFirstImage(nextSuper);
            if (nextSuperImage != null) {
                Collection nextSubs = new ArrayList(Util.getDirectSubclasses(nextSuper));
    	        Collection nextSubsImages = AlgorithmUtils.getImages (nextSubs, _results);
        	Collection nextSuperImageSubs = new ArrayList(Util.getDirectSubclasses(nextSuperImage));
            	nextSuperImageSubs.removeAll(nextSubsImages);
                nextSuperImageSubs.retainAll(unmatchedInO2);
	        nextSubs.retainAll(unmatchedInO1);

                // now, nextSubs has unmatched subclasses of nextSuper
            	// and nextSuperImageSubs contains unmatched subclasses of nextSuperImage

	        if (!nextSubs.isEmpty() && !nextSuperImageSubs.isEmpty())
        	    compareNamesForSiblings (nextSubs, nextSuperImageSubs);
                AlgorithmUtils.removeClsesWithSingleParent (nextSubs, unmatchedInO1);
            }
        }
    }
    private static void compareNamesForSiblings (Collection clses1, Collection clses2) {
      if (clses1 == null || clses2 == null) return;
      Iterator i = clses1.iterator();

      while (i.hasNext()) {
        Cls nextCls1 = (Cls)i.next();
        Iterator j = clses2.iterator();
        while (j.hasNext()) {
          Cls nextCls2 = (Cls)j.next();
          if (CompareNames.compareNames(Util.getLocalBrowserText(nextCls1), Util.getLocalBrowserText (nextCls2)) == CompareNames.APPROXIMATE_MATCH) {
            AlgorithmUtils.createNewMatch(nextCls1, nextCls2, "multiple unmatched siblings with similar names", _results);
            _changesMade = true;
            j.remove();
            break;
          }
        }
      }
    }