public void Add(string id, IDictionary<string, string> attributes, string version)
        {
            // Find the bucket name for each of attributes
              var partitions = new Dictionary<string, string>(attributes);
              foreach (var kv in attributes.Where(kv => _functions.ContainsKey(kv.Key)))
              {
              var attributeValue = attributes[kv.Key];
              var categoryFunction = _functions[kv.Key];
              partitions[kv.Key] = categoryFunction.OwningPartition(attributeValue);
              }

              var key = new BucketKey(partitions);
              if(!_digestBuckets.ContainsKey(key))
              {
              var bucket = new Bucket(key, partitions);
              _digestBuckets[key] = bucket;
              }
              _digestBuckets[key].Add(version);
        }
        public void Add(string id, IDictionary<string, string> attributes, string version)
        {
            // Find the bucket name for each of attributes
            var partitions = new Dictionary<string, string>();
            foreach (var kv in attributes.Where(kv => _functions.ContainsKey(kv.Key)))
            {
                var attributeValue = attributes[kv.Key];
                var categoryFunction = _functions[kv.Key];
                partitions[kv.Key] = categoryFunction.OwningPartition(attributeValue);
            }

            // Join names together to form label
            var keys = partitions.Keys.ToArray();
            Array.Sort(keys);
            var label = String.Join("_", from key in keys select partitions[key]);

            if(!_digestBuckets.ContainsKey(label))
            {
                var bucket = new Bucket(label, partitions);
                _digestBuckets[label] = bucket;
            }
            _digestBuckets[label].Add(version);
        }