/// <summary>
        /// Loads the status effects for the <see cref="CharacterStatusEffects.Character"/> that this collection belongs to from
        /// the database.
        /// </summary>
        public void Load()
        {
            Debug.Assert(_statusEffects.Count == 0, "Why is Load() being called while there are active effects here already?");

            var values = Character.DbController.GetQuery <SelectCharacterStatusEffectsQuery>().Execute(Character.ID);

            var currentTime = GetTime();

            // Load in the ActiveStatusEffects using the values read from the database
            foreach (var value in values)
            {
                var statusEffect = _statusEffectManager.Get(value.StatusEffect);
                if (statusEffect == null)
                {
                    const string errmsg = "Failed to get the StatusEffectBase for StatusEffectType `{0}` on Character `{1}`.";
                    if (log.IsErrorEnabled)
                    {
                        log.ErrorFormat(errmsg, value.StatusEffect, Character);
                    }
                    Debug.Fail(string.Format(errmsg, value.StatusEffect, Character));
                    continue;
                }

                var ase       = new ActiveStatusEffect(statusEffect, value.Power, (TickCount)(value.TimeLeftSecs * 1000 + currentTime));
                var aseWithID = new ASEWithID(value.ID, ase);
                _statusEffects.Add(aseWithID);
                OnAdded(ase);
            }
        }
        bool TryGetStatusEffect(StatusEffectType statusEffectType, out ASEWithID statusEffect)
        {
            foreach (var item in _statusEffects)
            {
                if (item.Value.StatusEffect.StatusEffectType == statusEffectType)
                {
                    statusEffect = item;
                    return(true);
                }
            }

            statusEffect = default(ASEWithID);
            return(false);
        }
        /// <summary>
        /// Updates a <see cref="ActiveStatusEffect"/> in the database.
        /// </summary>
        /// <param name="item">The <see cref="ActiveStatusEffect"/> and <see cref="ActiveStatusEffectID"/> to update.</param>
        void UpdateInDatabase(ASEWithID item)
        {
            // Convert the time
            var secsLeft = GetSecsLeft(item.Value);

            // Create the row
            var values = new CharacterStatusEffectTable
            {
                CharacterID  = Character.ID,
                ID           = item.ID,
                Power        = item.Value.Power,
                TimeLeftSecs = (ushort)secsLeft,
                StatusEffect = item.Value.StatusEffect.StatusEffectType
            };

            // Update the row
            _updateQuery.Execute(values);
        }
        /// <summary>
        /// When overridden in the derived class, tries to add an <see cref="IStatusEffect{StatType, StatusEffectType}"/> to
        /// this collection.
        /// </summary>
        /// <param name="statusEffect">The status effect to add.</param>
        /// <param name="power">The power of the status effect.</param>
        /// <returns>True if the <paramref name="statusEffect"/> of the given <paramref name="power"/> was added
        /// to this collection; otherwise false.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="statusEffect" /> is <c>null</c>.</exception>
        public override bool TryAdd(IStatusEffect <StatType, StatusEffectType> statusEffect, ushort power)
        {
            if (statusEffect == null)
            {
                throw new ArgumentNullException("statusEffect");
            }

            ASEWithID existingStatusEffect;
            var       alreadyExists = TryGetStatusEffect(statusEffect.StatusEffectType, out existingStatusEffect);

            var time        = GetTime();
            var disableTime = (TickCount)(time + statusEffect.GetEffectTime(power));

            if (alreadyExists)
            {
                // Status effect already exists - merge with it
                var changed = existingStatusEffect.Value.MergeWith(time, power, disableTime);
                if (changed)
                {
                    RecalculateStatBonuses();
                    UpdateInDatabase(existingStatusEffect);
                }
                return(changed);
            }
            else
            {
                // Status effect doesn't exist - create new instance
                var ase = new ActiveStatusEffect(statusEffect, power, disableTime);

                var id = InsertInDatabase(ase);

                var aseWithID = new ASEWithID(id, ase);
                _statusEffects.Add(aseWithID);

                OnAdded(aseWithID.Value);

                return(true);
            }
        }
        /// <summary>
        /// Updates a <see cref="ActiveStatusEffect"/> in the database.
        /// </summary>
        /// <param name="item">The <see cref="ActiveStatusEffect"/> and <see cref="ActiveStatusEffectID"/> to update.</param>
        void UpdateInDatabase(ASEWithID item)
        {
            // Convert the time
            var secsLeft = GetSecsLeft(item.Value);

            // Create the row
            var values = new CharacterStatusEffectTable
            {
                CharacterID = Character.ID,
                ID = item.ID,
                Power = item.Value.Power,
                TimeLeftSecs = (ushort)secsLeft,
                StatusEffect = item.Value.StatusEffect.StatusEffectType
            };

            // Update the row
            _updateQuery.Execute(values);
        }
        bool TryGetStatusEffect(StatusEffectType statusEffectType, out ASEWithID statusEffect)
        {
            foreach (var item in _statusEffects)
            {
                if (item.Value.StatusEffect.StatusEffectType == statusEffectType)
                {
                    statusEffect = item;
                    return true;
                }
            }

            statusEffect = default(ASEWithID);
            return false;
        }
        /// <summary>
        /// When overridden in the derived class, tries to add an <see cref="IStatusEffect{StatType, StatusEffectType}"/> to
        /// this collection.
        /// </summary>
        /// <param name="statusEffect">The status effect to add.</param>
        /// <param name="power">The power of the status effect.</param>
        /// <returns>True if the <paramref name="statusEffect"/> of the given <paramref name="power"/> was added
        /// to this collection; otherwise false.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="statusEffect" /> is <c>null</c>.</exception>
        public override bool TryAdd(IStatusEffect<StatType, StatusEffectType> statusEffect, ushort power)
        {
            if (statusEffect == null)
                throw new ArgumentNullException("statusEffect");

            ASEWithID existingStatusEffect;
            var alreadyExists = TryGetStatusEffect(statusEffect.StatusEffectType, out existingStatusEffect);

            var time = GetTime();
            var disableTime = (TickCount)(time + statusEffect.GetEffectTime(power));

            if (alreadyExists)
            {
                // Status effect already exists - merge with it
                var changed = existingStatusEffect.Value.MergeWith(time, power, disableTime);
                if (changed)
                {
                    RecalculateStatBonuses();
                    UpdateInDatabase(existingStatusEffect);
                }
                return changed;
            }
            else
            {
                // Status effect doesn't exist - create new instance
                var ase = new ActiveStatusEffect(statusEffect, power, disableTime);

                var id = InsertInDatabase(ase);

                var aseWithID = new ASEWithID(id, ase);
                _statusEffects.Add(aseWithID);

                OnAdded(aseWithID.Value);

                return true;
            }
        }
        /// <summary>
        /// Loads the status effects for the <see cref="CharacterStatusEffects.Character"/> that this collection belongs to from
        /// the database.
        /// </summary>
        public void Load()
        {
            Debug.Assert(_statusEffects.Count == 0, "Why is Load() being called while there are active effects here already?");

            var values = Character.DbController.GetQuery<SelectCharacterStatusEffectsQuery>().Execute(Character.ID);

            var currentTime = GetTime();

            // Load in the ActiveStatusEffects using the values read from the database
            foreach (var value in values)
            {
                var statusEffect = _statusEffectManager.Get(value.StatusEffect);
                if (statusEffect == null)
                {
                    const string errmsg = "Failed to get the StatusEffectBase for StatusEffectType `{0}` on Character `{1}`.";
                    if (log.IsErrorEnabled)
                        log.ErrorFormat(errmsg, value.StatusEffect, Character);
                    Debug.Fail(string.Format(errmsg, value.StatusEffect, Character));
                    continue;
                }

                var ase = new ActiveStatusEffect(statusEffect, value.Power, (TickCount)(value.TimeLeftSecs * 1000 + currentTime));
                var aseWithID = new ASEWithID(value.ID, ase);
                _statusEffects.Add(aseWithID);
                OnAdded(ase);
            }
        }