public async Task <DataReturnVersion> GenerateAsync(TestFileSettings settings)
        {
            if (settings.NumberOfAatfs < 0 || settings.NumberOfAatfs > 250)
            {
                throw new ArgumentOutOfRangeException("settings", "The number of AATFs specified in the settings number be in the range [0, 250].");
            }

            if (settings.NumberOfAes < 0 || settings.NumberOfAes > 50)
            {
                throw new ArgumentOutOfRangeException("settings", "The number of AEs specified in the settings number be in the range [0, 50].");
            }

            Domain.Scheme.Scheme scheme = await dataAccess.FetchSchemeAsync(settings.OrganisationID);

            Quarter quarter = new Quarter(
                settings.Quarter.Year,
                (QuarterType)settings.Quarter.Q);

            DataReturn dataReturn = new DataReturn(scheme, quarter);

            DataReturnVersion dataReturnVersion = new DataReturnVersion(dataReturn);

            IEnumerable <ReturnItem> returnItemsCollectedFromDcf = CreateReturnItems(null);

            foreach (var returnItem in returnItemsCollectedFromDcf)
            {
                dataReturnVersion.WeeeCollectedReturnVersion.AddWeeeCollectedAmount(
                    new WeeeCollectedAmount(WeeeCollectedAmountSourceType.Dcf,
                                            returnItem.ObligationType,
                                            returnItem.WeeeCategory,
                                            returnItem.Tonnage));
            }

            int numberOfDeliveredToAatfs     = settings.NumberOfAatfs;
            int aatfApprovalNumberSeedOffset = r.Next(250);

            List <string> aatfApprovalNumbers = new List <string>();

            for (int index = 0; index < numberOfDeliveredToAatfs; ++index)
            {
                int approvalNumberSeed = (index + aatfApprovalNumberSeedOffset) % 250;
                aatfApprovalNumbers.Add(GetAtfApprovalNumber(approvalNumberSeed));
            }

            IOrderedEnumerable <string> orderedAatfApprovalNumbers = aatfApprovalNumbers.OrderBy(x => x);

            foreach (string approvalNumber in orderedAatfApprovalNumbers)
            {
                var deliveredToAatfs = CreateDeliveredToAatfs(approvalNumber);
                foreach (var deliveredToAatf in deliveredToAatfs)
                {
                    dataReturnVersion.WeeeDeliveredReturnVersion.AddWeeeDeliveredAmount(deliveredToAatf);
                }
            }

            int numberOfDeliveredToAes      = settings.NumberOfAes;
            int aaeApprovalNumberSeedOffset = r.Next(50);

            List <string> aaeApprovalNumbers = new List <string>();

            for (int index = 0; index < numberOfDeliveredToAes; ++index)
            {
                int approvalNumberSeed = (index + aaeApprovalNumberSeedOffset) % 250;
                aaeApprovalNumbers.Add(GetAeApprovalNumber(approvalNumberSeed));
            }

            IOrderedEnumerable <string> orderedAaeApprovalNumbers = aaeApprovalNumbers.OrderBy(x => x);

            foreach (string approvalNumber in orderedAaeApprovalNumbers)
            {
                var deliveredToAes = CreateDeliveredToAes(approvalNumber);
                foreach (var deliveredToAe in deliveredToAes)
                {
                    dataReturnVersion.WeeeDeliveredReturnVersion.AddWeeeDeliveredAmount(deliveredToAe);
                }
            }

            IEnumerable <ReturnItem> b2cWeeeFromDistributors = CreateReturnItems(ObligationType.B2C);

            foreach (var returnItem in b2cWeeeFromDistributors)
            {
                dataReturnVersion.WeeeCollectedReturnVersion.AddWeeeCollectedAmount(
                    new WeeeCollectedAmount(WeeeCollectedAmountSourceType.Distributor,
                                            returnItem.ObligationType,
                                            returnItem.WeeeCategory,
                                            returnItem.Tonnage));
            }

            IEnumerable <ReturnItem> b2cWeeeFromFinalHolders = CreateReturnItems(ObligationType.B2C);

            foreach (var returnItem in b2cWeeeFromFinalHolders)
            {
                dataReturnVersion.WeeeCollectedReturnVersion.AddWeeeCollectedAmount(
                    new WeeeCollectedAmount(WeeeCollectedAmountSourceType.FinalHolder,
                                            returnItem.ObligationType,
                                            returnItem.WeeeCategory,
                                            returnItem.Tonnage));
            }

            IList <RegisteredProducer> registeredProducers = await dataAccess.FetchRegisteredProducersAsync(scheme, quarter.Year);

            int numberOfProducers;

            if (settings.AllProducers)
            {
                numberOfProducers = registeredProducers.Count;
            }
            else
            {
                numberOfProducers = Math.Min(settings.NumberOfProduces, registeredProducers.Count);
            }

            IOrderedEnumerable <RegisteredProducer> producersToInclude = registeredProducers
                                                                         .Shuffle()
                                                                         .Take(numberOfProducers)
                                                                         .OrderBy(x => x.ProducerRegistrationNumber);

            foreach (RegisteredProducer producerToInclude in producersToInclude)
            {
                var eeeOutputAmounts = CreateEeeOutputAmounts(producerToInclude);

                foreach (var eeeOutputAmount in eeeOutputAmounts)
                {
                    dataReturnVersion.EeeOutputReturnVersion.AddEeeOutputAmount(eeeOutputAmount);
                }
            }

            return(dataReturnVersion);
        }