private NodeSet quickSelectAncestorDescendant(NodeSet al, int mode, boolean rememberContext) {
private NodeSet quickSelectAncestorDescendant(NodeSet al, int mode, boolean includeSelf, boolean rememberContext) {
	private NodeSet quickSelectAncestorDescendant(NodeSet al, int mode, boolean rememberContext) {	    final NodeSet result = new ExtArrayNodeSet();		final Iterator ia = al.iterator();		final Iterator ib = iterator();		final long start = System.currentTimeMillis();		NodeProxy na = (NodeProxy) ia.next(), nb = (NodeProxy) ib.next();		long pa, pb;		while (true) {			// first, try to find nodes belonging to the same doc			if (na.doc.getDocId() < nb.doc.getDocId()) {				if (ia.hasNext())					na = (NodeProxy) ia.next();				else					break;			} else if (na.doc.getDocId() > nb.doc.getDocId()) {				if (ib.hasNext())					nb = (NodeProxy) ib.next();				else					break;			} else {			    // same document			    pa = na.gid; 			    pb = nb.gid;			    int la = na.doc.getTreeLevel(pa);				int lb = nb.doc.getTreeLevel(pb);				while (la < lb) {					pb = XMLUtil.getParentId(nb.doc, pb, lb);					--lb;				}				if (pa < pb) {					if (ia.hasNext())						na = (NodeProxy) ia.next();					else						break;				} else if (pa > pb) {					if (ib.hasNext())						nb = (NodeProxy) ib.next();					else						break;				} else {				    if(mode == NodeSet.DESCENDANT) {				        if (rememberContext)				            nb.addContextNode(na);				        else				            nb.copyContext(na);				        result.add(nb);				    } else {				        if (rememberContext)				            na.addContextNode(nb);				        else				            na.copyContext(nb);				        result.add(na);				    }				    if (ib.hasNext())						nb = (NodeProxy) ib.next();					else						break;				}			}		}		LOG.debug("quickSelect took " + (System.currentTimeMillis() - start));		return result;	}