/// <summary>
        ///     Gets an instance of the template using the cached compiled type, or compiles the template type
        ///     if it does not exist in the cache.
        /// </summary>
        /// <typeparam name="T">Type of the model</typeparam>
        /// <param name="razorTemplate">The string template.</param>
        /// <param name="model">The model instance or NULL if there is no model for this template.</param>
        /// <param name="cacheName">The name of the template type in the cache.</param>
        /// <returns>
        ///     An instance of <see cref="ITemplate{T}" />.
        /// </returns>
        private ITemplate GetTemplate <T>(string razorTemplate, object model, string cacheName)
        {
            if (razorTemplate == null)
            {
                throw new ArgumentNullException("razorTemplate");
            }

            var hashCode = razorTemplate.GetHashCode();

            CachedTemplateItem item;

            if (!(_cache.TryGetValue(cacheName, out item) && item.CachedHashCode == hashCode))
            {
                var type = CreateTemplateType(razorTemplate, (model == null) ? typeof(T) : model.GetType(), new NullLogger());
                item = new CachedTemplateItem(hashCode, type);

                _cache.AddOrUpdate(cacheName, item, (n, i) => item);
            }

            var instance = CreateTemplate(null, item.TemplateType, model, new NullLogger());

            return(instance);
        }