private void EventTracer_EventRaising(FunctionalEvent functionalEvent, FunctionalEventTracingArgs e)
        {
            TestingElement previous = e.PreviousElement as TestingElement;
            TestingElement next = e.NextElement as TestingElement;
            string previousName = previous != null ? previous.Name : "";
            string nextName = next != null ? next.Name : "";
            string currentName = (e.CurrentElement as TestingElement).Name;

            WriteEventTracingLine(string.Format("[EventRaising] Event: {0}   Previous: {1}  Current: {2}  Next: {3}", functionalEvent.Name, previousName, currentName, nextName));
        }
        private void RaiseEventOnElement(IFunctionalTreeElement element, 
            FunctionalEventArgs eventArgs, 
            FunctionalEventTracingArgs tracingEventArgs, 
            Predicate<IFunctionalTreeElement> predicate = null)
        {
            if (element == null || eventArgs == null || (predicate != null && !predicate(element)))
                return;

            List<FunctionalEventHandlerContainer> eventHandlerList = GetHandlerList(eventArgs.FunctionalEvent, element);
            if (eventHandlerList != null && eventHandlerList.Count() > 0)
            {
                foreach (FunctionalEventHandlerContainer handlerContainer in eventHandlerList)
                {
                    if (!eventArgs.Handled || handlerContainer.HandledEventsToo)
                    {
                        eventArgs.FunctionalEvent.EventTracer.RaiseEventRaising(eventArgs.FunctionalEvent, tracingEventArgs);
                        if (tracingEventArgs.Abort)
                            return;

                        foreach (Delegate handler in handlerContainer.Handler.GetInvocationList())
                            handler.Method.Invoke(element, new object[] { element, eventArgs });

                        eventArgs.FunctionalEvent.EventTracer.RaiseEventRaised(eventArgs.FunctionalEvent, tracingEventArgs);
                        if (tracingEventArgs.Abort)
                            return;
                    }
                }
            }
        }
        internal void RaiseEvent(FunctionalEventArgs eventArgs, Predicate<IFunctionalTreeElement> predicate = null)
        {
            if (eventArgs == null)
                throw new ArgumentNullException("eventArgs", "eventArgs is null.");
            if (eventArgs.FunctionalEvent == null)
                throw new ArgumentNullException("eventArgs", "eventArgs is null.");

            if (!FunctionalEventsInternal.ContainsKey(eventArgs.FunctionalEvent.OwnerType))
                return;

            FunctionalEvent functionalEvent = eventArgs.FunctionalEvent;
            FunctionalElementRoute route = null;
            switch (functionalEvent.FunctionalStretegy)
            {
                case FunctionalStrategy.Bubble:
                    route = BuildBubbleEventRoute(eventArgs.Source, eventArgs);
                    break;
                case FunctionalStrategy.Tunnel:
                    route = BuildTunnelEventRoute(eventArgs.Source, eventArgs);
                    break;
                case FunctionalStrategy.Spread:
                    route = BuildSpreadEventRoute(eventArgs.Source, eventArgs);
                    break;
                case FunctionalStrategy.Children:
                    route = BuildChildrenEventRoute(eventArgs.Source, eventArgs);
                    break;
                case FunctionalStrategy.Descendents:
                    route = BuildDescendentsEventRoute(eventArgs.Source, eventArgs);
                    break;
                case FunctionalStrategy.Siblings:
                    route = BuildSiblingsEventRoute(eventArgs.Source, eventArgs);
                    break;
                case FunctionalStrategy.Parent:
                    route = BuildParentEventRoute(eventArgs.Source, eventArgs);
                    break;
            }

            FunctionalEventTracingArgs tracingEventArgs = new FunctionalEventTracingArgs(route);
            foreach (IFunctionalTreeElement element in route)
            {
                tracingEventArgs.UpdateCurrentIndex(route.IndexOf(element));
                RaiseEventOnElement(element, eventArgs, tracingEventArgs, predicate);
                if (tracingEventArgs.Abort)
                    break;
            }
        }
 internal void RaiseEventRaising(FunctionalEvent functionalEvent, FunctionalEventTracingArgs eventRaisingArgs)
 {
     if (EventRaising != null)
         EventRaising(functionalEvent, eventRaisingArgs);
 }