public Task <ReadOnlyCollection <ShippingRuleDto> > ListMatchingRulesAsync(int toZipCode, int weightGrams, double volume)
        {
            var destination = new ZipCode(toZipCode);
            var weight      = new Weight(weightGrams);

            var items = repository.GetAllMethods()
                        .SelectMany(method => method.Rules.Select(rule => new KeyValuePair <string, ShippingRule>(method.Name, rule)))
                        .Where(item => destination.IsInRange(item.Value.RangeFrom, item.Value.RangeTo))
                        .Where(item => weight.IsInRange(item.Value.MinWeight, item.Value.MaxWeight))
                        .Where(item => volume <= item.Value.MaxVolume)
                        .Select(item => new ShippingRuleDto
            {
                MethodName       = item.Key,
                ZipCodeOrigin    = item.Value.Origin,
                ZipCodeRangeFrom = item.Value.RangeFrom,
                ZipCodeRangeTo   = item.Value.RangeTo,
                MinWeightGrams   = item.Value.MinWeight,
                MaxWeightGrams   = item.Value.MaxWeight,
                MaxVolume        = item.Value.MaxVolume,
                DeliveryTimeDays = item.Value.DeliveryTime,
                PriceCents       = item.Value.Price,
                AdValorem        = item.Value.AdValorem
            });

            return(Task.FromResult(items.ToReadOnly()));
        }