/// <summary>
        /// Delete an entity with key <paramref name="dictionaryKey"/> in the nested dictionary specified by <paramref name="propertyExpression"/> of an object with key <paramref name="key"/>.
        /// The key of the new entity is automatically generated.
        /// </summary>
        /// <typeparam name="T"> Type of the root elements. </typeparam>
        /// <typeparam name="TSelector"> Type of the dictionary being modified</typeparam>
        /// <typeparam name="TProperty"> Type of the value within the dictionary being modified</typeparam>
        /// <param name="db"> Database instance. </param>
        /// <param name="key"> Key of the root element to modify. </param>
        /// <param name="propertyExpression"> Expression on the root element leading to target value to modify. </param>
        /// <param name="dictionaryKey"> Key within the nested dictionary to delete. </param>
        /// <param name="syncOnline"> Indicates whether the item should be synced online. </param>
        /// <param name="priority"> The priority. Objects with higher priority will be synced first. Higher number indicates higher priority. </param>
        public static void Delete <T, TProperty>(this RealtimeDatabase <T> db, string key, Expression <Func <T, IDictionary <string, TProperty> > > propertyExpression, string dictionaryKey, bool syncOnline = true, int priority = 1)
            where T : class
        {
            var expression = Expression.Lambda <Func <T, TProperty> >(Expression.Call(propertyExpression.Body, typeof(IDictionary <string, TProperty>).GetRuntimeMethod("get_Item", new[] { typeof(string) }), Expression.Constant(dictionaryKey)), propertyExpression.Parameters);

            db.Set(key, expression, null, syncOnline ? SyncOptions.Put : SyncOptions.None, priority);
        }
        /// <summary>
        /// Adds a new entity to the Database.
        /// </summary>
        /// <param name="obj"> The object to add.  </param>
        /// <param name="syncOnline"> Indicates whether the item should be synced online. </param>
        /// <param name="priority"> The priority. Objects with higher priority will be synced first. Higher number indicates higher priority. </param>
        /// <returns> The generated key for this object. </returns>
        public static string Post <T>(this RealtimeDatabase <T> db, T obj, bool syncOnline = true, int priority = 1)
            where T : class
        {
            var key = FirebaseKeyGenerator.Next();

            db.Set(key, obj, syncOnline ? SyncOptions.Put : SyncOptions.None, priority);

            return(key);
        }
        /// <summary>
        /// Post a new entity into the nested dictionary specified by <paramref name="propertyExpression"/> of an object with key <paramref name="key"/>.
        /// The key of the new entity is automatically generated.
        /// </summary>
        /// <typeparam name="T"> Type of the root elements. </typeparam>
        /// <typeparam name="TSelector"> Type of the dictionary being modified</typeparam>
        /// <typeparam name="TProperty"> Type of the value within the dictionary being modified</typeparam>
        /// <param name="db"> Database instance. </param>
        /// <param name="key"> Key of the root element to modify. </param>
        /// <param name="propertyExpression"> Expression on the root element leading to target value to modify. </param>
        /// <param name="value"> Value to put. </param>
        /// <param name="syncOnline"> Indicates whether the item should be synced online. </param>
        /// <param name="priority"> The priority. Objects with higher priority will be synced first. Higher number indicates higher priority. </param>
        public static void Post <T, TSelector, TProperty>(this RealtimeDatabase <T> db, string key, Expression <Func <T, TSelector> > propertyExpression, TProperty value, bool syncOnline = true, int priority = 1)
            where T : class
            where TSelector : IDictionary <string, TProperty>
        {
            var nextKey    = FirebaseKeyGenerator.Next();
            var expression = Expression.Lambda <Func <T, TProperty> >(Expression.Call(propertyExpression.Body, typeof(TSelector).GetRuntimeMethod("get_Item", new[] { typeof(string) }), Expression.Constant(nextKey)), propertyExpression.Parameters);

            db.Set(key, expression, value, syncOnline ? SyncOptions.Put : SyncOptions.None, priority);
        }
 /// <summary>
 /// Do a Put for a nested property specified by <paramref name="propertyExpression"/> of an object with key <paramref name="key"/>.
 /// </summary>
 /// <typeparam name="T"> Type of the root elements. </typeparam>
 /// <typeparam name="TProperty"> Type of the property being modified</typeparam>
 /// <param name="db"> Database instance. </param>
 /// <param name="key"> Key of the root element to modify. </param>
 /// <param name="propertyExpression"> Expression on the root element leading to target value to modify. </param>
 /// <param name="value"> Value to put. </param>
 /// <param name="syncOnline"> Indicates whether the item should be synced online. </param>
 /// <param name="priority"> The priority. Objects with higher priority will be synced first. Higher number indicates higher priority. </param>
 public static void Put <T, TProperty>(this RealtimeDatabase <T> db, string key, Expression <Func <T, TProperty> > propertyExpression, TProperty value, bool syncOnline = true, int priority = 1)
     where T : class
 {
     db.Set(key, propertyExpression, value, syncOnline ? SyncOptions.Put : SyncOptions.None, priority);
 }
 /// <summary>
 /// Deletes the entity with the given key.
 /// </summary>
 /// <param name="key"> The key. </param>
 /// <param name="syncOnline"> Indicates whether the item should be synced online. </param>
 /// <param name="priority"> The priority. Objects with higher priority will be synced first. Higher number indicates higher priority. </param>
 public static void Delete <T>(this RealtimeDatabase <T> db, string key, bool syncOnline = true, int priority = 1)
     where T : class
 {
     db.Set(key, null, syncOnline ? SyncOptions.Put : SyncOptions.None, priority);
 }
 /// <summary>
 /// Overwrites existing object with given key leaving any missing properties intact in firebase.
 /// </summary>
 /// <param name="key"> The key. </param>
 /// <param name="obj"> The object to set. </param>
 /// <param name="syncOnline"> Indicates whether the item should be synced online. </param>
 /// <param name="priority"> The priority. Objects with higher priority will be synced first. Higher number indicates higher priority. </param>
 public static void Patch <T>(this RealtimeDatabase <T> db, string key, T obj, bool syncOnline = true, int priority = 1)
     where T : class
 {
     db.Set(key, obj, syncOnline ? SyncOptions.Patch : SyncOptions.None, priority);
 }