/// <summary>
        /// Atomically sets the element at <paramref name="index"/> to <paramref name="newValue"/>
        /// if the current value equals the <paramref name="expectedValue"/>.
        /// </summary>
        /// <param name="index">
        /// The index
        /// </param>
        /// <param name="expectedValue">
        /// The expected value
        /// </param>
        /// <param name="newValue">
        /// The new value
        /// </param>
        /// <returns>
        /// true if successful. False return indicates that
        /// the actual value was not equal to the expected value.
        /// </returns>
        public bool CompareAndSet(int index, T expectedValue, T newValue)
        {
            ValueHolder <T> current = _atomicReferenceArray[index];

            return(Equals(expectedValue, current.Value) &&
                   (Equals(newValue, current.Value) || _atomicReferenceArray.CompareAndSet(index, current, new ValueHolder <T>(newValue))));
        }
        public void CompareExistingValueAndSetNewValue()
        {
            AtomicReferenceArray <T> ai = new AtomicReferenceArray <T>(DEFAULT_COLLECTION_SIZE);

            for (int i = 0; i < DEFAULT_COLLECTION_SIZE; ++i)
            {
                ai.Exchange(i, one);
                Assert.IsTrue(ai.CompareAndSet(i, one, two));
                Assert.IsTrue(ai.CompareAndSet(i, two, m4));
                Assert.AreEqual(m4, ai[i]);
                Assert.IsFalse(ai.CompareAndSet(i, m5, seven));
                Assert.IsFalse((seven.Equals(ai[i])));
                Assert.IsTrue(ai.CompareAndSet(i, m4, seven));
                Assert.AreEqual(seven, ai[i]);
            }
        }
        public void CompareAndSetInMultipleThreads()
        {
            AtomicReferenceArray <T> a = new AtomicReferenceArray <T>(1);

            a.Exchange(0, one);
            Thread t = ThreadManager.StartAndAssertRegistered(
                "T1", () => { while (!a.CompareAndSet(0, two, three))
                              {
                                  Thread.Sleep(Delays.Short);
                              }
                });

            Assert.IsTrue(a.CompareAndSet(0, one, two));
            ThreadManager.JoinAndVerify(Delays.Long);
            Assert.IsFalse(t.IsAlive);
            Assert.AreEqual(a[0], three);
        }