parseAndHandleEntityV2 = function (parsedContent, luResource, log, locale) {
    let featuresToProcess = [];
    // handle new entity definitions.
    let entities = luResource.Sections.filter(s => s.SectionType === SectionType.NEWENTITYSECTION);
    if (entities && entities.length > 0) {
        for (const entity of entities) {
            if (entity.Type !== INTENTTYPE) {
                if (entity.Name.endsWith(PLCONSTS.INTERCHANGEABLE)) {
                    entity.Name = entity.Name.slice(0, entity.Name.length - PLCONSTS.INTERCHANGEABLE.length).trim().replace(/^[\'\"]|[\'\"]$/g, "") + PLCONSTS.INTERCHANGEABLE
                } else {
                    entity.Name = entity.Name.replace(/^[\'\"]|[\'\"]$/g, "");
                }
                
                let entityName = entity.Name.endsWith('=') ? entity.Name.slice(0, entity.Name.length - 1) : entity.Name;
                let entityType = !entity.Type ? getEntityType(entity.Name, entities) : entity.Type;
                if (!entityType) {
                    let errorMsg = `No type definition found for entity "${entityName}". Supported types are ${Object.values(EntityTypeEnum).join(', ')}. Note: Type names are case sensitive.`;
                    let error = BuildDiagnostic({
                        message: errorMsg,
                        range: entity.Range
                    })
                    throw (new exception(retCode.errorCode.INVALID_INPUT, error.toString(), [error]));
                };

                if (entityType === entityName) {
                    let errorMsg = `Entity name "${entityName}" cannot be the same as entity type "${entityType}"`;
                    let error = BuildDiagnostic({
                        message: errorMsg,
                        range: entity.Range
                    })
                    throw (new exception(retCode.errorCode.INVALID_INPUT, error.toString(), [error]));
                }
                let entityRoles = validateAndGetRoles(parsedContent, entity.Roles, entity.Range, entityName, entityType);
                let PAEntityRoles = RemoveDuplicatePatternAnyEntity(parsedContent, entityName, entityType, entity.Range);
                if (PAEntityRoles.length > 0) {
                    PAEntityRoles.forEach(role => {
                        if (!entityRoles.includes(role)) entityRoles.push(role);
                    })
                }
                switch(entityType) {
                    case EntityTypeEnum.ML:
                        handleNDepthEntity(parsedContent, entityName, entityRoles, entity.ListBody, entity.Range);
                        break;
                    case EntityTypeEnum.SIMPLE: 
                        addItemOrRoleIfNotPresent(parsedContent.LUISJsonStructure, LUISObjNameEnum.ENTITIES, entityName, entityRoles);
                        break;
                    case EntityTypeEnum.COMPOSITE:
                        let candidateChildren = [];
                        if (entity.CompositeDefinition) {
                            entity.CompositeDefinition.replace(/[\[\]]/g, '').split(/[,;]/g).map(item => item.trim()).forEach(item => candidateChildren.push(item));
                        }
                        if (entity.ListBody) {
                            entity.ListBody.forEach(line => {
                                line.trim().substr(1).trim().replace(/[\[\]]/g, '').split(/[,;]/g).map(item => item.trim()).forEach(item => candidateChildren.push(item));
                            })
                        }
                        handleComposite(parsedContent, entityName,`[${candidateChildren.join(',')}]`, entityRoles, entity.Range, false, entity.Type !== undefined);
                        break;
                    case EntityTypeEnum.LIST:
                        handleClosedList(parsedContent, entityName, entity.ListBody.map(item => item.trim()), entityRoles, entity.Range);
                        break;
                    case EntityTypeEnum.PATTERNANY:
                        handlePatternAny(parsedContent, entityName, entityRoles, entity.Range);
                        break;
                    case EntityTypeEnum.PREBUILT:
                        handlePrebuiltEntity(parsedContent, 'prebuilt', entityName, entityRoles, locale, log, entity.Range);
                        break;
                    case EntityTypeEnum.REGEX:
                        if (entity.ListBody[0]) {
                            handleRegExEntity(parsedContent, entityName, entity.ListBody[0].trim().substr(1).trim(), entityRoles, entity.Range);
                        } else {
                            handleRegExEntity(parsedContent, entityName, entity.RegexDefinition, entityRoles, entity.Range);
                        } 
                        break;
                    case EntityTypeEnum.ML:
                        break;
                    case EntityTypeEnum.PHRASELIST:
                        handlePhraseList(parsedContent, entityName, entity.Type, entityRoles, entity.ListBody.map(item => item.trim().substr(1).trim()), entity.Range);
                    default:
                        //Unknown entity type
                        break;
                }
                if (entity.Features !== undefined) {
                    featuresToProcess.push(entity);
                }
            } else {
                featuresToProcess.push(entity);
            }
        }
    }

    return featuresToProcess;
}
@param {parserObj} Object with that contains list of additional files to parse, parsed LUIS object and parsed QnA object
@param {LUResouce} luResource resources extracted from lu file content
@param {boolean} log indicates where verbose flag is set 
@param {String} locale current target locale
@throws {exception} Throws on errors. exception object includes errCode and text.
@returns {NewEntitySection[]} collection of NewEntitySection to process after all other sections are processed.