/**
  * Finalize the mapping and make sure that it is consistent.
  *
  * @throws MappingException if inconsistencies are discovered.
  */
 public function validateClassMapping()
 {
     // associative array fields need a separate property to store the keys.
     // make sure that generated or specified name does not collide with an
     // existing mapping.
     $assocFields = array();
     foreach ($this->fieldMappings as $fieldName) {
         $mapping = $this->mappings[$fieldName];
         if (empty($mapping['assoc'])) {
             continue;
         }
         if (isset($this->mappings[$mapping['assoc']])) {
             throw MappingException::assocOverlappingFieldDefinition($this->name, $fieldName, $mapping['assoc']);
         }
         if (!empty($assocFields[$mapping['assoc']])) {
             throw MappingException::assocOverlappingAssocDefinition($this->name, $fieldName, $assocFields[$mapping['assoc']]);
         }
         $assocFields[$mapping['assoc']] = $fieldName;
     }
     if (!empty($this->versionNameField) && !$this->versionable) {
         throw new MappingException(sprintf("You cannot use the @VersionName annotation on the non-versionable document %s (field = %s)", $this->name, $this->versionNameField));
     }
     if (!empty($this->versionCreatedField) && !$this->versionable) {
         throw new MappingException(sprintf("You cannot use the @VersionCreated annotation on the non-versionable document %s (field = %s)", $this->name, $this->versionCreatedField));
     }
     if (count($this->translatableFields)) {
         if (!isset($this->localeMapping)) {
             throw new MappingException("You must define a locale mapping for translatable document '" . $this->name . "'");
         }
     }
     // we allow mixed referrers on non-referenceable documents. maybe the mix:referenceable is just not mapped
     if (count($this->referrersMappings)) {
         if (!$this->referenceable) {
             throw new MappingException('You can not have referrers mapped on document "' . $this->name . '" as the document is not referenceable');
         }
         foreach ($this->referrersMappings as $referrerName) {
             $mapping = $this->mappings[$referrerName];
             // only a santiy check with reflection. otherwise we could run into endless loops
             if (!ClassLoader::classExists($mapping['referringDocument'])) {
                 throw new MappingException(sprintf('Invalid referrer mapping on document "%s" for field "%s": The referringDocument class "%s" does not exist', $this->name, $mapping['fieldName'], $mapping['referringDocument']));
             }
             $reflection = new ReflectionClass($mapping['referringDocument']);
             if (!$reflection->hasProperty($mapping['referencedBy'])) {
                 throw new MappingException(sprintf('Invalid referrer mapping on document "%s" for field "%s": The referringDocument "%s" has no property "%s"', $this->name, $mapping['fieldName'], $mapping['referringDocument'], $mapping['referencedBy']));
             }
         }
     }
     $this->validateIdentifier();
 }