/// <summary>
        ///     Resolves the intelligent billboard based on a set of provided parameters asynchronously.
        /// </summary>
        /// <param name="from">The first day of the first week of the set of weeks for which the intelligent billboard is to be calculated.</param>
        /// <param name="numberOfWeeks">The number of weeks a billboard is to be calculated.</param>
        /// <param name="numberOfBigRooms">The number of big rooms.</param>
        /// <param name="numberOfSmallRooms">The number of small rooms.</param>
        /// <param name="city">The city location.</param>
        /// <returns>The intelligent billboard of recommendations for the set of weeks that corresponds to the provided parameters.</returns>
        public async Task <IEnumerable <IntelligentBillboardRecommendation> > ResolveAsync(DateTime from, int numberOfWeeks, int numberOfBigRooms, int numberOfSmallRooms, string city)
        {
            IEnumerable <string> keywordIds = await GetKeywordIdsOfSuccessfulMoviesInCity(city);

            var moviesAlreadyAssigned = new ConcurrentDictionary <string, byte>();
            var result = new List <IntelligentBillboardRecommendation>();
            var tasks  = new List <Task>();

            for (int index = 0; index < numberOfWeeks; index++)
            {
                var intelligentBillboardRecommendation = new IntelligentBillboardRecommendation();
                intelligentBillboardRecommendation.WeekNumber = index + 1;
                result.Add(intelligentBillboardRecommendation);

                // We recommend movies that have been released during the last month.
                DateTime localFrom = from.AddDays(-daysPerMonth + (daysPerWeek * index));
                DateTime to        = from.AddDays(daysPerWeek * index);

                tasks.Add(GenerateBillboardsAsync(localFrom, to, keywordIds, numberOfBigRooms, numberOfSmallRooms, moviesAlreadyAssigned, intelligentBillboardRecommendation));
            }

            await Task.WhenAll(tasks);

            return(result);
        }
        private async Task GenerateBillboardsAsync(DateTime from, DateTime to, IEnumerable <string> keywordIds, int numBigRooms, int numSmallRooms,
                                                   ConcurrentDictionary <string, byte> moviesAlreadyAssigned, IntelligentBillboardRecommendation intelligentBillboardRecommendation)
        {
            // Generate billboard for the small rooms.
            var smallRoomsTask = GenerateBillboardAsync(from, to, _genresResolver.GetMinoritaryGenres(), keywordIds, numSmallRooms, moviesAlreadyAssigned);

            // Generate billboard for the big rooms.
            var bigRoomsTask = GenerateBillboardAsync(from, to, _genresResolver.GetBlockbusterGenres(), keywordIds, numBigRooms, moviesAlreadyAssigned);

            await Task.WhenAll(smallRoomsTask, bigRoomsTask);

            intelligentBillboardRecommendation.SmallRooms = await smallRoomsTask;
            intelligentBillboardRecommendation.BigRooms   = await bigRoomsTask;
        }