domDb.remove(doc.getAddress());
	public void removeDocument(String docName) throws PermissionDeniedException {		if (readOnly)			throw new PermissionDeniedException("database is read-only");		try {			if (!docName.startsWith("/"))				docName = '/' + docName;			final DocumentImpl doc = (DocumentImpl) getDocument(docName);			if (doc == null) {				LOG.debug("document " + docName + " not found");				return;			}			if (!doc.getCollection().getPermissions().validate(user, Permission.WRITE))				throw new PermissionDeniedException(					"write access to collection denied; user=" + user.getName());			if (!doc.getPermissions().validate(user, Permission.WRITE))				throw new PermissionDeniedException("permission to remove document denied");			LOG.info("removing document " + doc.getDocId() + "...");			// drop element-index			short collectionId = doc.getCollection().getId();			Value ref = new ElementValue(collectionId);			IndexQuery query = new IndexQuery(IndexQuery.TRUNC_RIGHT, ref);			Lock lock = elementsDb.getLock();			try {				lock.acquire(Lock.WRITE_LOCK);				ArrayList elements = elementsDb.findKeys(query);				LOG.debug("found " + elements.size() + " elements.");				Value key;				Value value;				byte[] data;				byte[] ndata;				VariableByteInputStream is;				VariableByteOutputStream os;				int len;				int docId;				long delta;				long address;				boolean changed;				for (int i = 0; i < elements.size(); i++) {					key = (Value) elements.get(i);					value = elementsDb.get(key);					data = value.getData();					is = new VariableByteInputStream(data);					os = new VariableByteOutputStream();					changed = false;					try {						while (is.available() > 0) {							docId = is.readInt();							len = is.readInt();							if (docId != doc.getDocId()) {								// copy data to new buffer								os.writeInt(docId);								os.writeInt(len);								for (int j = 0; j < len; j++) {									delta = is.readLong();									address = StorageAddress.read(is);									os.writeLong(delta);									StorageAddress.write(address, os);								}							} else {								changed = true;								// skip								is.skip(len * 4);							}						}					} catch (EOFException e) {						LOG.debug("eof: " + is.available());					}					if (changed) {						//ndata = os.toByteArray();						if (elementsDb.put(key, os.data()) < 0)							LOG.debug("could not save element");					}				}			} catch (LockException e) {				LOG.warn("could not acquire lock on elements", e);			} finally {				lock.release();			}			elementPool.clear();			((NativeTextEngine) textEngine).removeDocument(doc);			LOG.debug("removing dom");			new DOMTransaction(this, domDb) {				public Object start() {					NodeList children = doc.getChildNodes();					domDb.remove(doc.getAddress());					NodeImpl node;					for (int i = 0; i < children.getLength(); i++) {						node = (NodeImpl) children.item(i);						Iterator j =							getDOMIterator(								new NodeProxy(									doc,									node.getGID(),									node.getInternalAddress()));						removeNodes(j);					}					return null;				}			}			.run();			LOG.debug("removing dom index");			ref = new NodeRef(doc.getDocId());			final IndexQuery idx = new IndexQuery(IndexQuery.TRUNC_RIGHT, ref);			new DOMTransaction(this, domDb) {				public Object start() {					try {						domDb.remove(idx, null);						domDb.flush();					} catch (BTreeException e) {						LOG.warn("error while removing doc", e);					} catch (DBException e) {						LOG.warn("error while removing doc", e);					} catch (IOException e) {						LOG.warn("error while removing doc", e);					}					return null;				}			}			.run();			LOG.info("removed document.");		} catch (IOException ioe) {			ioe.printStackTrace();			LOG.warn(ioe);		} catch (BTreeException bte) {			bte.printStackTrace();			LOG.warn(bte);		} catch (ReadOnlyException e) {			LOG.warn("database is read-only");		}	}