Item key = rightSeq.itemAt(0).atomize();
	protected Sequence quickNodeSetCompare(Sequence contextSequence)		throws XPathException {		// if the context sequence hasn't changed we can return a cached result		if(cached != null && cached.isValid(contextSequence)) {//			LOG.debug("Returning cached result for " + ExpressionDumper.dump(this));			return cached.getResult();		}		//	evaluate left expression		NodeSet nodes = (NodeSet) getLeft().eval(contextSequence);				if(nodes.getLength() < 2)			// fall back to nodeSetCompare if we just have to check a single node			return nodeSetCompare(nodes, contextSequence);				// evaluate right expression		Sequence rightSeq = getRight().eval(contextSequence);		if (rightSeq.getLength() > 1)			// fall back to nodeSetCompare			return nodeSetCompare(nodes, contextSequence);				// get the type of a possible index		int indexType = nodes.getIndexType();				// we can't use the index if the node has mixed content		boolean hasMixedContent = nodes.hasMixedContent();				DocumentSet docs = nodes.getDocumentSet();		NodeSet result = null;			    if(!hasMixedContent && indexType != Type.ITEM) {	        // we have a range index defined on the nodes in this sequence	        Item key = rightSeq.itemAt(0).atomize();	        if(truncation != Constants.TRUNC_NONE) {	        	// truncation is only possible on strings	        	key = key.convertTo(Type.STRING);	        } else if(key.getType() != indexType) {	            // index type doesn't match. If key is untyped atomic, convert it to string	            if(key.getType() == Type.ATOMIC)	                key = key.convertTo(Type.STRING);	            // If index has a numeric type, we convert to xs:double 	            if(Type.subTypeOf(indexType, Type.NUMBER))	                key = key.convertTo(Type.DOUBLE);	        }	        // if key does not implement Indexable, we can't use the index	        if(key instanceof Indexable && Type.subTypeOf(key.getType(), indexType)) {	        	if(truncation != Constants.TRUNC_NONE) {					try {						result = context.getBroker().getValueIndex().match(docs, nodes, getComparisonString(rightSeq).replace('%', '*'), 								DBBroker.MATCH_WILDCARDS);					} catch (EXistException e) {						throw new XPathException(getASTNode(), e.getMessage(), e);					}	        	} else {		            LOG.debug("Using value index for key: " + key.getStringValue());		            result = context.getBroker().getValueIndex().find(relation, docs, nodes, (Indexable)key);				}	        } else	            return nodeSetCompare(nodes, contextSequence);	        	    } else if (!hasMixedContent && relation == Constants.EQ && nodes.hasTextIndex()) {	        	        // we can use the fulltext index	        String cmp = getComparisonString(rightSeq);	        if(cmp.length() < NativeTextEngine.MAX_WORD_LENGTH)	            nodes = useFulltextIndex(cmp, nodes, docs);	        // now compare the input node set to the search expression			result =				context.getBroker().getNodesEqualTo(nodes, docs, relation, cmp, getCollator(contextSequence));					} else if(Type.subTypeOf(rightSeq.getItemType(), Type.STRING) ||		        rightSeq.getItemType() == Type.ATOMIC) {		    		    // no usable index found. Fall back to a sequential scan of the nodes		    result =				context.getBroker().getNodesEqualTo(nodes, docs, relation, getComparisonString(rightSeq), 				        getCollator(contextSequence));		} else {		    		    // no usable index found. Fall back to nodeSetCompare		    return nodeSetCompare(nodes, contextSequence);		}				// can this result be cached? Don't cache if the result depends on local variables.		boolean canCache = 		    contextSequence instanceof NodeSet &&	        (getRight().getDependencies() & Dependency.LOCAL_VARS) == 0 &&	        (getLeft().getDependencies() & Dependency.LOCAL_VARS) == 0;		if(canCache)			cached = new CachedResult((NodeSet)contextSequence, result);		return result;	}