lock.release(this);
lock.release();
	public Occurrences[] scanIndexTerms(		User user,		Collection collection,		String start,		String end,		boolean inclusive)		throws PermissionDeniedException {		if (!collection.getPermissions().validate(user, Permission.READ))			throw new PermissionDeniedException("permission denied");		List collections = inclusive ? collection.getDescendants(user) : new ArrayList();		collections.add(collection);		final Lock lock = dbWords.getLock();		short collectionId;		Collection current;		IndexQuery query;		ArrayList values;		Value[] val;		String term;		Object2ObjectAVLTreeMap map = new Object2ObjectAVLTreeMap();		Occurrences oc;		VariableByteInputStream is;		int docId;		int len;		for (Iterator i = collections.iterator(); i.hasNext();) {			current = (Collection) i.next();			collectionId = current.getId();			query =				new IndexQuery(					null,					IndexQuery.BW,					new WordRef(collectionId, start),					new WordRef(collectionId, end));			try {				lock.acquire(this);				lock.enter(this);				values = dbWords.findEntries(query);				for (Iterator j = values.iterator(); j.hasNext();) {					val = (Value[]) j.next();					term = new String(val[0].getData(), 2, val[0].getLength() - 2, "UTF-8");					oc = (Occurrences) map.get(term);					if (oc == null) {						oc = new Occurrences(term);						map.put(term, oc);					}					is = new VariableByteInputStream(val[1].getData());					try {						while (is.available() > 0) {							docId = is.readInt();							len = is.readInt();							is.skip(len);							oc.addOccurrences(len);						}					} catch (EOFException e) {					}				}			} catch (LockException e) {				LOG.warn("cannot get lock on words", e);			} catch (IOException e) {				LOG.warn("error while reading words", e);			} catch (BTreeException e) {				LOG.warn("error while reading words", e);			} finally {				lock.release(this);			}		}		Occurrences[] result = new Occurrences[map.size()];		return (Occurrences[]) map.values().toArray(result);	}