/// <summary>
 /// Creates and starts a binary log writer putting records down to the specified file. The name
 /// of the file will not be modified if addSuffixToBaseFileName is false.
 /// </summary>
 /// <param name="baseFileName">The basic part of the file name.</param>
 /// <param name="logOptions">The options specifying what information will be saved into the log.</param>
 /// <param name="addSuffixToBaseFileName">true to add suffix (date, time, and extension) to the file name.</param>
 public static void SetUpLoggingToFile(string baseFileName, string logOptions, bool addSuffixToBaseFileName)
 {
     lock (_accessToLocalMembers)
     {
         BinaryLogWriter binaryLogWriter = new BinaryLogWriter(new FileWritingStream(baseFileName, addSuffixToBaseFileName));
         SetUpLoggingOptionsFromString(binaryLogWriter, GenuineLoggingServices.DefaultLoggingOptions);
         SetUpLoggingOptionsFromString(binaryLogWriter, logOptions);
         GenuineLoggingServices.BinaryLogWriter = binaryLogWriter;
     }
 }
        /// <summary>
        /// Creates and starts a binary log writer putting records down to the memory stream, which can be obtained remotely.
        /// </summary>
        /// <param name="maximumMemorySize">The maximum possible size of memory space occupied by log records.</param>
        /// <param name="logOptions">The options specifying what information will be saved into the log.</param>
        public static void SetUpLoggingToMemory(int maximumMemorySize, string logOptions)
        {
            lock (_accessToLocalMembers)
            {
                if (_memoryWritingWriter == null)
                {
                    _memoryWritingStream = new MemoryWritingStream(maximumMemorySize);
                    _memoryWritingWriter = new BinaryLogWriter(_memoryWritingStream);

                    SetUpLoggingOptionsFromString(_memoryWritingWriter, GenuineLoggingServices.DefaultLoggingOptions);
                    SetUpLoggingOptionsFromString(_memoryWritingWriter, logOptions);

                    _remoteLogService = new RemoteLogService(_memoryWritingStream);
                    RemotingServices.Marshal(_remoteLogService, GenuineLoggingServices.RemoteLogServiceObjectUri);
                    Belikov.GenuineChannels.DirectExchange.DirectExchangeManager.RegisterGlobalServerService(GenuineLoggingServices.RemoteLogServiceObjectUri, _remoteLogService);
                    Belikov.GenuineChannels.Security.SecuritySessionServices.SetGlobalKey(GenuineLoggingServices.LoggingSESSPName, new Belikov.GenuineChannels.Security.KeyProvider_SelfEstablishingSymmetric());
                }

                GenuineLoggingServices.BinaryLogWriter = _memoryWritingWriter;
            }
        }
        /// <summary>
        /// Initializes the specified BinaryLogWriter with the logging options from the specified string.
        /// </summary>
        /// <param name="binaryLogWriter">The BinaryLogWriter.</param>
        /// <param name="logOptions">The logging options.</param>
        public static void SetUpLoggingOptionsFromString(BinaryLogWriter binaryLogWriter, string logOptions)
        {
            if (logOptions == null || logOptions.Length <= 0)
            {
                return;
            }

            for (int i = 0; i < logOptions.Length; i += 2)
            {
                if (logOptions.Length - i < 2 || !Char.IsDigit(logOptions[i + 1]))
                {
                    continue;
                }

                int level = (int)((short)logOptions[i + 1] - '0');

                switch (Char.ToUpper(logOptions[i]))
                {
                case 'C':
                    binaryLogWriter[LogCategory.Connection] = level;
                    break;

                case 'E':
                    binaryLogWriter[LogCategory.ChannelEvent] = level;
                    break;

                case 'M':
                    binaryLogWriter[LogCategory.MessageProcessing] = level;
                    break;

                case 'I':
                    binaryLogWriter[LogCategory.ImplementationWarning] = level;
                    break;

                case 'S':
                    binaryLogWriter[LogCategory.Security] = level;
                    break;

                case 'B':
                    binaryLogWriter[LogCategory.BroadcastEngine] = level;
                    break;

                case 'T':
                    binaryLogWriter[LogCategory.Transport] = level;
                    break;

                case 'X':
                    binaryLogWriter[LogCategory.DXM] = level;
                    break;

                case 'H':
                    binaryLogWriter[LogCategory.HostInformation] = level;
                    break;

                case 'A':
                    binaryLogWriter[LogCategory.AcceptingConnection] = level;
                    break;

                case 'D':
                    binaryLogWriter[LogCategory.Debugging] = level;
                    break;

                case 'V':
                    binaryLogWriter[LogCategory.Version] = level;
                    break;

                case 'L':
                    binaryLogWriter[LogCategory.LowLevelTransport] = level;
                    break;

                case 'N':
                    binaryLogWriter[LogCategory.StatisticCounters] = level;
                    break;
                }
            }
        }
        /// <summary>
        /// Puts down a record describing the creation of the response message.
        /// </summary>
        /// <param name="binaryLogWriter">The binary log writer.</param>
        /// <param name="reply">The response message.</param>
        /// <param name="ret">The response.</param>
        /// <param name="message">The text of the message.</param>
        /// <param name="parameters">Parameters to the message text.</param>
        internal void PutDownRecordAboutResponseCreation(BinaryLogWriter binaryLogWriter, Message reply, IMessage ret, string message, params object[] parameters)
        {
            string invocationTarget = ret.Properties["__Uri"] as string;
            string methodName = BinaryLogWriter.ParseInvocationMethod(ret.Properties["__MethodName"] as string, ret.Properties["__TypeName"] as string);

            binaryLogWriter.WriteMessageCreatedEvent("GenuineReceivingHanlder.PutDownRecordAboutResponseCreation",
                LogMessageType.MessageCreated, null, reply, false, reply.Recipient,
                this.ITransportContext.BinaryLogWriter[LogCategory.MessageProcessing] > 1 ? reply.Stream : null,
                invocationTarget, methodName,
                GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, -1, -1, null, -1, null,
                message, parameters);

            reply.ITransportHeaders[Message.TransportHeadersInvocationTarget] = invocationTarget;
            reply.ITransportHeaders[Message.TransportHeadersMethodName] = methodName;
        }
        /// <summary>
        /// Stops putting down log records.
        /// </summary>
        public static void StopLogging()
        {
            lock (_accessToLocalMembers)
            {
                GenuineLoggingServices.BinaryLogWriter = null;

                if (_memoryWritingWriter != null)
                {
                    RemotingServices.Disconnect(_remoteLogService);
                    _remoteLogService.StopLogging();
                    _remoteLogService = null;

                    _memoryWritingStream = null;
                    _memoryWritingWriter = null;
                }
            }
        }
        /// <summary>
        /// Creates and starts a binary log writer putting records down to the memory stream, which can be obtained remotely.
        /// </summary>
        /// <param name="maximumMemorySize">The maximum possible size of memory space occupied by log records.</param>
        /// <param name="logOptions">The options specifying what information will be saved into the log.</param>
        public static void SetUpLoggingToMemory(int maximumMemorySize, string logOptions)
        {
            lock (_accessToLocalMembers)
            {
                if (_memoryWritingWriter == null)
                {
                    _memoryWritingStream = new MemoryWritingStream(maximumMemorySize);
                    _memoryWritingWriter = new BinaryLogWriter(_memoryWritingStream);

                    SetUpLoggingOptionsFromString(_memoryWritingWriter, GenuineLoggingServices.DefaultLoggingOptions);
                    SetUpLoggingOptionsFromString(_memoryWritingWriter, logOptions);

                    _remoteLogService = new RemoteLogService(_memoryWritingStream);
                    RemotingServices.Marshal(_remoteLogService, GenuineLoggingServices.RemoteLogServiceObjectUri);
                    Belikov.GenuineChannels.DirectExchange.DirectExchangeManager.RegisterGlobalServerService(GenuineLoggingServices.RemoteLogServiceObjectUri, _remoteLogService);
                    Belikov.GenuineChannels.Security.SecuritySessionServices.SetGlobalKey(GenuineLoggingServices.LoggingSESSPName, new Belikov.GenuineChannels.Security.KeyProvider_SelfEstablishingSymmetric());
                }

                GenuineLoggingServices.BinaryLogWriter = _memoryWritingWriter;
            }
        }
 /// <summary>
 /// Creates and starts a binary log writer putting records down to the specified file. The name 
 /// of the file will not be modified if addSuffixToBaseFileName is false.
 /// </summary>
 /// <param name="baseFileName">The basic part of the file name.</param>
 /// <param name="logOptions">The options specifying what information will be saved into the log.</param>
 /// <param name="addSuffixToBaseFileName">true to add suffix (date, time, and extension) to the file name.</param>
 public static void SetUpLoggingToFile(string baseFileName, string logOptions, bool addSuffixToBaseFileName)
 {
     lock (_accessToLocalMembers)
     {
         BinaryLogWriter binaryLogWriter = new BinaryLogWriter(new FileWritingStream(baseFileName, addSuffixToBaseFileName));
         SetUpLoggingOptionsFromString(binaryLogWriter, GenuineLoggingServices.DefaultLoggingOptions);
         SetUpLoggingOptionsFromString(binaryLogWriter, logOptions);
         GenuineLoggingServices.BinaryLogWriter = binaryLogWriter;
     }
 }
        /// <summary>
        /// Initializes the specified BinaryLogWriter with the logging options from the specified string.
        /// </summary>
        /// <param name="binaryLogWriter">The BinaryLogWriter.</param>
        /// <param name="logOptions">The logging options.</param>
        public static void SetUpLoggingOptionsFromString(BinaryLogWriter binaryLogWriter, string logOptions)
        {
            if (logOptions == null || logOptions.Length <= 0)
                return ;

            for ( int i = 0; i < logOptions.Length; i+= 2)
            {
                if (logOptions.Length - i < 2 || ! Char.IsDigit(logOptions[i+1]))
                    continue;

                int level = (int) ( (short) logOptions[i+1] - '0' );

                switch (Char.ToUpper(logOptions[i]))
                {
                    case 'C':
                        binaryLogWriter[LogCategory.Connection] = level;
                        break;

                    case 'E':
                        binaryLogWriter[LogCategory.ChannelEvent] = level;
                        break;

                    case 'M':
                        binaryLogWriter[LogCategory.MessageProcessing] = level;
                        break;

                    case 'I':
                        binaryLogWriter[LogCategory.ImplementationWarning] = level;
                        break;

                    case 'S':
                        binaryLogWriter[LogCategory.Security] = level;
                        break;

                    case 'B':
                        binaryLogWriter[LogCategory.BroadcastEngine] = level;
                        break;

                    case 'T':
                        binaryLogWriter[LogCategory.Transport] = level;
                        break;

                    case 'X':
                        binaryLogWriter[LogCategory.DXM] = level;
                        break;

                    case 'H':
                        binaryLogWriter[LogCategory.HostInformation] = level;
                        break;

                    case 'A':
                        binaryLogWriter[LogCategory.AcceptingConnection] = level;
                        break;

                    case 'D':
                        binaryLogWriter[LogCategory.Debugging] = level;
                        break;

                    case 'V':
                        binaryLogWriter[LogCategory.Version] = level;
                        break;

                    case 'L':
                        binaryLogWriter[LogCategory.LowLevelTransport] = level;
                        break;

                    case 'N':
                        binaryLogWriter[LogCategory.StatisticCounters] = level;
                        break;
                }
            }
        }