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 serializeImpl($instance, Clazz $instanceClass)
 {
     assert(!is_null($instance));
     $customSerializer = SerializabilityUtilEx::hasCustomFieldSerializer($instanceClass);
     if (!is_null($customSerializer)) {
         // Use custom field serializer
         $customFieldSerializer = SerializabilityUtilEx::loadCustomFieldSerializer($customSerializer);
         if (is_null($customFieldSerializer)) {
             $this->serializeWithCustomSerializer($customSerializer, $instance, $instanceClass);
         } else {
             $customFieldSerializer->serializeInstance($this, $instance);
         }
     } else {
         if ($instanceClass->isArray()) {
             $this->serializeArray($instanceClass, $instance);
         } else {
             if ($instanceClass->isEnum()) {
                 $this->writeInt($instance);
             } else {
                 // Regular class instance
                 $this->serializeClass($instance, $instanceClass);
             }
         }
     }
 }