/**
  * @param ORM\Mapping\ClassMetadata $metadata
  * @param array $config
  *
  * @return array
  *
  * @throws Exceptions\InvalidMappingException
  * @throws ORM\Mapping\MappingException
  */
 private function readExtendedMetadata(ORM\Mapping\ClassMetadata $metadata, array $config)
 {
     $class = $metadata->getReflectionClass();
     // Create doctrine annotation reader
     $reader = $this->getDefaultAnnotationReader();
     // Property annotations
     foreach ($class->getProperties() as $property) {
         if ($metadata->isMappedSuperclass && $property->isPrivate() === FALSE || $metadata->isInheritedField($property->getName()) || isset($metadata->associationMappings[$property->getName()]['inherited'])) {
             continue;
         }
         /** @var Mapping\Annotation\Timestampable $timestampable */
         if ($timestampable = $reader->getPropertyAnnotation($property, self::EXTENSION_ANNOTATION)) {
             $field = $property->getName();
             // No map field nor association
             if ($metadata->hasField($field) === FALSE && $metadata->hasAssociation($field) === FALSE && $this->configuration->useLazyAssociation() === FALSE) {
                 if ($this->configuration->autoMapField()) {
                     $metadata->mapField(['fieldName' => $field, 'type' => $this->configuration->dbFieldType, 'nullable' => TRUE]);
                 } else {
                     throw new Exceptions\InvalidMappingException("Unable to find timestampable [{$field}] as mapped property in entity - {$metadata->getName()}");
                 }
             }
             if ($metadata->hasField($field)) {
                 if (!$this->isValidField($metadata, $field) && $this->configuration->useLazyAssociation() === FALSE) {
                     throw new Exceptions\InvalidMappingException("Field - [{$field}] type is not valid and must be 'string' or a one-to-many relation in class - {$metadata->getName()}");
                 }
             }
             // Check for valid events
             if (!in_array($timestampable->on, ['update', 'create', 'change', 'delete'])) {
                 throw new Exceptions\InvalidMappingException("Field - [{$field}] trigger 'on' is not one of [update, create, change] in class - {$metadata->getName()}");
             }
             if ($timestampable->on === 'change') {
                 if (!isset($timestampable->field)) {
                     throw new Exceptions\InvalidMappingException("Missing parameters on property - {$field}, field must be set on [change] trigger in class - {$metadata->getName()}");
                 }
                 if (is_array($timestampable->field) && isset($timestampable->value)) {
                     throw new Exceptions\InvalidMappingException("Timestampable extension does not support multiple value changeset detection yet.");
                 }
                 $field = ['field' => $field, 'trackedField' => $timestampable->field, 'value' => is_array($timestampable->value) ? $timestampable->value : [$timestampable->value]];
             }
             // properties are unique and mapper checks that, no risk here
             $config[$timestampable->on][] = $field;
         }
     }
     return $config;
 }