class BusinessObjectDataStatusChangeMessageBuilder extends AbstractNotificationMessageBuilder implements NotificationMessageBuilder {

    @Override
    @SuppressFBWarnings(value = "BC_UNCONFIRMED_CAST", justification =
        "The NotificationEvent is cast to a BusinessObjectDataStatusChangeNotificationEvent which is always the case since" +
            " we manage the event type to a builder in a map defined in NotificationMessageManager")
    public Map<String, Object> getNotificationMessageVelocityContextMap(NotificationEvent notificationEvent)
    {
        BusinessObjectDataStatusChangeNotificationEvent event = (BusinessObjectDataStatusChangeNotificationEvent) notificationEvent;

        // Create a context map of values that can be used when building the message.
        Map<String, Object> velocityContextMap = new HashMap<>();
        addObjectPropertyToContext(velocityContextMap, "businessObjectDataKey", event.getBusinessObjectDataKey(),
            escapeJsonBusinessObjectDataKey(event.getBusinessObjectDataKey()), escapeXmlBusinessObjectDataKey(event.getBusinessObjectDataKey()));
        addStringPropertyToContext(velocityContextMap, "newBusinessObjectDataStatus", event.getNewBusinessObjectDataStatus());
        addStringPropertyToContext(velocityContextMap, "oldBusinessObjectDataStatus", event.getOldBusinessObjectDataStatus());

        // Retrieve business object data entity and business object data id to the context.
        BusinessObjectDataEntity businessObjectDataEntity = businessObjectDataDaoHelper.getBusinessObjectDataEntity(event.getBusinessObjectDataKey());
        velocityContextMap.put("businessObjectDataId", businessObjectDataEntity.getId());

        BusinessObjectFormatEntity businessObjectFormatEntity = businessObjectDataEntity.getBusinessObjectFormat();

        // Load all attribute definitions for this business object data in a map for easy access.
        Map<String, BusinessObjectDataAttributeDefinitionEntity> attributeDefinitionEntityMap =
            businessObjectFormatHelper.getAttributeDefinitionEntities(businessObjectFormatEntity);

        // Build an ordered map of business object data attributes that are flagged to be published in notification messages.
        Map<String, String> businessObjectDataAttributes = new LinkedHashMap<>();
        Map<String, String> businessObjectDataAttributesWithJson = new LinkedHashMap<>();
        Map<String, String> businessObjectDataAttributesWithXml = new LinkedHashMap<>();
        if (!attributeDefinitionEntityMap.isEmpty())
        {
            for (BusinessObjectDataAttributeEntity attributeEntity : businessObjectDataEntity.getAttributes())
            {
                if (attributeDefinitionEntityMap.containsKey(attributeEntity.getName().toUpperCase()))
                {
                    BusinessObjectDataAttributeDefinitionEntity attributeDefinitionEntity =
                        attributeDefinitionEntityMap.get(attributeEntity.getName().toUpperCase());

                    if (BooleanUtils.isTrue(attributeDefinitionEntity.getPublish()))
                    {
                        businessObjectDataAttributes.put(attributeEntity.getName(), attributeEntity.getValue());
                        businessObjectDataAttributesWithJson.put(escapeJson(attributeEntity.getName()), escapeJson(attributeEntity.getValue()));
                        businessObjectDataAttributesWithXml.put(escapeXml(attributeEntity.getName()), escapeXml(attributeEntity.getValue()));
                    }

                    if (BooleanUtils.isTrue(attributeDefinitionEntity.getPublishForFilter()))
                    {

                        // Get notification header key for filter attribute value
                        String filterAttributeKey = configurationHelper.getRequiredProperty(ConfigurationValue.MESSAGE_HEADER_KEY_FILTER_ATTRIBUTE_VALUE);
                        if (velocityContextMap.containsKey(filterAttributeKey))
                        {
                            throw new IllegalStateException(String.format("Multiple attributes are marked as publishForFilter for business object format {%s}.",
                                    businessObjectFormatHelper.businessObjectFormatEntityAltKeyToString(businessObjectFormatEntity)));
                        }

                        addStringPropertyToContext(velocityContextMap, filterAttributeKey, attributeEntity.getValue());
                    }
                }
            }
        }

        // Add the map of business object data attributes to the context.
        addObjectPropertyToContext(velocityContextMap, "businessObjectDataAttributes", businessObjectDataAttributes, businessObjectDataAttributesWithJson,
            businessObjectDataAttributesWithXml);

        // Add the namespace Velocity property for the header.
        addStringPropertyToContext(velocityContextMap, "namespace", event.getBusinessObjectDataKey().getNamespace());

        return velocityContextMap;
    }

}