Used for generating Code using CodeDom
        /// <summary>
        /// Generates source code for the virtual path of the build provider, and adds the source code to a specified assembly builder.
        /// </summary>
        /// <param name="assemblyBuilder">The assembly builder that references the source code generated by the build provider.</param>
        public override void GenerateCode(AssemblyBuilder assemblyBuilder)
        {
            if (assemblyBuilder == null)
            {
                throw new ArgumentNullException("assemblyBuilder");
            }

            // get name and namespace from the filename
            string ns   = string.Empty;
            string name = VirtualPathUtility.GetFileName(VirtualPath);
            int    i    = name.LastIndexOf('.');

            if (i > 0)
            {
                name = name.Substring(0, i);  // discard extension
                i    = name.LastIndexOf('.'); // and split into namespace and class

                if (i > 0)
                {
                    name = name.Substring(i + 1);
                    ns   = name.Substring(0, i);
                }
            }

            // load as XML
            XmlDocument doc = new XmlDocument();

            using (Stream s = OpenStream(VirtualPath))
            {
                doc.Load(s);
            }

            // compile the channel
            CodeCompileUnit ccu = new CodeCompileUnit();

            RssCodeGenerator.GenerateCodeDomTree(doc.OuterXml, string.Empty, ns, name, ccu, true);
            assemblyBuilder.AddCodeCompileUnit(this, ccu);
        }
        public override void GenerateCode(AssemblyBuilder assemblyBuilder)
        {
            if (assemblyBuilder == null)
            {
                throw new ArgumentNullException("assemblyBuilder");
            }

            // load as XML
            XmlDocument doc = new XmlDocument();

            using (Stream s = OpenStream(VirtualPath))
            {
                doc.Load(s);
            }

            // validate root rssdl node
            XmlNode root = doc.DocumentElement;

            if (root.Name != "rssdl")
            {
                throw new InvalidDataException(string.Format(CultureInfo.InvariantCulture, "Unexpected root node '{0}' -- expected root 'rssdl' node", root.Name));
            }

            // iterate through rss nodes
            for (XmlNode n = root.FirstChild; n != null; n = n.NextSibling)
            {
                if (n.NodeType != XmlNodeType.Element)
                {
                    continue;
                }

                if (n.Name != "rss")
                {
                    throw new InvalidDataException(
                              string.Format(
                                  CultureInfo.InvariantCulture,
                                  "Unexpected node '{0}' -- expected root 'rss' node",
                                  root.Name));
                }

                string file            = string.Empty;
                string url             = string.Empty;
                string classNamePrefix = string.Empty;
                string namespaceName   = string.Empty;

                foreach (XmlAttribute attr in n.Attributes)
                {
                    switch (attr.Name)
                    {
                    case "name":
                        classNamePrefix = attr.Value;
                        break;

                    case "url":
                        url = attr.Value;
                        break;

                    case "file":
                        file = VirtualPathUtility.Combine(VirtualPathUtility.GetDirectory(VirtualPath), attr.Value);
                        break;

                    case "namespace":
                        namespaceName = attr.Value;
                        break;

                    default:
                        throw new InvalidDataException(
                                  string.Format(CultureInfo.InvariantCulture, "Unexpected attribute '{0}'", attr.Name));
                    }
                }

                if (string.IsNullOrEmpty(classNamePrefix))
                {
                    throw new InvalidDataException("Missing 'name' attribute");
                }

                if (string.IsNullOrEmpty(url) && string.IsNullOrEmpty(file))
                {
                    throw new InvalidDataException("Missing 'url' or 'file' attribute - one must be specified");
                }

                if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(file))
                {
                    throw new InvalidDataException("Only one of 'file' and 'url' can be specified");
                }

                // compile channel
                CodeCompileUnit ccu = new CodeCompileUnit();

                if (!string.IsNullOrEmpty(url))
                {
                    // load RssDocument
                    using (Stream feedStream = DownloadManager.GetFeed(url))
                    {
                        using (XmlTextReader reader = new XmlTextReader(feedStream))
                        {
                            string codeString = RssXmlHelper.ConvertToRssXml(reader);
                            RssCodeGenerator.GenerateCodeDomTree(codeString, url, namespaceName, classNamePrefix, ccu, true);
                        }
                    }
                }
                else
                {
                    using (XmlTextReader reader = new XmlTextReader(file))
                    {
                        string codeString = RssXmlHelper.ConvertToRssXml(reader);
                        RssCodeGenerator.GenerateCodeDomTree(codeString, url, namespaceName, classNamePrefix, ccu, true);
                    }
                }

                assemblyBuilder.AddCodeCompileUnit(this, ccu);
            }
        }