/// <summary>
        /// This is the only function that should be called from outside.
        /// It takes a RegexTree and creates a corresponding RegexCode.
        /// </summary>
        internal static RegexCode Write(RegexTree t)
        {
            RegexWriter w      = new RegexWriter();
            RegexCode   retval = w.RegexCodeFromRegexTree(t);

#if DEBUG
            if (t.Debug)
            {
                t.Dump();
                retval.Dump();
            }
#endif
            return(retval);
        }
        /// <summary>
        /// This is the only function that should be called from outside.
        /// It takes a RegexTree and creates a corresponding RegexCode.
        /// </summary>
        public static RegexCode Write(RegexTree tree)
        {
            Span <int> emittedSpan  = stackalloc int[EmittedSize];
            Span <int> intStackSpan = stackalloc int[IntStackSize];

            var       writer = new RegexWriter(emittedSpan, intStackSpan);
            RegexCode code   = writer.RegexCodeFromRegexTree(tree);

            writer.Dispose();

#if DEBUG
            if (tree.Debug)
            {
                tree.Dump();
                code.Dump();
            }
#endif

            return(code);
        }
        private Regex(string pattern, RegexOptions options, TimeSpan matchTimeout, bool useCache)
        {
            // validate parameters:
            if (pattern == null)
            {
                throw new ArgumentNullException(nameof(pattern));
            }
            if (options < RegexOptions.None || (((int)options) >> MaxOptionShift) != 0)
            {
                throw new ArgumentOutOfRangeException(nameof(options));
            }
            if ((options & RegexOptions.ECMAScript) != 0 &&
                (options & ~(RegexOptions.ECMAScript |
                             RegexOptions.IgnoreCase |
                             RegexOptions.Multiline |
                             RegexOptions.CultureInvariant
#if DEBUG
                             | RegexOptions.Debug
#endif
                             )) != 0)
            {
                throw new ArgumentOutOfRangeException(nameof(options));
            }

            ValidateMatchTimeout(matchTimeout);

            this.pattern  = pattern;
            this.roptions = options;

            // Try to look up this regex in the cache.  We do this regardless of whether useCache is true since there's
            // really no reason not to.
            var key    = new CachedCodeEntryKey(options, pattern);
            var cached = LookupCachedAndUpdate(key);

            internalMatchTimeout = matchTimeout;

            if (cached == null)
            {
                // Parse the input
                var tree = RegexParser.Parse(pattern, roptions);

                // Extract the relevant information
                capnames = tree.CapNames;
                capslist = tree.CapsList;
                _code    = RegexWriter.Write(tree);
                caps     = _code._caps;
                capsize  = _code._capsize;

                InitializeReferences();

                if (useCache)
                {
                    CacheCode(key);
                }
            }
            else
            {
                caps             = cached._caps;
                capnames         = cached._capnames;
                capslist         = cached._capslist;
                capsize          = cached._capsize;
                _code            = cached._code;
                _runnerref       = cached._runnerref;
                _replref         = cached._replref;
                _refsInitialized = true;
            }
        }