class ComplaintEventListener implements ApplicationListener<AcmObjectHistoryEvent> {

    @Override
    public void onApplicationEvent(AcmObjectHistoryEvent event)
    {
        if (event != null)
        {
            AcmObjectHistory acmObjectHistory = (AcmObjectHistory) event.getSource();

            boolean isComplaint = checkExecution(acmObjectHistory.getObjectType());

            if (isComplaint)
            {

                String ipAddress = event.getIpAddress();

                // Converter for JSON string to Object
                AcmUnmarshaller converter = getObjectConverter().getJsonUnmarshaller();

                String jsonUpdatedComplaint = acmObjectHistory.getObjectString();
                Complaint updatedComplaint = converter.unmarshall(jsonUpdatedComplaint, Complaint.class);

                AcmAssignment acmAssignment = createAcmAssignment(updatedComplaint);

                AcmObjectHistory acmObjectHistoryExisting = getAcmObjectHistoryService()
                        .getAcmObjectHistory(updatedComplaint.getComplaintId(), ComplaintConstants.OBJECT_TYPE);

                if (acmObjectHistoryExisting != null)
                {
                    String json = acmObjectHistoryExisting.getObjectString();
                    Complaint existing = converter.unmarshall(json, Complaint.class);

                    acmAssignment.setOldAssignee(ParticipantUtils.getAssigneeIdFromParticipants(existing.getParticipants()));

                    if (isPriorityChanged(existing, updatedComplaint))
                    {
                        getComplaintEventPublisher().publishComplaintModified(updatedComplaint, ipAddress, "priority.changed");
                    }

                    if (isDetailsChanged(existing, updatedComplaint))
                    {
                        getComplaintEventPublisher().publishComplaintModified(updatedComplaint, ipAddress, "details.changed");
                    }

                    if (isStatusChanged(existing, updatedComplaint))
                    {
                        String calId = updatedComplaint.getContainer().getCalendarFolderId();
                        if (shouldDeleteOnClose() && calId != null && complaintStatusClosed.contains(updatedComplaint.getStatus()))
                        {

                            // delete shared calendar if complaint closed
                            Optional<AcmOutlookUser> user = calendarAdminService
                                    .getEventListenerOutlookUser(ComplaintConstants.OBJECT_TYPE);
                            // if integration is not enabled the user will be null.
                            if (user.isPresent())
                            {
                                getCalendarService().deleteFolder(user.get(), updatedComplaint.getContainer(),
                                        DeleteMode.MoveToDeletedItems);

                                folderCreatorDao.deleteObjectReference(updatedComplaint.getId(), updatedComplaint.getObjectType());
                            }
                        }
                        getComplaintEventPublisher().publishComplaintModified(updatedComplaint, ipAddress, "status.changed",
                                "from " + existing.getStatus() + " to " + updatedComplaint.getStatus());
                    }

                    if (isLocationChanged(existing, updatedComplaint))
                    {
                        getComplaintEventPublisher().publishComplaintModified(updatedComplaint, ipAddress, "location.updated");
                    }

                    checkParticipants(existing, updatedComplaint, event.getIpAddress());

                }

                if (isAssigneeChanged(acmAssignment))
                {
                    // Save assignment change in the database
                    getAcmAssignmentDao().save(acmAssignment);

                    // Raise an event
                    getAcmObjectHistoryEventPublisher().publishAssigneeChangeEvent(acmAssignment, event.getUserId(), ipAddress);
                }
            }
        }
    }

}