public async Task GetTeamWithRankAsync(int rank, string location, DivisionWithCategory?divisionAndCat, Tier?tier)
        {
            using (Context.Channel.EnterTypingState())
            {
                if (rank < 1)
                {
                    throw new ArgumentOutOfRangeException(nameof(rank));
                }

                var filter = new ScoreboardFilterInfo(divisionAndCat?.Division, tier, divisionAndCat?.Category, location);

                var teams = await ScoreRetrievalService.GetScoreboardAsync(filter).ConfigureAwait(false);

                System.Collections.Generic.IEnumerable <ScoreboardSummaryEntry> teamList = teams.TeamList;


                var team = teamList.Skip(rank - 1).First();
                ScoreboardDetails teamScore = await ScoreRetrievalService.GetDetailsAsync(team.TeamId).ConfigureAwait(false);

                if (teamScore == null)
                {
                    throw new Exception("Error obtaining team score.");
                }

                string classSpec = Utilities.JoinNonNullNonEmpty(", ",
                                                                 LocationResolutionService.GetFullNameOrNull(location),
                                                                 filter.Division.HasValue ? (filter.Division.Value.ToStringCamelCaseToSpace() + " Division") : null,
                                                                 filter.Category?.ToCanonicalName(),
                                                                 tier.HasValue ? (tier.Value.ToStringCamelCaseToSpace() + " Tier") : null);

                await ReplyAsync(
                    "**" + Utilities.AppendOrdinalSuffix(rank) + " place " + (classSpec.Length == 0 ? "overall" : "in " + classSpec) + ": " + team.TeamId + "**",
                    embed : ScoreEmbedBuilder.CreateTeamDetailsEmbed(teamScore,
                                                                     completeScoreboard : await ScoreRetrievalService.GetScoreboardAsync(new ScoreboardFilterInfo(null, null)).ConfigureAwait(false),
                                                                     peerFilter : CompetitionRoundLogicService.GetPeerFilter(ScoreRetrievalService.Round, team),
                                                                     timeZone : await Preferences.GetTimeZoneAsync(Context.Guild, Context.User).ConfigureAwait(false)).Build()).ConfigureAwait(false);
            }
        }
        public async Task GetTeamAsync(TeamId teamId)
        {
            using (Context.Channel.EnterTypingState())
            {
                ScoreboardDetails teamScore = await ScoreRetrievalService.GetDetailsAsync(teamId).ConfigureAwait(false);

                if (teamScore == null)
                {
                    throw new Exception("Error obtaining team score.");
                }
                await ReplyAsync(string.Empty, embed : ScoreEmbedBuilder.CreateTeamDetailsEmbed(teamScore,
                                                                                                completeScoreboard : await ScoreRetrievalService.GetScoreboardAsync(ScoreboardFilterInfo.NoFilter).ConfigureAwait(false),
                                                                                                peerFilter : CompetitionRoundLogicService.GetPeerFilter(ScoreRetrievalService.Round, teamScore.Summary),
                                                                                                timeZone : await Preferences.GetTimeZoneAsync(Context.Guild, Context.User).ConfigureAwait(false)).Build()).ConfigureAwait(false);
            }
        }
        public async Task GeneratePeerLeaderboardAsync(TeamId team)
        {
            using (Context.Channel.EnterTypingState())
            {
                ScoreboardDetails teamDetails = await ScoreRetrievalService.GetDetailsAsync(team).ConfigureAwait(false);

                if (teamDetails == null)
                {
                    throw new Exception("Error obtaining team score.");
                }

                CompleteScoreboardSummary peerScoreboard = await ScoreRetrievalService.GetScoreboardAsync(CompetitionRoundLogicService.GetPeerFilter(ScoreRetrievalService.Round, teamDetails.Summary)).ConfigureAwait(false);

                await ReplyAsync(ScoreEmbedBuilder.CreatePeerLeaderboardEmbed(teamDetails.TeamId, peerScoreboard, timeZone: await Preferences.GetTimeZoneAsync(Context.Guild, Context.User).ConfigureAwait(false))).ConfigureAwait(false);
            }
        }
        public async Task GetTeamWithPercentileAsync(double rank, DivisionWithCategory?divAndCat = null, Tier?tier = null)
        {
            using (Context.Channel.EnterTypingState())
            {
                if (rank < 1)
                {
                    throw new ArgumentOutOfRangeException(nameof(rank));
                }

                var teams = await ScoreRetrievalService.GetScoreboardAsync(new ScoreboardFilterInfo(divAndCat?.Division, tier, divAndCat?.Category, null)).ConfigureAwait(false);

                // teams list in descending order
                int expectedIndex           = ((int)Math.Round(((100 - rank) / 100) * teams.TeamList.Count)).Clamp(0, teams.TeamList.Count);
                ScoreboardDetails teamScore = await ScoreRetrievalService.GetDetailsAsync(teams.TeamList[expectedIndex].TeamId).ConfigureAwait(false);

                if (teamScore == null)
                {
                    throw new Exception("Error obtaining team score.");
                }

                await ReplyAsync(string.Empty,
                                 embed : ScoreEmbedBuilder.CreateTeamDetailsEmbed(teamScore,
                                                                                  completeScoreboard : await ScoreRetrievalService.GetScoreboardAsync(new ScoreboardFilterInfo(null, null)).ConfigureAwait(false),
                                                                                  peerFilter : CompetitionRoundLogicService.GetPeerFilter(ScoreRetrievalService.Round, teamScore.Summary),
                                                                                  timeZone : await Preferences.GetTimeZoneAsync(Context.Guild, Context.User).ConfigureAwait(false)).Build()).ConfigureAwait(false);
            }
        }