if (right.returnsType() == Type.STRING) {
if (Type.subTypeOf(right.returnsType(), Type.STRING) || Type.subTypeOf(right.returnsType(), Type.NODE)) {
	protected Sequence nodeSetCompare(		Expression left,		Expression right,		StaticContext context,		DocumentSet docs,		Sequence contextSequence) throws XPathException {		NodeSet result = new ArraySet(100);		if(!(contextSequence.getItemType() == Type.NODE))			throw new XPathException("context is not a node sequence");		NodeSet contextSet = (NodeSet)contextSequence;		// TODO: not correct: should test if right is a string literal		if (right.returnsType() == Type.STRING) {			// evaluate left expression			NodeSet nodes = (NodeSet) left.eval(context, docs, contextSequence);			String cmp = right.eval(context, docs, contextSequence).getStringValue();			if (getLeft().returnsType() == Type.NODE && relation == Constants.EQ &&				nodes.hasIndex() && cmp.length() > 0) {				String cmpCopy = cmp;				cmp = maskWildcards(cmp);				// try to use a fulltext search expression to reduce the number				// of potential nodes to scan through				SimpleTokenizer tokenizer = new SimpleTokenizer();				tokenizer.setText(cmp);				TextToken token;				String term;				boolean foundNumeric = false;				// setup up an &= expression using the fulltext index				containsExpr = new ExtFulltext(Constants.FULLTEXT_AND);				for (int i = 0; i < 5 && (token = tokenizer.nextToken(true)) != null; i++) {					// remember if we find an alphanumeric token					if(token.getType() == TextToken.ALPHANUM)						foundNumeric = true;					containsExpr.addTerm(token.getText());				} 				// check if all elements are indexed. If not, we can't use the				// fulltext index.				if(foundNumeric)					foundNumeric = checkArgumentTypes(context, docs);				if((!foundNumeric) && containsExpr.countTerms() > 0) {					// all elements are indexed: use the fulltext index					nodes = (NodeSet)containsExpr.eval(context, docs, nodes, null);				}				cmp = cmpCopy;			}			// now compare the input node set to the search expression				result = context.getBroker().getNodesEqualTo(nodes, docs, relation, cmp);		} else if (Type.subTypeOf(right.returnsType(), Type.NUMBER)) {			DecimalValue rvalue;			DecimalValue lvalue;			NodeProxy ln;			NodeSet temp = new SingleNodeSet();			NodeSet lset = (NodeSet) left.eval(context, docs, contextSequence);			for (Iterator i = lset.iterator(); i.hasNext();) {				ln = (NodeProxy) i.next();				lvalue = (DecimalValue)ln.convertTo(Type.DECIMAL);				temp.add(ln);				rvalue = (DecimalValue)right.eval(context, docs, temp).convertTo(Type.DECIMAL);				if (cmpNumbers(lvalue.getDouble(), rvalue.getDouble()))					result.add(ln);			}		} else if (Type.subTypeOf(right.returnsType(), Type.BOOLEAN)) {			NodeProxy n;			NodeProxy parent;			boolean rvalue;			boolean lvalue;			long pid;			NodeSet lset = (NodeSet) left.eval(context, docs, contextSequence);			// get left arguments node set			NodeSet temp = new SingleNodeSet();			// get that part of context for which left argument's node set would			// be > 0			for (Iterator i = lset.iterator(); i.hasNext();) {				n = (NodeProxy) i.next();				parent = contextSet.parentWithChild(n, false, true);				if (parent != null)					temp.add(parent);			}			SingleNodeSet ltemp = new SingleNodeSet();			// now compare every node of context with the temporary set			for (Iterator i = contextSet.iterator(); i.hasNext();) {				n = (NodeProxy) i.next();				ltemp.add(n);				lvalue = temp.contains(n);				rvalue = ((BooleanValue)right.eval(context, docs, ltemp).convertTo(Type.BOOLEAN)).getValue();				if (cmpBooleans(lvalue, rvalue))					result.add(n);			}		}		return result;	}