Ejemplo n.º 1
0
 protected Notify(Dictionary<String, Object> attributes,
                   bool deliverInsecure,
                   Keys keys)
 {
     this.attributes = attributes;
     this.deliverInsecure = deliverInsecure;
     this.keys = keys;
 }
Ejemplo n.º 2
0
 public UNotify(int clientMajorVersion,
                 int clientMinorVersion,
                 Dictionary<String, Object> attributes,
                 bool deliverInsecure,
                 Keys keys)
     : base(attributes, deliverInsecure, keys)
 {
     this.clientMajorVersion = clientMajorVersion;
     this.clientMinorVersion = clientMinorVersion;
 }
Ejemplo n.º 3
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="elvin"></param>
        /// <param name="subscriptionExpr"></param>
        /// <param name="secureMode"></param>
        /// <param name="keys"></param>
        /// <exception cref="ArgumentException">subscriptionExpr is null or empty</exception>
        public Subscription(Elvin elvin, String subscriptionExpr, SecureMode secureMode, Keys keys)
        {
            if (keys == null) throw new ArgumentNullException("keys");
            if (secureMode == null) throw new ArgumentNullException("secureMode");

            this.Elvin = elvin;
            this.SubscriptionExpr = checkSubscription(subscriptionExpr);
            this.SecureMode = secureMode;
            this.Keys = keys;
        }
Ejemplo n.º 4
0
        public void addRemove()
        {
            Keys keys = new Keys();

            keys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Producer, new Key("dual key 1"));
            keys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, new Key("dual key 2"));

            keys.Add(KeyScheme.Sha1Producer, new Key("producer key 1"));
            keys.Add(KeyScheme.Sha1Consumer, new Key("consumer key 1"));

            DualKeySet dualKeys = keys.KeysetFor(KeyScheme.Sha1Dual);

            Assert.AreEqual(1, dualKeys.ConsumerKeys.Count);
            Assert.AreEqual(1, dualKeys.ProducerKeys.Count);

            keys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Producer, new Key("dual key 3"));
            Assert.AreEqual(2, keys.KeysetFor(KeyScheme.Sha1Dual).ProducerKeys.Count);

            keys.Remove(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Producer, new Key("dual key 3"));
            Assert.AreEqual(1, keys.KeysetFor(KeyScheme.Sha1Dual).ProducerKeys.Count);

            keys.Remove(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Producer, new Key("dual key 1"));
            Assert.AreEqual(0, keys.KeysetFor(KeyScheme.Sha1Dual).ProducerKeys.Count);

            // remove a non-existent key, check nothing Bad happens
            keys.Remove(KeyScheme.Sha1Consumer, new Key("blah"));

            keys.Remove(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, new Key("dual key 2"));
            Assert.AreEqual(0, keys.KeysetFor(KeyScheme.Sha1Dual).ConsumerKeys.Count);

            SingleKeySet consumerKeys = keys.KeysetFor(KeyScheme.Sha1Consumer);
            Assert.AreEqual(1, consumerKeys.Count);
            keys.Remove(KeyScheme.Sha1Consumer, new Key("consumer key 1"));
            Assert.AreEqual(0, consumerKeys.Count);

            SingleKeySet producerKeys = keys.KeysetFor(KeyScheme.Sha1Producer);
            Assert.AreEqual(1, producerKeys.Count);
            keys.Remove(KeyScheme.Sha1Producer, new Key("producer key 1"));
            Assert.AreEqual(0, producerKeys.Count);

            Assert.IsTrue(keys.IsEmpty);

            // remove a non-existent key, check nothing Bad happens
            keys.Remove(KeyScheme.Sha1Consumer, new Key("blah"));
        }
Ejemplo n.º 5
0
        public void addRemoveSets()
        {
            Keys keys1 = new Keys();
            Keys keys2 = new Keys();
            Keys keys3 = new Keys();

            keys1.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Producer, new Key("dual key prod 1"));
            keys1.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, new Key("dual key cons 1"));
            keys1.Add(KeyScheme.Sha1Producer, new Key("producer key 1.1"));
            keys1.Add(KeyScheme.Sha1Producer, new Key("producer key 1.2"));

            keys2.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Producer, new Key("dual key prod 2"));
            keys2.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, new Key("dual key cons 2"));
            keys2.Add(KeyScheme.Sha1Consumer, new Key("consumer key 1"));

            // add keys in bulk to keys3
            keys3.Add(keys1);

            Assert.AreEqual(1, keys3.KeysetFor(KeyScheme.Sha1Dual).ConsumerKeys.Count);
            Assert.AreEqual(1, keys3.KeysetFor(KeyScheme.Sha1Dual).ProducerKeys.Count);
            Assert.AreEqual(2, keys3.KeysetFor(KeyScheme.Sha1Producer).Count);
            Assert.AreEqual(0, keys3.KeysetFor(KeyScheme.Sha1Consumer).Count);

            keys3.Add(keys2);
            Assert.AreEqual(2, keys3.KeysetFor(KeyScheme.Sha1Dual).ConsumerKeys.Count);
            Assert.AreEqual(2, keys3.KeysetFor(KeyScheme.Sha1Dual).ProducerKeys.Count);
            Assert.AreEqual(2, keys3.KeysetFor(KeyScheme.Sha1Producer).Count);
            Assert.AreEqual(1, keys3.KeysetFor(KeyScheme.Sha1Consumer).Count);

            keys3.remove(keys1);
            Assert.AreEqual(1, keys3.KeysetFor(KeyScheme.Sha1Dual).ConsumerKeys.Count);
            Assert.AreEqual(1, keys3.KeysetFor(KeyScheme.Sha1Dual).ProducerKeys.Count);
            Assert.AreEqual(0, keys3.KeysetFor(KeyScheme.Sha1Producer).Count);
            Assert.AreEqual(1, keys3.KeysetFor(KeyScheme.Sha1Consumer).Count);

            keys3.remove(keys2);

            Assert.IsTrue(keys3.IsEmpty);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Shortcut to efficiently generate a key collection that represents
        /// this key collection's union with another.
        /// </summary>
        /// <param name="keys">The keys to add.</param>
        /// <returns>If keys is empty, this method will simply return this
        ///        collection. If this collection is empty, keys will be
        ///         returned. Otherwise a new collection instance is created
        ///         as the union of both.</returns>
        public Keys AddedTo(Keys keys)
        {
            if (keys.IsEmpty)
            {
                return this;
            }
            else if (IsEmpty)
            {
                return keys;
            }
            else
            {
                Keys newKeys = new Keys(this);

                newKeys.Add(keys);

                return newKeys;
            }
        }
Ejemplo n.º 7
0
        public static Keys Decode(Stream inStream)
        {
            int length;

            using (BinReader r = new BinReader(inStream))
            {
                length = r.ReadInt32();
            }

            if (length == 0)
                return EmptyKeys;

            try
            {
                Keys keys = new Keys();

                for (; length > 0; length--)
                {
                    using (BinReader r = new BinReader(inStream))
                    {
                        KeyScheme scheme = KeyScheme.SchemeFor(r.ReadInt32());
                        int keySetCount = r.ReadInt32();

                        if (scheme.IsDual())
                        {
                            if (keySetCount != 2)
                                throw new ProtocolCodecException("Dual key scheme with " + keySetCount + " key sets");

                            DualKeySet keyset = keys.NewKeysetFor((DualKeyScheme)scheme);

                            DecodeKeys(inStream, keyset.ProducerKeys);
                            DecodeKeys(inStream, keyset.ConsumerKeys);
                        }
                        else
                        {
                            if (keySetCount != 1)
                                throw new ProtocolCodecException
                                  ("Single key scheme with " + keySetCount + " key sets");

                            DecodeKeys(inStream, keys.NewKeysetFor((SingleKeyScheme)scheme));
                        }
                    }
                }

                return keys;
            }
            catch (ArgumentException ex)
            {
                // most likely an invalid KeyScheme ID
                throw new ProtocolCodecException("Could not decode keys.", ex);
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Add all keys in a collection.
        /// </summary>
        /// <param name="keys">The keys to add.</param>
        public virtual void Add(Keys keys)
        {
            if (keys == this)
                throw new ArgumentException("Cannot add key collection to itself");

            foreach (KeyScheme scheme in keys.keySets.Keys)
                Add(scheme, keys.keySets[scheme]);
        }
Ejemplo n.º 9
0
        public void consumer()
        {
            Key bobPrivate = new Key("bob private");
            Key bobPublic = bobPrivate.PublicKeyFor(KeyScheme.Sha1Consumer);

            Keys aliceNtfnKeys = new Keys();
            aliceNtfnKeys.Add(KeyScheme.Sha1Consumer, bobPublic);

            Keys bobSubKeys = new Keys();
            bobSubKeys.Add(KeyScheme.Sha1Consumer, bobPrivate);

            Keys eveSubKeys = new Keys();
            eveSubKeys.Add(KeyScheme.Sha1Consumer, new Key("Not bob's key"));

            Assert.IsTrue(bobSubKeys.Match(aliceNtfnKeys));
            Assert.IsFalse(eveSubKeys.Match(aliceNtfnKeys));
        }
Ejemplo n.º 10
0
 public override void Decode(Stream inStream)
 {
     attributes = XdrCoding.getNameValues(inStream);
     deliverInsecure = XdrCoding.getBool(inStream);
     keys = Keys.Decode(inStream);
 }
Ejemplo n.º 11
0
        public void delta()
        {
            Keys addedKeys = new Keys();
            Keys removedKeys = new Keys();
            Keys baseKeys = new Keys();

            addedKeys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Producer, new Key("added/removed key"));
            addedKeys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, new Key("added key 1"));
            addedKeys.Add(KeyScheme.Sha1Producer, new Key("added key 2"));

            removedKeys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Producer, new Key("added/removed key"));
            removedKeys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, new Key("non existent key"));
            removedKeys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, new Key("removed key"));

            baseKeys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Producer, new Key("kept key"));
            baseKeys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, new Key("removed key"));

            Keys delta = baseKeys.Alter(addedKeys, removedKeys);

            Keys correctKeys = new Keys();
            correctKeys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, new Key("added key 1"));
            correctKeys.Add(KeyScheme.Sha1Producer, new Key("added key 2"));
            correctKeys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Producer, new Key("kept key"));

            Assert.AreEqual(correctKeys, delta);

            // check delta works with empty keys
            Keys keys4 = Keys.EmptyKeys.Alter(addedKeys, removedKeys);

            correctKeys = new Keys();
            correctKeys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, new Key("added key 1"));
            correctKeys.Add(KeyScheme.Sha1Producer, new Key("added key 2"));

            Assert.AreEqual(correctKeys, keys4);
        }
Ejemplo n.º 12
0
 protected Notify()
 {
     this.attributes = new Dictionary<string, object>();
     this.deliverInsecure = true;
     this.keys = Keys.EmptyKeys;
 }
Ejemplo n.º 13
0
        /// <summary>
        /// Remove all keys in a collection.
        /// </summary>
        /// <param name="keys">The keys to remove</param>
        public virtual void remove(Keys keys)
        {
            if (keys == this)
                throw new ArgumentException("Cannot remove key collection from itself");

            foreach (KeyScheme scheme in keys.keySets.Keys)
            {
                IKeySet myKeys;

                if (keySets.TryGetValue(scheme, out myKeys))
                {
                    myKeys.Remove(keys.KeysetFor(scheme));

                    if (myKeys.IsEmpty)
                        keySets.Remove(scheme);
                }
            }
        }
Ejemplo n.º 14
0
        public void computeDeltaSingleScheme()
        {
            Keys keys1 = new Keys();
            Keys keys2 = new Keys();

            Key key1 = new Key("key 1");
            Key key2 = new Key("key 2");

            Delta delta = keys1.DeltaFrom(keys2);

            Assert.AreEqual(0, delta.Added.KeysetFor(KeyScheme.Sha1Producer).Count);
            Assert.AreEqual(0, delta.Added.KeysetFor(KeyScheme.Sha1Consumer).Count);
            Assert.AreEqual(0, delta.Added.KeysetFor(KeyScheme.Sha1Dual).Count);

            Assert.AreEqual(0, delta.Removed.KeysetFor(KeyScheme.Sha1Producer).Count);
            Assert.AreEqual(0, delta.Removed.KeysetFor(KeyScheme.Sha1Consumer).Count);
            Assert.AreEqual(0, delta.Removed.KeysetFor(KeyScheme.Sha1Dual).Count);

            // add a single producer key
            keys2.Add(KeyScheme.Sha1Producer, key1);

            delta = keys1.DeltaFrom(keys2);
            Assert.AreEqual(1, delta.Added.KeysetFor(KeyScheme.Sha1Producer).Count);
            Assert.AreEqual(0, delta.Removed.KeysetFor(KeyScheme.Sha1Producer).Count);

            checkApplyDelta(delta, keys1, keys2);

            // remove a single producer key
            keys1.Add(KeyScheme.Sha1Producer, key2);

            delta = keys1.DeltaFrom(keys2);
            Assert.AreEqual(1, delta.Added.KeysetFor(KeyScheme.Sha1Producer).Count);
            Assert.AreEqual(1, delta.Removed.KeysetFor(KeyScheme.Sha1Producer).Count);

            checkApplyDelta(delta, keys1, keys2);

            // key1 is now in both sets
            keys1.Add(KeyScheme.Sha1Producer, key1);

            delta = keys1.DeltaFrom(keys2);
            Assert.AreEqual(0, delta.Added.KeysetFor(KeyScheme.Sha1Producer).Count);
            Assert.AreEqual(1, delta.Removed.KeysetFor(KeyScheme.Sha1Producer).Count);

            // key2 is not in both
            keys2.Add(KeyScheme.Sha1Producer, key2);

            delta = keys1.DeltaFrom(keys2);
            Assert.AreEqual(0, delta.Added.KeysetFor(KeyScheme.Sha1Producer).Count);
            Assert.AreEqual(0, delta.Removed.KeysetFor(KeyScheme.Sha1Producer).Count);

            checkApplyDelta(delta, keys1, keys2);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Create a new key collection with some keys added/removed. This
        /// does not modify the current collection.
        /// </summary>
        /// <param name="toAdd">Keys to add.</param>
        /// <param name="toRemove">Keys to remove</param>
        /// <returns>A new key set with keys added/removed. If both add/remove
        /// key sets are empty, this returns the current instance.</returns>
        public Keys Alter(Keys toAdd, Keys toRemove)
        {
            if (toAdd.IsEmpty && toRemove.IsEmpty)
            {
                return this;
            }
            else
            {
                Keys keys = new Keys(this);

                keys.Add(toAdd);
                keys.remove(toRemove);

                return keys;
            }
        }
Ejemplo n.º 16
0
        public bool Equals(Keys keys)
        {
            if (keySets.Count != keys.keySets.Count)
                return false;

            foreach (KeyScheme scheme in keys.keySets.Keys)
            {
                if (!KeysetFor(scheme).Equals(keys.KeysetFor(scheme)))
                    return false;
            }

            return true;
        }
Ejemplo n.º 17
0
 /// <summary>
 /// Check applying delta to keys1 gives keys2
 /// </summary>
 /// <param name="delta"></param>
 /// <param name="keys1"></param>
 /// <param name="keys2"></param>
 private static void checkApplyDelta(Delta delta,
                                      Keys keys1, Keys keys2)
 {
     Assert.AreEqual(keys1.Alter(delta.Added, delta.Removed), keys2);
 }
Ejemplo n.º 18
0
        public void producer()
        {
            Key alicePrivate = new Key("alice private");
            Key alicePublic = alicePrivate.PublicKeyFor(KeyScheme.Sha1Producer);

            Keys aliceNtfnKeys = new Keys();
            aliceNtfnKeys.Add(KeyScheme.Sha1Producer, alicePrivate);

            Keys bobSubKeys = new Keys();
            bobSubKeys.Add(KeyScheme.Sha1Producer, alicePublic);

            Keys eveSubKeys = new Keys();
            eveSubKeys.Add(KeyScheme.Sha1Producer, new Key("Not alice's key").PublicKeyFor(KeyScheme.Sha1Producer));

            Assert.IsTrue(bobSubKeys.Match(aliceNtfnKeys));
            Assert.IsFalse(eveSubKeys.Match(aliceNtfnKeys));
        }
Ejemplo n.º 19
0
        public void IO()
        {
            using (MemoryStream buff = new MemoryStream())
            {
                Keys keys = new Keys();

                keys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Producer, new Key("dual key 1"));
                keys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, new Key("dual key 2"));
                keys.Add(KeyScheme.Sha1Producer, new Key("producer key 1"));
                keys.Add(KeyScheme.Sha1Consumer, new Key("consumer key 1"));
                keys.Add(KeyScheme.Sha1Consumer, new Key("consumer key 2"));

                // test roundtrip encode/decode
                keys.Encode(buff);

                buff.Seek(0, SeekOrigin.Begin); // reset to start

                Keys newKeys = Keys.Decode(buff);

                Assert.IsTrue(keys.Equals(newKeys));
            }
        }
Ejemplo n.º 20
0
        public void equality()
        {
            Assert.IsTrue(new Key("a test key number 1").Equals(new Key("a test key number 1")));
            Assert.IsFalse(new Key("a test key number 1").Equals(new Key("a test key number 2")));

            Assert.AreEqual(new Key("a test key number 1").GetHashCode(),
                          new Key("a test key number 1").GetHashCode());

            // test Keys.equals ()
            Keys keys1 = new Keys();
            keys1.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Producer, new Key("dual key 1"));
            keys1.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, new Key("dual key 2"));

            keys1.Add(KeyScheme.Sha1Producer, new Key("producer key 1"));
            keys1.Add(KeyScheme.Sha1Consumer, new Key("consumer key 1"));

            Keys keys2 = new Keys();
            keys2.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Producer, new Key("dual key 1"));
            keys2.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, new Key("dual key 2"));

            keys2.Add(KeyScheme.Sha1Producer, new Key("producer key 1"));
            keys2.Add(KeyScheme.Sha1Consumer, new Key("consumer key 1"));

            Assert.AreEqual(keys1.GetHashCode(), keys2.GetHashCode());
            Assert.AreEqual(keys1, keys2);

            keys2.Remove(KeyScheme.Sha1Consumer, new Key("consumer key 1"));

            Assert.IsFalse(keys1.Equals(keys2));
        }
Ejemplo n.º 21
0
        public void dual()
        {
            Key alicePrivate = new Key("alice private");
            Key alicePublic = alicePrivate.PublicKeyFor(KeyScheme.Sha1Dual);
            Key bobPrivate = new Key("bob private");
            Key bobPublic = bobPrivate.PublicKeyFor(KeyScheme.Sha1Dual);

            Keys aliceNtfnKeys = new Keys();
            aliceNtfnKeys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, bobPublic);
            aliceNtfnKeys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Producer, alicePrivate);

            Keys bobSubKeys = new Keys();
            bobSubKeys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, bobPrivate);
            bobSubKeys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Producer, alicePublic);

            Keys eveSubKeys = new Keys();
            Key randomPrivate = new Key("Not bob's key");
            eveSubKeys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, randomPrivate);
            eveSubKeys.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Producer, randomPrivate.PublicKeyFor(KeyScheme.Sha1Dual));

            Assert.IsTrue(bobSubKeys.Match(aliceNtfnKeys));
            Assert.IsFalse(aliceNtfnKeys.Match(bobSubKeys));
            Assert.IsFalse(eveSubKeys.Match(aliceNtfnKeys));
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Compute the changes between one key collection and another.
        /// </summary>
        /// <param name="keys">The target key collection.</param>
        /// <returns>The delta (i.e. key sets to be added and removed)
        /// required to change this collection into the target.</returns>
        public Delta DeltaFrom(Keys keys)
        {
            if (keys == this)
                return Delta.EMPTY_DELTA;

            Keys addedKeys = new Keys();
            Keys removedKeys = new Keys();

            foreach (KeyScheme scheme in KeyScheme.Schemes)
            {
                IKeySet existingKeyset = KeysetFor(scheme);
                IKeySet otherKeyset = keys.KeysetFor(scheme);

                addedKeys.Add(scheme, otherKeyset.Subtract(existingKeyset));
                removedKeys.Add(scheme, existingKeyset.Subtract(otherKeyset));
            }

            return new Delta(addedKeys, removedKeys);
        }
Ejemplo n.º 23
0
        public ElvinOptions(ConnectionOptions connectionOptions,
                             Keys notificationKeys,
                             Keys subscriptionKeys)
        {
            if (notificationKeys == null) throw new ArgumentNullException("notificationKeys");
            if (subscriptionKeys == null) throw new ArgumentNullException("subscriptionKeys");
            if (connectionOptions == null) throw new ArgumentNullException("connectionOptions");

            this.connectionOptions = connectionOptions;
            this.notificationKeys = notificationKeys;
            this.subscriptionKeys = subscriptionKeys;
            this.requireAuthenticatedServer = false;
            this.receiveTimeout = 10000;
            this.livenessTimeout = 60000;
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Test whether a given key collection matches this one for the
        /// purpose of notification delivery.
        /// </summary>
        /// <param name="producerKeys">The producer keys to match against this (consumer) key collection.</param>
        /// <returns>True if a consumer using this key collection could
        /// receive a notification from a producer with the given
        /// producer key collection.</returns>
        public bool Match(Keys producerKeys)
        {
            if (IsEmpty || producerKeys.IsEmpty)
                return false;

            foreach (var entry in producerKeys.keySets)
            {
                KeyScheme scheme = entry.Key;
                IKeySet keyset = entry.Value;

                if (keySets.ContainsKey(scheme) &&
                    scheme.Match(keyset, keySets[scheme]))
                {
                    return true;
                }
            }

            return false;
        }
Ejemplo n.º 25
0
 public NotifyEmit(Dictionary<String, Object> attributes,
                    bool deliverInsecure,
                    Keys keys)
     : base(attributes, deliverInsecure, keys)
 {
 }
Ejemplo n.º 26
0
 public Keys(Keys keys)
     : this()
 {
     Add(keys);
 }
Ejemplo n.º 27
0
        public void computeDeltaDual()
        {
            Keys keys1 = new Keys();
            Keys keys2 = new Keys();

            Key key1 = new Key("key 1");
            Key key2 = new Key("key 2");
            Key key3 = new Key("key 3");

            keys1.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Producer, key1);
            keys1.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, key2);
            keys1.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, key3);

            keys2.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Producer, key3);
            keys2.Add(KeyScheme.Sha1Dual, DualKeyScheme.Subset.Consumer, key3);

            Delta delta = keys1.DeltaFrom(keys2);
            Assert.AreEqual(1, delta.Added.KeysetFor(KeyScheme.Sha1Dual).ProducerKeys.Count);
            Assert.AreEqual(1, delta.Removed.KeysetFor(KeyScheme.Sha1Dual).ProducerKeys.Count);

            Assert.AreEqual(0, delta.Added.KeysetFor(KeyScheme.Sha1Dual).ConsumerKeys.Count);
            Assert.AreEqual(1, delta.Removed.KeysetFor(KeyScheme.Sha1Dual).ConsumerKeys.Count);

            checkApplyDelta(delta, keys1, keys2);
        }