internal void RollBack(EntityBase entityBase)
 {
     Replace(entityBase);
 }
        /// <summary>
        /// Replaces core data from the specified field (FieldInfo) in entity.
        /// </summary>
        protected void ReplaceForFieldInfo(FieldInfo fi, EntityBase entity)
        {
            // if the field is a NuSoft Framework entity or entityList, then we need to take care to
            // preserve the currently existing entity and entityList instantiated objects as the consumer may
            // have reference to them (ie. data bound to a presentation control)
            if ((fi.FieldType.IsGenericType) && (fi.FieldType.GetGenericTypeDefinition().Equals(typeof(EntityList <>))))
            {
                System.Collections.IList entityListSource = fi.GetValue(entity) as System.Collections.IList;
                System.Collections.IList entityListTarget = fi.GetValue(this) as System.Collections.IList;

                if ((entityListSource == null) && (entityListTarget != null))
                {
                    // un-lazy load the private member of the source so that the entityList items are visible... after loading the items, then the
                    // "if ((entityList != null) && (entityListSource != null))" clause will be hit below, effectively adding the items to the already-
                    // existing entityList instantiated object.
                    string memberName = fi.Name;
                    if (memberName.IndexOf('_') == 0)
                    {
                        string       propertyName = memberName.Substring(1, 1).ToUpper() + memberName.Substring(2);
                        PropertyInfo propertyInfo = this.GetType().GetProperty(propertyName);
                        if (propertyInfo != null)
                        {
                            // we're not going to do anything with entityListForProperty... we just access it get the the entityList lazily-loaded.
                            System.Collections.IList entityListForProperty = propertyInfo.GetValue(entity, null) as System.Collections.IList;
                            entityListSource = fi.GetValue(entity) as System.Collections.IList;
                            entityListTarget = fi.GetValue(this) as System.Collections.IList;
                        }
                    }
                }
                if ((entityListTarget != null) && (entityListSource != null))
                {
                    // todo:mjj move this section to entityList.Replace(entityList)
                    for (int i = entityListTarget.Count - 1; i >= 0; i--)
                    {
                        EntityBase entityTarget = (EntityBase)entityListTarget[i];
                        EntityBase entitySource = (EntityBase)((ISearchable)entityListSource).GetEntityById(entityTarget.UniqueIdentifier);
                        if (entityTarget.IsDeleted)
                        {
                            entityListTarget.Remove(entityTarget);
                        }
                        else if (entitySource != null)
                        {
                            entityTarget.Replace(entitySource);
                        }
                        else
                        {
                            entityListTarget.Remove(entityTarget);
                        }
                    }
                    foreach (EntityBase entitySource in entityListSource)
                    {
                        EntityBase entityTarget = (EntityBase)((ISearchable)entityListTarget).GetEntityById(entitySource.UniqueIdentifier);
                        if (entityTarget == null)
                        {
                            entityListTarget.Add(entitySource);
                        }
                    }
                }
                else if ((entityListSource != null) && (entityListTarget == null))
                {
                    SetFieldValueAndTriggerPropertyChangedEvent(this, fi, ((ICloneable)fi.GetValue(entity)).Clone());
                }
                else
                {
                    SetFieldValueAndTriggerPropertyChangedEvent(this, fi, fi.GetValue(entity));
                }
            }
            else if (fi.FieldType.IsSubclassOf(typeof(EntityBase)))
            {
                EntityBase entityBaseTarget = fi.GetValue(this) as EntityBase;
                EntityBase entityBaseSource = fi.GetValue(entity) as EntityBase;
                if ((entityBaseSource == null) && (entityBaseTarget != null))
                {
                    // provoke source entity's corresponding property to get it lazily loaded
                    string memberName = fi.Name;
                    if (memberName.IndexOf('_') == 0)
                    {
                        string       propertyName = memberName.Substring(1, 1).ToUpper() + memberName.Substring(2);
                        PropertyInfo propertyInfo = this.GetType().GetProperty(propertyName);
                        if (propertyInfo != null)
                        {
                            // we're not going to do anything with entityBase... we just access it to get it lazily-loaded.
                            EntityBase entityBase = propertyInfo.GetValue(entity, null) as EntityBase;
                            entityBaseSource = fi.GetValue(entity) as EntityBase;
                        }
                    }
                }
                if ((entityBaseTarget != null) && (entityBaseSource != null))
                {
                    if (entityBaseTarget.UniqueIdentifier == entityBaseSource.UniqueIdentifier)
                    {
                        entityBaseTarget.Replace(entityBaseSource);
                    }
                    else
                    {
                        SetFieldValueAndTriggerPropertyChangedEvent(this, fi, fi.GetValue(entity));
                    }
                }
                else if ((entityBaseSource != null) && (entityBaseTarget == null))
                {
                    SetFieldValueAndTriggerPropertyChangedEvent(this, fi, ((ICloneable)fi.GetValue(entity)).Clone());
                }
                else
                {
                    SetFieldValueAndTriggerPropertyChangedEvent(this, fi, fi.GetValue(entity));
                }
            }
            else
            {
                SetFieldValueAndTriggerPropertyChangedEvent(this, fi, fi.GetValue(entity));
            }
        }
        /// <summary>
        /// Replaces data from the specified property (PropertyInfo) in entity.
        /// </summary>
        protected void ReplaceForPropertyInfo(PropertyInfo propertyInfo, EntityBase entity)
        {
            // If the setter method of the property is not public, then don't process it. This will exclude ID fields, for instance.
            if (propertyInfo.GetSetMethod(false) != null)
            {
                // if the property is a NuSoft Framework entity or entityList, then we need to take care to
                // preserve the currently existing entity and entityList instantiated objects as the consumer may
                // have reference to them (ie. data bound to a presentation control)

                // if the property is an entityList...
                if ((propertyInfo.PropertyType.IsGenericType) && (propertyInfo.PropertyType.GetGenericTypeDefinition().Equals(typeof(EntityList <>))))
                {
                    // Get the source object's private member that corresponds to the property (ie. the property backer).
                    // If it's value is not null, then let's get the collection's members and merge them into the target's collection.
                    // A null collection for the source does not mean that the target should then be null; it only means that the
                    // source's collection was never lazily loaded.
                    string    propertyName = propertyInfo.Name;
                    string    memberName   = "_" + propertyName.Substring(0, 1).ToLower() + propertyName.Substring(1);
                    FieldInfo fieldInfo    = this.GetType().GetField(memberName, BINDINGS_PRIVATE_INSTANCES);
                    if ((fieldInfo != null) && ((fieldInfo.GetValue(entity) as System.Collections.IList) != null))
                    {
                        // By virture of unique identifer...
                        // - Exists in source collection, and exists in target collection, then merge to target collection
                        // - Exists in source, but not is target, add to target.
                        // - Doesn't exist in source, and doesn't exist in target, do nothing.
                        // - Doesn't exist in source, but does in target, delete/remove from source.
                        System.Collections.IList entityListSource = propertyInfo.GetValue(entity, null) as System.Collections.IList;
                        System.Collections.IList entityListTarget = propertyInfo.GetValue(this, null) as System.Collections.IList;

                        for (int i = entityListTarget.Count - 1; i >= 0; i--)
                        {
                            EntityBase entityTarget = (EntityBase)entityListTarget[i];
                            if (!entityTarget.IsDeleted)
                            {
                                EntityBase entitySource = (EntityBase)((ISearchable)entityListSource).GetEntityById(entityTarget.UniqueIdentifier);
                                if (entitySource != null)
                                {
                                    entityTarget.Merge(entitySource);
                                }
                                else
                                {
                                    entityListTarget.Remove(entityTarget);
                                }
                            }
                        }
                        foreach (EntityBase entitySource in entityListSource)
                        {
                            EntityBase entityTarget = (EntityBase)((ISearchable)entityListTarget).GetEntityById(entitySource.UniqueIdentifier);
                            if (entityTarget == null)
                            {
                                entityListTarget.Add(entitySource);
                            }
                            else if (entitySource.IsDeleted)
                            {
                                entityTarget.SetDeleted(true);
                            }
                        }
                    }
                }
                // else if the property is an entity...
                else if (propertyInfo.PropertyType.IsSubclassOf(typeof(EntityBase)))
                {
                    EntityBase entityBaseTarget = propertyInfo.GetValue(this, null) as EntityBase;
                    EntityBase entityBaseSource = propertyInfo.GetValue(entity, null) as EntityBase;
                    if ((entityBaseTarget != null) && (entityBaseSource != null))
                    {
                        if (entityBaseTarget.UniqueIdentifier == entityBaseSource.UniqueIdentifier)
                        {
                            entityBaseTarget.Replace(entityBaseSource);
                        }
                        else if (propertyInfo.CanWrite)
                        {
                            propertyInfo.SetValue(this, propertyInfo.GetValue(entity, null), null);
                        }
                    }
                    else if ((entityBaseSource != null) && (entityBaseTarget == null))
                    {
                        if (propertyInfo.CanWrite)
                        {
                            propertyInfo.SetValue(this, ((ICloneable)propertyInfo.GetValue(entity, null)).Clone(), null);
                        }
                    }
                    else
                    {
                        if (propertyInfo.CanWrite)
                        {
                            propertyInfo.SetValue(this, propertyInfo.GetValue(entity, null), null);
                        }
                    }
                }
                else                    // just copy the value or object
                {
                    if (propertyInfo.CanWrite)
                    {
                        propertyInfo.SetValue(this, propertyInfo.GetValue(entity, null), null);
                    }
                }
            }
        }