protected List<String> findBestTrailForUrlPathElems(Delegator delegator, List<List<String>> possibleTrails, List<AltUrlPartResults> pathElems) throws GenericEntityException {
        if (pathElems.isEmpty()) return null;
        List<String> bestTrail = null;
        for(List<String> trail : possibleTrails) {
            if (pathElems.size() > trail.size()) continue; // sure to fail
            ListIterator<AltUrlPartResults> pit = pathElems.listIterator(pathElems.size());
            ListIterator<String> tit = trail.listIterator(trail.size());
            boolean matched = true;
            while(matched && pit.hasPrevious()) {
                AltUrlPartResults urlInfos = pit.previous();
                String categoryId = tit.previous();
                // simplistic check: ignores exact vs name-only matches, but may be good enough
                if (!urlInfos.containsKey(categoryId)) {
                    matched = false;
                }
            }
            if (matched) {
                if (trail.size() == pathElems.size()) { // ideal case
                    bestTrail = trail;
                    break;
                } else if (bestTrail == null || trail.size() < bestTrail.size()) { // smaller = better
                    bestTrail = trail;
                }
            }
        }
        return bestTrail;
    }
protected List<String> findBestTrailForUrlPathElems(Delegator delegator, List<List<String>> possibleTrails, List<AltUrlPartResults> pathElems) throws GenericEntityException {
        if (pathElems.isEmpty()) return null;
        List<String> bestTrail = null;
        for(List<String> trail : possibleTrails) {
            if (pathElems.size() > trail.size()) continue;
            ListIterator<AltUrlPartResults> pit = pathElems.listIterator(pathElems.size());
            ListIterator<String> tit = trail.listIterator(trail.size());
            boolean matched = true;
            while(matched && pit.hasPrevious()) {
                AltUrlPartResults urlInfos = pit.previous();
                String categoryId = tit.previous();
               
                if (!urlInfos.containsKey(categoryId)) {
                    matched = false;
                }
            }
            if (matched) {
                if (trail.size() == pathElems.size()) {
                    bestTrail = trail;
                    break;
                } else if (bestTrail == null || trail.size() < bestTrail.size()) {
                    bestTrail = trail;
                }
            }
        }
        return bestTrail;
    }
protected list<string> findbesttrailforurlpathelems(delegator delegator, list<list<string>> possibletrails, list<alturlpartresults> pathelems) throws genericentityexception { if (pathelems.isempty()) return null; list<string> besttrail = null; for(list<string> trail : possibletrails) { if (pathelems.size() > trail.size()) continue; listiterator<alturlpartresults> pit = pathelems.listiterator(pathelems.size()); listiterator<string> tit = trail.listiterator(trail.size()); boolean matched = true; while(matched && pit.hasprevious()) { alturlpartresults urlinfos = pit.previous(); string categoryid = tit.previous(); if (!urlinfos.containskey(categoryid)) { matched = false; } } if (matched) { if (trail.size() == pathelems.size()) { besttrail = trail; break; } else if (besttrail == null || trail.size() < besttrail.size()) { besttrail = trail; } } } return besttrail; }