public HTMLDefinitionNode(XmlNode node, HTMLParserContext context)
        {
            m_sourceNode = node.CloneNode(true);
            m_name = node.Name;
            m_subNodes = new ArrayList();
            m_attributes = new Dictionary<string, AttributeProperties>();

            //Instead of dealing with xml nodes themselves its going to be easier to just deconstruct the whole thing, and recreate XML nodes in the final document
            decodeSourceNode(node, context);
        }
        public HTMLDefinitionNode Clone(HTMLParserContext context)
        {
            HTMLDefinitionNode copiedNode = new HTMLDefinitionNode();
            HTMLDefinitionNode[] nodeArray = new HTMLDefinitionNode[m_subNodes.Count];
            m_subNodes.CopyTo(nodeArray);
            copiedNode.m_subNodes = new ArrayList( nodeArray );
            copiedNode.m_name = m_name;
            copiedNode.m_sourceNode = m_sourceNode.CloneNode(true);
            copiedNode.m_attributes = new Dictionary<string, AttributeProperties>(m_attributes);

            return copiedNode;
        }
        private void ProcessCurrentXmlDocument(XmlDocument document, HTMLParserContext parseContext)
        {
            //Start looking for include files
            foreach (XmlNode includeNode in document.SelectNodes("//include"))
            {
                foreach (XmlAttribute attribute in includeNode.Attributes)
                {
                    parseContext.addIncludeFile(attribute.Value);
                }
            }
            //Look for definition tags in all of the files and add these to the parse context, we need these to figure out what certain groups mean, might just do a text replace
            foreach (XmlNode definitions in document.SelectNodes("//definition"))
            {
                foreach (XmlNode definitionNode in definitions.ChildNodes)
                {
                    parseContext.addDefinitionNode(definitionNode);
                }
            }
            //Find style tags, these might be in a single external file or anywhere through out the HTML code
            foreach (XmlNode styles in document.SelectNodes("//style"))
            {
                //Should only be one of these and all we want is the inner xml which contain css definitions
                var stylesString = styles.InnerXml.Trim();
                string[] cssEndMark = {"}"};
                string[] stylesStrings = stylesString.Split(cssEndMark, StringSplitOptions.RemoveEmptyEntries);
                foreach (var style in stylesStrings)
                {
                    parseContext.addStyleNode(style);
                }
            }

            //Parse the body for each file with the above information and transform to final output file(s)
            //We are using an intermediate file for each first to replace the shortcut HTML

            XmlNode body_node = document.SelectSingleNode("//body");
            XmlNode importedBodyNode = parseContext.IntermediateDocument.ImportNode(body_node, true);
            foreach (XmlNode child in importedBodyNode.ChildNodes)
            {
                parseContext.IntermediateRootElement.AppendChild(child);
            }

            parseContext.IntermediateDocument.AppendChild(parseContext.IntermediateRootElement);
            parseContext.IntermediateDocument.Save(m_settings.m_rootPath + "intermediate.xml");
        }
        public void CompileHTMLFile(String inputFileName)
        {
            if (File.Exists(inputFileName))
            {
                XmlDocument document = new XmlDocument();
                document.Load(inputFileName);

                HTMLParserContext parseContext = new HTMLParserContext();
                parseContext.IntermediateDocument = new XmlDocument();
                parseContext.IntermediateRootElement = parseContext.IntermediateDocument.CreateNode(XmlNodeType.Element, "xml", "");
                //From here this is recursive
                ProcessCurrentXmlDocument(document, parseContext);
                //Recurse through the includes above for other includes, definitions and styles before moving on to transforming the body element, we might need these to be present before we can read that node
                foreach (String includeFileName in parseContext.getIncludeFileNames()) //this will break when included files start including files :(
                {
                    String fileName = includeFileName;
                    if (!Path.IsPathRooted(fileName))
                    {
                        fileName = m_settings.m_rootPath + includeFileName;
                    }
                    if (File.Exists(fileName))
                    {
                        XmlDocument includedDocument = new XmlDocument();
                        includedDocument.Load(fileName);
                        ProcessCurrentXmlDocument(includedDocument, parseContext);
                    }
                    else
                    {
                        Console.WriteLine("Trying to read file {0}, but the file doesn't exist", includeFileName);
                    }
                }

                foreach(XmlNode childNode in parseContext.IntermediateRootElement.ChildNodes)
                {
                    Console.WriteLine("Body Node being dealt with: {0}", childNode.Name);
                    walkBodyNodes(childNode, parseContext);
                }
                parseContext.IntermediateDocument.Save(m_settings.m_rootPath + "intermediate.xml");
            }
        }
        private void walkBodyNodes(XmlNode node, HTMLParserContext parseContext)
        {
            XmlNodeList list = node.ChildNodes;
            for (int index = 0; index < list.Count; ++index )
            {
                XmlNode newNode = parseContext.replaceNode(list[index]);

                if (node.HasChildNodes && node != parseContext.IntermediateRootElement)
                {
                    //if (newNode.HasChildNodes)
                    //{
                    //    walkBodyNodes(newNode, parseContext); //Context of the original attributes is gone here so this should be moved to replaceNode
                    //}
                    node.ReplaceChild(newNode, list[index]);
                }
                else
                {
                    node.AppendChild(newNode);
                }

            }
        }
        private void decodeSourceNode(XmlNode node, HTMLParserContext context)
        {
            if (node.Attributes != null)
            {
                foreach (XmlAttribute attribute in node.Attributes)
                {
                    AttributeProperties overridableNameAndDefaultValue = new AttributeProperties();
                    if (attribute.Value.Contains("#"))
                    {
                        string attributeValue = attribute.Value;
                        attributeValue = attributeValue.Substring(attributeValue.IndexOf("#") + 1);
                        string[] splitAttributeValues = attributeValue.Split('#'); //0 will be the name of the attribute to get from the childNode, 1 is the default value if it exists which is used if the value is not overriden in the childnode
                        if (splitAttributeValues.Length > 1)
                        {
                            overridableNameAndDefaultValue.m_overrideableAttributeName = splitAttributeValues[0];
                            overridableNameAndDefaultValue.m_defaultAttributeValue = splitAttributeValues[1];
                        }
                        else
                        {
                            overridableNameAndDefaultValue.m_overrideableAttributeName = splitAttributeValues[0];
                            overridableNameAndDefaultValue.m_defaultAttributeValue = "";
                        }
                    }
                    else
                    {
                        //This node is an override of something else so store the actual attribute value
                        overridableNameAndDefaultValue.m_overrideableAttributeName = attribute.Value;
                        overridableNameAndDefaultValue.m_defaultAttributeValue = attribute.Value;
                    }

                    m_attributes.Add(attribute.Name, overridableNameAndDefaultValue);
                }
            }
            //Should deal with inner text here that has no nodes in it. so we can replace this stuff too important for text as that is just a div

            if (node.ChildNodes != null)
            {

                foreach (XmlNode childNode in node.ChildNodes)
                {
                    m_subNodes.Add(new HTMLDefinitionNode(childNode, context));
                }
            }

            for (int counter = 0; counter < m_subNodes.Count; ++counter )
            {
                //Need to check whether subnodes are definition nodes if they are we need to copy that node and deal with the attributes of that node.
                HTMLDefinitionNode subNode = m_subNodes[counter] as HTMLDefinitionNode;
                if (context.hasDefinition(subNode.m_name))
                {
                    var newSubNode = context.getDefinitionNode(subNode.m_name).Clone(context);
                    foreach (XmlAttribute attribute in subNode.m_sourceNode.Attributes) //Still some issues here definitions in definitions are still broken
                    {
                        newSubNode.FillOutAttribute(attribute);
                        m_subNodes[counter] = newSubNode;
                    }

                }
            }
        }
        /// <summary>
        /// This only works if we recursively replace stuff in the definition node first
        /// </summary>
        /// <param name="childNode"></param>
        public void replaceRecursiveDefinitionNodes(XmlNode childNode, HTMLParserContext context)
        {
            //for (int index = 0; index < m_subNodes.Count; ++index )
            //{
            //    HTMLDefinitionNode subNode = (HTMLDefinitionNode)m_subNodes[index];
            //    if (context.hasDefinition(subNode.m_name))
            //    {
            //        //Modify the original node and replace with the definition on. Have to take care with the definition because it can have embbeded definitions internally.
            //        var definitionNode = context.getDefinitionNode(subNode.m_name); //This needs to be a copy not a reference
            //        var cloned = new HTMLDefinitionNode(definitionNode.SourceNode, context);
            //        if (definitionNode != null)
            //        {
            //            //replace subnode with new definition node
            //            m_subNodes[index] = cloned;
            //        }
            //    }
            //}

            foreach (HTMLDefinitionNode subnode in m_subNodes)
            {
                foreach (XmlAttribute attribute in childNode.Attributes)
                {
                    subnode.FillOutAttribute(attribute);
                }
            }
        }
        public XmlNode generateXmlNode(HTMLParserContext context)
        {
            XmlDocument doc = context.IntermediateDocument;
            var element = doc.CreateNode(XmlNodeType.Element, m_name, "");
            foreach (var pair in m_attributes)
            {

                var attribute = doc.CreateAttribute(pair.Key);

                if (pair.Value.m_filledOutAttributeValue != null)
                {
                    if (pair.Value.m_filledOutAttributeValue != "")
                    {
                        attribute.Value = pair.Value.m_filledOutAttributeValue;
                    }
                    else
                    {
                        attribute.Value = pair.Value.m_defaultAttributeValue;
                    }
                }
                else
                {
                    attribute.Value = pair.Value.m_defaultAttributeValue;
                }
                element.Attributes.Append(attribute);
            }

            foreach (HTMLDefinitionNode subnode in m_subNodes)
            {
                element.AppendChild(subnode.generateXmlNode(context));
            }

            return element;
        }
 public HTMLDefinitionNode Clone(HTMLParserContext context)
 {
     return new HTMLDefinitionNode(m_sourceNode, context); //expensive but easy :)
 }
        private void decodeSourceNode(XmlNode node, HTMLParserContext context)
        {
            if (node.Attributes != null)
            {
                foreach (XmlAttribute attribute in node.Attributes)
                {
                    AttributeProperties overridableNameAndDefaultValue = new AttributeProperties();
                    if (attribute.Value.Contains("#"))
                    {
                        string attributeValue = attribute.Value;
                        attributeValue = attributeValue.Substring(attributeValue.IndexOf("#") + 1);
                        string[] splitAttributeValues = attributeValue.Split('#'); //0 will be the name of the attribute to get from the childNode, 1 is the default value if it exists which is used if the value is not overriden in the childnode
                        if (splitAttributeValues.Length > 1)
                        {
                            overridableNameAndDefaultValue.m_overrideableAttributeName = splitAttributeValues[0];
                            overridableNameAndDefaultValue.m_defaultAttributeValue = splitAttributeValues[1];
                        }
                        else
                        {
                            overridableNameAndDefaultValue.m_overrideableAttributeName = splitAttributeValues[0];
                            overridableNameAndDefaultValue.m_defaultAttributeValue = "";
                        }
                    }
                    else
                    {
                        //This node is an override of something else so store the actual attribute value
                        overridableNameAndDefaultValue.m_overrideableAttributeName = attribute.Value;
                        overridableNameAndDefaultValue.m_defaultAttributeValue = attribute.Value;
                    }

                    m_attributes.Add(attribute.Name, overridableNameAndDefaultValue);
                }
            }
            //Should deal with inner text here that has no nodes in it. so we can replace this stuff too important for text as that is just a div

            if (node.ChildNodes != null)
            {

                foreach (XmlNode childNode in node.ChildNodes)
                {
                    if (context.hasDefinition(childNode.Name))
                    {
                        HTMLDefinitionNode defNode = context.getDefinitionNode(childNode.Name).Clone(context);
                        //Need to fill out definition node here
                        foreach (XmlAttribute attribute in defNode.SourceNode.Attributes)
                        {
                            defNode.FillOutAttribute(attribute);
                        }
                        m_subNodes.Add(defNode);
                    }
                    else
                    {
                        m_subNodes.Add(new HTMLDefinitionNode(childNode, context));
                    }
                }
            }
        }