private void WriteElement(ICompositionElement element, XElement parent)
        {
            XElement el = new XElement("element");

            el.Add(new XAttribute("type", TypeKeyAttribute.GetTypeKeyOf(element)));

            foreach (string propKey in element.Properties.Keys)
            {
                el.Add(new XAttribute(propKey, element.Properties[propKey]));
            }

            if (element.ChildrenSupported)
            {
                foreach (ICompositionElement child in element.Children)
                {
                    WriteElement(child, el);
                }
            }

            parent.Add(el);
        }
        Stream IReportTemplateSerializer.Serialize(IReportTemplate template)
        {
            if (template == null)
            {
                throw new ArgumentNullException("template");
            }

            MemoryStream stream = new MemoryStream();

            XDocument doc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));

            /* Write template root.
             */
            XElement root = new XElement("template");

            /* Write description.
             */
            XElement desc = new XElement("description");

            desc.Add(new XElement("name", template.Description.Name));
            desc.Add(new XElement("author", template.Description.Author));
            root.Add(desc);

            /* Write data sources.
             */
            XElement data = new XElement("data");

            foreach (IDataSource item in template.DataSources)
            {
                XElement ds = new XElement("source");
                ds.Add(new XAttribute("name", item.Name));
                ds.Add(new XAttribute("provider", TypeKeyAttribute.GetTypeKeyOf(item.Provider)));

                foreach (string key in item.Provider.Properties.Keys)
                {
                    string value = item.Provider.Properties[key];

                    ds.Add(new XElement(key, new XCData(value)));
                }

                data.Add(ds);
            }

            root.Add(data);

            /* Write layout sections.
             */
            XElement layout = new XElement("layout");

            foreach (IReportTemplateSection item in template.Sections)
            {
                XElement section = new XElement("section");
                section.Add(new XAttribute("name", item.Type.ToString().ToLower()));
                section.Add(new XAttribute("rootContainer", TypeKeyAttribute.GetTypeKeyOf(item.RootElement)));

                WriteElement(item.RootElement, section);

                layout.Add(section);
            }

            root.Add(layout);

            doc.Add(root);

            doc.Save(stream);

            stream.Position = 0L;

            return(stream);
        }