/// <summary>
        /// Handles the disposal of resources. Derived from abstract class <see cref="DisposableObjectSlim"/> which handles common required locking logic.
        /// </summary>
        protected override void DisposeResources()
        {
            if (_profiler != null)
            {
                _profiler.DisposeIfDisposable();
            }

            if (_profilerStep != null)
            {
                _profilerStep.Dispose();
            }

            if (_logType.HasValue && _endMessage.IsNullOrWhiteSpace() == false && _loggerType != null && _logger != null)
            {
                switch (_logType)
                {
                case LogType.Debug:
                    _logger.Debug(_loggerType, () => _endMessage + " (took " + Stopwatch.ElapsedMilliseconds + "ms)");
                    break;

                case LogType.Info:
                    _logger.Info(_loggerType, () => _endMessage + " (took " + Stopwatch.ElapsedMilliseconds + "ms)");
                    break;

                default:
                    throw new ArgumentOutOfRangeException("logType");
                }
            }

            if (_callback != null)
            {
                _callback.Invoke(Stopwatch.ElapsedMilliseconds);
            }
        }
        internal DisposableTimer(ILogger logger, LogType logType, IProfiler profiler, Type loggerType, string startMessage, string endMessage)
        {
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }
            if (loggerType == null)
            {
                throw new ArgumentNullException("loggerType");
            }

            _callback = x =>
            {
                if (profiler != null)
                {
                    profiler.DisposeIfDisposable();
                }
                switch (logType)
                {
                case LogType.Debug:
                    logger.Debug(loggerType, () => endMessage + " (took " + x + "ms)");
                    break;

                case LogType.Info:
                    logger.Info(loggerType, () => endMessage + " (took " + x + "ms)");
                    break;

                default:
                    throw new ArgumentOutOfRangeException("logType");
                }
            };
            switch (logType)
            {
            case LogType.Debug:
                logger.Debug(loggerType, startMessage);
                break;

            case LogType.Info:
                logger.Info(loggerType, startMessage);
                break;

            default:
                throw new ArgumentOutOfRangeException("logType");
            }

            if (profiler != null)
            {
                profiler.Step(loggerType, startMessage);
            }
        }