/// <summary>
        /// Глубокое клонирование. Обход дерева и построение такой же структуры.
        /// </summary>
        /// <param name="fromClone">Источник клонирования</param>
        /// <returns>Новый экземпляр</returns>
        public static ITrackable DeepClone(this ITrackable fromClone)
        {
            ITrackable toClone = null;

            if (fromClone != null)
            {
                if (fromClone.GetMonitor() is EntityStateMonitor monitor)
                {
                    InnerClone(fromClone, out toClone, monitor.PropertyInfoDictionary);
                }
                else
                {
                    InnerClone(fromClone, out toClone, null);
                }
            }

            return(toClone);
        }
        /// <summary>
        /// Очистить все дочернии коллекции, начиная от текущего. (При очищении, помечаются в трекере как удаленные)
        /// </summary>
        /// <param name="rootEntity">Элемент, от которого поиск</param>
        public static void ClearAllCollectionFromCurrent([NotNull] this ITrackable rootEntity)
        {
            var flatList = new Dictionary <IList, IList>(ReferenceEqualityComparer.Instance);

            var monitor = rootEntity.GetMonitor() as EntityStateMonitor;

            if (monitor == null)
            {
                return;
            }

            monitor.TraverseGraph(rootEntity, x =>
            {
                if (x is IList list && !flatList.ContainsKey(list))
                {
                    flatList.Add(list, list);
                }

                return(true); //обходим дерево дальше
            });
        /// <summary>
        /// Получить из делева плоский список ВСЕХ дочерние сущьностей, относительно текущего узла
        /// </summary>
        /// <param name="rootEntity">Элемент, от которого поиск</param>
        /// <param name="predicat">Фильтр полученных элементов </param>
        public static IEnumerable <BaseEntity> GetFromCurrent([NotNull] this ITrackable rootEntity, Func <BaseEntity, bool> predicat = null)
        {
            var flatList = new Dictionary <BaseEntity, BaseEntity>(ReferenceEqualityComparer.Instance);

            var monitor = rootEntity.GetMonitor() as EntityStateMonitor;

            if (monitor == null)
            {
                return(new List <BaseEntity>());
            }


            monitor.TraverseGraph(rootEntity, x =>
            {
                if (x is BaseEntity baseEntity) // это сущьность
                {
                    if (!flatList.ContainsKey(baseEntity))
                    {
                        if (predicat != null)
                        {
                            if (predicat.Invoke(baseEntity))
                            {
                                flatList.Add(baseEntity, baseEntity);
                            }
                        }
                        else
                        {
                            flatList.Add(baseEntity, baseEntity);
                        }
                    }
                }
                return(true); //обходим дерево дальше
            });

            return(flatList.Keys);
        }