public void DoClusterAction(Action <IEntityExtensions> action, ClusterTraversalMode mode)
 {
     DoClusterAction((e, n) => action(e), mode);
 }
        public void DoClusterAction(Action <IEntityExtensions, int> action, ClusterTraversalMode mode)
        {
            var visited = new Dictionary <object, object>(ObjectReferenceEqualityComparerer <object> .Default);

            SafeRecursiveActionInternal((e, n) => action(e, n), visited, 0, mode);
        }
        protected void SafeRecursiveActionInternal(Action <EntityExtensions, int> action, Dictionary <object, object> visited, int level, ClusterTraversalMode mode)
        {
            if (visited.ContainsKey(this))
            {
                return;
            }
            visited.Add(this, null);

            action(this, level);

            if (mode == ClusterTraversalMode.SelfOnly)
            {
                return;
            }

            var elemets = Enumerable.Empty <IEntityExtensions>();

            if (mode == ClusterTraversalMode.ChildProperties || mode == ClusterTraversalMode.All)
            {
                elemets = elemets.Union(Initializer.GraphMonitoringStrategy.GetProperties(Target));
            }
            if (mode == ClusterTraversalMode.ChildCollections || mode == ClusterTraversalMode.All)
            {
                elemets = elemets.Union(Initializer.GraphMonitoringStrategy.GetCollectionsElements(Target));
            }

            foreach (var childEntityExtension in elemets)
            {
                var entityExtension = (EntityExtensions)childEntityExtension;
                entityExtension.SafeRecursiveActionInternal(action, visited, level + 1, mode);
            }
        }