/// <summary>
        /// Atomically sets the value of the stamp to the given update value
        /// if the current value and the expected value <see cref="AreEqual"/>.
        /// Any given invocation of this operation may fail
        /// (return false) spuriously, but repeated invocation
        /// when the current value holds the expected value and no other
        /// thread is also attempting to set the value will eventually
        /// succeed.
        /// </summary>
        /// <param name="expectedValue">
        /// The expected value
        /// </param>
        /// <param name="newStamp">
        /// The new value for the stamp
        /// </param>
        /// <returns>
        /// True if successful
        /// </returns>
        public virtual bool AttemptStamp(T expectedValue, int newStamp)
        {
            ValueIntegerPair current = Pair;

            return(AreEqual(expectedValue, current.Value) &&
                   (newStamp == current.Integer || _atomicReference.CompareAndSet(current, new ValueIntegerPair(expectedValue, newStamp))));
        }
        /// <summary>
        /// Atomically sets both the value and stamp to the given update values
        /// if the current value and the expected value <see cref="AreEqual"/>
        /// and the current stamp is equal to the expected stamp.
        /// </summary>
        /// <param name="expectedValue">
        /// The expected value
        /// </param>
        /// <param name="newValue">
        /// The new value
        /// </param>
        /// <param name="expectedStamp">
        /// The expected value of the stamp
        /// </param>
        /// <param name="newStamp">
        /// The new value for the stamp
        /// </param>
        /// <returns>
        /// True if successful, false otherwise.
        /// </returns>
        public virtual bool CompareAndSet(T expectedValue, T newValue, int expectedStamp, int newStamp)
        {
            ValueIntegerPair current = Pair;

            return(AreEqual(expectedValue, current.Value) && expectedStamp == current.Integer &&
                   ((newValue.Equals(current.Value) && newStamp == current.Integer) || _atomicReference.WeakCompareAndSet(current, new ValueIntegerPair(newValue, newStamp))));
        }
        /// <summary>
        /// Returns both the current value and the stamp.
        /// Typical usage is:
        /// <code>
        /// int stamp;
        /// object value = v.GetValue(out stamp);
        /// </code>
        /// </summary>
        /// <param name="stamp">
        /// An array of size of at least one.  On return,
        /// <tt>stampholder[0]</tt> will hold the value of the stamp.
        /// </param>
        /// <returns>
        /// The current value
        /// </returns>
        public T GetValue(out int stamp)
        {
            ValueIntegerPair p = Pair;

            stamp = p.Integer;
            return(p.Value);
        }
        /// <summary>
        /// Unconditionally sets both the value and stamp if any of them are
        /// not equal. Method <see cref="AreEqual"/> is used to compare the
        /// value.
        /// </summary>
        /// <param name="newValue">
        /// The new value
        /// </param>
        /// <param name="newStamp">
        /// The new value for the stamp
        /// </param>
        public void SetNewAtomicValue(T newValue, int newStamp)
        {
            ValueIntegerPair current = Pair;

            if (!AreEqual(newValue, current.Value) || newStamp != current.Integer)
            {
                _atomicReference.Value = new ValueIntegerPair(newValue, newStamp);
            }
        }