private function deserializeClass(Clazz $instanceClass, $instance)
 {
     /**
      * A map from field names to corresponding setter methods. The reference 
      * will be null for classes that do not require special handling for
      * server-only fields.
      */
     $setters = null;
     /**
      * A list of fields of this class known to the client. If null, assume the class is not
      * enhanced and don't attempt to deal with server-only fields.
      */
     $clientFieldNames = $this->serializationPolicy->getClientFieldNamesForEnhancedClass($instanceClass);
     if (!is_null($clientFieldNames)) {
         // Read and set server-only instance fields encoded in RPC data
         try {
             $encodedData = $this->readString();
             if (!is_null($encodedData)) {
                 $serializedData = Base64Utils::fromBase6($encodedData);
                 $ois = new ObjectInputStream($serializedData);
                 $count = $ois->readInt();
                 for ($i = 0; $i < $count; $i++) {
                     $fieldName = $ois->readString();
                     $fieldValue = $ois->readObject();
                     $field = $instanceClass->getField($fieldName);
                     $field->setAccessible(true);
                     $field->setValue($instance, $fieldValue);
                 }
             }
         } catch (Exception $e) {
             throw new SerializationException($e);
         }
         $setters = $this->getSetters($instanceClass);
     }
     $serializableFields = SerializabilityUtilEx::applyFieldSerializationPolicy($instanceClass);
     foreach ($serializableFields as $declField) {
         assert(!is_null($declField));
         if (!is_null($clientFieldNames) && !$clientFieldNames->contains($declField->getName())) {
             continue;
         }
         assert($declField->hasType());
         $value = $this->deserializeValue($declField->getType());
         $fieldName = $declField->getName();
         $setter = null;
         /*
          * If setters is non-null and there is a setter method for the given
          * field, call the setter. Otherwise, set the field value directly. For
          * persistence APIs such as JDO, the setter methods have been enhanced to
          * manipulate additional object state, causing direct field writes to fail
          * to update the object state properly.
          */
         if (!is_null($setters) && !is_null($setters = $setters->get($fieldName))) {
             $setter->invoke($instance, $value);
         } else {
             $isAccessible = $declField->isAccessible();
             $needsAccessOverride = !$isAccessible && !$declField->isPublic();
             if ($needsAccessOverride) {
                 // Override access restrictions
                 $declField->setAccessible(true);
             }
             $declField->setValue($instance, $value);
         }
     }
     $superClass = $instanceClass->getSuperClass();
     if ($this->serializationPolicy->shouldDeserializeFields($superClass)) {
         $this->deserializeImpl(SerializabilityUtilEx::hasCustomFieldSerializer($superClass), $superClass, $instance);
     }
 }
 private function serializeClass($instance, Clazz $instanceClass)
 {
     assert(!is_null($instance));
     $serializableFields = SerializabilityUtilEx::applyFieldSerializationPolicy($instanceClass);
     /*
      * If clientFieldNames is non-null, identify any additional server-only fields and serialize
      * them separately.  Java serialization is used to construct a byte array, which is encoded
      * as a String and written prior to the rest of the field data.
      */
     $clientFieldNames = $this->serializationPolicy->getClientFieldNamesForEnhancedClass($instanceClass);
     if (!is_null($clientFieldNames)) {
         $serverFields = array();
         foreach ($serializableFields as $declField) {
             assert(!is_null($declField));
             // Identity server-only fields
             if (!$clientFieldNames->contains($declField->getName())) {
                 $serverFields[] = $declField;
                 continue;
             }
         }
         // Serialize the server-only fields into a byte array and encode as a String
         $oos = new ObjectOutputStream();
         $oos->writeInt(count($serverFields));
         foreach ($serverFields as $f) {
             $oos->writeObject($f->getName());
             $f->setAccessible(true);
             $fieldData = $f->get($instance);
             $oos->writeObject($fieldData);
         }
         $oos->close();
         $encodedData = Base64Utils::toBase64((string) $oos);
         $this->writeString($encodedData);
     }
     // Write the client-visible field data
     foreach ($serializableFields as $declField) {
         if (!is_null($clientFieldNames) && !$clientFieldNames->contains($decl->getName())) {
             // Skip server-only fields
             continue;
         }
         $isAccessible = $declField->isAccessible();
         $needsAccessOverride = !$isAccessible && !$declField->isPublic();
         if ($needsAccessOverride) {
             // Override the access restrictions
             $declField->setAccessible(true);
         }
         $value = $declField->getValue($instance);
         $this->serializeValue($value, $declField->getType());
     }
     $superClass = $instanceClass->getSuperClass();
     if ($this->serializationPolicy->shouldSerializeFields($superClass)) {
         $this->serializeImpl($instance, $superClass);
     }
 }