public void encode(ExtendedObjectOutput out, Object v)
      throws IOException, IllegalAccessException, InvocationTargetException {
    String detachedState = null;

    if (v instanceof HibernateProxy) {
      HibernateProxy proxy = (HibernateProxy) v;

      // Only write initialized flag, detachedState & id if v is an uninitialized proxy.
      if (proxy.getHibernateLazyInitializer().isUninitialized()) {

        Class<?> persistentClass = proxy.getHibernateLazyInitializer().getPersistentClass();
        if (!serializableProxyAdapters.containsKey(persistentClass)) {
          try {
            SerializableProxyAdapter proxyAdapter = new SerializableProxyAdapter(proxy);
            serializableProxyAdapters.putIfAbsent(persistentClass, proxyAdapter);
          } catch (Exception e) {
            throw new IOException("Could not create SerializableProxyAdapter for: " + proxy);
          }
        }

        Serializable id = proxy.getHibernateLazyInitializer().getIdentifier();
        log.debug("Writing uninitialized HibernateProxy %s with id %s", detachedState, id);

        out.writeBoolean(false);
        out.writeUTF(null);
        out.writeObject(id);
        return;
      }

      // Proxy is initialized, get the underlying persistent object.
      log.debug("Writing initialized HibernateProxy...");
      v = proxy.getHibernateLazyInitializer().getImplementation();
    }

    // Write initialized flag & detachedState.
    out.writeBoolean(true);
    out.writeUTF(null);

    // Write all properties in lexical order.
    List<Property> properties = out.getReflection().findSerializableProperties(v.getClass());
    for (Property property : properties) out.getAndWriteProperty(v, property);
  }
  protected Class<?> getClass(ExtendedObjectOutput out, Object v) {
    Class<?> cls = v.getClass();

    if (v instanceof HibernateProxy) {
      LazyInitializer initializer = ((HibernateProxy) v).getHibernateLazyInitializer();

      String className =
          (initializer.isUninitialized()
              ? initializer.getEntityName()
              : initializer.getImplementation().getClass().getName());

      if (className != null && className.length() > 0) {
        try {
          cls = out.getReflection().loadClass(className);
        } catch (ClassNotFoundException e) {
          cls = initializer.getPersistentClass();
        }
      }
    }

    return cls;
  }