/// <summary>
        /// Expand a @Current match inside an @Each iterator
        /// </summary>
        /// <param name="contents">Contents of the @Each block</param>
        /// <param name="item">Current item from the @Each enumerable</param>
        /// <param name="host">View engine host</param>
        /// <returns>String result of the expansion of the @Each.</returns>
        private static string ReplaceCurrentMatch(string contents, object item, IViewEngineHost host)
        {
            return(EachItemSubstitutionRegEx.Replace(
                       contents,
                       eachMatch =>
            {
                if (string.IsNullOrEmpty(eachMatch.Groups["ParameterName"].Value))
                {
                    return eachMatch.Groups["Encode"].Success ? host.HtmlEncode(item.ToString()) : item.ToString();
                }

                var properties = GetCaptureGroupValues(eachMatch, "ParameterName");

                var substitution = GetPropertyValueFromParameterCollection(item, properties);

                if (!substitution.Item1)
                {
                    return "[ERR!]";
                }

                if (substitution.Item2 == null)
                {
                    return string.Empty;
                }

                return eachMatch.Groups["Encode"].Success ? host.HtmlEncode(substitution.Item2.ToString()) : substitution.Item2.ToString();
            }));
        }
        /// <summary>
        /// Performs single @Context.PropertyName substitutions.
        /// </summary>
        /// <param name="template">The template.</param>
        /// <param name="model">The model.</param>
        /// <param name="host">View engine host</param>
        /// <returns>Template with @Context.PropertyName blocks expanded.</returns>
        private static string PerformContextSubstitutions(string template, object model, IViewEngineHost host)
        {
            return(ContextSubstitutionsRegEx.Replace(
                       template,
                       m =>
            {
                var properties = GetCaptureGroupValues(m, "ParameterName");

                var substitution = GetPropertyValueFromParameterCollection(host.Context, properties);

                if (!substitution.Item1)
                {
                    return "[ERR!]";
                }

                if (substitution.Item2 == null)
                {
                    return string.Empty;
                }

                return m.Groups["Encode"].Success ? host.HtmlEncode(substitution.Item2.ToString()) : substitution.Item2.ToString();
            }));
        }
        /// <summary>
        /// Expand a @Current match inside an @Each iterator
        /// </summary>
        /// <param name="contents">Contents of the @Each block</param>
        /// <param name="item">Current item from the @Each enumerable</param>
        /// <param name="host">View engine host</param>
        /// <returns>String result of the expansion of the @Each.</returns>
        private static string ReplaceCurrentMatch(string contents, object item, IViewEngineHost host)
        {
            return EachItemSubstitutionRegEx.Replace(
                contents,
                eachMatch =>
                {
                    if (string.IsNullOrEmpty(eachMatch.Groups["ParameterName"].Value))
                    {
                        return eachMatch.Groups["Encode"].Success ? host.HtmlEncode(item.ToString()) : item.ToString();
                    }

                    var properties = GetCaptureGroupValues(eachMatch, "ParameterName");

                    var substitution = GetPropertyValueFromParameterCollection(item, properties);

                    if (!substitution.Item1)
                    {
                        return "[ERR!]";
                    }

                    if (substitution.Item2 == null)
                    {
                        return string.Empty;
                    }

                    return eachMatch.Groups["Encode"].Success ? host.HtmlEncode(substitution.Item2.ToString()) : substitution.Item2.ToString();
                });
        }
        /// <summary>
        /// Performs single @ViewBag.PropertyName substitutions.
        /// </summary>
        /// <param name="template">The template.</param>
        /// <param name="model">This parameter is not used, the model is based on the "host.Context.ViewBag".</param>
        /// <param name="host">View engine host</param>
        /// <returns>Template with @ViewBag.PropertyName blocks expanded.</returns>
        private static string PerformViewBagSubstitutions(string template, object model, IViewEngineHost host)
        {
            return ViewBagSubstitutionsRegEx.Replace(
                template,
                m =>
                {
                    var properties = GetCaptureGroupValues(m, "ParameterName");

                    var substitution = GetPropertyValueFromParameterCollection(((dynamic)host.Context).ViewBag, properties);

                    if (!substitution.Item1)
                    {
                        return "[ERR!]";
                    }

                    if (substitution.Item2 == null)
                    {
                        return string.Empty;
                    }

                    return m.Groups["Encode"].Success ? host.HtmlEncode(substitution.Item2.ToString()) : substitution.Item2.ToString();
                });
        }