/// <summary>
        /// Emits the MSIL that calls the logging method with the specified format provider, message and arguments.
        /// </summary>
        /// <param name="emitter">IL emitter.</param>
        /// <param name="log">Field that stores reference to the logger.</param>
        /// <param name="method">Logging method to use. The method must return no value and must take 3 arguments of types <see cref="IFormatProvider"/>, <see cref="string"/> and <see cref="Array"/> of <see cref="object"/>s.</param>
        /// <param name="formatProviderGetter">Getter of the property that returns the <see cref="IFormatProvider"/> instance.</param>
        /// <param name="formatString">Format string for the log.</param>
        /// <param name="args">Variable storing reference to array of arguments for placeholders used in the format string.</param>
        /// <exception cref="ArgumentNullException"><paramref name="emitter"/>, <paramref name="log"/>, <paramref name="formatProviderGetter"/>, <paramref name="formatString"/> or <paramref name="args"/> is <see langword="null"/>.</exception>
        /// <remarks>
        /// <para>Code emitted by this method makes no assumptions on the state of the evaluation stack 
        /// and it leaves the stack unmodified.</para>
        /// </remarks>
        private static void EmitLogProviderStringArgs(InstructionEmitter emitter, FieldDefDeclaration log, IMethod method, IMethod formatProviderGetter, string formatString, LocalVariableSymbol args)
        {
            if (emitter == null)
              {
            throw new ArgumentNullException("emitter");
              }
              if (log == null)
              {
            throw new ArgumentNullException("log");
              }
              if (method == null)
              {
            throw new ArgumentNullException("method");
              }
              if (formatProviderGetter == null)
              {
            throw new ArgumentNullException("formatProviderGetter");
              }
              if (args == null)
              {
            throw new ArgumentNullException("args");
              }

              emitter.EmitInstructionField(OpCodeNumber.Ldsfld, GenericHelper.GetFieldCanonicalGenericInstance(log));
              emitter.EmitInstructionMethod(OpCodeNumber.Call, formatProviderGetter);
              emitter.EmitInstructionString(OpCodeNumber.Ldstr, formatString);
              emitter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, args);
              emitter.EmitInstructionMethod(OpCodeNumber.Callvirt, method);
        }
        /// <summary>
        /// Emits the MSIL that calls the logging method with the specified message and exception.
        /// </summary>
        /// <param name="emitter">IL emitter.</param>
        /// <param name="log">Field that stores reference to the logger.</param>
        /// <param name="method">Logging method to use. The method must return no value and must take 2 parameters of types <see cref="string"/> and <see cref="Exception"/>.</param>
        /// <param name="message">Message to log.</param>
        /// <param name="exception">Local variable where reference to the exception is stored.</param>
        /// <exception cref="ArgumentNullException"><paramref name="emitter"/>, <paramref name="log"/>, <paramref name="method"/>, <paramref name="message"/> or <paramref name="exception"/> is <see langword="null"/>.</exception>
        /// <remarks>
        /// <para>Code emitted by this method makes no assumptions on the state of the evaluation stack 
        /// and it leaves the stack unmodified.</para>
        /// </remarks>
        private static void EmitLogStringException(InstructionEmitter emitter, FieldDefDeclaration log, IMethod method, string message, LocalVariableSymbol exception)
        {
            if (emitter == null)
              {
            throw new ArgumentNullException("emitter");
              }
              if (log == null)
              {
            throw new ArgumentNullException("log");
              }
              if (method == null)
              {
            throw new ArgumentNullException("method");
              }
              if (message == null)
              {
            throw new ArgumentNullException("message");
              }
              if (exception == null)
              {
            throw new ArgumentNullException("exception");
              }

              emitter.EmitInstructionField(OpCodeNumber.Ldsfld, GenericHelper.GetFieldCanonicalGenericInstance(log));
              emitter.EmitInstructionString(OpCodeNumber.Ldstr, message);
              emitter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc_S, exception);
              emitter.EmitInstructionMethod(OpCodeNumber.Callvirt, method);
        }
        /// <summary>
        /// Emits the MSIL code that jumps to the specified label if logging is disabled.
        /// </summary>
        /// <param name="emitter">IL emitter.</param>
        /// <param name="logLevelSupportItem">Item for the logging level.</param>
        /// <param name="perTypeLoggingData">Data for the type being woven.</param>
        /// <param name="afterLoggingSequence">Sequence to jump to if logging is disabled.</param>
        /// <exception cref="ArgumentNullException"><paramref name="emitter"/>, <paramref name="logLevelSupportItem"/>, <paramref name="perTypeLoggingData"/> or <paramref name="afterLoggingSequence"/> is <see langword="null"/>.</exception>
        /// <remarks>
        /// <para>Code emitted by this method makes no assumptions on the state of the evaluation stack 
        /// and it leaves the stack unmodified.</para>
        /// </remarks>
        private static void EmitLoggingEnabledCheck(InstructionEmitter emitter, LogLevelSupportItem logLevelSupportItem, PerTypeLoggingData perTypeLoggingData, InstructionSequence afterLoggingSequence)
        {
            if (emitter == null)
              {
            throw new ArgumentNullException("emitter");
              }
              if (logLevelSupportItem == null)
              {
            throw new ArgumentNullException("logLevelSupportItem");
              }
              if (perTypeLoggingData == null)
              {
            throw new ArgumentNullException("perTypeLoggingData");
              }
              if (afterLoggingSequence == null)
              {
            throw new ArgumentNullException("afterLoggingSequence");
              }

              emitter.EmitInstructionField(OpCodeNumber.Ldsfld, GenericHelper.GetFieldCanonicalGenericInstance(perTypeLoggingData.Log));
              emitter.EmitInstructionMethod(OpCodeNumber.Callvirt, logLevelSupportItem.IsLoggingEnabledGetter);
              emitter.EmitInstruction(OpCodeNumber.Ldc_I4_0);
              emitter.EmitInstruction(OpCodeNumber.Ceq);
              emitter.EmitBranchingInstruction(OpCodeNumber.Brtrue_S, afterLoggingSequence);
        }