// nodeMatcher: func(WebNode, WebNode) -> double static Map web_matchAllPerms_x(Web patternWeb, Web inputWeb, O nodeMatcher) { L patternNodes = web_nodes(patternWeb); L inputNodes = web_nodes(inputWeb); if (l(patternNodes) != l(inputNodes)) null; //fail("Can't match, differing number of nodes: " + l(patternNodes) + "/" + l(inputNodes)); LL perms = allPermutations(inputNodes); new Best> best; for (L perm : perms) best.put(perm, web_matchNodeLists_x(patternNodes, perm, nodeMatcher)); L l = best.getIfScoreAbove(0); ret l == null ? null : twoListsToOrderedMap(patternNodes, l); }