long start = System.currentTimeMillis();
	public NodeSet getNodesExact(DocumentSet docs, NodeSet context, String expr) {		if (expr == null)			return null;		if (stoplist.contains(expr))			return null;		//		long start = System.currentTimeMillis();		DocumentImpl doc;		Value ref;		byte[] data;		long gid;		int docId;		int len;		int section;		int sizeHint = -1;		long last;		long delta;		Collection collection;		short collectionId;		VariableByteInputStream is;		InputStream dis = null;		NodeProxy parent, current = new NodeProxy();		NodeSet result;		if (context == null)			result = new TextSearchResult(trackMatches != Serializer.TAG_NONE);		else			result = new ExtArrayNodeSet(docs.getLength(), 250);		String term = (stem) ? stemmer.stem(expr.toLowerCase()) : expr				.toLowerCase();		int count = 0;		for (Iterator iter = docs.getCollectionIterator(); iter.hasNext();) {			collection = (Collection) iter.next();			collectionId = collection.getId();			ref = new WordRef(collectionId, term);			Lock lock = dbWords.getLock();			try {				lock.acquire();				dis = dbWords.getAsStream(ref);				if (dis == null) {					continue;				}				is = new VariableByteInputStream(dis);				while (is.available() > 0) {					docId = is.readInt();					section = is.readByte();					len = is.readInt();					if ((doc = docs.getDoc(docId)) == null							|| (context != null && !context.containsDoc(doc))) {						is.skip(len);						continue;					}					if (context != null)						sizeHint = context.getSizeHint(doc);					last = 0;					for (int j = 0; j < len; j++) {						delta = is.readLong();						gid = last + delta;						last = gid;						count++;						if (context != null) {							current = (section == TEXT_SECTION ? new NodeProxy(									doc, gid, Node.TEXT_NODE) : new NodeProxy(									doc, gid, Node.ATTRIBUTE_NODE));							parent = context.parentWithChild(current, false,									true, -1);							if (parent != null) {								result.add(parent, sizeHint);								if (trackMatches != Serializer.TAG_NONE)									parent.addMatch(new Match(term, gid));							}						} else							((TextSearchResult) result).add(doc, gid, term);					}				}			} catch (EOFException e) {			} catch (LockException e) {				LOG.warn("could not acquire lock on words db", e);			} catch (IOException e) {				LOG.warn("io error while reading words", e);			} finally {				lock.release();			}		}		if (context != null)			((ExtArrayNodeSet) result).sort();		//		LOG.debug(		//			"found "		//				+ expr		//				+ ": "		//				+ result.getLength()		//				+ " ("		//				+ count		//				+ ") "		//				+ " in "		//				+ (System.currentTimeMillis() - start)		//				+ "ms.");		return result;	}