// Search down the stack for the next caller for the specified text file.
        private string GetCaller(TextFileState fileData)
        {
            // For text files, the stack depth is decremented BEFORE this is called,
            // so check stackdepth > 0.
            if (fileData.StackDepth > 0)
            {
                for (StackEntry caller = TopStackEntry.Caller; caller != null; caller = caller.Caller)
                {
                    if (caller.TextFileState == fileData)
                    {
                        return(caller.MethodName);
                    }
                }

                Debug.Assert(false, "A caller should have been found.");
            }

            return("");
        }
        // Looks up the thread-specific state for the specified binary file,
        // creating a new one if necessary.
        internal TextFileState GetTextFileState(TextFile file)
        {
            TextFileState result = TextFileState;

            if (TextFileState == null || TextFileState.File != file)
            {
                // Look up or create the state data for the specified file.
                if (!_textFileStatesForThisThread.TryGetValue(file, out result))
                {
                    result      = new TextFileState();
                    result.File = file;
                    _textFileStatesForThisThread.Add(file, result);
                }

                TextFileState = result;
            }
            else
            {
                // We already have the data for the specified file.
            }

            return(result);
        }
        // Log the exit of a method call to each destination indicated by TopStackEntry.
        internal void LogCallExit()
        {
            if ((TopStackEntry.Destinations & Destinations.EventHandler) != 0)
            {
                // Although this LogMsg() call raises a cancellable event, method-exit messages aren't really cancellable because
                // we must "balance" the original method-entry message.
                --EventHandlerState.StackDepth;
                EventHandlerLogging.LogMsg(TopStackEntry.Logger, this, TopStackEntry.Level, TopStackEntry.MethodName + " exiting", false, true);
                EventHandlerState.CurrentMethod = GetCaller(Destinations.EventHandler);
            }

            if ((TopStackEntry.Destinations & Destinations.BinaryFile) != 0)
            {
                // Make sure BinaryFileState corresponds to the BinaryFile instance
                // the method-exit should be logged to (the same BinaryFile the
                // method-entry for TopStackEntry was logged to).
                BinaryFileState = TopStackEntry.BinaryFileState;

                if (TopStackEntry.Logger.BinaryFile.LogExit(this))
                {
                    // BinaryFileState.StackDepth depth is decremented after logging so any meta-logging has the right depth.
                    // GetCaller() also depends on the stack depth.
                    BinaryFileState.CurrentMethod = GetCaller(BinaryFileState);
                    --BinaryFileState.StackDepth;
                }
            }

            if ((TopStackEntry.Destinations & Destinations.TextFile) != 0)
            {
                // Make sure BinaryFileState corresponds to the BinaryFile instance
                // the method-exit should be logged to (the same BinaryFile the
                // method-entry for TopStackEntry was logged to).
                TextFileState = TopStackEntry.TextFileState;

                --TextFileState.StackDepth;
                TopStackEntry.Logger.TextFile.LogMsg(TopStackEntry.Logger, this, TopStackEntry.Level, TopStackEntry.MethodName + " exiting");
                TextFileState.CurrentMethod = GetCaller(TextFileState);
            }

            if ((TopStackEntry.Destinations & Destinations.Console) != 0)
            {
                --ConsoleState.StackDepth;
                ConsoleLogging.LogMsg(TopStackEntry.Logger, this, TopStackEntry.Level, TopStackEntry.MethodName + " exiting");
                ConsoleState.CurrentMethod = GetCaller(Destinations.Console);
            }

            if ((TopStackEntry.Destinations & Destinations.Debug) != 0)
            {
                --DebugState.StackDepth;
                DebugLogging.LogMsg(TopStackEntry.Logger, this, TopStackEntry.Level, TopStackEntry.MethodName + " exiting");
                DebugState.CurrentMethod = GetCaller(Destinations.Debug);
            }

            if ((TopStackEntry.Destinations & Destinations.EventLog) != 0)
            {
                --EventLogState.StackDepth;
                //EventLogging.LogMsg(TopStackEntry.Logger, this, TopStackEntry.Level, TopStackEntry.MethodName + " exiting");
                EventLogState.CurrentMethod = GetCaller(Destinations.EventLog);
            }

            LastLoggerAnyDest = TopStackEntry.Logger;
            TopStackEntry     = TopStackEntry.Caller;
            --MasterStackDepth;
        }