/// <summary>
        /// Initializes a new instance of the <see cref="LogAdvice"/> class.
        /// </summary>
        /// <param name="parent">Task that creates the advice.</param>
        /// <param name="attribute">Attribute the advice is associated with.</param>
        /// <exception cref="ArgumentNullException"><paramref name="parent"/> or <see cref="attribute"/> is <see langword="null"/>.</exception>
        public LogAdvice(LogTask parent, LogAttribute attribute)
        {
            if (parent == null) {
                throw new ArgumentNullException("parent");
            }
            if (attribute == null) {
                throw new ArgumentNullException("attribute");
            }

            this.parent = parent;
            this.attribute = attribute;
        }
        /// <summary>
        /// Performs the logging of the exiting message based on the <see cref="LogAttribute"/>(s) applicable to the 
        /// current executing method.
        /// </summary>
        /// <param name="logAttribute">An instance of <see cref="MethodExecutionArgs"/> giving details of the currently 
        /// executing method.</param>
        /// <param name="methodName">Name of the method being executed.</param>
        /// <param name="logMethodArgs">An instance of <see cref="MethodExecutionArgs"/> giving details of the currently executing method.</param>
        public string GetExitMessage(MethodExecutionArgs logMethodArgs, LogAttribute logAttribute, string methodName)
        {
            if (!String.IsNullOrEmpty(logAttribute.ExitMessage))
            {
                return logAttribute.ExitMessage;
            }

            if (logMethodArgs.Exception == null)
            {
                return String.Format("Exited method '{0}' successfully.", methodName);
            }

            return String.Format("Exited method '{0}' with {1}: {2}", methodName, logMethodArgs.Exception.GetType().FullName, logMethodArgs.Exception.Message);
        }
        /// <summary>
        /// Performs the logging of the entry message based on the <see cref="LogAttribute"/>(s) applicable to the 
        /// current executing method.
        /// </summary>
        /// <param name="logMethodArgs">An instance of <see cref="MethodExecutionArgs"/> giving details of the currently 
        /// executing method.</param>
        /// <param name="logAttribute">The instance of <see cref="LogAttribute"/> that is applicable for the current
        /// method being traced.</param>
        /// <param name="methodName">Name of the method being executed.</param>
        /// <param name="serializationDepth">String containing all parameters and arguments concatenated together.</param>
        public string GetEntryMessage(MethodExecutionArgs logMethodArgs, LogAttribute logAttribute, string methodName, int serializationDepth)
        {
            if (!String.IsNullOrEmpty(logAttribute.EntryMessage))
            {
                return logAttribute.EntryMessage;
            }

            var message = String.Format("Entering method '{0}'", methodName);

            string argumentsString = SerializeArguments(logMethodArgs.Method.GetParameters(), logMethodArgs.Arguments, serializationDepth);
            if (!String.IsNullOrEmpty(argumentsString))
            {
                message += String.Format(" with arguments : {0}", argumentsString);
            }

            return message;
        }
        /// <summary>
        /// The should log.
        /// </summary>
        /// <param name="logAttribute">
        /// The log attribute.
        /// </param>
        /// <returns>
        /// Whether the logger should be activated or not.
        /// </returns>
        public bool ShouldLog(LogAttribute logAttribute)
        {
            if (!ConfigFileSource.IsEnabled) return false;
            ICollection<TagElement> tags = ConfigFileSource.Tags.OfType<TagElement>().ToList();
            List<string> includedTags =
                tags.Where(element => element.IncludeTag).Select(element => element.Name).ToList();
            List<string> excludedTags =
                tags.Where(element => element.ExcludeTag).Select(element => element.Name).ToList();

            if (includedTags.Any(tag => logAttribute.CurrentMethodFullName.StartsWith(tag, StringComparison.OrdinalIgnoreCase)))
            {
                return true;
            }

            if (excludedTags.Any(tag => logAttribute.CurrentMethodFullName.StartsWith(tag, StringComparison.OrdinalIgnoreCase)))
            {
                return false;
            }

            if (!string.IsNullOrWhiteSpace(logAttribute.Tags))
            {
                ICollection<string> currentTags = logAttribute.Tags.Split(_separators, StringSplitOptions.RemoveEmptyEntries).Select(tag => tag.Trim()).ToList();

                if (currentTags.Any(currentTag => includedTags.Any(includedTag => currentTag.Equals(includedTag, StringComparison.OrdinalIgnoreCase))))
                {
                    return true;
                }

                if (currentTags.Any(currentTag => excludedTags.Any(excludedTag => currentTag.Equals(excludedTag, StringComparison.OrdinalIgnoreCase))))
                {
                    return false;
                }
            }

            return true;
        }
 public void WhenCreatingALogAttributeShouldNotBeNull()
 {
     LogAttribute sut = new LogAttribute();
     sut.Should().NotBeNull();
 }
        public void WhenPassingAnEnabledConfigWithANominalTagShouldReturnTrue()
        {
            ConfigFileConfigurationProvider sut = new ConfigFileConfigurationProvider();
            Mock<IConfigFileSource> mock = new Mock<IConfigFileSource>();
            mock.Setup(source => source.IsEnabled).Returns(true);
            TagCollection tagCollection = new TagCollection();
            mock.Setup(source => source.Tags).Returns(tagCollection);
            sut.ConfigFileSource = mock.Object;

            LogAttribute attribute = new LogAttribute();

            bool shouldLog = sut.ShouldLog(attribute);

            shouldLog.Should().Be(true);
        }
        public void WhenPassingADisabledConfigShouldReturnFalse()
        {
            ConfigFileConfigurationProvider sut = new ConfigFileConfigurationProvider();
            Mock<IConfigFileSource> mock = new Mock<IConfigFileSource>();
            mock.Setup(source => source.IsEnabled).Returns(false);
            sut.ConfigFileSource = mock.Object;

            LogAttribute attribute = new LogAttribute();

            bool shouldLog = sut.ShouldLog(attribute);

            shouldLog.Should().Be(false);
        }
        public void WhenPassingNoConfigShouldReturnFalse()
        {
            ConfigFileConfigurationProvider sut = new ConfigFileConfigurationProvider();
            LogAttribute attribute = new LogAttribute();

            bool shouldLog = sut.ShouldLog(attribute);

            shouldLog.Should().Be(false);
        }