private void DeleteInvalidTransitions(ObservableCollection <ObjectModel.ITransition> transitionList)
        {
            IEnumerable <ObjectModel.ITransition> invalidTransitions = transitionList.Where(t => t.TransitionType == ViewModel.Transition.TransitionTypes.Group && !t.IsValid).ToArray();

            foreach (Transition groupTransition in invalidTransitions)
            {
                groupTransition.Remove();
                MembershipChanged?.Invoke(this, new MembershipChangeArgument(MembershipChangeAction.RemoveTransition, groupTransition));
            }
        }
        private void Members_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
            case NotifyCollectionChangedAction.Add:
                if (e.NewItems.Count == 1 && e.NewItems[0] is ObjectModel.ITransitionEndpoint endpoint)
                {
                    MonitorEndpoint(endpoint);
                    System.Threading.Interlocked.Increment(ref ValidationPendingCount);
                    ThreadHelper.Generic.BeginInvoke(new System.Action(() =>
                    {
                        if (System.Threading.Interlocked.Exchange(ref ValidationPendingCount, 0) > 0)
                        {
                            ValidateTransitions();
                        }
                        MembershipChanged?.Invoke(this, new MembershipChangeArgument(MembershipChangeAction.Add, endpoint));
                    }));
                    break;
                }
                else
                {
                    throw new NotImplementedException();
                }

            case NotifyCollectionChangedAction.Remove:
                if (e.OldItems.Count == 1 && e.OldItems[0] is ObjectModel.ITransitionEndpoint endpoint1)
                {
                    UnmonitorEndpoint(endpoint1);
                    System.Threading.Interlocked.Increment(ref ValidationPendingCount);
                    ThreadHelper.Generic.BeginInvoke(new System.Action(() =>
                    {
                        if (System.Threading.Interlocked.Exchange(ref ValidationPendingCount, 0) > 0)
                        {
                            ValidateTransitions();
                        }
                        MembershipChanged?.Invoke(this, new MembershipChangeArgument(MembershipChangeAction.Remove, endpoint1));
                    }));
                    break;
                }
                else
                {
                    throw new NotImplementedException();
                }

            default:
                throw new NotImplementedException();
            }
        }
        private void MemberPropertyChangedHandler(object sender, PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
            case "GroupStatus":
                if (sender is ObjectModel.ITransitionEndpoint endpoint)
                {
                    ValidateTransitions();
                    MembershipChanged?.Invoke(this, new MembershipChangeArgument(MembershipChangeAction.Change, endpoint));
                }
                break;

            default:
                break;
            }
        }
        private void MemberTransitionsCollectionChangedHandler(object sender, NotifyCollectionChangedEventArgs e)
        {
            System.Threading.Interlocked.Increment(ref ValidationPendingCount);
            ThreadHelper.Generic.BeginInvoke(new System.Action(() =>
            {
                if (System.Threading.Interlocked.Exchange(ref ValidationPendingCount, 0) > 0)
                {
                    ValidateTransitions();
                }
                switch (e.Action)
                {
                case NotifyCollectionChangedAction.Add:
                    if (e.NewItems.Count == 1 && e.NewItems[0] is ObjectModel.ITransition transition)
                    {
                        if (transition.DestinationState != null && transition.SourceState != null)
                        {
                            transition.PropertyChanged += TransitionPropertyChangedHandler;
                            MembershipChanged?.Invoke(this, new MembershipChangeArgument(MembershipChangeAction.AddTransition, transition));
                        }
                        break;
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }

                case NotifyCollectionChangedAction.Remove:
                    if (e.OldItems.Count == 1 && e.OldItems[0] is ObjectModel.ITransition transition1)
                    {
                        if (transition1.DestinationState != null && transition1.SourceState != null)
                        {
                            transition1.PropertyChanged -= TransitionPropertyChangedHandler;
                            MembershipChanged?.Invoke(this, new MembershipChangeArgument(MembershipChangeAction.RemoveTransition, transition1));
                        }
                        break;
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }

                default:
                    throw new NotImplementedException();
                }
            }));
        }
 private void AddTransitionsForEndpoint(ObjectModel.ITransitionEndpoint endpoint)
 {
     endpoint.TransitionsFrom.CollectionChanged += MemberTransitionsCollectionChangedHandler;
     foreach (ObjectModel.ITransition transition in endpoint.TransitionsFrom)
     {
         if (transition.SourceState != null && transition.DestinationState != null)
         {
             ObjectModel.LayerPosition layerPosition = transition.DestinationState.LayerPositions.Where(lp => lp.Layer == Layer).FirstOrDefault();
             if (Members.Contains(transition.SourceState) &&
                 this != transition.DestinationState &&
                 (layerPosition == null || layerPosition.GroupStatus != LayerPosition.GroupStatuses.Explicit))
             {
                 Transition groupTransition = TransitionsFrom.FirstOrDefault(t => t.SourceState == this && t.DestinationState == transition.DestinationState && t.TriggerEvent == transition.TriggerEvent) as Transition;
                 if (groupTransition == null)
                 {
                     groupTransition = new Transition(Controller, this, transition.DestinationState, transition.TriggerEvent);
                     MembershipChanged?.Invoke(this, new MembershipChangeArgument(MembershipChangeAction.AddTransition, groupTransition));
                 }
                 groupTransition.IsValid = true;
             }
         }
     }
     endpoint.TransitionsTo.CollectionChanged += MemberTransitionsCollectionChangedHandler;
     foreach (ObjectModel.ITransition transition in endpoint.TransitionsTo)
     {
         if (transition.SourceState != null && transition.DestinationState != null)
         {
             ObjectModel.LayerPosition layerPosition = transition.SourceState.LayerPositions.Where(lp => lp.Layer == Layer).FirstOrDefault();
             if (Members.Contains(transition.DestinationState) &&
                 this != transition.SourceState &&
                 (layerPosition == null || layerPosition.GroupStatus != LayerPosition.GroupStatuses.Explicit))
             {
                 Transition groupTransition = TransitionsTo.FirstOrDefault(t => t.SourceState == transition.SourceState && t.DestinationState == this && t.TriggerEvent == transition.TriggerEvent) as Transition;
                 if (groupTransition == null)
                 {
                     groupTransition = new Transition(Controller, transition.SourceState, this, transition.TriggerEvent);
                     MembershipChanged?.Invoke(this, new MembershipChangeArgument(MembershipChangeAction.AddTransition, groupTransition));
                 }
                 groupTransition.IsValid = true;
             }
         }
     }
 }