private IRegexFSMTransition <T> GenerateNFATransitionFromRegexZeroLengthObject(
            RegexZeroLengthObject <T> zeroLength,
            IRegexNFA <T> nfa,
            IRegexNFAState <T> state
            )
        {
            const string PROGRESS_SERVICE_KEY = "PROGRESS_SERVICE";
            const string PROGRESS_KEY         = "TIMEPOINT";

            IRegexNFAState <T> nextState = state;

            RegexFSMPredicateTransition <T> predicateTransition;

            predicateTransition = new RegexFSMPredicateTransition <T>((sender, args) =>
            {
                if (args.FirstOrDefault() is IRegexFSM <T> fsm)
                {
                    var progressService = fsm.GetService <RegexFSM <T> .ProgressService>();
                    var progress        = progressService.GetProgress();
                    fsm.UserData[PROGRESS_SERVICE_KEY] = progressService;
                    fsm.UserData[PROGRESS_KEY]         = progress;

                    return(true);
                }
                return(false);
            });
            nfa.AttachTransition(nextState, predicateTransition);
            nextState = this.contextInfo.ActivateRegexNFAState();
            nfa.SetTarget(predicateTransition, nextState);

            var transition = this.GenerateNFATransitionFromRegexObject(zeroLength.InnerRegex, nfa, nextState);

            nextState = this.contextInfo.ActivateRegexNFAState();
            nfa.SetTarget(transition, nextState);

            predicateTransition = new RegexFSMPredicateTransition <T>((sender, args) =>
            {
                if (args.FirstOrDefault() is IRegexFSM <T> fsm)
                {
                    var progressService = (RegexFSM <T> .ProgressService)fsm.UserData[PROGRESS_SERVICE_KEY];
                    var progress        = (RegexFSM <T> .ProgressService.Progress)fsm.UserData[PROGRESS_KEY];
                    progressService.SetProgress(progress);

                    return(true);
                }
                return(false);
            });

            return(predicateTransition);
        }
        public IRegexFSM <T> GenerateRegexFSMFromRegexObject(RegexObject <T> regex, RegexOptions options)
        {
            if (regex == null)
            {
                throw new ArgumentNullException(nameof(regex));
            }

            IRegexNFA <T>      nfa        = this.contextInfo.ActivateRegexNFA();
            IRegexNFAState <T> startState = this.contextInfo.ActivateRegexNFAState();

            nfa.StartState = startState;

            IRegexFSMTransition <T> transition = this.GenerateNFATransitionFromRegexObject(regex, nfa, startState);
            IRegexNFAState <T>      endState   = this.contextInfo.ActivateRegexNFAState(true);

            nfa.SetTarget(transition, endState);

            return(nfa);
        }