final int packValue(Object value, int offs, ByteBuffer buf)
			throws Exception {
		if (value == null) {
			buf.extend(offs + 4);
			Bytes.pack4(buf.arr, offs, -1);
			offs += 4;
		}
		else if (value instanceof IPersistent) {
			buf.extend(offs + 8);
			Bytes.pack4(buf.arr, offs, -2 - ClassDescriptor.tpObject);
			Bytes.pack4(buf.arr, offs + 4,
					swizzle((IPersistent) value, buf.finalized));
			offs += 8;
		}
		else {
			Class c = value.getClass();

			if (c == Boolean.class) {
				buf.extend(offs + 5);
				Bytes.pack4(buf.arr, offs, -2 - ClassDescriptor.tpBoolean);
				buf.arr[offs + 4] = (byte) (((Boolean) value).booleanValue() ? 1
						: 0);
				offs += 5;
			}
			else if (c == Character.class) {
				buf.extend(offs + 6);
				Bytes.pack4(buf.arr, offs, -2 - ClassDescriptor.tpChar);
				Bytes.pack2(buf.arr, offs + 4,
						(short) ((Character) value).charValue());
				offs += 6;
			}
			else if (c == Byte.class) {
				buf.extend(offs + 5);
				Bytes.pack4(buf.arr, offs, -2 - ClassDescriptor.tpByte);
				buf.arr[offs + 4] = ((Byte) value).byteValue();
				offs += 5;
			}
			else if (c == Short.class) {
				buf.extend(offs + 6);
				Bytes.pack4(buf.arr, offs, -2 - ClassDescriptor.tpShort);
				Bytes.pack2(buf.arr, offs + 4, ((Short) value).shortValue());
				offs += 6;
			}
			else if (c == Integer.class) {
				buf.extend(offs + 8);
				Bytes.pack4(buf.arr, offs, -2 - ClassDescriptor.tpInt);
				Bytes.pack4(buf.arr, offs + 4, ((Integer) value).intValue());
				offs += 8;
			}
			else if (c == Long.class) {
				buf.extend(offs + 12);
				Bytes.pack4(buf.arr, offs, -2 - ClassDescriptor.tpLong);
				Bytes.pack8(buf.arr, offs + 4, ((Long) value).longValue());
				offs += 12;
			}
			else if (c == Float.class) {
				buf.extend(offs + 8);
				Bytes.pack4(buf.arr, offs, -2 - ClassDescriptor.tpFloat);
				Bytes.pack4(buf.arr, offs + 4,
						Float.floatToIntBits(((Float) value).floatValue()));
				offs += 8;
			}
			else if (c == Double.class) {
				buf.extend(offs + 12);
				Bytes.pack4(buf.arr, offs, -2 - ClassDescriptor.tpDouble);
				Bytes.pack8(buf.arr, offs + 4,
						Double.doubleToLongBits(((Double) value).doubleValue()));
				offs += 12;
			}
			else if (c == Date.class) {
				buf.extend(offs + 12);
				Bytes.pack4(buf.arr, offs, -2 - ClassDescriptor.tpDate);
				Bytes.pack8(buf.arr, offs + 4, ((Date) value).getTime());
				offs += 12;
			}
			else {
				ByteArrayOutputStream bout = new ByteArrayOutputStream();
				ObjectOutputStream out = loaderMap != null
						&& (compatibilityMode & CLASS_LOADER_SERIALIZATION_COMPATIBILITY_MODE) == 0 ? (ObjectOutputStream) new AnnotatedPersistentObjectOutputStream(
						bout)
						: (ObjectOutputStream) new PersistentObjectOutputStream(
								bout);
				out.writeObject(value);
				out.close();
				byte[] arr = bout.toByteArray();
				int len = arr.length;
				buf.extend(offs + 4 + len);
				Bytes.pack4(buf.arr, offs, len);
				offs += 4;
				System.arraycopy(arr, 0, buf.arr, offs, len);
				offs += len;
			}
		}

		return offs;
	}