protected boolean usesSelector(Join join, SelectorName selector) {
   Source left = join.getLeft();
   if (left instanceof Selector && selector.equals(((Selector) left).aliasOrName())) return true;
   if (left instanceof Join && usesSelector((Join) left, selector)) return true;
   Source right = join.getRight();
   if (right instanceof Selector && selector.equals(((Selector) right).aliasOrName())) return true;
   if (right instanceof Join && usesSelector((Join) right, selector)) return true;
   return false;
 }
 protected Source rewrite(JoinableSources joinableSources) {
   // Find the order of the joins ...
   List<Join> joins = new LinkedList<Join>();
   for (SameNodeJoinCondition joinCondition : joinableSources.getJoinConditions()) {
     SelectorName selector1 = joinCondition.selector1Name();
     SelectorName selector2 = joinCondition.selector2Name();
     boolean found = false;
     ListIterator<Join> iter = joins.listIterator();
     while (iter.hasNext()) {
       Join next = iter.next();
       Join replacement = null;
       if (usesSelector(next, selector1)) {
         Source right = joinableSources.getSelectors().get(selector2.name());
         replacement = new Join(next, JoinType.INNER, right, joinCondition);
       } else if (usesSelector(next, selector2)) {
         Source left = joinableSources.getSelectors().get(selector1.name());
         replacement = new Join(left, JoinType.INNER, next, joinCondition);
       }
       if (replacement != null) {
         iter.previous();
         iter.remove();
         joins.add(replacement);
         found = true;
         break;
       }
     }
     if (!found) {
       // Nothing matched, so add a new join ...
       Source left = joinableSources.getSelectors().get(selector1.name());
       Source right = joinableSources.getSelectors().get(selector2.name());
       if (left == null) {
         Position pos = joinableSources.getJoinCriteriaPosition();
         String msg =
             JcrI18n.selectorUsedInEquiJoinCriteriaDoesNotExistInQuery.text(
                 selector1.name(), pos.getLine(), pos.getColumn());
         throw new ParsingException(pos, msg);
       }
       if (right == null) {
         Position pos = joinableSources.getJoinCriteriaPosition();
         String msg =
             JcrI18n.selectorUsedInEquiJoinCriteriaDoesNotExistInQuery.text(
                 selector2.name(), pos.getLine(), pos.getColumn());
         throw new ParsingException(pos, msg);
       }
       joins.add(new Join(left, JoinType.INNER, right, joinCondition));
     }
   }
   if (joins.size() == 1) {
     return joins.get(0);
   }
   // Otherwise the join conditions were not sufficient
   return null;
 }