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;
            }
        }