/// <summary>
        /// Generates the node list.
        /// </summary>
        /// <param name="configs">The configs.</param>
        private static List <Node <string> > GenerateNodeList(RenderConfig renderConfig, IRenderConfigLogger log)
        {
            //Create list of all nodes, without dependencies
            log.LogMessage("Generating Node List...");
            List <Node <string> > nodes = CreateInitialNodeList(renderConfig);

            foreach (Configuration config in renderConfig.Configurations)
            {
                //Split the dependencies, and then for each of them find a node in nodeList, and add as a dependency
                if (!String.IsNullOrEmpty(config.Depends))
                {
                    string[] dependencies = config.Depends.Split(',', ';');
                    foreach (string depends in dependencies)
                    {
                        Node <string> dependencyNode = SearchForNodeByIdentity(nodes, depends.Trim());
                        if (dependencyNode == null)
                        {
                            throw new ApplicationException("Error in configuration, cannot resolve dependency " + depends);
                        }
                        else
                        {
                            SearchForNodeByIdentity(nodes, config.Name).Dependencies.Add(dependencyNode);
                        }
                    }
                }
            }

            return(nodes);
        }
        /// <summary>
        /// Deserializes and Included files, and adds them as Configuration objects.
        /// </summary>
        /// <param name="configs">The configs.</param>
        private void DeserializeAndAddIncludes(RenderConfig configs)
        {
            XmlSerializer configSerializer = new XmlSerializer(typeof(Configuration));

            foreach (Include include in configs.Includes)
            {
                string includeFile = include.file;

                if (!File.Exists(includeFile))
                {
                    FileInfo configFile = new FileInfo(config.ConfigFile);
                    includeFile = Path.Combine(configFile.Directory.FullName, include.file);
                }

                if (File.Exists(includeFile))
                {
                    log.LogMessage("Attempting to include file: " + include.file);
                    try
                    {
                        XmlDocument includeXml = new XmlDocument();
                        includeXml.Load(includeFile);
                        XmlNodeList nodes = includeXml.SelectNodes(@"//Configuration");
                        if (nodes.Count > 0)
                        {
                            log.LogMessage(string.Concat(include.file, " contained ", nodes.Count, " Configuration Nodes"));
                            foreach (XmlNode node in nodes)
                            {
                                using (XmlReader nodeReader = XmlReader.Create(new StringReader(node.OuterXml.ToString())))
                                {
                                    configs.Configurations.Add((Configuration)configSerializer.Deserialize(nodeReader));
                                }
                            }
                        }
                        else
                        {
                            log.LogError(string.Concat("Could not find any Configuration nodes in ", include.file));
                        }
                    }
                    catch (ApplicationException i)
                    {
                        log.LogError("Could not load include file: " + include.file);
                        throw new ApplicationException("Could not load include file: " + include.file, i);
                    }
                }
                else
                {
                    log.LogError("Could not find include file: " + include.file);
                    throw new ApplicationException("Could not find include file: " + include.file);
                }
            }
        }
        /// <summary>
        /// Creates the config process stack.
        /// </summary>
        /// <param name="configs">The configs.</param>
        /// <param name="dependencyStack">The dependency stack.</param>
        /// <returns></returns>
        private Queue <Configuration> CreateConfigProcessQueue(RenderConfig renderConfig, Stack <Node <string> > dependencyStack)
        {
            Queue <Configuration> configQueue = new Queue <Configuration>();

            while (dependencyStack.Count > 0)
            {
                Node <string> node = dependencyStack.Pop();
                foreach (Configuration c in renderConfig.Configurations)
                {
                    if (c.Name == node.Identity)
                    {
                        configQueue.Enqueue(c);
                    }
                }
            }
            return(configQueue);
        }
        /// <summary>
        /// Creates the initial node list.
        /// </summary>
        /// <param name="configs">The configs.</param>
        private static List <Node <string> > CreateInitialNodeList(RenderConfig renderConfig)
        {
            List <Node <string> > nodes = new List <Node <string> >();

            foreach (Configuration config in renderConfig.Configurations)
            {
                if (SearchForNodeByIdentity(nodes, config.Name) != null)
                {
                    throw new ApplicationException("Configuration exists in file twice");
                }
                else
                {
                    Node <string> node = new Node <string>(config.Name);
                    nodes.Add(node);
                }
            }
            return(nodes);
        }
        /// <summary>
        /// Renders the configuration specified.
        /// </summary>
        /// <returns></returns>
        public bool Render()
        {
            LogUtilities.LogSettings(config, log);
            nodeList = new List <Node <string> >();
            Boolean returnCode = true;

            if (File.Exists(config.ConfigFile))
            {
                log.LogMessage("Reading in configuration file...");
                RenderConfig renderConfig = ReadConfigurationFile();


                if (renderConfig != null)
                {
                    //HACK We should be using a deep copy so that all this becomes "variableStack = dependencyStack.Clone();"
                    //Get the list of nodes
                    nodeList = GenerateNodeList(renderConfig, log);
                    if (SearchForNodeByIdentity(nodeList, config.Configuration) == null)
                    {
                        throw new ApplicationException("Could not find Configuration : " + config.Configuration);
                    }
                    List <Node <string> > n2 = GenerateNodeList(renderConfig, log);
                    //Generate the dependency path
                    DepthFirstSearch <string> dfs  = new DepthFirstSearch <string>(nodeList);
                    DepthFirstSearch <string> dfs2 = new DepthFirstSearch <string>(n2);
                    dependencyStack = dfs.GetDependencyPath(config.Configuration);
                    //HACK Need to write a deep copy Queue Clone to get rid of this...
                    variableStack = dfs2.GetDependencyPath(config.Configuration);
                }
                if (Directory.Exists(config.OutputDirectory))
                {
                    if (config.DeleteOutputDirectory)
                    {
                        log.LogMessage("Deleting and recreating output directory...");
                        Directory.Delete(config.OutputDirectory, true);
                        Directory.CreateDirectory(config.OutputDirectory);
                    }
                }
                else
                {
                    log.LogMessage("Creating output directory...");
                    Directory.CreateDirectory(config.OutputDirectory);
                }


                //Create a queue of mods to run and a queue of EnvironmentVariables to implement
                //Variables have to be put in place before the mods...
                log.LogMessage("Building dependency queue...");
                Queue <Configuration> configsToRun = CreateConfigProcessQueue(renderConfig, dependencyStack);
                //HACK This is ugly, needs a deep copy here....
                Queue <Configuration> envQueue = CreateConfigProcessQueue(renderConfig, variableStack);

                while (envQueue.Count > 0)
                {
                    Configuration varConfig = envQueue.Dequeue();

                    //First, we need to get all the Variables and create them.

                    foreach (EnvironmentVariable variable in varConfig.EnvironmentVariables)
                    {
                        Environment.SetEnvironmentVariable(variable.variable, variable.Value);
                    }
                }

                while (configsToRun.Count > 0)
                {
                    Configuration currentConfig = configsToRun.Dequeue();
                    log.LogMessage(MessageImportance.High, "Running modification: " + currentConfig.Name);

                    if (currentConfig.TargetFiles != null)
                    {
                        if (!currentConfig.Apply(config, log))
                        {
                            log.LogError("Failed to apply configuration: " + currentConfig.Name);
                            returnCode = false;
                        }
                    }
                }
            }
            else
            {
                log.LogError("Could not find configuration file: " + config.ConfigFile);
                returnCode = false;
            }

            //Let 'em know
            if (returnCode)
            {
                log.LogMessage(MessageImportance.High, "Configuration rendered!");
            }
            else
            {
                log.LogError("Failed to render configuration.");
            }

            return(returnCode);
        }
        /// <summary>
        /// Deserializes and Included files, and adds them as Configuration objects.
        /// </summary>
        /// <param name="configs">The configs.</param>
        private void DeserializeAndAddIncludes(RenderConfig configs)
        {
            XmlSerializer configSerializer = new XmlSerializer(typeof(Configuration));

            foreach (Include include in configs.Includes)
            {
                string includeFile = include.file;

                if (!File.Exists(includeFile))
                {
                    FileInfo configFile = new FileInfo(config.ConfigFile);
                    includeFile = Path.Combine(configFile.Directory.FullName, include.file);
                }

                if (File.Exists(includeFile))
                {
                    log.LogMessage("Attempting to include file: " + include.file);
                    try
                    {
                        XmlDocument includeXml = new XmlDocument();
                        includeXml.Load(includeFile);
                        XmlNodeList nodes = includeXml.SelectNodes(@"//Configuration");
                        if (nodes.Count > 0)
                        {
                            log.LogMessage(string.Concat(include.file, " contained ",nodes.Count," Configuration Nodes"));
                            foreach (XmlNode node in nodes)
                            {
                                using (XmlReader nodeReader = XmlReader.Create(new StringReader(node.OuterXml.ToString())))
                                {
                                    configs.Configurations.Add((Configuration)configSerializer.Deserialize(nodeReader));
                                }
                            }
                        }
                        else
                        {
                            log.LogError(string.Concat("Could not find any Configuration nodes in ",include.file));
                        }
                    }
                    catch (ApplicationException i)
                    {
                        log.LogError("Could not load include file: " + include.file);
                        throw new ApplicationException("Could not load include file: " + include.file, i);
                    }
                }
                else
                {
                    log.LogError("Could not find include file: " + include.file);
                    throw new ApplicationException("Could not find include file: " + include.file);
                }
            }
        }
 /// <summary>
 /// Creates the initial node list.
 /// </summary>
 /// <param name="configs">The configs.</param>
 private static List<Node<string>> CreateInitialNodeList(RenderConfig renderConfig)
 {
     List<Node<string>> nodes = new List<Node<string>>();
     foreach (Configuration config in renderConfig.Configurations)
     {
         if (SearchForNodeByIdentity(nodes, config.Name) != null)
         {
             throw new ApplicationException("Configuration exists in file twice");
         }
         else
         {
             Node<string> node = new Node<string>(config.Name);
             nodes.Add(node);
         }
     }
     return nodes;
 }
        /// <summary>
        /// Generates the node list.
        /// </summary>
        /// <param name="configs">The configs.</param>
        private static List<Node<string>> GenerateNodeList(RenderConfig renderConfig, IRenderConfigLogger log)
        {
            //Create list of all nodes, without dependencies
            log.LogMessage("Generating Node List...");
            List<Node<string>> nodes = CreateInitialNodeList(renderConfig);

            foreach (Configuration config in renderConfig.Configurations)
            {
                //Split the dependencies, and then for each of them find a node in nodeList, and add as a dependency
                if (!String.IsNullOrEmpty(config.Depends))
                {
                    string[] dependencies = config.Depends.Split(',', ';');
                    foreach (string depends in dependencies)
                    {
                        Node<string> dependencyNode = SearchForNodeByIdentity(nodes, depends.Trim());
                        if (dependencyNode == null)
                        {
                            throw new ApplicationException("Error in configuration, cannot resolve dependency " + depends);
                        }
                        else
                        {
                            SearchForNodeByIdentity(nodes, config.Name).Dependencies.Add(dependencyNode);
                        }
                    }
                }
            }

            return nodes;
        }
 /// <summary>
 /// Creates the config process stack.
 /// </summary>
 /// <param name="configs">The configs.</param>
 /// <param name="dependencyStack">The dependency stack.</param>
 /// <returns></returns>
 private Queue<Configuration> CreateConfigProcessQueue(RenderConfig renderConfig, Stack<Node<string>> dependencyStack)
 {
     Queue<Configuration> configQueue = new Queue<Configuration>();
     while (dependencyStack.Count > 0)
     {
         Node<string> node = dependencyStack.Pop();
         foreach (Configuration c in renderConfig.Configurations)
         {
             if (c.Name == node.Identity)
             {
                 configQueue.Enqueue(c);
             }
         }
     }
     return configQueue;
 }