public CallbackData Copy(DebugUtilities d)
            {
                var sb = new DbgStringBuilder(d, Data.Length);

                sb.Append(Data);
                return(new CallbackData(Mask, sb, IsDML, DMLFlags));
            }
        /// <summary>
        ///     Gets a copy of all stored output if PassThroughOnly is not active.
        /// </summary>
        /// <returns>Any stored output.</returns>
        public string GetText()
        {
            lock (this)
            {
                if (PassThroughOnly)
                {
                    return("PassThroughOnly specified. No local recording of data performed");
                }

                var sb = new DbgStringBuilder(ExecutionUtilities, 2048);
                sb.Append(DataBuffer);
                foreach (var LineBuffer in LineBuffers)
                {
                    if (LineBuffer.Value.Length != 0)
                    {
                        sb.Append(FilterLine(LineBuffer.Key, LineBuffer.Value.ToString(), PreviousTextWasDml, PreviousDmlFlags));
                    }
                }

                return(sb.ToString());
            }
        }
        /// <summary>
        ///     Implements IDebugOutputCallbacks2::Output2
        /// </summary>
        public int Output2(DEBUG_OUTCB Which, DEBUG_OUTCBF Flags, ulong Arg, string Text)
        {
            var mask = (DEBUG_OUTPUT)Arg;

            if (string.IsNullOrEmpty(Text))
            {
                return(S_OK);
            }

            _executionUtilities.OutputMaskRestore();
            var textIsDml = Which == DEBUG_OUTCB.DML;

            if (_outputActive)
            {
                lock (this)
                {
                    _outputActive = false;

                    var sb = new DbgStringBuilder(_passthroughUtilities, Text.Length);
                    sb.Append(Text);
                    var callbackData = new CallbackData(mask, sb, textIsDml, Flags);

                    // The advanced filter gets 1st crack at the data before it goes to the line by line filter.
                    callbackData = _outputFilter.AdvancedFilterText(callbackData);
                    if (callbackData == null)
                    {
                        _outputActive = true;
                        return(S_OK);
                    }
                    // It can force data to be output now, skipping the line-by-line filtering.
                    if (callbackData.ForceOutputNow)
                    {
                        PassThroughLine(callbackData);
                        _outputActive = true;
                        return(S_OK);
                    }

                    Text = callbackData.Data.ToString();
                    // Was there a partial line for this mask? if so, lets finish it and send it to the filter!
                    CallbackData lineBuffer;
                    _lineBuffers.TryGetValue(callbackData.Mask, out lineBuffer);

                    if (lineBuffer == null)
                    {
                        lineBuffer         = new CallbackData(callbackData.Mask, new DbgStringBuilder(_passthroughUtilities, Text.Length), callbackData.IsDML, callbackData.DMLFlags);
                        _lineBuffers[mask] = lineBuffer;
                    }

                    for (var i = 0; i < Text.Length; ++i)
                    {
                        var c = Text[i];
                        if (c == '\n')
                        {
                            lineBuffer.Data.Append(c);
                            ProcessLine(lineBuffer.Copy(_passthroughUtilities));
                            lineBuffer.Clear();
                        }
                        else if (c == '\r')
                        {
                            if ((i + 1) < Text.Length && Text[i + 1] != '\n')
                            {
                                lineBuffer.Clear();
                            }
                        }
                        else
                        {
                            lineBuffer.Data.Append(c);
                        }
                    }

                    //if (Which == DEBUG_OUTCB.EXPLICIT_FLUSH)
                    //{
                    //    _passthroughUtilities.DebugClient.FlushCallbacks();
                    //}
                    _outputActive = true;
                }
            }

            return(S_OK);
        }