/**
  * Denormalizes a relation.
  *
  * @param ResourceInterface          $currentResource
  * @param AttributeMetadataInterface $attributeMetadata
  * @param string                     $class
  * @param mixed                      $value
  * @param array                      $context
  *
  * @return object|null
  *
  * @throws InvalidArgumentException
  */
 private function denormalizeRelation(ResourceInterface $currentResource, AttributeMetadataInterface $attributeMetadata, $class, $value, array $context)
 {
     if ('DateTime' === $class) {
         return $this->serializer->denormalize($value, $class ?: null, self::FORMAT, $context);
     }
     $attributeName = $attributeMetadata->getName();
     // Always allow IRI to be compliant with the Hydra spec
     if (is_string($value)) {
         $item = $this->iriConverter->getItemFromIri($value);
         if (null === $item) {
             throw new InvalidArgumentException(sprintf('IRI  not supported (found "%s" in "%s" of "%s")', $value, $attributeName, $currentResource->getEntityClass()));
         }
         return $item;
     }
     if (!($resource = $this->resourceCollection->getResourceForEntity($class))) {
         throw new InvalidArgumentException(sprintf('Type not supported (found "%s" in attribute "%s" of "%s")', $class, $attributeName, $currentResource->getEntityClass()));
     }
     if (!$attributeMetadata->isDenormalizationLink()) {
         return $this->serializer->denormalize($value, $class, self::FORMAT, $this->createRelationContext($resource, $context));
     }
     throw new InvalidArgumentException(sprintf('Nested objects for attribute "%s" of "%s" are not enabled. Use serialization groups to change that behavior.', $attributeName, $currentResource->getEntityClass()));
 }
 /**
  * Populates normalization and denormalization links.
  *
  * @param ClassMetadataInterface     $classMetadata
  * @param string                     $attributeName
  * @param AttributeMetadataInterface $attributeMetadata
  * @param array|null                 $normalizationGroups
  * @param array|null                 $denormalizationGroups
  *
  * @return ClassMetadataInterface
  */
 private function populateNormalizationLinks(ClassMetadataInterface $classMetadata, $attributeName, AttributeMetadataInterface $attributeMetadata, array $normalizationGroups = null, array $denormalizationGroups = null)
 {
     if (!$classMetadata->hasAttributeMetadata($attributeName) || !$attributeMetadata->isLink() || $attributeMetadata->isNormalizationLink() && $attributeMetadata->isDenormalizationLink()) {
         return $classMetadata;
     }
     $relationSerializerMetadata = $this->serializerClassMetadataFactory->getMetadataFor($attributeMetadata->getLinkClass());
     if (!$relationSerializerMetadata) {
         $attributeMetadata = $attributeMetadata->withNormalizationLink(true)->withDenormalizationLink(true);
         return $classMetadata->withAttributeMetadata($attributeName, $attributeMetadata);
     }
     foreach ($relationSerializerMetadata->getAttributesMetadata() as $serializerAttributeMetadata) {
         $serializerAttributeGroups = $serializerAttributeMetadata->getGroups();
         if (null !== $normalizationGroups && 1 <= count(array_intersect($normalizationGroups, $serializerAttributeGroups))) {
             $normalizationLink = false;
         }
         if (null !== $denormalizationGroups && 1 <= count(array_intersect($denormalizationGroups, $serializerAttributeGroups))) {
             $denormalizationLink = false;
         }
         if (isset($normalizationLink) && isset($denormalizationLink)) {
             $classMetadata = $classMetadata->withAttributeMetadata($attributeName, $attributeMetadata);
         }
     }
     if (!isset($normalizationLink)) {
         $attributeMetadata = $attributeMetadata->withNormalizationLink(true);
     }
     if (!isset($denormalizationLink)) {
         $attributeMetadata = $attributeMetadata->withDenormalizationLink(true);
     }
     return $classMetadata->withAttributeMetadata($attributeName, $attributeMetadata);
 }