final void cloneBitmap(long pos, long size) {
		synchronized (objectCache) {
			if (insideCloneBitmap) {
				Assert.that(size == Page.pageSize);
				cloneList = new CloneNode(pos, cloneList);
			}
			else {
				insideCloneBitmap = true;

				while (true) {
					long quantNo = pos >>> dbAllocationQuantumBits;
					int objBitSize = (int) ((size + dbAllocationQuantum - 1) >>> dbAllocationQuantumBits);
					int pageId = (int) (quantNo >>> (Page.pageSizeLog + 3));
					int offs = (int) (quantNo & (Page.pageSize * 8 - 1)) >> 3;
					int bitOffs = (int) quantNo & 7;
					int oid = getBitmapPageId(pageId);
					pos = getPos(oid);

					if ((pos & dbModifiedFlag) == 0) {
						dirtyPagesMap[oid >>> (dbHandlesPerPageBits + 5)] |= 1 << ((oid >>> dbHandlesPerPageBits) & 31);
						allocate(Page.pageSize, oid);
						cloneBitmap(pos & ~dbFlagsMask, Page.pageSize);
					}

					if (objBitSize > 8 - bitOffs) {
						objBitSize -= 8 - bitOffs;
						offs += 1;

						while (objBitSize + offs * 8 > Page.pageSize * 8) {
							oid = getBitmapPageId(++pageId);
							pos = getPos(oid);

							if ((pos & dbModifiedFlag) == 0) {
								dirtyPagesMap[oid >>> (dbHandlesPerPageBits + 5)] |= 1 << ((oid >>> dbHandlesPerPageBits) & 31);
								allocate(Page.pageSize, oid);
								cloneBitmap(pos & ~dbFlagsMask, Page.pageSize);
							}

							objBitSize -= (Page.pageSize - offs) * 8;
							offs = 0;
						}
					}

					if (cloneList == null) {
						break;
					}

					pos = cloneList.pos;
					size = Page.pageSize;
					cloneList = cloneList.next;
				}

				insideCloneBitmap = false;
			}
		}
	}