/// <summary>
        /// Adds a javascript file statement to the head section
        /// </summary>
        /// <param name="pathToJSFileUnderAppPath"></param>
        public void AddJavascriptFile(JavascriptGroup jsGroup, string pathToJSFileUnderAppPath, AggregateMode aggregationMode)
        {
            // -- add only unique items
            string jsPath = pathToJSFileUnderAppPath.Trim();

            if (!isExternallyHosted(jsPath))
            {
                jsPath = removeBeginningSlash(jsPath);
            }

            JavascriptGroup?existingGroup = getGroupForJavascriptFile(jsPath, aggregationMode);

            if (existingGroup == null)
            {
                if (aggregationMode == AggregateMode.Aggregate)
                {
                    jsFilePaths_Aggregate[jsGroup].Add(jsPath);
                }
                else
                {
                    jsFilePaths_DoNotAggregate[jsGroup].Add(jsPath);
                }
            }
            else if (existingGroup != null && existingGroup != jsGroup)
            {
                throw new ArgumentException(pathToJSFileUnderAppPath + " has already been added to the " + existingGroup.ToString() + " javascript group");
            }
        } // Add JavascriptFile
        /// <summary>
        /// Combines locally hosted JS files into a single file.
        /// Returns the URL of the file that was generated, or string.Empty on error
        /// </summary>
        /// <param name="jsGroup"></param>
        /// <param name="jsFilePathsToAggregate"></param>
        /// <param name="embeddedJsFiles"></param>
        /// <returns></returns>
        private string combineInternalJsFiles(JavascriptGroup jsGroup, List <string> jsFilePathsToAggregate, List <EmbeddedJsFileInfo> embeddedJsFiles)
        {
            if (jsFilePathsToAggregate.Count == 0 && embeddedJsFiles.Count == 0)
            {
                return("");
            }

            StringBuilder outFileContents = new StringBuilder();

            // -- read each internal file
            foreach (string jsPath in jsFilePathsToAggregate)
            {
                if (!isExternallyHosted(jsPath))
                {
                    string jsFn = System.Web.Hosting.HostingEnvironment.MapPath("~/" + jsPath);
                    string js   = System.IO.File.ReadAllText(jsFn);
                    outFileContents.Append(js);
                    outFileContents.Append(Environment.NewLine);
                }
            }

            foreach (EmbeddedJsFileInfo embeddedJs in embeddedJsFiles)
            {
                string[] embeddedNames = embeddedJs.assemblyWithEmbeddedFile.GetManifestResourceNames();
                foreach (string embeddedFullName in embeddedNames)
                {
                    if (embeddedFullName.EndsWith(embeddedJs.embeddedFilename, StringComparison.CurrentCultureIgnoreCase))
                    {
                        System.IO.Stream stream = embeddedJs.assemblyWithEmbeddedFile.GetManifestResourceStream(embeddedFullName);
                        string           js     = new System.IO.StreamReader(stream).ReadToEnd();

                        outFileContents.Append(js);
                        outFileContents.Append(Environment.NewLine);
                        break;
                    }
                }
            } // foreach


            // -- the filename is based on the contents of the file
            string outName = jsGroup.ToString() + "_" + outFileContents.ToString().GetHashCode().ToString();

            outName = System.IO.Path.ChangeExtension(outName, ".js");
            string outUrl = VirtualPathUtility.ToAbsolute("~/_system/writable/js/" + outName);

            string outFn = System.Web.Hosting.HostingEnvironment.MapPath(outUrl);

            if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(outFn)))
            {
                throw new System.IO.FileNotFoundException("Please ensure that the directory exists: ~/system/writable/js/");
            }
            if (!System.IO.File.Exists(outFn))
            {
                System.IO.File.WriteAllText(outFn, outFileContents.ToString(), System.Text.Encoding.UTF8);
            }

            return(outUrl);
        }
 public EmbeddedJsFileInfo(JavascriptGroup group, System.Reflection.Assembly assembly, string filename)
 {
     jsGroup = group;
     assemblyWithEmbeddedFile = assembly;
     embeddedFilename         = filename;
 }
        } // Add JavascriptFile

        public void AddEmbeddedJavascriptFile(JavascriptGroup jsGroup, System.Reflection.Assembly assemblyWithEmbeddedFile, string embeddedFilename)
        {
            jsEmbeddedResources[jsGroup].Add(new EmbeddedJsFileInfo(jsGroup, assemblyWithEmbeddedFile, embeddedFilename));
        }
 /// <summary>
 /// Adds a javascript file statement to the head section. This file will be aggregated with other files in the same group.
 /// </summary>
 /// <param name="pathToJSFileUnderAppPath"></param>
 public void AddJavascriptFile(JavascriptGroup jsGroup, string pathToJSFileUnderAppPath)
 {
     AddJavascriptFile(jsGroup, pathToJSFileUnderAppPath, AggregateMode.Aggregate);
 }