protected function CastResponseToEntity($response, $entityClassName, $asDependentObject = false)
    {
        if (is_array($response)) {
            $list = array();
            foreach ($response as $responseObject) {
                array_push($list, $this->CastResponseToEntity($responseObject, $entityClassName));
            }

            return $list;
        }

        if (is_string($entityClassName)) {
            $entity = new $entityClassName();
        } else {
            throw new Exception('Cannot cast response to entity object. Wrong entity class name');
        }

        $responseReflection = new \ReflectionObject($response);
        $entityReflection = new \ReflectionObject($entity);
        $responseProperties = $responseReflection->getProperties();

        $subObjects = $entity->GetSubObjects();
        $dependsObjects = $entity->GetDependsObjects();

        foreach ($responseProperties as $responseProperty) {
            $responseProperty->setAccessible(true);

            $name = $responseProperty->getName();
            $value = $responseProperty->getValue($response);

            if ($entityReflection->hasProperty($name)) {
                $entityProperty = $entityReflection->getProperty($name);
                $entityProperty->setAccessible(true);

                if ($entityProperty->getName() == "DeclaredUBOs") {
                    $declaredUbos = [];
                    foreach ($value as $declaredUboRaw) {
                        $declaredUbo = new \MangoPay\DeclaredUbo();
                        $declaredUbo->UserId = $declaredUboRaw->UserId;
                        $declaredUbo->Status = $declaredUboRaw->Status;
                        $declaredUbo->RefusedReasonType = $declaredUboRaw->RefusedReasonMessage;
                        $declaredUbo->RefusedReasonMessage = $declaredUboRaw->RefusedReasonMessage;
                        array_push($declaredUbos, $declaredUbo);
                    }
                    $value = $declaredUbos;
                }

                // is sub object?
                if (isset($subObjects[$name])) {
                    if (is_null($value)) {
                        $object = null;
                    } else {
                        $object = $this->CastResponseToEntity($value, $subObjects[$name]);
                    }

                    $entityProperty->setValue($entity, $object);
                } else {
                    $entityProperty->setValue($entity, $value);
                }

                // has dependent object?
                if (isset($dependsObjects[$name])) {
                    $dependsObject = $dependsObjects[$name];
                    $entityDependProperty = $entityReflection->getProperty($dependsObject['_property_name']);
                    $entityDependProperty->setAccessible(true);
                    $entityDependProperty->setValue($entity, $this->CastResponseToEntity($response, $dependsObject[$value], true));
                }
            } else {
                if ($asDependentObject || !empty($dependsObjects)) {
                    continue;
                } else {
                    /* UNCOMMENT THE LINE BELOW TO ENABLE RESTRICTIVE REFLECTION MODE */
                    //throw new Exception('Cannot cast response to entity object. Missing property ' . $name .' in entity ' . $entityClassName);

                    continue;
                }
            }
        }

        return $entity;
    }