/// <summary>
        /// Increases a specified variable by one and stores the result as an atomic operation.
        /// </summary>
        /// <param name="target">The shared object whose property is to be incremented.</param>
        /// <param name="propertyName">The property on that object to be incremented.</param>
        /// <param name="callback">The action to be run when the asynchronous operation completes.</param>
        public void Increment(INotifyPropertyChanged target, string propertyName, Action <int> callback)
        {
            InterlockedPropertyInfo propInfo     = GetPropertyInfo(target, propertyName, typeof(int));
            Action <long>           longCallback = l => callback((int)l);

            this.SendPayload(propInfo, AtomicOperators.Add, longCallback, 1L);
        }
        /// <summary>
        /// Compares two shared objects for equality and, if they are equal, replaces the target value, returning the result in the callback.
        /// </summary>
        /// <param name="target">The destination object, whose property value is compared with <see cref="comparand"/> and possibly replaced.</param>
        /// <param name="value">The value to replace the <see cref="target"/>'s property value if the comparison results in equality.</param>
        /// <param name="comparand">The value that is compared to the property value at the destination object.</param>
        /// <param name="propertyName">The name of the property on the destination object whose value is compared with <see cref="comparand"/> and possibly replaced.</param>
        /// <param name="callback">The action to be issued when the asynchronous operation completes.</param>
        public void CompareExchange(INotifyPropertyChanged target, string propertyName, int value, int comparand, Action <int> callback)
        {
            InterlockedPropertyInfo propInfo     = GetPropertyInfo(target, propertyName, typeof(int));
            Action <long>           longCallback = l => callback((int)l);

            this.SendPayload(propInfo, AtomicOperators.CompareExchange, longCallback, (long)value, (long)comparand);
        }
        // Send method for operations with callbacks. Store the callback in a queue for retrieval upon completion of server operation.
        private void SendPayload <T>(InterlockedPropertyInfo propInfo, AtomicOperators operation, Action <T> callback, params T[] parameters)
        {
            AtomicPayload payload =
                new AtomicPayload
                (
                    this.Client.ClientId,
                    propInfo.ObjectId,
                    propInfo.Property.Index,
                    propInfo.PropertyType.AssemblyQualifiedName,
                    operation,
                    parameters.Select(p => Json.WriteObject(p)).ToArray()
                );

            // For operations with callbacks, we need to create an async result and queue it up for retrieval when the server operation completes
            if (callback != null)
            {
                var getResult = new SharedAsyncResult <T>(EndSendAtomicPayload <T>, payload.PayloadId, callback);
                this.Client.EnqueueAsyncResult(getResult, payload.PayloadId);
            }

            this.Client.SendPublishEvent(payload);
        }
        /// <summary>
        /// Decreases a specified variable by one and stores the result as an atomic operation.
        /// </summary>
        /// <param name="target">The shared object whose property is to be decremeneted.</param>
        /// <param name="propertyName">The property on that object to be decremented.</param>
        public void Decrement(INotifyPropertyChanged target, string propertyName)
        {
            InterlockedPropertyInfo propInfo = GetPropertyInfo(target, propertyName, typeof(long), typeof(int));

            this.SendPayload(propInfo, AtomicOperators.Add, null, -1L);
        }
        /// <summary>
        /// Compares two shared objects for equality and, if they are equal, replaces the target value, returning the result in the callback.
        /// </summary>
        /// <param name="target">The destination object, whose property value is compared with <see cref="comparand"/> and possibly replaced.</param>
        /// <param name="value">The value to replace the <see cref="target"/>'s property value if the comparison results in equality.</param>
        /// <param name="comparand">The value that is compared to the property value at the destination object.</param>
        /// <param name="propertyName">The name of the property on the destination object whose value is compared with <see cref="comparand"/> and possibly replaced.</param>
        /// <param name="callback">The action to be issued when the asynchronous operation completes.</param>
        public void CompareExchange(INotifyPropertyChanged target, string propertyName, string value, string comparand, Action <string> callback)
        {
            InterlockedPropertyInfo propInfo = GetPropertyInfo(target, propertyName, typeof(string));

            this.SendPayload(propInfo, AtomicOperators.CompareExchange, callback, value, comparand);
        }
        /// <summary>
        /// Adds two 64-bit integers and replaces the first integer with the sum as an atomic operation.
        /// </summary>
        /// <param name="target">The shared object whose property is to be added.</param>
        /// <param name="propertyName">The property on that Int64 to be added.</param>
        /// <param name="value">The value to add on to the target's property.</param>
        /// <param name="callback">The action to be run when the asynchronous operation completes.</param>
        public void Add(INotifyPropertyChanged target, string propertyName, long value, Action <long> callback)
        {
            InterlockedPropertyInfo propInfo = GetPropertyInfo(target, propertyName, typeof(long));

            this.SendPayload(propInfo, AtomicOperators.Add, callback, value);
        }
        /// <summary>
        /// Adds two integers and replaces the first integer with the sum as an atomic operation.
        /// </summary>
        /// <param name="target">The shared object whose property is to be added.</param>
        /// <param name="propertyName">The property on that Int32 to be added.</param>
        /// <param name="value">The value to add on to the target's property.</param>
        public void Add(INotifyPropertyChanged target, string propertyName, int value)
        {
            InterlockedPropertyInfo propInfo = GetPropertyInfo(target, propertyName, typeof(int), typeof(long));

            this.SendPayload(propInfo, AtomicOperators.Add, null, (long)value);
        }