/// <summary>
        /// Returns the Pokemon's encounters in all version groups.
        /// </summary>
        private async Task <List <WithId <EncounterEntry[]> > > GetEncounters(Pokemon pokemon)
        {
            var encounterEntriesList = new List <WithId <EncounterEntry[]> >();

            // enumerate version groups spanned by this Pokemon's encounters
            // TODO: create encounters cache service
            var encounters = await PokeApi.GetEncounters(pokemon);

            var versions = await VersionService.UpsertMany(encounters.GetDistinctVersions());

            var versionGroups = await VersionGroupsService.UpsertManyByVersionIds(versions.Select(v => v.VersionId));

            foreach (var vg in versionGroups)
            {
                var relevantEncounters = encounters.Where(e => IsInVersionGroup(e, vg));

                // create entries for relevant encounters
                var encounterEntries = new List <EncounterEntry>();
                foreach (var encounter in relevantEncounters)
                {
                    var locationArea = await LocationAreasService.Upsert(encounter.LocationArea);

                    var displayNames = await GetDisplayNames(encounter);

                    // filter to relevant version details
                    var relevantVersionDetails = encounter.VersionDetails.Where(vd =>
                    {
                        var versionName = vd.Version.Name;
                        return(vg.Versions.Select(v => v.Name).Contains(versionName));
                    });

                    var chances = await GetChances(relevantVersionDetails);

                    var encounterDetails = await GetEncounterDetails(relevantVersionDetails);

                    var encounterEntry = new EncounterEntry
                    {
                        LocationAreaId = locationArea.LocationAreaId,
                        DisplayNames   = displayNames.ToList(),
                        Details        = encounterDetails.ToList()
                    };

                    encounterEntries.Add(encounterEntry);
                }

                // add encounter entries to list indexed by version group ID
                var entryList = new WithId <EncounterEntry[]>(vg.VersionGroupId, encounterEntries.ToArray());
                encounterEntriesList.Add(entryList);
            }

            return(encounterEntriesList);
        }