public WpfOutputParser(StringCache stringCache)
        {
            this.stringCache = stringCache;

            const RegexOptions overallRegexOptions = RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture | RegexOptions.Singleline | RegexOptions.Multiline;
            const RegexOptions lineRegexOptions    = RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture;

            this.processTextRegex = new Regex($@"^System.Windows.(?<{WpfOutputParser.CaptureCategory}>Data|ResourceDictionary) (?<{WpfOutputParser.CaptureSeverity}>.+?): (?<{WpfOutputParser.CaptureCode}>\d+) : (?<{WpfOutputParser.CaptureText}>.+?)$", overallRegexOptions);

            // 1
            Regex regexCannotCreateDefaultValueConverter = new Regex($@"Cannot create default converter to perform '(one-way|two-way)' conversions between types '(?<{WpfEntry.SourceFullType}>.+?)' and '(?<{WpfEntry.TargetFullType}>.+?)'. Consider using Converter property of Binding. {WpfOutputParser.CaptureBindingExpression()}", lineRegexOptions);
            // 5
            Regex regexBadValueAtTransfer = new Regex($@"Value produced by BindingExpression is not valid for target property.; Value='(?<DataValue>.+?)' {WpfOutputParser.CaptureBindingExpression()}", lineRegexOptions);
            // 40
            Regex regexClrReplaceItem = new Regex($@"BindingExpression path error: '(?<{nameof(WpfEntry.SourceProperty)}>.+?)' property not found on '(object|current item of collection)' '{WpfOutputParser.CaptureItem(nameof(WpfEntry.SourcePropertyType), nameof(WpfEntry.SourcePropertyName))}'. {WpfOutputParser.CaptureBindingExpression()}", lineRegexOptions);

            this.codeToRegex = new Dictionary <WpfTraceCode, Regex>()
            {
                { WpfTraceCode.CannotCreateDefaultValueConverter, regexCannotCreateDefaultValueConverter },
                { WpfTraceCode.BadValueAtTransfer, regexBadValueAtTransfer },
                { WpfTraceCode.ClrReplaceItem, regexClrReplaceItem },
            };
        }
        public WpfOutputParser()
        {
            this.stringCache = new StringCache();

            this.processTextRegex = new Regex($@"^System.Windows.(?<{WpfOutputParser.CaptureCategory}>Data|ResourceDictionary) (?<{WpfOutputParser.CaptureSeverity}>.+?): (?<{WpfOutputParser.CaptureCode}>\d+) : (?<{WpfOutputParser.CaptureText}>.+?)$",
                                              RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture | RegexOptions.Singleline | RegexOptions.Multiline);

            this.codeToRegex = new Dictionary <WpfTraceCode, Lazy <Regex> >(Enum.GetNames(typeof(WpfTraceCode)).Length);

            this.AddRegex(WpfTraceCode.CannotCreateDefaultValueConverter,
                          $@"Cannot create default converter to perform '(one-way|two-way)' conversions between types '(?<{WpfEntry.SourceFullType}>.+?)' and '(?<{WpfEntry.TargetFullType}>.+?)'\. Consider using Converter property of Binding\. {WpfOutputParser.CaptureBindingExpression()}");

            this.AddRegex(WpfTraceCode.NoMentor,
                          $@"Cannot find governing FrameworkElement or FrameworkContentElement for target element\. {WpfOutputParser.CaptureBindingExpression()}");

            this.AddRegex(WpfTraceCode.NoSource,
                          $@"Cannot find source for binding with reference '(?<{WpfEntry.ExtraInfo}>.+?)'\. {WpfOutputParser.CaptureBindingExpression()}");

            this.AddRegex(WpfTraceCode.BadValueAtTransfer,
                          $@"Value produced by BindingExpression is not valid for target property\.((; Value=)| (?<DataValueType>.+?):)'(?<DataValue>.+?)' {WpfOutputParser.CaptureBindingExpression()}");

            this.AddRegex(WpfTraceCode.BadConverterForTransfer,
                          $@"'.*?' converter failed to convert value '(?<DataValue>.*?)' \(type '(?<DataValueType>.*?)'\); fallback value will be used, if available\. {WpfOutputParser.CaptureBindingExpression()}(?<{WpfEntry.ExtraInfo}>.*)");

            this.AddRegex(WpfTraceCode.NoValueToTransfer,
                          $@"Cannot retrieve value using the binding and no valid fallback value exists; using default instead\. {WpfOutputParser.CaptureBindingExpression()}");

            this.AddRegex(WpfTraceCode.CannotGetClrRawValue,
                          $@"Cannot get '.*?' value \(type '.*?'\) from '.*?' \(type '.*?'\)\. {WpfOutputParser.CaptureBindingExpression()}(?<{WpfEntry.ExtraInfo}>.*)");

            this.AddRegex(WpfTraceCode.MissingInfo,
                          $@"BindingExpression cannot retrieve value due to missing information\. {WpfOutputParser.CaptureBindingExpression()}");

            this.AddRegex(WpfTraceCode.NullDataItem,
                          $@"BindingExpression cannot retrieve value from null data item\. This could happen when binding is detached or when binding to a Nullable type that has no value\. {WpfOutputParser.CaptureBindingExpression()}");

            this.AddRegex(WpfTraceCode.ClrReplaceItem,
                          $@"BindingExpression path error: '(?<{nameof(WpfEntry.SourceProperty)}>.+?)' property not found on '(object|current item of collection)' '{WpfOutputParser.CaptureItem(nameof(WpfEntry.SourcePropertyType), nameof(WpfEntry.SourcePropertyName))}'\. {WpfOutputParser.CaptureBindingExpression()}");

            this.AddRegex(WpfTraceCode.NullItem,
                          $@"BindingExpression path error: '(?<{WpfEntry.ExtraInfo}>.*?)' property not found for '(?<{WpfEntry.ExtraInfo2}>.*?)' because data item is null\.  This could happen because the data provider has not produced any data yet\. {WpfOutputParser.CaptureBindingExpression()}");
        }