I've just been looking at this now, in general it looks good
Most of the points below relate to performance, many of them were/are in fact present in the get_users_by_id method as well I think when I pointed it out to Jerome he choose to create issues so you could if this is urgent as well just link to those issues and comment in them that this new method needs to be cleaned up as well.
- Please fix the indenting of the get_course_participants_by_id_returns, could you please also fix the indenting of get_users_by_id_returns at the same time (I asked Jerome too but obviously forgot to check again before integrating).
- The if (empty($user->deleted)) should check check !empty and continue, it should also be at the top of the function before any other calls. Alternativily if you switch to fetching uses manually as suggested below in the perf notes you could just check it as a database condition.
Things that could be done to improve performance:
- Rather than fetching all user contexts and then all users through user_get_users_by_id you should just use a recordset to retrieve users AND their contexts at the same time (using context_instance_preload* functions).
- Rather than fetching the course and context for each user within foreach you should really be fetching all courses (unique($courseids)) and could be doing the same as above and preloading the contexts at the same time.
- When fetching the custom fields the code is fetching all the categories and foreach category fetching all fields, certainly this could be one query rather than queries within a foreach, just fetch all fields sorting by category.sortorder, then field sortorder.
So 2 minor points + 3 performance options. All looks good to me otherwise