Type.subTypeOf(type, Type.BOOLEAN) || Type.subTypeOf(type, Type.STRING)) {
Type.subTypeOf(type, Type.BOOLEAN)) {
	public Sequence eval(		StaticContext context,		DocumentSet docs,		Sequence contextSequence,		Item contextItem)		throws XPathException {		setInPredicate(true);		//long start = System.currentTimeMillis();		Expression inner = getExpression(0);		if (inner == null)			return Sequence.EMPTY_SEQUENCE;		if (contextItem != null)			contextSequence = contextItem.toSequence();		int type = inner.returnsType();		if (Type.subTypeOf(type, Type.NODE)) {			ExtArrayNodeSet result = new ExtArrayNodeSet();			NodeSet nodes =				(NodeSet) super.eval(context, docs, contextSequence, null);			NodeProxy current;			ContextItem contextNode;			NodeProxy next;			DocumentImpl lastDoc = null;			int count = 0, sizeHint = -1;			for (Iterator i = nodes.iterator(); i.hasNext(); count++) {				current = (NodeProxy) i.next();				if(lastDoc == null || current.doc != lastDoc) {					lastDoc = current.doc;					sizeHint = nodes.getSizeHint(lastDoc);				}				contextNode = current.getContext();				if (contextNode == null) {					throw new XPathException("Internal evaluation error: context node is missing!");				}				while (contextNode != null) {					next = contextNode.getNode();					next.addMatches(current.match);					if (!result.contains(next))						result.add(next, sizeHint);					contextNode = contextNode.getNextItem();				}			}			return result;		} else if (			Type.subTypeOf(type, Type.BOOLEAN)				|| Type.subTypeOf(type, Type.STRING)) {			//string has no special meaning			NodeSet result = new ExtArrayNodeSet();			Item item;			Sequence v;			for (SequenceIterator i = contextSequence.iterate();				i.hasNext();				) {				item = i.nextItem();				v = inner.eval(context, docs, contextSequence, item);				if (((BooleanValue) v.convertTo(Type.BOOLEAN)).getValue())					result.add(item);			}			return result;		} else if (Type.subTypeOf(type, Type.NUMBER)) {			NodeProxy p;			NodeProxy n;			NodeSet set;			int level;			int count;			int pos;			long pid;			long last_pid = 0;			long f_gid;			long e_gid;			DocumentImpl doc;			DocumentImpl last_doc = null;			NodeSet contextSet = (NodeSet) contextSequence;			NodeSet result = new ExtArrayNodeSet();			// evaluate predicate expression for each context node			for (Iterator i = contextSet.iterator(); i.hasNext();) {				p = (NodeProxy) i.next();				pos =					((NumericValue) inner						.eval(context, docs, contextSet, p)						.convertTo(Type.NUMBER))						.getInt();				doc = (DocumentImpl) p.getDoc();				level = doc.getTreeLevel(p.getGID());				pid =					(p.getGID() - doc.getLevelStartPoint(level))						/ doc.getTreeLevelOrder(level)						+ doc.getLevelStartPoint(level - 1);				if (pid == last_pid					&& last_doc != null					&& doc.getDocId() == last_doc.getDocId())					continue;				last_pid = pid;				last_doc = doc;				f_gid =					(pid - doc.getLevelStartPoint(level - 1))						* doc.getTreeLevelOrder(level)						+ doc.getLevelStartPoint(level);				e_gid = f_gid + doc.getTreeLevelOrder(level);				count = 1;				set = contextSet.getRange(doc, f_gid, e_gid);				for (Iterator j = set.iterator(); j.hasNext(); count++) {					n = (NodeProxy) j.next();					if (count == pos) {						result.add(n);						break;					}				}			}			return result;		} else			LOG.debug("unable to determine return type of predicate expression");		return Sequence.EMPTY_SEQUENCE;	}