protected Object unswizzle(int oid, Class cls, boolean recursiveLoading) {
		if (oid == 0) {
			return null;
		}

		if (recursiveLoading) {
			return lookupObject(oid, cls);
		}

		Object stub = objectCache.get(oid);

		if (stub != null) {
			return stub;
		}

		ClassDescriptor desc;

		if (cls == Object.class || (desc = findClassDescriptor(cls)) == null
				|| desc.hasSubclasses) {
			long pos = getPos(oid);
			int offs = (int) pos & (Page.pageSize - 1);

			if ((offs & (dbFreeHandleFlag | dbPageObjectFlag)) != 0) {
				throw new StorageError(StorageError.DELETED_OBJECT);
			}

			Page pg = pool.getPage(pos - offs);
			int typeOid = ObjectHeader.getType(pg.data, offs & ~dbFlagsMask);
			pool.unfix(pg);
			desc = findClassDescriptor(typeOid);
		}

		stub = desc.newInstance();
		assignOid(stub, oid, true);
		objectCache.put(oid, stub);
		return stub;
	}