public function addProperty(Property $property)
    {
        $fieldName = $property->getName();

        // Check for empty field name
        if (empty($fieldName)) {
            throw MappingException::missingFieldName($this->className);
        }

        $property->setDeclaringClass($this);

        switch (true) {
            case $property instanceof VersionFieldMetadata:
                $this->validateAndCompleteFieldMapping($property);
                $this->validateAndCompleteVersionFieldMapping($property);
                break;

            case $property instanceof FieldMetadata:
                $this->validateAndCompleteFieldMapping($property);
                break;

            case $property instanceof OneToOneAssociationMetadata:
                $this->validateAndCompleteAssociationMapping($property);
                $this->validateAndCompleteToOneAssociationMetadata($property);
                $this->validateAndCompleteOneToOneMapping($property);
                break;

            case $property instanceof OneToManyAssociationMetadata:
                $this->validateAndCompleteAssociationMapping($property);
                $this->validateAndCompleteToManyAssociationMetadata($property);
                $this->validateAndCompleteOneToManyMapping($property);
                break;

            case $property instanceof ManyToOneAssociationMetadata:
                $this->validateAndCompleteAssociationMapping($property);
                $this->validateAndCompleteToOneAssociationMetadata($property);
                $this->validateAndCompleteManyToOneMapping($property);
                break;

            case $property instanceof ManyToManyAssociationMetadata:
                $this->validateAndCompleteAssociationMapping($property);
                $this->validateAndCompleteToManyAssociationMetadata($property);
                $this->validateAndCompleteManyToManyMapping($property);
                break;

            default:
                // Transient properties are ignored on purpose here! =)
                break;
        }

        $this->addDeclaredProperty($property);
    }