private void TraceChanges(HibernateProperty newProperty, HibernateProperty oldProperty, ChangeHandler changes, string parentClassName)
        {
            if (!newProperty.Type.IsCollection)
            {
                if (newProperty.Type.IsComponent)
                {
                    TraceChangesInComponent(changes, newProperty, oldProperty);
                    return;
                }

                if (newProperty.ShouldTraverse())
                {
                    TraceChanges(newProperty.Value, oldProperty.Value, changes, newProperty.ReturnClassName);
                    return;
                }

                MarkIfChanged(changes, newProperty, oldProperty, parentClassName);
            }
        }
        private void TraceChangesInComponent(ChangeHandler changes, HibernateProperty newProperty, HibernateProperty oldProperty)
        {
            if (newProperty.Value != null)
            {
                List<HibernateProperty> properties = newProperty.ComponentProperties;
                List<HibernateProperty> oldProperties;

                if (oldProperty != null && oldProperty.Value != null)
                    oldProperties = oldProperty.ComponentProperties;
                else
                {
                    oldProperties = new List<HibernateProperty>();
                    for (int i = 0; i < properties.Count; i++)
                        oldProperties.Add(new NullHibernateProperty());
                }
                for (int i = 0; i < properties.Count; i++)
                    TraceChanges(properties[i], oldProperties[i], changes, newProperty.Name);
            }
        }
        private void MarkIfChanged(ChangeHandler changes, HibernateProperty newProperty, HibernateProperty oldProperty, string parentClassName)
        {
            if (S.AreDifferent(newProperty.Value, oldProperty.Value) && !newProperty.IgnoreAudit)
            {
                string oldValue = S.Value(oldProperty.Value);
                string newValue = S.Value(newProperty.Value);

                if (oldValue.Length >= 2000 || newValue.Length >= 2000) return;
                changes(newEntity, parentClassName + " " + newProperty.Name, oldValue, newValue);
            }
        }