class AsyncTaskLifeCycleEventProducer extends PersistableEventListener implements TaskLifeCycleEventListener {

    @Override
    public void afterTaskUpdatedEvent(TaskEvent event) {
        String userId = event.getTaskContext().getUserId();
        Task ti = event.getTask();
        
        List<TaskEventImpl> taskEvents = new ArrayList<>();
        
        TaskPersistenceContext persistenceContext = getPersistenceContext(((TaskContext)event.getTaskContext()).getPersistenceContext());
        try {
            AuditTaskImpl auditTaskImpl = getAuditTask(persistenceContext, ti); 
            if((ti.getDescription() != null && !ti.getDescription().equals(auditTaskImpl.getDescription()))
                    || (ti.getDescription() == null && auditTaskImpl.getDescription() != null)){
                String message = getUpdateFieldLog("Description", auditTaskImpl.getDescription(), ti.getDescription());
    
                TaskEventImpl taskEvent = new TaskEventImpl(ti.getId(),
                            org.kie.internal.task.api.model.TaskEvent.TaskEventType.UPDATED,
                            ti.getTaskData().getProcessInstanceId(), ti.getTaskData().getWorkItemId(), userId, message);
                taskEvents.add(taskEvent);
            }
            if( (ti.getName() != null && !ti.getName().equals(auditTaskImpl.getName()))
                    || (ti.getName() == null && auditTaskImpl.getName() != null)){
                String message = getUpdateFieldLog("Name", auditTaskImpl.getName(), ti.getName());
                TaskEventImpl taskEvent = new TaskEventImpl(ti.getId(),
                            org.kie.internal.task.api.model.TaskEvent.TaskEventType.UPDATED,
                            ti.getTaskData().getProcessInstanceId(), ti.getTaskData().getWorkItemId(), userId, message);
                taskEvents.add(taskEvent);
            }
            if( auditTaskImpl.getPriority() != ti.getPriority()){
                String message = getUpdateFieldLog("Priority", String.valueOf(auditTaskImpl.getPriority()), String.valueOf(ti.getPriority()));
                TaskEventImpl taskEvent = new TaskEventImpl(ti.getId(),
                            org.kie.internal.task.api.model.TaskEvent.TaskEventType.UPDATED,
                            ti.getTaskData().getProcessInstanceId(), ti.getTaskData().getWorkItemId(), userId, message);
                taskEvents.add(taskEvent);
            }
    
            if((auditTaskImpl.getDueDate() != null && ti.getTaskData().getExpirationTime() != null 
                    && auditTaskImpl.getDueDate().getTime() != ti.getTaskData().getExpirationTime().getTime()) 
                    || (auditTaskImpl.getDueDate() == null && ti.getTaskData().getExpirationTime() != null)
                    || (auditTaskImpl.getDueDate() != null && ti.getTaskData().getExpirationTime() == null)){
                String fromDate = (auditTaskImpl.getDueDate() != null ? new Date(auditTaskImpl.getDueDate().getTime()).toString(): null);
                String toDate = (ti.getTaskData().getExpirationTime()!= null ? ti.getTaskData().getExpirationTime().toString() : "" );
                String message = getUpdateFieldLog( "DueDate",
                                                    fromDate,
                                                    toDate );
                TaskEventImpl taskEvent = new TaskEventImpl(ti.getId(),
                            org.kie.internal.task.api.model.TaskEvent.TaskEventType.UPDATED,
                            ti.getTaskData().getProcessInstanceId(), ti.getTaskData().getWorkItemId(), userId, message);
                taskEvents.add(taskEvent);
            }
    
            auditTaskImpl.setDescription(ti.getDescription());
            auditTaskImpl.setName(ti.getName());
            auditTaskImpl.setPriority(ti.getPriority());
            auditTaskImpl.setDueDate(ti.getTaskData().getExpirationTime());
            auditTaskImpl.setLastModificationDate(event.getEventDate());
            
            sendMessage(new AuditTaskData(auditTaskImpl, taskEvents), 4);
        } finally {
            cleanup(persistenceContext);
        }
    }

    public  AsyncTaskLifeCycleEventProducer();

}