/// <summary>
        /// Evaluates rule that can work one way
        /// </summary>
        /// <param name="traits">character traits to modify</param>
        /// <param name="rule">rules to evaluate</param>
        private static void EvaluateSimpleRule(CharacterTraits traits, QualityTraitRule rule)
        {
            var leadingProperty  = traits.GetType().GetProperty(rule.LeadingQuality);
            var attachedProperty = traits.GetType().GetProperty(rule.AttachedQuality);

            if (leadingProperty == null || attachedProperty == null)
            {
                return;
            }

            int leadingValue;
            int attachedValue;

            if (ValuesAreWithinRange(traits, rule, leadingProperty, attachedProperty, out leadingValue, out attachedValue))
            {
                return;
            }

            if (leadingValue > attachedValue)
            {
                //We won't raise if it's a weakness
                if (!traits.WeakPoints.Contains(rule.AttachedQuality))
                {
                    attachedProperty.SetValue(traits, leadingValue - rule.RangeLimit + 1);
                }
            }
            else
            {
                //We won't lower it if it's a strong point
                if (!traits.StrongPoints.Contains(rule.AttachedQuality))
                {
                    attachedProperty.SetValue(traits, leadingValue + rule.RangeLimit - 1);
                }
            }
        }
        /// <summary>
        /// Evaluates rule that can work both ways
        /// </summary>
        /// <param name="traits">character traits to modify</param>
        /// <param name="rule">rules to evaluate</param>
        private void EvaluateBidirectionalRule(CharacterTraits traits, QualityTraitRule rule)
        {
            var leadingProperty  = traits.GetType().GetProperty(rule.LeadingQuality);
            var attachedProperty = traits.GetType().GetProperty(rule.AttachedQuality);

            if (leadingProperty == null || attachedProperty == null)
            {
                return;
            }

            int leadingValue;
            int attachedValue;

            if (ValuesAreWithinRange(traits, rule, leadingProperty, attachedProperty, out leadingValue, out attachedValue))
            {
                return;
            }

            if (leadingValue > attachedValue)
            {
                //If the attached is a weak point AND the leading is a NOT a strong point,
                //then we just lower the leading property. Otherwise we raise the attached quality.
                if (traits.WeakPoints.Contains(rule.AttachedQuality))
                {
                    if (!traits.StrongPoints.Contains(rule.LeadingQuality))
                    {
                        leadingProperty.SetValue(traits, attachedValue + rule.RangeLimit + 1);
                    }
                }
                else
                {
                    attachedProperty.SetValue(traits, leadingValue - rule.RangeLimit + 1);
                }
            }
            else
            {
                //If the leading value is a weakness AND the attached is not a strong point,
                //we lower the attached property. Otherwise we raise the leading quality
                if (traits.WeakPoints.Contains(rule.LeadingQuality))
                {
                    if (!traits.StrongPoints.Contains(rule.AttachedQuality))
                    {
                        attachedProperty.SetValue(traits, leadingValue + rule.RangeLimit - 1);
                    }
                }
                else
                {
                    leadingProperty.SetValue(traits, attachedValue - rule.RangeLimit + 1);
                }
            }
        }
        /// <summary>
        /// Evaluates all rules and applies them
        /// </summary>
        /// <param name="traits">character traits</param>
        public void EvaluateAndApplyAllRules(CharacterTraits traits)
        {
            var rules = GetAllEmotionalTraitRules();

            foreach (var rule in rules)
            {
                var quality = traits.GetType().GetProperty(rule.Quality);
                var emotion = traits.LongTermEmotions.GetType().GetProperty(rule.Emotion);

                if (quality == null || emotion == null)
                {
                    continue;
                }

                int randomValue         = RandomValueGenerator.GeneratePercentileIntegerValue();
                int qualityValue        = (int)quality.GetValue(traits);
                int currentEmotionValue = (int)emotion.GetValue(traits.LongTermEmotions);

                if (rule.IsComparedBelowQualityValue && qualityValue > randomValue ||
                    (!rule.IsComparedBelowQualityValue && qualityValue < randomValue))
                {
                    //If conditions are met, emotion is modified, but by at most 3.
                    emotion.SetValue(traits.LongTermEmotions, currentEmotionValue + RandomValueGenerator.GenerateIntWithMaxValue(3));
                }
            }
        }