private void raid_roster_impl(Context ctx, int id, string roles)
        {
            //Get a handle to the raid
            var handle = RaidManager.GetRaidFromID(id).Value;

            //Extract the roles to create our filter
            var filter = this.raidConfig.MatchRoles(roles);

            //Get the raiders that match the filter
            var roster = RaidManager.CoalesceRaiders(handle)
                         .Where(e => e.roles.Intersect(filter).Count() > 0)
                         .ToList();

            //Check that it's not empty
            if (roster.Count > 0)
            {
                //Resolve their names and roles
                var tmp = roster.Select(e =>
                {
                    //Get the name
                    var name = (e.user_id.HasValue) ? Bot.GetBotInstance().GetUserName(e.user_id.Value)
                                                    : e.user_name;

                    //Check if this entry is a backup
                    if (e.backup)
                    {
                        //Add the roles and cursive style
                        return($"*{name} - {string.Join(", ", e.roles)}*");
                    }

                    //Add the roles
                    return($"{name} - {string.Join(", ", e.roles)}");
                }).ToList();

                //Display the roster
                Bot.GetBotInstance()
                .SendSuccessMessage(ctx.message.Channel, "Result:", string.Join("\n", tmp), $"Count: {tmp.Count}");
            }
            else
            {
                //Empty roster
                Bot.GetBotInstance()
                .SendSuccessMessage(ctx.message.Channel, "Result:", $"None");
            }
        }
        private void raid_make_comp_impl(Context ctx, RaidHandle handle, /*readonly*/ string[] layout)
        {
            //Get the raiders
            var raiders = RaidManager.CoalesceRaiders(handle);

            //Generate composition
            var result = this.GenerateComp(raiders, layout, out Entry[] unused);

            //Setup the embed builder
            var builder = new EmbedBuilder().WithColor(Color.Blue);

            //Get the unique roles in this composition
            var roles = layout.Distinct().ToArray();

            //Go through each role
            foreach (var r in roles)
            {
                //Count the instances of this role in the layout
                var roleCount = layout.Count(str => r == str);

                //Get all players with this assigned role
                var players = result.Where(p => p.assignment == r);

                //Format the names
                var formatted = players.Select(p =>
                {
                    //Get the name of the player
                    var name = (p.player.user_id.HasValue ? Bot.GetBotInstance().GetUserName(p.player.user_id.Value) : p.player.user_name);

                    //Check if backup
                    if (p.player.backup)
                    {
                        //Add cursive
                        return($"*{name}*");
                    }
                    else
                    {
                        return(name);
                    }
                }).ToArray();

                //Check that it's not empty
                if (formatted.Length > 0)
                {
                    //Write the formatted names
                    builder = builder.AddField($"{r} ({formatted.Length}/{roleCount}):", string.Join('\n', formatted));
                }
                else
                {
                    //Add an empty field
                    builder = builder.AddField($"{r} (0/{roleCount}):", "...");
                }
            }

            //Check if we need to add a "not included" category
            if (unused.Length > 0)
            {
                //Format the names
                var formatted = unused.Select(p =>
                {
                    //Get the name of the player
                    var name = (p.user_id.HasValue ? Bot.GetBotInstance().GetUserName(p.user_id.Value) : p.user_name);

                    //Check if backup
                    if (p.backup)
                    {
                        //Add cursive
                        return($"*{name}*");
                    }
                    else
                    {
                        return(name);
                    }
                }).ToArray();

                //Add the field
                builder = builder.AddField("Not included:", string.Join('\n', formatted));
            }

            //Build the embed
            var embed = builder.WithTitle("This is the best comp I could make:")
                        .Build();

            //Send the message
            ctx.message.Channel.SendMessageAsync("", false, embed).GetAwaiter().GetResult();
        }