class AsyncCaseInstanceAuditEventProducer implements CaseEventListener, Cacheable {

    @Override
    public void afterCaseStarted(CaseStartEvent event) {
        
        CaseFileInstance caseFile = event.getCaseFile();
        if (caseFile == null) {
            return;
        }
        List<CaseRoleAssignmentLog> caseRoleAssignmentsLogs = new ArrayList<>();
        Collection<CaseRoleInstance> caseRoleAssignments = ((CaseFileInstanceImpl)caseFile).getAssignments();
        if (caseRoleAssignments != null && !caseRoleAssignments.isEmpty()) {
            for (CaseRoleInstance roleAssignment : caseRoleAssignments) {
                logger.debug("Role {} has following assignments {}", roleAssignment.getRoleName(), roleAssignment.getRoleAssignments());
                
                if (roleAssignment.getRoleAssignments() != null && !roleAssignment.getRoleAssignments().isEmpty()) {
                    
                    roleAssignment.getRoleAssignments().forEach(entity -> {
                        CaseRoleAssignmentLog assignmentLog = new CaseRoleAssignmentLog(event.getProcessInstanceId(), event.getCaseId(), roleAssignment.getRoleName(), entity);
                        
                        caseRoleAssignmentsLogs.add(assignmentLog);
                    });
                    
                }
            }
        } else {
            // add public role so it can be found by queries that take assignments into consideration
            CaseRoleAssignmentLog assignmentLog = new CaseRoleAssignmentLog(event.getProcessInstanceId(), event.getCaseId(), "*", TaskModelProvider.getFactory().newGroup(AuthorizationManager.PUBLIC_GROUP));
            caseRoleAssignmentsLogs.add(assignmentLog);
        }
        
        Map<String, Object> initialData = caseFile.getData();
        List<CaseFileData> caseFileDataLogs = new ArrayList<>();
        if (!initialData.isEmpty()) {
        
        
            initialData.forEach((name, value) -> {
                
                if (value != null) {
                    List<CaseFileData> indexedValues = indexManager.index(event, name, value); 
                                                        
                    caseFileDataLogs.addAll(indexedValues);                    
                }
            });
        }
        sendMessage(AFTER_CASE_STARTED_EVENT_TYPE, new AuditCaseInstanceData(event.getCaseId(), caseFileDataLogs, caseRoleAssignmentsLogs), 8);
    }

    public  AsyncCaseInstanceAuditEventProducer();

}