class FunctionalityService {

    public List<FunctionalityWithChildrenDTO> moveList(long projectId, MoveFunctionalitiesDTO moveRequest) throws BadRequestException {
        if (moveRequest == null) {
            throw new BadRequestException(Messages.PARAMETER_IS_MISSING, Entities.FUNCTIONALITY, "move_functionality_list_missing_move_request_parameter");
        }
        Long destinationId = moveRequest.getReferenceId();
        if (destinationId == null) {
            throw new BadRequestException(Messages.PARAMETER_HAS_ONE_OR_MORE_MISSING_FIELDS, Entities.FUNCTIONALITY, "move_functionality_list_missing_reference_id");
        }
        List<Long> sourceIds = moveRequest.getSourceIds();
        if (CollectionUtils.isEmpty(sourceIds)) {
            throw new BadRequestException(Messages.PARAMETER_HAS_ONE_OR_MORE_MISSING_FIELDS, Entities.FUNCTIONALITY, "move_functionality_list_missing_sources_id");
        }
        Functionality referenceFunctionality = repository.findByProjectIdAndId(projectId, destinationId)
                .orElseThrow(() -> new NotFoundException(Messages.NOT_FOUND_FUNCTIONALITY_OR_FOLDER_REFERENCE, Entities.FUNCTIONALITY));

        List<Functionality> sourceFunctionalities = repository.findByProjectIdAndIdIn(projectId, sourceIds);
        Boolean notAllTheFunctionalitiesAreFound = sourceIds.size() != sourceFunctionalities.size();
        if (notAllTheFunctionalitiesAreFound) {
            throw new NotFoundException(Messages.NOT_FOUND_FUNCTIONALITY_OR_FOLDER_REFERENCE, Entities.FUNCTIONALITY);
        }

        for (Functionality sourceFunctionality : sourceFunctionalities) {
            TreePosition treePosition = computeDestinationTreePosition(projectId, destinationId, moveRequest.getRelativePosition(), sourceFunctionality);
            sourceFunctionality.setParentId(treePosition.getParentId());
            sourceFunctionality.setOrder(treePosition.getOrder());
        }

        repository.saveAll(sourceFunctionalities);
        return findAllAsTree(projectId);
    }

}