collection.getLock().release();
parent.getLock().release();
    public boolean removeCollection(final Txn transaction, Collection collection) throws PermissionDeniedException {        if (readOnly)            throw new PermissionDeniedException(DATABASE_IS_READ_ONLY);                if (!collection.getPermissions().validate(user, Permission.WRITE))            throw new PermissionDeniedException("User '"+ user.getName() + "' not allowed to remove collection '" + collection.getURI() + "'");        long start = System.currentTimeMillis();        final CollectionCache collectionsCache = pool.getCollectionsCache();        synchronized(collectionsCache) {            final XmldbURI name = collection.getURI();            final boolean isRoot = collection.getParentURI() == null;            //Drop all index entries            notifyDropIndex(collection);                        if (!isRoot) {                // remove from parent collection                Collection parent = openCollection(collection.getParentURI(), Lock.WRITE_LOCK);                // keep the lock for the transaction                if (transaction != null)                    transaction.registerLock(parent.getLock(), Lock.WRITE_LOCK);                if (parent != null) {                    try {                        LOG.debug("Removing collection '" + name + "' from its parent...");                        //TODO : resolve from collection's base URI                        parent.removeCollection(name.lastSegment());                        saveCollection(transaction, parent);                    } catch (LockException e) {                        LOG.warn("LockException while removing collection '" + name + "'");                    } finally {                        if (transaction == null)                            collection.getLock().release();                    }                }            }            // remove child collections            LOG.debug("Removing children collections from their parent '" + name + "'...");            for (Iterator i = collection.collectionIterator(); i.hasNext();) {                final XmldbURI childName = (XmldbURI) i.next();                //TODO : resolve from collection's base URI                Collection childCollection = openCollection(name.append(childName), Lock.WRITE_LOCK);                try {                                        removeCollection(transaction, childCollection);                                    } finally {                    childCollection.getLock().release();                }            }            //Update current state            Lock lock = collectionsDb.getLock();            try {                lock.acquire(Lock.WRITE_LOCK);                // if this is not the root collection remove it...                if (!isRoot) {                    Value key;                    try {                        key = new Value(name.toString().getBytes("UTF-8"));                    } catch (UnsupportedEncodingException e) {                        //TODO : real exception ; we are in trouble ! -pb                        LOG.error("Can not encode '" + name + "' in UTF-8", e);                        key = new Value(name.toString().getBytes());                    }                      //... from the disk                    collectionsDb.remove(transaction, key);                    //... from the cache                    collectionsCache.remove(collection);                    //and free its id for any futher use                    freeCollectionId(transaction, collection.getId());                } else {                    //Simply save the collection on disk                    //It will remain cached                    //and its id well never be made available                     saveCollection(transaction, collection);                }                            } catch (LockException e) {                LOG.warn("Failed to acquire lock on '" + collectionsDb.getFile().getName() + "'");            } catch (ReadOnlyException e) {                throw new PermissionDeniedException(DATABASE_IS_READ_ONLY);            } finally {                lock.release();            }            //Remove child resources            LOG.debug("Removing resources in '" + name + "'...");            for (Iterator i = collection.iterator(this); i.hasNext();) {                final DocumentImpl doc = (DocumentImpl) i.next();                //Remove doc's metadata                removeResourceMetadata(transaction, doc);                //Remove document nodes' index entries                new DOMTransaction(this, domDb, Lock.WRITE_LOCK) {                    public Object start() {                        try {                                                      Value ref = new NodeRef(doc.getDocId());                            IndexQuery query = new IndexQuery(IndexQuery.TRUNC_RIGHT, ref);                                                       domDb.remove(transaction, query, null);                        } catch (BTreeException e) {                            LOG.warn("btree error while removing document", e);                        } catch (IOException e) {                            LOG.warn("io error while removing document", e);                        } catch (TerminatedException e) {                            LOG.warn("method terminated", e);                        }                        return null;                    }                }                .run();                  //Remove nodes themselves                new DOMTransaction(this, domDb, Lock.WRITE_LOCK) {                    public Object start() {                        if(doc.getResourceType() == DocumentImpl.BINARY_FILE) {                        	long page = ((BinaryDocument)doc).getPage();                        	if (page > -1)                        		domDb.removeOverflowValue(transaction, page);                        } else {                                                        StoredNode node = (StoredNode)doc.getFirstChild();                            domDb.removeAll(transaction, node.getInternalAddress());                        }                        return null;                    }                }                .run();                //Make doc's id available again                freeResourceId(transaction, doc.getDocId());            }            LOG.debug("Removing collection '" + name + "' took " + (System.currentTimeMillis() - start));            return true;        }    }