Exemple #1
0
        public CheckGridEntity(DocConceptRoot docRoot, DocModelView docView, DocProject docProject)
        {
            this.m_root         = docRoot;
            this.m_view         = docView;
            this.m_project      = docProject;
            this.m_listTemplate = new List <DocTemplateDefinition>();

            List <DocTemplateDefinition> listTemplate = docProject.GetTemplateList();

            //... filter out templates to only those that apply to entity...

            foreach (DocTemplateDefinition docTemplate in listTemplate)
            {
                if (docTemplate.Rules != null && docTemplate.Rules.Count > 0)                 // don't include abstract/organizational templates
                {
                    bool include = false;

                    // check for inheritance
                    DocObject docApplicableEntity = docProject.GetDefinition(docTemplate.Type) as DocEntity;

                    if (docTemplate.Type != null && docApplicableEntity is DocEntity)
                    {
                        // check for inheritance
                        DocEntity docBase = docRoot.ApplicableEntity;
                        while (docBase != null)
                        {
                            if (docBase == docApplicableEntity)
                            {
                                include = true;
                                break;
                            }

                            if (docBase.BaseDefinition == null)
                            {
                                break;
                            }

                            docBase = docProject.GetDefinition(docBase.BaseDefinition) as DocEntity;
                        }
                    }

                    if (include)
                    {
                        this.m_listTemplate.Add(docTemplate);
                    }
                }
            }
        }
Exemple #2
0
        public static CvtValuePath FromTemplateDefinition(DocTemplateDefinition dtd, DocProject docProject)
        {
            if (dtd.Rules.Count > 0 && dtd.Rules[0] is DocModelRuleAttribute)
            {
                DocModelRuleAttribute docRuleAtt = (DocModelRuleAttribute)dtd.Rules[0];

                DocEntity docEnt = docProject.GetDefinition(dtd.Type) as DocEntity;
                if (docEnt != null)
                {
                    CvtValuePath pathInner = null;
                    if (docRuleAtt.Rules.Count > 0 && docRuleAtt.Rules[0] is DocModelRuleEntity)
                    {
                        pathInner = FromModelRule((DocModelRuleEntity)docRuleAtt.Rules[0], docProject);
                    }

                    DocAttribute docAtt     = docEnt.ResolveAttribute(docRuleAtt.Name, docProject);
                    string       identifier = null;

                    if (docRuleAtt.Name.Equals("IsDefinedBy"))
                    {
                        // hack for compat
                        docRuleAtt.ToString();

                        // look for identifier
                        if (docRuleAtt.Rules.Count > 0)
                        {
                            try
                            {
                                DocModelRuleConstraint docRuleIndexCon = (DocModelRuleConstraint)docRuleAtt.Rules[0].Rules[0].Rules[0].Rules[1].Rules[0].Rules[0];

                                if (docRuleIndexCon != null)
                                {
                                    if (docRuleIndexCon.Expression is DocOpStatement)
                                    {
                                        DocOpStatement docOpStatement = (DocOpStatement)docRuleIndexCon.Expression;
                                        if (docOpStatement.Value != null)
                                        {
                                            identifier = docOpStatement.Value.ToString();
                                            if (identifier.StartsWith("'") && identifier.EndsWith("'"))
                                            {
                                                identifier = identifier.Substring(1, identifier.Length - 2);
                                            }
                                        }
                                    }
                                }
                            }
                            catch
                            {
                            }
                        }
                    }

                    CvtValuePath pathRoot = new CvtValuePath(docEnt, docAtt, identifier, pathInner);
                    return(pathRoot);
                }
            }

            return(null);
        }
Exemple #3
0
        public static void UploadTemplateUsage(DocProject docProject, string baseurl, string sessionid, string parentid, DocTemplateUsage docConc)
        {
            // MVD Concept entry is a relationship in BSDD; contexts are exchanges
            foreach (DocTemplateItem docItem in docConc.Items)
            {
                if (docItem.Concepts.Count == 0)
                {
                    string code = docItem.GetParameterValue("Reference");
                    if (String.IsNullOrEmpty(code))
                    {
                        code = docItem.Name;
                    }
                    code = HttpUtility.UrlEncode(code);

                    string name = docItem.GetParameterValue("Name");
                    if (code != null && name != null)
                    {
                        // if no sub-concepts, then its a property
                        IfdBase ifdItem = CreateConcept(baseurl, sessionid, docItem, code, name, null, IfdConceptTypeEnum.PROPERTY);
                        CreateRelationship(baseurl, sessionid, parentid, ifdItem.guid, IfdRelationshipTypeEnum.ASSIGNS_PROPERTIES);

                        string paramval = docItem.GetParameterValue("Value");
                        if (!String.IsNullOrEmpty(paramval))
                        {
                            DocDefinition docDef = docProject.GetDefinition(paramval);
                            if (docDef != null)
                            {
                                // get the measure type
                                IfdBase ifdType = SearchConcept(baseurl, sessionid, docDef.Name, IfdConceptTypeEnum.MEASURE);
                                if (ifdType == null)
                                {
                                    // create concept
                                    ifdType = CreateConcept(baseurl, sessionid, docDef, docDef.Name, docDef.Name, null, IfdConceptTypeEnum.MEASURE);
                                }
                                CreateRelationship(baseurl, sessionid, ifdItem.guid, ifdType.guid, IfdRelationshipTypeEnum.ASSIGNS_MEASURES);
                            }
                        }
                    }
                }
                else
                {
                    // otherwise its a nest
                    if (docItem.Name != null)
                    {
                        IfdBase ifdItem = CreateConcept(baseurl, sessionid, docItem, docItem.Name, docItem.Name, null, IfdConceptTypeEnum.NEST);
                        CreateRelationship(baseurl, sessionid, parentid, ifdItem.guid, IfdRelationshipTypeEnum.ASSIGNS_COLLECTIONS);

                        // recurse -- e.g. properties within property sets
                        foreach (DocTemplateUsage docInner in docItem.Concepts)
                        {
                            UploadTemplateUsage(docProject, baseurl, sessionid, ifdItem.guid, docInner);
                        }
                    }
                }
            }
        }
Exemple #4
0
        private static CvtValuePath FromModelRule(DocModelRuleEntity docRuleEntity, DocProject docProject)
        {
            DocDefinition docDef     = docProject.GetDefinition(docRuleEntity.Name);
            DocAttribute  docAtt     = null;
            string        identifier = null;
            CvtValuePath  pathInner  = null;

            if (docDef is DocEntity && docRuleEntity.Rules.Count > 0 && docRuleEntity.Rules[0] is DocModelRuleAttribute)
            {
                DocModelRuleAttribute docRuleAtt = (DocModelRuleAttribute)docRuleEntity.Rules[0];
                DocEntity             docEnt     = (DocEntity)docDef;
                docAtt = docEnt.ResolveAttribute(docRuleAtt.Name, docProject);

                if (docRuleAtt.Rules.Count > 0 && docRuleAtt.Rules[0] is DocModelRuleEntity)
                {
                    DocModelRuleEntity docRuleInner = (DocModelRuleEntity)docRuleAtt.Rules[0];
                    pathInner = FromModelRule(docRuleInner, docProject);


                    // look for identifier
                    if (docRuleInner.Rules.Count > 1 && docRuleInner.Rules[1] is DocModelRuleAttribute)
                    {
                        DocModelRuleAttribute docRuleIndexAtt = (DocModelRuleAttribute)docRuleInner.Rules[1];
                        if (docRuleIndexAtt.Rules.Count > 0)
                        {
                            DocModelRuleEntity docRuleIndexEnt = (DocModelRuleEntity)docRuleIndexAtt.Rules[0];
                            if (docRuleIndexEnt.Rules.Count > 0 && docRuleIndexEnt.Rules[0] is DocModelRuleConstraint)
                            {
                                DocModelRuleConstraint docRuleIndexCon = (DocModelRuleConstraint)docRuleIndexEnt.Rules[0];
                                if (docRuleIndexCon.Expression is DocOpStatement)
                                {
                                    DocOpStatement docOpStatement = (DocOpStatement)docRuleIndexCon.Expression;
                                    if (docOpStatement.Value != null)
                                    {
                                        identifier = docOpStatement.Value.ToString();
                                        if (identifier.StartsWith("'") && identifier.EndsWith("'"))
                                        {
                                            identifier = identifier.Substring(1, identifier.Length - 2);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            CvtValuePath pathOuter = new CvtValuePath(docDef, docAtt, identifier, pathInner);

            return(pathOuter);
        }
        private void LoadEntity(DocEntity entity, DocProject project, string selection)
        {
            if (entity == null)
            {
                return;
            }

            // recurse to base
            if (entity.BaseDefinition != null)
            {
                DocEntity docBase = project.GetDefinition(entity.BaseDefinition) as DocEntity;
                LoadEntity(docBase, project, selection);
            }

            // load attributes
            foreach (DocAttribute docAttr in entity.Attributes)
            {
                // if attribute is derived, dont add, but remove existing
                if (!String.IsNullOrEmpty(docAttr.Derived))
                {
                    foreach (ListViewItem lvi in this.listView.Items)
                    {
                        if (lvi.Text.Equals(docAttr.Name))
                        {
                            lvi.Remove();
                            break;
                        }
                    }
                }
                else
                {
                    ListViewItem lvi = new ListViewItem();
                    lvi.Tag  = docAttr;
                    lvi.Text = docAttr.Name;
                    lvi.SubItems.Add(docAttr.DefinedType);                     // INVERSE / SET / LIST / OPTIONAL...
                    this.listView.Items.Add(lvi);

                    if (selection != null && lvi.Text.Equals(selection))
                    {
                        lvi.Selected = true;
                    }
                }
            }
        }
        private void LoadEntity(DocEntity entity, DocProject project, string selection)
        {
            if (entity == null)
                return;

            // recurse to base
            if (entity.BaseDefinition != null)
            {
                DocEntity docBase = project.GetDefinition(entity.BaseDefinition) as DocEntity;
                LoadEntity(docBase, project, selection);                
            }

            // load attributes
            foreach (DocAttribute docAttr in entity.Attributes)
            {
                // if attribute is derived, dont add, but remove existing
                if (!String.IsNullOrEmpty(docAttr.Derived))
                {
                    foreach (ListViewItem lvi in this.listView.Items)
                    {
                        if (lvi.Text.Equals(docAttr.Name))
                        {
                            lvi.Remove();
                            break;
                        }
                    }
                }
                else
                {
                    ListViewItem lvi = new ListViewItem();
                    lvi.Tag = docAttr;
                    lvi.Text = docAttr.Name;
                    lvi.SubItems.Add(docAttr.DefinedType); // INVERSE / SET / LIST / OPTIONAL...
                    this.listView.Items.Add(lvi);

                    if(selection != null && lvi.Text.Equals(selection))
                    {
                        lvi.Selected = true;
                    }
                }
            }
        }
        private static string FormatEntityConcepts(
            DocProject docProject, 
            DocEntity entity, 
            Dictionary<string, DocObject> mapEntity, 
            Dictionary<string, string> mapSchema, 
            Dictionary<DocObject, bool> included, 
            List<ContentRef> listFigures, 
            List<ContentRef> listTables)
        {
            StringBuilder sb = new StringBuilder();

            // find concepts for entity
            foreach (DocModelView docView in docProject.ModelViews)
            {
                if (included == null || included.ContainsKey(docView))
                {
                    // check if there are any applicable concepts
                    bool hasConceptsAtEntity = false;
                    foreach (DocConceptRoot docRoot in docView.ConceptRoots)
                    {
                        if (docRoot.ApplicableEntity == entity)
                        {
                            hasConceptsAtEntity = true;
                        }
                    }

                    // inherited use definitions

                    // build list of inherited views
                    DocModelView[] listViews = docProject.GetViewInheritance(docView);
                    
                    List<string> listLines = new List<string>();
                    Dictionary<DocTemplateDefinition, DocTemplateUsage> mapSuper = new Dictionary<DocTemplateDefinition, DocTemplateUsage>();
                    List<DocTemplateDefinition> listSuppress = new List<DocTemplateDefinition>();
                    DocEntity docSuper = entity;
                    while (docSuper != null)
                    {
                        // find parent concept roots
                        bool renderclass = false;
                        foreach (DocModelView docViewBase in listViews)
                        {
                            foreach (DocConceptRoot docSuperRoot in docViewBase.ConceptRoots)
                            {
                                if (docSuperRoot.ApplicableEntity == docSuper)
                                {
                                    StringBuilder sbSuper = new StringBuilder();

                                    string schema = mapSchema[docSuper.Name].ToLower();

                                    if (!renderclass)
                                    {
                                        renderclass = true;

                                        sbSuper.Append("<tr><td colspan=\"3\">");
                                        sbSuper.Append("<a href=\"../../" + schema + "/lexical/" + MakeLinkName(docSuper) + ".htm\">");
                                        if (docSuper.IsAbstract())
                                        {
                                            sbSuper.Append("<i>");
                                            sbSuper.Append(docSuper.Name);
                                            sbSuper.Append("</i>");
                                        }
                                        else
                                        {
                                            sbSuper.Append(docSuper.Name);
                                        }
                                        sbSuper.Append("</a></td></tr>");
                                    }
                                    
                                    foreach (DocTemplateUsage docSuperUsage in docSuperRoot.Concepts)
                                    {
                                        if (docSuperUsage.Suppress && !listSuppress.Contains(docSuperUsage.Definition))
                                        {
                                            listSuppress.Add(docSuperUsage.Definition);
                                        }
                                        else if (docSuperUsage.Definition != null && !mapSuper.ContainsKey(docSuperUsage.Definition))
                                        {
                                            bool suppress = listSuppress.Contains(docSuperUsage.Definition);

                                            sbSuper.Append("<tr><td> </td><td>");

                                            mapSuper.Add(docSuperUsage.Definition, docSuperUsage);

                                            string templateid = MakeLinkName(docSuperUsage.Definition);

                                            sbSuper.Append("<a href=\"../../");
                                            sbSuper.Append(schema);
                                            sbSuper.Append("/lexical/" + MakeLinkName(docSuper) + ".htm#" + templateid + "\">");
                                            if (suppress)
                                            {
                                                sbSuper.Append("<del>");
                                            }
                                            sbSuper.Append(docSuperUsage.Definition.Name);
                                            if (suppress)
                                            {
                                                sbSuper.Append("</del>");
                                            }
                                            sbSuper.Append("</a>");

                                            sbSuper.Append("</td><td>");
                                            sbSuper.Append(docViewBase.Name);
                                            sbSuper.Append("</td></tr>");

                                        }
                                    }

                                    listLines.Add(sbSuper.ToString());
                                }
                            }
                        }

                        // go to base type
                        docSuper = docProject.GetDefinition(docSuper.BaseDefinition) as DocEntity;
                    }

                    if (hasConceptsAtEntity || listLines.Count > 0)
                    {
                        sb.AppendLine("<section>");
                        sb.AppendLine("<h5 class=\"num\">Definitions applying to " + docView.Name + "</h5>");

                        // link to instance diagram
                        if (hasConceptsAtEntity)
                        {
                            string linkdiagram = MakeLinkName(docView) + "/" + MakeLinkName(entity) + ".htm";
                            sb.Append("<p><a href=\"../../../annex/annex-d/" + linkdiagram + "\"><img style=\"border: 0px\" src=\"../../../img/diagram.png\" />&nbsp;Instance diagram</a></p>");
                        }

                        sb.AppendLine("<hr />");

                        foreach (DocConceptRoot docRoot in docView.ConceptRoots)
                        {
                            if (docRoot.ApplicableEntity == entity)
                            {

                                sb.Append(docRoot.Documentation);

                                if (docRoot.Concepts.Count > 0)
                                {
                                    sb.AppendLine("<details>");
                                    sb.AppendLine("<summary>Concept usage</summary>");
                                    foreach (DocTemplateUsage eachusage in docRoot.Concepts)
                                    {
                                        FormatEntityUsage(docProject, entity, docRoot, eachusage, mapEntity, mapSchema, listFigures, listTables, included, sb);
                                    }
                                    sb.AppendLine("</details>");
                                }



                            }
                        }
                    }


                    // now format inherited use definitions
                    if (listLines.Count > 0)
                    {
                        sb.AppendLine("<section>");

                        sb.AppendLine("<details>");
                        sb.AppendLine("<summary>Concept inheritance</summary>");
                        sb.AppendLine("<p><table class=\"attributes\">");
                        sb.AppendLine("<tr><th><b>#</b></th><th><b>Concept</b></td><th><b>Model View</b></th></tr>");
                        for (int iLine = listLines.Count - 1; iLine >= 0; iLine--)
                        {
                            // reverse order
                            sb.AppendLine(listLines[iLine]);
                        }
                        sb.AppendLine("</table>");
                        sb.AppendLine("</details>");
                        sb.AppendLine("</section>");

                    }


                    sb.AppendLine("</section>");
                }
            }

            sb = sb.Replace("<EPM-HTML>", "");
            sb = sb.Replace("</EPM-HTML>", "");

            return sb.ToString();
        }
Exemple #8
0
        private static string FormatEntityConcepts(
            DocProject docProject, 
            DocEntity entity, 
            Dictionary<string, DocObject> mapEntity, 
            Dictionary<string, string> mapSchema, 
            Dictionary<DocObject, bool> included, 
            List<ContentRef> listFigures, 
            List<ContentRef> listTables,
            string path,
            DocPublication docPublication)
        {
            StringBuilder sb = new StringBuilder();

            // find concepts for entity
            foreach (DocModelView docView in docProject.ModelViews)
            {
                if (included == null || included.ContainsKey(docView))
                {
                    // check if there are any applicable concepts
                    bool hasConceptsAtEntity = false;
                    foreach (DocConceptRoot docRoot in docView.ConceptRoots)
                    {
                        if (docRoot.ApplicableEntity == entity)
                        {
                            hasConceptsAtEntity = true;
                        }
                    }

                    // inherited use definitions

                    // build list of inherited views
                    DocModelView[] listViews = docProject.GetViewInheritance(docView);

                    List<string> listLines = new List<string>();
                    Dictionary<DocTemplateDefinition, DocTemplateUsage> mapSuper = new Dictionary<DocTemplateDefinition, DocTemplateUsage>();
                    List<DocTemplateDefinition> listSuppress = new List<DocTemplateDefinition>();
                    List<DocTemplateDefinition> listOverride = new List<DocTemplateDefinition>();
                    DocEntity docSuper = entity;
                    while (docSuper != null)
                    {
                        StringBuilder sbSuper = new StringBuilder();

                        // find parent concept roots
                        bool renderclass = false;
                        foreach (DocModelView docViewBase in listViews)
                        {
                            foreach (DocConceptRoot docSuperRoot in docViewBase.ConceptRoots)
                            {
                                if (docSuperRoot.ApplicableEntity == docSuper)
                                {
                                    string schema = mapSchema[docSuper.Name].ToLower();

                                    foreach (DocTemplateUsage docSuperUsage in docSuperRoot.Concepts)
                                    {
                                        bool flag = false;
                                        if (docSuperUsage.Suppress)
                                        {
                                            if (!listSuppress.Contains(docSuperUsage.Definition))
                                            {
                                                listSuppress.Add(docSuperUsage.Definition);
                                                flag = true;
                                            }
                                        }
                                        else if (docSuperUsage.Override)
                                        {
                                            if (!listOverride.Contains(docSuperUsage.Definition))
                                            {
                                                listOverride.Add(docSuperUsage.Definition);
                                                flag = true;
                                            }
                                        }

                                        if (docSuperUsage.Definition != null && !mapSuper.ContainsKey(docSuperUsage.Definition) && !docSuperUsage.Suppress)
                                        {
                                            if (!renderclass)
                                            {
                                                renderclass = true;

                                                sbSuper.Append("<tr><td colspan=\"3\">");
                                                sbSuper.Append("<a href=\"../../" + schema + "/lexical/" + MakeLinkName(docSuper) + ".htm\">");
                                                if (docSuper.IsAbstract())
                                                {
                                                    sbSuper.Append("<i>");
                                                    sbSuper.Append(docSuper.Name);
                                                    sbSuper.Append("</i>");
                                                }
                                                else
                                                {
                                                    sbSuper.Append(docSuper.Name);
                                                }
                                                sbSuper.Append("</a></td></tr>");
                                            }

                                            bool suppress = listSuppress.Contains(docSuperUsage.Definition);
                                            bool overiden = listOverride.Contains(docSuperUsage.Definition);

                                            foreach(DocTemplateDefinition dtd in listSuppress)
                                            {
                                                if (docSuperUsage.Definition == dtd || docSuperUsage.Definition.Templates.Contains(dtd))
                                                {
                                                    suppress = true;
                                                    break;
                                                }
                                            }

                                            foreach (DocTemplateDefinition dtd in listOverride)
                                            {
                                                if (docSuperUsage.Definition == dtd || docSuperUsage.Definition.Templates.Contains(dtd))
                                                {
                                                    overiden = true;
                                                    break;
                                                }
                                            }

                                            if(flag)
                                            {
                                                suppress = false;
                                                overiden = false;
                                            }

                                            sbSuper.Append("<tr><td> </td><td>");

                                            mapSuper.Add(docSuperUsage.Definition, docSuperUsage);

                                            string templateid = MakeLinkName(docSuperUsage.Definition);

                                            sbSuper.Append("<a href=\"../../");
                                            sbSuper.Append(schema);
                                            sbSuper.Append("/lexical/" + MakeLinkName(docSuper) + ".htm#" + templateid + "\">");
                                            if (suppress || overiden)
                                            {
                                                sbSuper.Append("<del>");
                                            }
                                            if (!String.IsNullOrEmpty(docSuperUsage.Name))
                                            {
                                                sbSuper.Append(docSuperUsage.Name);
                                            }
                                            else
                                            {
                                                sbSuper.Append(docSuperUsage.Definition.Name);
                                            }
                                            if (suppress || overiden)
                                            {
                                                sbSuper.Append("</del>");
                                            }
                                            sbSuper.Append("</a>");
                                            if(overiden)
                                            {
                                                sbSuper.Append(" (overridden)");
                                            }
                                            else if(suppress)
                                            {
                                                sbSuper.Append(" (suppressed)");
                                            }

                                            sbSuper.Append("</td><td>");
                                            sbSuper.Append("<a href=\"../../templates/" + MakeLinkName(docSuperUsage.Definition) + ".htm\">" + docSuperUsage.Definition + "</a>");
                                            sbSuper.Append("</td><td>");
                                            sbSuper.Append(docViewBase.Name);
                                            sbSuper.Append("</td></tr>");
                                            sbSuper.AppendLine();
                                        }
                                    }

                                }
                            }
                        }

                        if (sbSuper.Length > 0)
                        {
                            listLines.Add(sbSuper.ToString());
                        }

                        // go to base type
                        docSuper = docProject.GetDefinition(docSuper.BaseDefinition) as DocEntity;
                    }

                    if (hasConceptsAtEntity || listLines.Count > 0)
                    {
                        sb.AppendLine("<section>");
                        sb.AppendLine("<h5 class=\"num\">Definitions applying to " + docView.Name + "</h5>");

                        // link to instance diagram
                        if (hasConceptsAtEntity)
                        {
                            string linkdiagram = MakeLinkName(docView) + "/" + MakeLinkName(entity) + ".htm";
                            sb.Append("<p><a href=\"../../../annex/annex-d/" + linkdiagram + "\"><img style=\"border: 0px\" src=\"../../../img/diagram.png\" />&nbsp;Instance diagram</a></p>");
                        }

                        sb.AppendLine("<hr />");

                        foreach (DocConceptRoot docRoot in docView.ConceptRoots)
                        {
                            if (docRoot.ApplicableEntity == entity)
                            {
                                sb.Append("<h5>" + docRoot.Name + "</h5>");

                                if (docRoot.ApplicableTemplate != null)
                                {
                                    string applicabletemplatetable = FormatConceptTable(docProject, docView, entity, docRoot, null, mapEntity, mapSchema);
                                    sb.Append(applicabletemplatetable);
                                }

                                sb.Append(docRoot.Documentation);

                                if (docRoot.Concepts.Count > 0)
                                {
                                    sb.AppendLine("<details open=\"open\">");
                                    sb.AppendLine("<summary>Concept usage</summary>");
                                    foreach (DocTemplateUsage eachusage in docRoot.Concepts)
                                    {
                                        FormatEntityUsage(docProject, entity, docRoot, eachusage, mapEntity, mapSchema, listFigures, listTables, included, sb, path, docPublication);
                                    }
                                    sb.AppendLine("</details>");

                                    //... mvdXML for entire root
                                    ConceptRoot mvdConceptRoot = new ConceptRoot();
                                    Program.ExportMvdConceptRoot(mvdConceptRoot, docRoot, false);
                                    XmlSerializer ser = new XmlSerializer(typeof(ConceptRoot));
                                    StringBuilder mvdOutput = new StringBuilder();
                                    using (System.IO.Stream streamMVD = new System.IO.MemoryStream())
                                    {
                                        ser.Serialize(streamMVD, mvdConceptRoot, null);
                                        streamMVD.Position = 0;
                                        using (System.IO.StreamReader reader = new System.IO.StreamReader(streamMVD))
                                        {
                                            while (!reader.EndOfStream)
                                            {
                                                string mvdLine = reader.ReadLine();

                                                int pos = 0;
                                                while (pos < mvdLine.Length && mvdLine[pos] == ' ')
                                                {
                                                    mvdOutput.Append("\t");
                                                    pos++;
                                                }

                                                // replace any leading spaces with tabs for proper formatting
                                                string mvdMark = mvdLine.Substring(pos, mvdLine.Length - pos);
                                                mvdOutput.AppendLine(mvdMark);
                                            }
                                        }
                                    }

                                    string html = System.Web.HttpUtility.HtmlEncode(mvdOutput.ToString());
                                    html = html.Replace("\r\n", "<br/>\r\n");
                                    html = html.Replace("\t", "&nbsp;");

                                    //sb.AppendLine("<section>");
                                    sb.AppendLine("<details><summary>mvdXML Specification</summary>");
                                    sb.AppendLine("<div class=\"xsd\"><code class=\"xsd\">");
                                    sb.AppendLine(html); //... need to use tabs...
                                    //sb.AppendLine(mvdOutput.ToString());
                                    sb.AppendLine("</code></div></details>");
                                    //sb.AppendLine("</section>");
                                }

                            }
                        }
                    }

                    // now format inherited use definitions
                    if (listLines.Count > 0)
                    {
                        sb.AppendLine("<section>");

                        sb.AppendLine("<details>");
                        sb.AppendLine("<summary>Concept inheritance</summary>");
                        sb.AppendLine("<p><table class=\"attributes\">");
                        sb.AppendLine("<tr><th><b>#</b></th><th><b>Concept</b></th><th><b>Template</b></th><th><b>Model View</b></th></tr>");
                        for (int iLine = listLines.Count - 1; iLine >= 0; iLine--)
                        {
                            // reverse order
                            sb.AppendLine(listLines[iLine]);
                        }
                        sb.AppendLine("</table>");
                        sb.AppendLine("</details>");
                        sb.AppendLine("</section>");

                    }

                    sb.AppendLine("</section>");
                }
            }

            sb = sb.Replace("<EPM-HTML>", "");
            sb = sb.Replace("</EPM-HTML>", "");

            return sb.ToString();
        }
Exemple #9
0
        /// <summary>
        /// Create an inheritance diagram for a particular entity, its entire hierarchy of supertypes, and one level of subtypes, within scope.
        /// </summary>
        /// <param name="docEntity"></param>
        /// <param name="font"></param>
        /// <param name="map"></param>
        /// <returns></returns>
        public static Image CreateInheritanceDiagramForEntity(DocProject docProject, Dictionary<DocObject, bool> included, DocEntity docEntity, Font font, Dictionary<Rectangle, DocEntity> map)
        {
            // determine items within scope
            Dictionary<DocObject, bool> hierarchy = new Dictionary<DocObject,bool>();
            DocEntity docBase = docEntity;
            DocEntity docRoot = docBase;
            while (docBase != null)
            {
                docRoot = docBase;
                if (included == null || included.ContainsKey(docBase))
                {
                    hierarchy.Add(docBase, true);
                }
                docBase = docProject.GetDefinition(docBase.BaseDefinition) as DocEntity;
            }

            foreach (DocSection docSection in docProject.Sections)
            {
                foreach (DocSchema docSchema in docSection.Schemas)
                {
                    foreach (DocEntity docEnt in docSchema.Entities)
                    {
                        if (docEnt.BaseDefinition == docEntity.Name)
                        {
                            if (included == null || included.ContainsKey(docEnt))
                            {
                                hierarchy.Add(docEnt, true);
                            }
                        }
                    }
                }
            }

            return CreateInheritanceDiagram(docProject, hierarchy, docRoot, docEntity, font, map);
        }
Exemple #10
0
        private static string FormatReference(DocProject docProject, string value)
        {
            if (value == null)
                return null;

            StringBuilder sb = new StringBuilder();
            string[] parts = value.Split('\\');
            foreach (string part in parts)
            {
                string[] tokens = part.Split('.');
                if (tokens.Length > 0)
                {
                    sb.Append("\\");

                    DocDefinition docToken = docProject.GetDefinition(tokens[0]);
                    if (docToken != null)
                    {
                        DocSchema docSchema = docProject.GetSchemaOfDefinition(docToken);
                        string relative = @"../../";
                        string hyperlink = relative + docSchema.Name.ToLower() + @"/lexical/" + docToken.Name.ToLower() + ".htm";
                        string format = "<a href=\"" + hyperlink + "\">" + tokens[0] + "</a>";
                        sb.Append(format);
                    }

                    if (tokens.Length > 1)
                    {
                        sb.Append(".");
                        sb.Append(tokens[1]);
                    }

                    sb.Append("<br>");
                }
            }

            return sb.ToString();
        }
Exemple #11
0
        /// <summary>
        /// Loads all content from a folder hierarchy (overlaying anything already existing)
        /// </summary>
        /// <param name="project"></param>
        /// <param name="path"></param>
        public static void LoadFolder(DocProject project, string path)
        {
            // get all files within folder hierarchy
            string pathSchema         = path + @"\schemas";
            IEnumerable <string> en   = System.IO.Directory.EnumerateFiles(pathSchema, "*.cs", System.IO.SearchOption.AllDirectories);
            List <string>        list = new List <string>();

            foreach (string s in en)
            {
                list.Add(s);
            }
            string[] files = list.ToArray();

            Dictionary <string, string> options = new Dictionary <string, string> {
                { "CompilerVersion", "v4.0" }
            };

            Microsoft.CSharp.CSharpCodeProvider        prov  = new Microsoft.CSharp.CSharpCodeProvider(options);
            System.CodeDom.Compiler.CompilerParameters parms = new System.CodeDom.Compiler.CompilerParameters();
            parms.GenerateInMemory   = true;
            parms.GenerateExecutable = false;
            parms.ReferencedAssemblies.Add("System.dll");
            parms.ReferencedAssemblies.Add("System.Core.dll");
            parms.ReferencedAssemblies.Add("System.ComponentModel.dll");
            parms.ReferencedAssemblies.Add("System.ComponentModel.DataAnnotations.dll");
            parms.ReferencedAssemblies.Add("System.Data.dll");
            parms.ReferencedAssemblies.Add("System.Runtime.Serialization.dll");
            parms.ReferencedAssemblies.Add("System.Xml.dll");

            System.CodeDom.Compiler.CompilerResults results = prov.CompileAssemblyFromFile(parms, files);
            System.Reflection.Assembly assem = results.CompiledAssembly;

            LoadAssembly(project, assem);

            // EXPRESS rules (eventually in C#, though .exp file snippets for now)
            en = System.IO.Directory.EnumerateFiles(pathSchema, "*.exp", System.IO.SearchOption.AllDirectories);
            foreach (string file in en)
            {
                string name = Path.GetFileNameWithoutExtension(file);
                string expr = null;
                using (StreamReader readExpr = new StreamReader(file, Encoding.UTF8))
                {
                    if (name.Contains('-'))
                    {
                        // where rule
                        expr = readExpr.ReadToEnd();
                    }
                    else
                    {
                        // function: skip first and last lines
                        readExpr.ReadLine();

                        StringBuilder sbExpr = new StringBuilder();
                        while (!readExpr.EndOfStream)
                        {
                            string line = readExpr.ReadLine();
                            if (!readExpr.EndOfStream)
                            {
                                sbExpr.AppendLine(line);
                            }
                        }

                        expr = sbExpr.ToString();
                    }
                }

                if (name.Contains('-'))
                {
                    // where rule
                    string[] parts = name.Split('-');
                    if (parts.Length == 2)
                    {
                        DocWhereRule docWhere = new DocWhereRule();
                        docWhere.Name       = parts[1];
                        docWhere.Expression = expr;

                        DocDefinition docDef = project.GetDefinition(parts[0]);
                        if (docDef is DocEntity)
                        {
                            DocEntity docEnt = (DocEntity)docDef;
                            docEnt.WhereRules.Add(docWhere);
                        }
                        else if (docDef is DocDefined)
                        {
                            DocDefined docEnt = (DocDefined)docDef;
                            docEnt.WhereRules.Add(docWhere);
                        }
                        else if (docDef == null)
                        {
                            //... global rule...
                        }
                    }
                }
                else
                {
                    // function
                    string schema = Path.GetDirectoryName(file);
                    schema = Path.GetDirectoryName(schema);
                    schema = Path.GetFileName(schema);
                    DocSchema docSchema = project.GetSchema(schema);
                    if (docSchema != null)
                    {
                        DocFunction docFunction = new DocFunction();
                        docSchema.Functions.Add(docFunction);
                        docFunction.Name       = name;
                        docFunction.Expression = expr;
                    }
                }
            }

            // now, hook up html documentation
            en = System.IO.Directory.EnumerateFiles(pathSchema, "*.htm", System.IO.SearchOption.AllDirectories);
            foreach (string file in en)
            {
                string    name   = Path.GetFileNameWithoutExtension(file);
                DocObject docObj = null;
                if (name == "schema")
                {
                    string schema = Path.GetDirectoryName(file);
                    schema = Path.GetFileName(schema);
                    docObj = project.GetSchema(schema);
                }
                else if (name.Contains('-'))
                {
                    // where rule
                    string[] parts = name.Split('-');
                    if (parts.Length == 2)
                    {
                        DocDefinition docDef = project.GetDefinition(parts[0]);
                        if (docDef is DocEntity)
                        {
                            DocEntity docEnt = (DocEntity)docDef;
                            foreach (DocWhereRule docWhereRule in docEnt.WhereRules)
                            {
                                if (docWhereRule.Name.Equals(parts[1]))
                                {
                                    docObj = docWhereRule;
                                    break;
                                }
                            }
                        }
                        else if (docDef is DocDefined)
                        {
                            DocDefined docEnt = (DocDefined)docDef;
                            foreach (DocWhereRule docWhereRule in docEnt.WhereRules)
                            {
                                if (docWhereRule.Name.Equals(parts[1]))
                                {
                                    docObj = docWhereRule;
                                    break;
                                }
                            }
                        }
                    }
                }
                else
                {
                    docObj = project.GetDefinition(name);

                    if (docObj == null)
                    {
                        docObj = project.GetFunction(name);
                    }
                }

                if (docObj != null)
                {
                    using (StreamReader readHtml = new StreamReader(file, Encoding.UTF8))
                    {
                        docObj.Documentation = readHtml.ReadToEnd();
                    }
                }
            }

            // load schema diagrams
            en = System.IO.Directory.EnumerateFiles(pathSchema, "*.svg", System.IO.SearchOption.AllDirectories);
            foreach (string file in en)
            {
                string schema = Path.GetDirectoryName(file);
                schema = Path.GetFileName(schema);

                DocSchema docSchema = project.GetSchema(schema);
                if (docSchema != null)
                {
                    using (IfcDoc.Schema.SVG.SchemaSVG schemaSVG = new IfcDoc.Schema.SVG.SchemaSVG(file, docSchema, project, DiagramFormat.UML))
                    {
                        schemaSVG.Load();
                    }
                }
            }

            // psets, qsets
            //...

            // exchanges
            en = System.IO.Directory.EnumerateFiles(path, "*.mvdxml", System.IO.SearchOption.AllDirectories);
            foreach (string file in en)
            {
                IfcDoc.Schema.MVD.SchemaMVD.Load(project, file);
            }

            // examples
            string pathExamples = path + @"\examples";

            if (Directory.Exists(pathExamples))
            {
                en = System.IO.Directory.EnumerateFiles(pathExamples, "*.htm", SearchOption.TopDirectoryOnly);
                foreach (string file in en)
                {
                    DocExample docExample = new DocExample();
                    docExample.Name = Path.GetFileNameWithoutExtension(file);
                    project.Examples.Add(docExample);

                    using (StreamReader reader = new StreamReader(file))
                    {
                        docExample.Documentation = reader.ReadToEnd();
                    }

                    string dirpath = file.Substring(0, file.Length - 4);
                    if (Directory.Exists(dirpath))
                    {
                        IEnumerable <string> suben = System.IO.Directory.EnumerateFiles(dirpath, "*.ifc", SearchOption.TopDirectoryOnly);
                        foreach (string ex in suben)
                        {
                            DocExample docEx = new DocExample();
                            docEx.Name = Path.GetFileNameWithoutExtension(ex);
                            docExample.Examples.Add(docEx);

                            // read the content of the file
                            using (FileStream fs = new FileStream(ex, FileMode.Open, FileAccess.Read))
                            {
                                docEx.File = new byte[fs.Length];
                                fs.Read(docEx.File, 0, docEx.File.Length);
                            }

                            // read documentation
                            string exdoc = ex.Substring(0, ex.Length - 4) + ".htm";
                            if (File.Exists(exdoc))
                            {
                                using (StreamReader reader = new StreamReader(exdoc))
                                {
                                    docEx.Documentation = reader.ReadToEnd();
                                }
                            }
                        }
                    }
                }
            }

            // localization
            en = System.IO.Directory.EnumerateFiles(path, "*.txt", System.IO.SearchOption.AllDirectories);
            foreach (string file in en)
            {
                using (FormatCSV format = new FormatCSV(file))
                {
                    try
                    {
                        format.Instance = project;
                        format.Load();
                    }
                    catch
                    {
                    }
                }
            }
        }
Exemple #12
0
        /// <summary>
        /// Draws entity and recurses.
        /// </summary>
        /// <param name="g">Graphics device.</param>
        /// <param name="lane">Horizontal lane for which to draw the entity.</param>
        /// <param name="lanes">List of lanes left-to-right.</param>
        /// <param name="docEntity">The entity to draw.</param>
        /// <param name="docView">The model view for which to draw the entity.</param>
        /// <param name="docTemplate">The template to draw.</param>
        /// <param name="docRule">Optional rule for recursing.</param>
        /// <param name="map">Map of definitions.</param>
        /// <param name="layout">Optional layout to receive rectangles for building image map</param>
        /// <param name="docProject">Required project.</param>
        /// <param name="instance">Optional instance where included or missing attributes are highlighted.</param>
        private static void DrawEntity(
            Graphics g, 
            int lane, 
            List<int> lanes, 
            DocEntity docEntity,
            DocModelView docView,
            DocTemplateDefinition docTemplate, 
            DocModelRuleEntity docRule, 
            Dictionary<string, DocObject> map, 
            Dictionary<Rectangle, DocModelRule> layout,
            DocProject docProject,
            DocSchema docSchema,
            object instance)
        {
            List<DocAttribute> listAttr = new List<DocAttribute>();
            BuildAttributeList(docEntity, listAttr, map);

            while(lanes.Count < lane + 1)
            {
                int miny = 0;
                if (lanes.Count > lane)
                {
                    miny = lanes[lane];
                }

                lanes.Add(miny);
            }

            int x = lane * CX + FormatPNG.Border;
            int y = lanes[lane] + FormatPNG.Border;

            if (g != null)
            {
                Brush brush = Brushes.Black;

                if (instance != null)
                {
                    brush = Brushes.Red;

                    if (instance is System.Collections.IList)
                    {
                        string typename = instance.GetType().Name;

                        // keep going until matching instance
                        System.Collections.IList list = (System.Collections.IList)instance;
                        foreach (object member in list)
                        {
                            string membertypename = member.GetType().Name;
                            DocEntity docType = docProject.GetDefinition(membertypename) as DocEntity;
                            while (docType != null)
                            {
                                if (docType == docEntity)
                                {
                                    brush = Brushes.Lime;
                                    instance = member;
                                    break;
                                }

                                docType = docProject.GetDefinition(docType.BaseDefinition) as DocEntity;
                            }

                            if (brush != Brushes.Red)
                                break;
                        }
                    }
                    else
                    {
                        string typename = instance.GetType().Name;
                        DocEntity docType = docProject.GetDefinition(typename) as DocEntity;
                        while (docType != null)
                        {
                            if (docType == docEntity)
                            {
                                brush = Brushes.Lime;
                                break;
                            }

                            docType = docProject.GetDefinition(docType.BaseDefinition) as DocEntity;
                        }
                    }
                }
                else if (docEntity.IsAbstract())
                {
                    brush = Brushes.Gray;
                }
                else
                {
                    brush = Brushes.Black;
                }
                g.FillRectangle(brush, x, y, CX - DX, CY);
                g.DrawRectangle(Pens.Black, x, y, CX - DX, CY);
                using (Font font = new Font(FontFamily.GenericSansSerif, 8.0f, FontStyle.Bold))
                {
                    g.DrawString(docEntity.Name, font, Brushes.White, x, y);
                }

                if (docRule != null && docRule.Identification == "Value")
                {
                    // mark rule serving as default value
                    g.FillEllipse(Brushes.Green, new Rectangle(x + CX - DX - CY, y, CY, CY));
                }

                g.DrawRectangle(Pens.Black, x, y + CY, CX - DX, CY * listAttr.Count);
                using (Font font = new Font(FontFamily.GenericSansSerif, 8.0f, FontStyle.Regular))
                {
                    for (int iAttr = 0; iAttr < listAttr.Count; iAttr++)
                    {
                        DocAttribute docAttr = listAttr[iAttr];

                        string display = docAttr.GetAggregationExpression();
                        brush = Brushes.Black;
                        if (docAttr.Inverse != null)
                        {
                            brush = Brushes.Gray;
                        }
                        if(String.IsNullOrEmpty(display))
                        {
                            if(docAttr.IsOptional)
                            {
                                display = "[0:1]";
                            }
                            else
                            {
                                display = "[1:1]";
                            }
                        }

                        g.DrawString(docAttr.Name, font, brush, x, y + CY * (iAttr + 1));
                        using (StringFormat fmt = new StringFormat())
                        {
                            fmt.Alignment = StringAlignment.Far;
                            g.DrawString(display, font, brush, new RectangleF(x, y + CY * (iAttr + 1), CX - DX, CY), fmt);
                        }

                    }
                }
            }

            // record rectangle
            if (layout != null)
            {
                layout.Add(new Rectangle(x, y, CX - DX, CY + CY * listAttr.Count), docRule);
            }

            SortedList<int, List<DocModelRuleAttribute>> mapAttribute = new SortedList<int, List<DocModelRuleAttribute>>();
            Dictionary<DocModelRuleAttribute, DocTemplateDefinition> mapTemplate = new Dictionary<DocModelRuleAttribute,DocTemplateDefinition>();
            if (docRule != null && docRule.Rules != null)
            {
                // map inner rules

                // sort
                foreach (DocModelRule rule in docRule.Rules)
                {
                    if (rule is DocModelRuleAttribute)
                    {
                        DocModelRuleAttribute ruleAttribute = (DocModelRuleAttribute)rule;
                        for (int i = 0; i < listAttr.Count; i++)
                        {
                            if (listAttr[i].Name.Equals(ruleAttribute.Name))
                            {
                                // found it
                                if (!mapAttribute.ContainsKey(i))
                                {
                                    mapAttribute.Add(i, new List<DocModelRuleAttribute>());
                                }

                                mapAttribute[i].Add(ruleAttribute);
                                break;
                            }
                        }
                    }
                }
            }
            else if (docTemplate != null)
            {
                if (docTemplate.Rules != null)
                {
                    foreach (DocModelRuleAttribute ruleAttribute in docTemplate.Rules)
                    {
                        for (int i = 0; i < listAttr.Count; i++)
                        {
                            if (listAttr[i].Name != null && listAttr[i].Name.Equals(ruleAttribute.Name))
                            {
                                // found it
                                //iAttr = i;
                                if (!mapAttribute.ContainsKey(i))
                                {
                                    mapAttribute.Add(i, new List<DocModelRuleAttribute>());
                                }
                                mapAttribute[i].Add(ruleAttribute);
                                break;
                            }
                        }
                    }
                }
            }
            else
            {
                // map each use definition at top-level

                // build list of inherited views
                List<DocModelView> listViews = new List<DocModelView>();
                DocModelView docBaseView = docView;
                while (docBaseView != null)
                {
                    listViews.Add(docBaseView);

                    if (!String.IsNullOrEmpty(docBaseView.BaseView))
                    {
                        Guid guidBase = Guid.Parse(docBaseView.BaseView);
                        if (guidBase != docBaseView.Uuid)
                        {
                            docBaseView = docProject.GetView(guidBase);
                        }
                        else
                        {
                            docBaseView = null;
                        }
                    }
                    else
                    {
                        docBaseView = null;
                    }
                }

                // build from inherited entities too

                List<DocTemplateDefinition> listTemplates = new List<DocTemplateDefinition>(); // keep track of templates so we don't repeat at supertypes
                List<DocTemplateDefinition> listSuppress = new List<DocTemplateDefinition>(); // list of templates that are suppressed

                DocEntity docEntitySuper = docEntity;
                while(docEntitySuper != null)
                {

                    foreach (DocModelView docEachView in docProject.ModelViews)
                    {
                        if (docView == null || listViews.Contains(docEachView))
                        {
                            foreach (DocConceptRoot docRoot in docEachView.ConceptRoots)
                            {
                                if (docRoot.ApplicableEntity == docEntitySuper)
                                {
                                    foreach (DocTemplateUsage docUsage in docRoot.Concepts)
                                    {
                                        if (docUsage.Definition != null && docUsage.Definition.Rules != null && !listTemplates.Contains(docUsage.Definition) && !listSuppress.Contains(docUsage.Definition))
                                        {
                                            if (docUsage.Suppress)
                                            {
                                                listSuppress.Add(docUsage.Definition);
                                            }
                                            else
                                            {

                                                listTemplates.Add(docUsage.Definition);

                                                foreach (DocModelRuleAttribute ruleAttribute in docUsage.Definition.Rules)
                                                {
                                                    for (int i = 0; i < listAttr.Count; i++)
                                                    {
                                                        if (listAttr[i].Name.Equals(ruleAttribute.Name))
                                                        {
                                                            // found it
                                                            if (!mapAttribute.ContainsKey(i))
                                                            {
                                                                mapAttribute.Add(i, new List<DocModelRuleAttribute>());
                                                            }

                                                            mapAttribute[i].Add(ruleAttribute);
                                                            if (!mapTemplate.ContainsKey(ruleAttribute))
                                                            {
                                                                mapTemplate.Add(ruleAttribute, docUsage.Definition);
                                                            }
                                                            break;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    DocObject docTest = null;
                    if (docEntitySuper.BaseDefinition != null && map.TryGetValue(docEntitySuper.BaseDefinition, out docTest))
                    {
                        docEntitySuper = docTest as DocEntity;
                    }
                    else
                    {
                        docEntitySuper = null;
                    }
                }
            }

            int offset = -mapAttribute.Values.Count / 2;

            DocTemplateDefinition lastTemplate = null;
            foreach (List<DocModelRuleAttribute> listSort in mapAttribute.Values)
            {
                if (docRule == null && docTemplate == null)
                {
                    // offset all lanes
                    int maxlane = 0;
                    for (int i = 1; i < lanes.Count; i++)
                    {
                        if (lanes[i] > maxlane)
                        {
                            maxlane = lanes[i];
                        }
                    }

                    for (int i = 1; i < lanes.Count; i++)
                    {
                        lanes[i] = maxlane;
                    }
                }

                foreach (DocModelRuleAttribute ruleAttributeSort in listSort)
                {
                    // indicate each template
                    DocTemplateDefinition eachTemplate = null;
                    if (mapTemplate.TryGetValue(ruleAttributeSort, out eachTemplate))
                    {
                        // offset for use definition
                        int minlan = 0;
                        for (int i = 1; i < lanes.Count; i++)
                        {
                            if (eachTemplate != lastTemplate)
                            {
                                lanes[i] += CY * 2;
                            }

                            if (lanes[i] > minlan)
                            {
                                minlan = lanes[i];
                            }
                        }

                        // verify this...
                        for (int i = 1; i < lanes.Count; i++)
                        {
                            if (lanes[i] < minlan)
                            {
                                lanes[i] = minlan;
                            }
                        }

                        if (g != null && eachTemplate != lastTemplate)
                        {
                            using (Font font = new Font(FontFamily.GenericSansSerif, 8.0f, FontStyle.Italic))
                            {
                                g.DrawString(eachTemplate.Name, font, Brushes.Gray, CX + FormatPNG.Border, lanes[1] - CY * 2 + FormatPNG.Border);
                            }
                            int lineY = lanes[1] - CY * 2 + FormatPNG.Border;
                            g.DrawLine(Pens.Gray, CX + FormatPNG.Border, lineY, 1920, lineY);
                        }

                        lastTemplate = eachTemplate;
                    }

                    DrawAttribute(g, lane, lanes, docEntity, docView, ruleAttributeSort, map, offset, layout, docProject, docSchema, instance as SEntity);
                }
                offset++;
            }

            // increment lane offset
            int minlane = y + CY * (listAttr.Count + 2);
            if (lanes[lane] < minlane)
            {
                lanes[lane] = minlane;
            }
        }
        public static void GenerateDocumentation(
            DocProject docProject, 
            string path,
            Dictionary<long, SEntity> instances,
            Dictionary<string, DocObject> mapEntity, 
            Dictionary<string, string> mapSchema, 
            DocModelView[] views,
            string[] locales,
            BackgroundWorker worker, 
            FormProgress formProgress)
        {
            // copy over static content * if it doesn't already exist *
            string pathContent = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
            if (pathContent.EndsWith(@"bin\x86\Debug")) // debugging
            {
                pathContent = System.IO.Path.GetDirectoryName(pathContent);
                pathContent = System.IO.Path.GetDirectoryName(pathContent);
                pathContent = System.IO.Path.GetDirectoryName(pathContent);
            }
            pathContent = System.IO.Path.Combine(pathContent, "content");

            if(!System.IO.Directory.Exists(path))
            {
                System.IO.Directory.CreateDirectory(path);
            }

            CopyFiles(pathContent, path);

            System.IO.Directory.CreateDirectory(Properties.Settings.Default.OutputPath + "\\diagrams");

            Dictionary<string, DocPropertyEnumeration> mapPropEnum = new Dictionary<string, DocPropertyEnumeration>();
            foreach (DocSection docSection in docProject.Sections)
            {
                foreach (DocSchema docSchema in docSection.Schemas)
                {
                    foreach (DocPropertyEnumeration docEnum in docSchema.PropertyEnums)
                    {
                        mapPropEnum.Add(docEnum.Name, docEnum);
                    }
                }
            }

            Dictionary<DocObject, string> mapNumber = new Dictionary<DocObject, string>(); // map items to section (e.g. "1.1.1.1")

            string pathSchema = path + @"\schema";

            // count progress
            int progressTotal = docProject.Sections.Count + docProject.Annexes.Count + 2;
            formProgress.SetProgressTotal(progressTotal);

            int progressCurrent = 0;


            // build list of locales in use
            SortedList<string, string> listLocale = new SortedList<string, string>();
            foreach (DocObject eachobj in mapEntity.Values)
            {
                if (eachobj.Localization != null)
                {
                    foreach (DocLocalization doclocal in eachobj.Localization)
                    {
                        // only deal with languages, not regions
                        if (doclocal.Locale != null && doclocal.Locale.Length >= 2)
                        {
                            string language = doclocal.Locale.Substring(0, 2);

                            if (!listLocale.ContainsKey(language))
                            {
                                listLocale.Add(language, doclocal.Locale);
                            }
                        }
                    }
                }
            }

            // build filter
            Dictionary<DocObject, bool> included = null;
            if (views != null)
            {
                included = new Dictionary<DocObject, bool>();
                foreach (DocModelView docEachView in views)
                {
                    docProject.RegisterObjectsInScope(docEachView, included);
                }
            }

            Dictionary<DocObject, bool>[] dictionaryViews = new Dictionary<DocObject, bool>[docProject.ModelViews.Count];
            for (int i = 0; i < docProject.ModelViews.Count; i++)
            {
                DocModelView docView = docProject.ModelViews[i];
                if (included != null && included.ContainsKey(docView))
                {
                    dictionaryViews[i] = new Dictionary<DocObject, bool>();
                    docProject.RegisterObjectsInScope(docProject.ModelViews[i], dictionaryViews[i]);
                }
            }


            DocEntity docEntityRoot = docProject.GetDefinition("IfcRoot") as DocEntity;

            // upper contents page
            string pathHeaderFrame = path + "\\content.htm";
            using (FormatHTM htmProp = new FormatHTM(pathHeaderFrame, mapEntity, mapSchema, included))
            {
                DocAnnotation docCover = docProject.Annotations[0];
                string projectname = docCover.Code;
                if (!String.IsNullOrEmpty(docCover.Version))
                {
                    projectname += " - " + docCover.Version;
                }
                if (!String.IsNullOrEmpty(docCover.Status))
                {
                    projectname += " [" + docCover.Status + "]";
                }
                string projectcopy = docCover.Copyright;

                htmProp.Write(
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n" + 
"<html lang=\"en\">" + 
  "<head>" +
    "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=us-ascii\">" +
    "<link rel=\"STYLESHEET\" href=\"./ifc-styles.css\" type=\"text/css\">" +
  "</head>" +
  "<body class=\"image\">" +
    "<div class=\"content\">" +
      "<table summary=\"title\" class=\"content\" frameborder=\"0\">" +
        "<tr>" +
          "<td>" +
            "<p class=\"td\">" +
              "<b>" + projectname + "</b>" +
            "</p>" +
          "</td>" +
          "<td>" +
            "<p class=\"td right\">" +
              "<b>" + projectcopy + "</b>" +
            "</p>" +
          "</td>" +
        "</tr>" +
      "</table>" +
      "<table summary=\"short table of content\" class=\"content\">" +
        "<col width=\"15%\">" +
        "<col width=\"25%\">" +
        "<col width=\"20%\">" +
        "<col width=\"25%\">" +
        "<col width=\"15%\">" +
        "<tr>" +
          "<td class=\"content\">" +
            "<ol class=\"td none\">" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"cover.htm\" target=\"info\">" + docProject.Annotations[0].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"toc.htm\" target=\"info\">" + docProject.Annotations[1].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"foreword.htm\" target=\"info\">" + docProject.Annotations[2].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"introduction.htm\" target=\"info\">" + docProject.Annotations[3].Name + "</a></li>" +
            "</ol>" +
          "</td>" +
          "<td class=\"content\">" +
            "<ol class=\"td num\">" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"schema/chapter-1.htm\" target=\"info\">" + docProject.Sections[0].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"schema/chapter-2.htm\" target=\"info\">" + docProject.Sections[1].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"schema/chapter-3.htm\" target=\"info\">" + docProject.Sections[2].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"schema/chapter-4.htm\" target=\"info\">" + docProject.Sections[3].Name + "</a></li>" +
            "</ol>" +
          "</td>" +
          "<td class=\"content\">" +
            "<ol class=\"td num\" start=\"5\">" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"schema/chapter-5.htm\" target=\"info\">" + docProject.Sections[4].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"schema/chapter-6.htm\" target=\"info\">" + docProject.Sections[5].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"schema/chapter-7.htm\" target=\"info\">" + docProject.Sections[6].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"schema/chapter-8.htm\" target=\"info\">" + docProject.Sections[7].Name + "</a></li>" +
            "</ol>" +
          "</td>" +
          "<td class=\"content\">" +
            "<ol class=\"td alpha\">" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"annex/annex-a.htm\" target=\"info\">" + docProject.Annexes[0].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"annex/annex-b.htm\" target=\"info\">" + docProject.Annexes[1].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"annex/annex-c.htm\" target=\"info\">" + docProject.Annexes[2].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"annex/annex-d.htm\" target=\"info\">" + docProject.Annexes[3].Name + "</a></li>" +
            "</ol>" +
          "</td>" +
          "<td class=\"content\">" +
            "<ol class=\"td alpha\" start=\"5\">" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"annex/annex-e.htm\" target=\"info\">" + docProject.Annexes[4].Name + "</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"annex/annex-f.htm\" target=\"info\">" + docProject.Annexes[5].Name + "</a></li>" +
            "</ol>" +
            "<ol class=\"td none\">" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"bibliography.htm\" target=\"info\">Bibliography</a></li>" +
              "<li class=\"std\"><a class=\"listing-link\" href=\"doc_index.htm\" target=\"info\">Index</a></li>" +
            "</ol>" +
          "</td>" +
        "</tr>" +
      "</table>" +
    "</div>" +
  "</body>" +
"</html>");
            }

            // cover

            using (FormatHTM htmSection = new FormatHTM(path + "\\cover.htm", mapEntity, mapSchema, included))
            {
                DocAnnotation docAnnotation = docProject.Annotations[0];
                htmSection.WriteHeader(docAnnotation.Name, 0);
                htmSection.Write(
                    "\r\n" +
                    "<script type=\"text/javascript\">\r\n" +
                    "<!--\r\n" +
                    "    parent.index.location.replace(\"credits.htm\");\r\n" +
                    "//-->\r\n" +
                    "</script>\r\n");
                htmSection.WriteLine(docAnnotation.Documentation);
                htmSection.WriteFooter(Properties.Settings.Default.Footer);
            }

            using (FormatHTM htmSection = new FormatHTM(path + "\\foreword.htm", mapEntity, mapSchema, included))
            {
                DocAnnotation docAnnotation = docProject.Annotations[2];
                htmSection.WriteHeader(docAnnotation.Name, 0);
                htmSection.Write(
                    "\r\n" +
                    "<script type=\"text/javascript\">\r\n" +
                    "<!--\r\n" +
                    "    parent.index.location.replace(\"blank.htm\");\r\n" +
                    "//-->\r\n" +
                    "</script>\r\n");

                htmSection.WriteLine("      <h1 class=\"std\">" + docAnnotation.Name + "</h1>");
                htmSection.WriteLine(docAnnotation.Documentation);
                htmSection.WriteLinkTo("foreword", 0);
                htmSection.WriteFooter(Properties.Settings.Default.Footer);
            }

            using (FormatHTM htmSection = new FormatHTM(path + "\\introduction.htm", mapEntity, mapSchema, included))
            {
                DocAnnotation docAnnotation = docProject.Annotations[3];
                htmSection.WriteHeader(docAnnotation.Name, 0);
                htmSection.Write(
                    "\r\n" +
                    "<script type=\"text/javascript\">\r\n" +
                    "<!--\r\n" +
                    "    parent.index.location.replace(\"blank.htm\");\r\n" +
                    "//-->\r\n" +
                    "</script>\r\n");

                htmSection.WriteLine("      <h1 class=\"std\">" + docAnnotation.Name + "</h1>");
                htmSection.WriteLine(docAnnotation.Documentation);
                htmSection.WriteLinkTo("introduction", 0);
                htmSection.WriteFooter(Properties.Settings.Default.Footer);
            }

#if false
            Dictionary<Rectangle, DocEntity> mapRectangle = new Dictionary<Rectangle, DocEntity>();
            using (Image imgDiagram = FormatPNG.CreateInheritanceDiagram(docProject, included, docEntityRoot, new Font(FontFamily.GenericSansSerif, 8.0f), mapRectangle))
            {
                imgDiagram.Save(path + @"\img\cover.png");
                    
                using (FormatHTM htmCover = new FormatHTM(path + @"\cover.htm", mapEntity, mapSchema, included))
                {
                    htmCover.WriteHeader(String.Empty, 1);

                    htmCover.WriteLine("<img src=\"" + path + "/img/cover.png\" usemap=\"#f\"/>");
                    htmCover.WriteLine("<map name=\"f\">");

                    foreach (Rectangle rc in mapRectangle.Keys)
                    {
                        DocEntity docEntref = mapRectangle[rc];
                        DocSchema docEntsch = docProject.GetSchemaOfDefinition(docEntref);

                        string hyperlink = "./schema/" + docEntsch.Name.ToLower() + "/lexical/" + docEntref.Name.ToLower() + ".htm";
                        htmCover.WriteLine("<area shape=\"rect\" coords=\"" + rc.Left + "," + rc.Top + "," + rc.Right + "," + rc.Bottom + "\" href=\"" + hyperlink + "\" alt=\"" + docEntref.Name + "\" />");
                    }
                    htmCover.WriteLine("</map>");


                    htmCover.WriteFooter(String.Empty);
                }
            }
#endif

            // NEW: property set index -- build index
            SortedList<string, SortedList<string, DocPropertySet>> mapProperty = new SortedList<string, SortedList<string, DocPropertySet>>();
            foreach (DocSection docSection in docProject.Sections)
            {
                foreach (DocSchema docSchema in docSection.Schemas)
                {
                    foreach (DocPropertySet docPset in docSchema.PropertySets)
                    {
                        if (included == null || included.ContainsKey(docPset))
                        {
                            // include locales
                            foreach (DocLocalization doclocal in docPset.Localization)
                            {
                                // only deal with languages, not regions
                                if (doclocal.Locale != null && doclocal.Locale.Length >= 2)
                                {
                                    string language = doclocal.Locale.Substring(0, 2);

                                    if (!listLocale.ContainsKey(language))
                                    {
                                        listLocale.Add(language, doclocal.Locale);
                                    }
                                }
                            }


                            foreach (DocProperty docProp in docPset.Properties)
                            {
                                string datatype = docProp.PrimaryDataType;
                                if (datatype == null)
                                {
                                    datatype = "IfcLabel"; // enumerations
                                }

                                string match = docProp.Name + " (" + docProp.PropertyType.ToString() + "/" + datatype.ToString() + ")";

                                SortedList<string, DocPropertySet> mapPset = null;
                                if (!mapProperty.TryGetValue(match, out mapPset))
                                {
                                    mapPset = new SortedList<string, DocPropertySet>();
                                    mapProperty.Add(match, mapPset);
                                }

                                mapPset.Add(docPset.Name, docPset);


                                // include locales
                                foreach (DocLocalization doclocal in docProp.Localization)
                                {
                                    // only deal with languages, not regions
                                    if (doclocal.Locale != null && doclocal.Locale.Length >= 2)
                                    {
                                        string language = doclocal.Locale.Substring(0, 2);

                                        if (!listLocale.ContainsKey(language))
                                        {
                                            listLocale.Add(language, doclocal.Locale);
                                        }
                                    }
                                }

                            }
                        }
                    }
                }
            }

            // now format listing of properties
            StringBuilder sbProperties = new StringBuilder();
            foreach (string nameProp in mapProperty.Keys)
            {
                sbProperties.Append("<li>");
                sbProperties.Append(nameProp);

                sbProperties.Append("<ul>");
                SortedList<string, DocPropertySet> mapPset = mapProperty[nameProp];

                foreach (DocPropertySet pset in mapPset.Values)
                {
                    string proplinkurl = "../../schema/" + mapSchema[pset.Name].ToLower() + "/pset/" + pset.Name.ToLower() + ".htm";

                    sbProperties.Append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
                    sbProperties.Append("<a class=\"listing-link\" href=\"");
                    sbProperties.Append(proplinkurl);
                    sbProperties.Append("\">");
                    sbProperties.Append(pset.Name);
                    sbProperties.Append("</a><br/>");
                }

                sbProperties.Append("</ul></li>");
            }
            string pathProps = path + @"/annex/annex-b/alphabeticalorder_properties.htm";
            using (FormatHTM htmProp = new FormatHTM(pathProps, mapEntity, mapSchema, included))
            {
                htmProp.WriteHeader("Properties", 2);

                htmProp.WriteLine("<h2 class=\"annex\">Individual Properties (" + mapProperty.Count + ")</h2>");
                htmProp.WriteLine("<ul class=\"std\">");

                htmProp.WriteLine(sbProperties.ToString());

                htmProp.WriteLine("</ul>");

                htmProp.WriteFooter(Properties.Settings.Default.Footer);
            }

            // capture figures and tables
            List<ContentRef> listFigures = new List<ContentRef>();
            List<ContentRef> listTables = new List<ContentRef>();

            // NEW: section 4 templates
            int iTemplate = 0;
            foreach (DocTemplateDefinition docTemplate in docProject.Templates)
            {
                if (included == null || included.ContainsKey(docTemplate))
                {
                    iTemplate++;
                    int[] indexpath = new int[] { 4, iTemplate };
                    GenerateTemplate(docProject, docTemplate, mapEntity, mapSchema, included, indexpath, listFigures, listTables);
                }
            }

            // NEW: model view definitions
            int iView = 0;
            if (Properties.Settings.Default.ConceptTables)
            {
                foreach (DocModelView docProjectModelView in docProject.ModelViews)
                {
                    if (included == null || included.ContainsKey(docProjectModelView))
                    {
                        iView++;
                        string pathTemplate = pathSchema + @"\views\" + docProjectModelView.Name.Replace(' ', '-').ToLower() + "\\index.htm";
                        using (FormatHTM htmTemplate = new FormatHTM(pathTemplate, mapEntity, mapSchema, included))
                        {
                            htmTemplate.WriteHeader(docProjectModelView.Name, 1, iView, 0, 0, Properties.Settings.Default.Header);
                            htmTemplate.WriteScript(1, iView, 0, 0);
                            {
                                string indexer = "1." + iView.ToString();
                                string tag = "h3";
                                string id = docProjectModelView.Name.ToLower();
                                htmTemplate.WriteLine("<" + tag + "><a id=\"" + id + "\" name=\"" + id + "\">" + indexer + " " + docProjectModelView.Name + "</a></" + tag + ">");

                                // write table of status for MVD
                                htmTemplate.WriteLine("<table class=\"gridtable\">");
                                htmTemplate.WriteLine("<tr><th>Code</th><th>Version</th><th>Status</th><th>Author</th><th>Copyright</th></tr>");
                                htmTemplate.WriteLine("<tr><td>" + docProjectModelView.Code + "</td><td>" + docProjectModelView.Version + "</td><td>" + docProjectModelView.Status + "</td><td>" + docProjectModelView.Author + "</td><td>" + docProjectModelView.Copyright + "</td></tr>");
                                htmTemplate.WriteLine("</table>");

                                string viewtable = FormatView(docProject, docProjectModelView, mapEntity, mapSchema);
                                htmTemplate.WriteDocumentationForISO(viewtable, docProjectModelView, false);
                            }

                            htmTemplate.WriteFooter(Properties.Settings.Default.Footer);
                        }
                        // each exchange... (or sub-page?)

                        if (Properties.Settings.Default.Requirement)
                        {
                            for (int iExchange = 0; iExchange < docProjectModelView.Exchanges.Count; iExchange++)
                            {
                                DocExchangeDefinition docExchange = docProjectModelView.Exchanges[iExchange];

                                string pathExchange = pathSchema + @"\views\" + MakeLinkName(docProjectModelView) + "\\" + MakeLinkName(docExchange) + ".htm";
                                using (FormatHTM htmExchange = new FormatHTM(pathExchange, mapEntity, mapSchema, included))
                                {
                                    htmExchange.WriteHeader(docExchange.Name, 1, iView, 0, 0, Properties.Settings.Default.Header);
                                    htmExchange.WriteScript(1, iView, iExchange + 1, 0);

                                    string indexer = "1." + iView.ToString() + "." + (iExchange + 1).ToString();
                                    string tag = "h4";
                                    string id = docExchange.Name.ToLower();

                                    htmExchange.WriteLine("<" + tag + "><a id=\"" + id + "\" name=\"" + id + "\">" + indexer + " " + docExchange.Name + "</a></" + tag + ">");
                                    htmExchange.WriteLine("<p class=\"std\">");

                                    string exchangedoc = FormatExchange(docProject, docProjectModelView, docExchange, mapEntity, mapSchema);
                                    htmExchange.WriteDocumentationForISO(exchangedoc, docExchange, false);
                                    htmExchange.WriteLine("</p>");
                                }

                                // icons for each exchange
                                if (docExchange.Icon != null)
                                {
                                    string pathIcon = path + @"\img\mvd-" + MakeLinkName(docExchange) + ".png";

                                    try
                                    {
                                        using (System.IO.FileStream fs = new System.IO.FileStream(pathIcon, System.IO.FileMode.Create))
                                        {
                                            fs.Write(docExchange.Icon, 0, docExchange.Icon.Length);
                                            fs.Close();
                                        }
                                    }
                                    catch
                                    {
                                    }
                                }
                            }
                        }
                    }
                }
            }

            string pathTOC = path + @"\toc.htm";
            using (FormatHTM htmTOC = new FormatHTM(pathTOC, mapEntity, mapSchema, included))
            {
                htmTOC.WriteHeader("Contents", 0);

                htmTOC.WriteLine("    <script type=\"text/javascript\">");
                htmTOC.WriteLine("        <!--");
                htmTOC.WriteLine("        parent.index.location = \"blank.htm\";");
                htmTOC.WriteLine("        parent.menu.location = \"content.htm\"");
                htmTOC.WriteLine("        -->");
                htmTOC.WriteLine("    </script>");

                htmTOC.WriteLine("      <h1 class=\"std\">Contents</h1>");

                htmTOC.WriteLine("<p>");

                // each section
                int iSection = 0;
                foreach (DocSection section in docProject.Sections)
                {
                    worker.ReportProgress(++progressCurrent, section);
                    if (worker.CancellationPending)
                        return;

                    iSection++;
                    using (FormatHTM htmSectionTOC = new FormatHTM(pathSchema + @"\toc-" + iSection.ToString() + ".htm", mapEntity, mapSchema, included))
                    {

                        htmSectionTOC.WriteLine(
                            "<html> \r\n" +
                            "<head> \r\n" +
                            "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"> \r\n" +
                            "<link rel=\"stylesheet\" type=\"text/css\" href=\"../ifc-styles.css\"> \r\n" +
                            "<title>Section Contents</title> \r\n" +
                            "</head> \r\n" +
                            "<body class=\"image\"> \r\n" +
                            "<div class=\"menu\">\r\n" +
                            "<table class=\"menu\" summary=\"Table of Contents\">\r\n");

                        htmTOC.WriteTOC(0, "<a class=\"listing-link\" href=\"schema/chapter-" + iSection.ToString() + ".htm\">" + iSection.ToString() + ". " + section.Name + "</a>");

                        mapNumber.Add(section, iSection.ToString() + ".");

                        htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + iSection + ". <a class=\"listing-link\" href=\"chapter-" + iSection + ".htm\" target=\"info\" >" + section.Name + "</a></td></tr>\r\n");

                        // write the section page
                        using (FormatHTM htmSection = new FormatHTM(pathSchema + @"\chapter-" + iSection.ToString() + @".htm", mapEntity, mapSchema, included))
                        {
                            htmSection.WriteHeader(section.Name, iSection - 1, 0, 0, 0, Properties.Settings.Default.Header);
                            htmSection.WriteScript(iSection, 0, 0, 0);
                            htmSection.WriteLine("<h1 class=\"num\" id=\"scope\">" + section.Name + "</h1>");

                            section.Documentation = UpdateNumbering(section.Documentation, listFigures, listTables, section);
                            htmSection.WriteDocumentationForISO(section.Documentation, section, Properties.Settings.Default.NoHistory);


                            if (iSection == 1)
                            {
                                if (Properties.Settings.Default.ConceptTables)
                                {
                                    int iModel = 0;
                                    foreach (DocModelView docModelView in docProject.ModelViews)
                                    {
                                        if (included == null || included.ContainsKey(docModelView))
                                        {
                                            iModel++;

                                            string htmllink = "<a class=\"listing-link\" href=\"views/" + MakeLinkName(docModelView) + "/index.htm\" target=\"info\">" +
                                                iSection.ToString() + "." + iModel.ToString() + " " + docModelView.Name + "</a>";
                                            htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"schema/views/" + MakeLinkName(docModelView) + "/index.htm\" >" +
                                                iSection.ToString() + "." + iModel.ToString() + " " + docModelView.Name + "</a>");
                                            htmSectionTOC.WriteLine("<tr><td>&nbsp;</td></tr>");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + htmllink + "</td></tr>");

                                            if (Properties.Settings.Default.Requirement)
                                            {
                                                int iExchange = 0;
                                                foreach (DocExchangeDefinition docExchange in docModelView.Exchanges)
                                                {
                                                    iExchange++;

                                                    htmllink = "<a class=\"listing-link\" href=\"views/" + MakeLinkName(docModelView) + "/" + MakeLinkName(docExchange) + ".htm\" target=\"info\">" +
                                                        iSection.ToString() + "." + iModel.ToString() + "." + iExchange.ToString() + " " + docExchange.Name + "</a>";

                                                    htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"schema/views/" + MakeLinkName(docModelView) + "/" + MakeLinkName(docExchange) + ".htm\" >" +
                                                        iSection.ToString() + "." + iModel.ToString() + "." + iExchange.ToString() + " " + docExchange.Name + "</a>");
                                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + htmllink + "</td></tr>");
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            else if (iSection == 2)
                            {
                                htmSection.WriteLine("<dl>");
                                if (docProject.NormativeReferences != null)
                                {
                                    foreach (DocReference docRef in docProject.NormativeReferences)
                                    {
                                        htmSection.WriteLine("<dt class=\"normativereference\"><a id=\"" + MakeLinkName(docRef) + "\">" + docRef.Name + "</a>, <i>" + docRef.Documentation + "</i></dt>");
                                        htmSection.WriteLine("<dd>&nbsp;</dd>");
                                    }
                                }
                                htmSection.WriteLine("</dl>");
                            }
                            else if (iSection == 3)
                            {
                                htmTOC.WriteTOC(0, "<a class=\"listing-link\" href=\"schema/chapter-3.htm#terms\">3.1 Terms and definitions</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">3.1 <a class=\"listing-link\" href=\"chapter-3.htm#terms\" target=\"info\" >Terms and definitions</a></td></tr>\r\n");

                                htmTOC.WriteTOC(0, "<a class=\"listing-link\" href=\"schema/chapter-3.htm#abbreviated\">3.2 Abbreviated terms</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">3.2 <a class=\"listing-link\" href=\"chapter-3.htm#abbreviated\" target=\"info\" >Abbreviated terms</a></td></tr>\r\n");

                                htmSection.WriteLine("<a id=\"terms\"/>");
                                htmSection.WriteLine("<h2>3.1 Terms and definitions</h2>");
                                htmSection.WriteLine("<dl>");
                                if (docProject.Terms != null)
                                {
                                    foreach(DocTerm docTerm in docProject.Terms)
                                    {
                                        htmSection.WriteTerm(docTerm);
                                    }
                                }
                                htmSection.WriteLine("</dl>");
                                htmSection.WriteLine("<a id=\"abbreviated\"/>");
                                htmSection.WriteLine("<h2>3.2 Abbreviated terms</h2>");
                                htmSection.WriteLine("<table class=\"abbreviatedterms\">");
                                if (docProject.Abbreviations != null)
                                {
                                    SortedList<string, DocAbbreviation> sl = new SortedList<string, DocAbbreviation>();
                                    foreach (DocAbbreviation docRef in docProject.Abbreviations)
                                    {
                                        sl.Add(docRef.Name, docRef);
                                    }

                                    foreach (string s in sl.Keys)
                                    {
                                        DocAbbreviation docRef = sl[s];
                                        htmSection.WriteLine("<tr><td class=\"abbreviatedterm\" id=\"" + MakeLinkName(docRef) + "\">" + docRef.Name + "</td>");
                                        htmSection.WriteLine("<td class=\"abbrebiatedterm\">" + docRef.Documentation + "</td></tr>");
                                    }
                                }
                                htmSection.WriteLine("</table>");
                            }
                            else if (iSection == 4)
                            {
                                FormatHTM.WriteTOCforTemplates(docProject.Templates, 1, iSection.ToString(), htmTOC, htmSectionTOC, included);

                                htmSection.WriteLine("<table class=\"gridtable\">");
                                htmSection.WriteLine("<tr><th>Template</th>");

                                for (int i = 0; i < docProject.ModelViews.Count; i++)
                                {
                                    DocModelView docView = docProject.ModelViews[i];
                                    if (included != null && included.ContainsKey(docView))
                                    {
                                        htmSection.WriteLine("<th>" + docProject.ModelViews[i].Name + "</th>");
                                    }
                                }

                                htmSection.WriteLine("</tr>");

                                foreach (DocTemplateDefinition docTemplateDefinition in docProject.Templates)
                                {
                                    htmSection.WriteTemplateTable(docProject, docTemplateDefinition, 0, dictionaryViews);
                                }
                                htmSection.WriteLine("</table>");


                            }

                            htmSection.WriteLine("<p>");

                            int iListSchema = 0;
                            foreach (DocSchema schema in section.Schemas)
                            {
                                if (included == null || included.ContainsKey(schema))
                                {
                                    iListSchema++;
                                    htmSection.WriteLine("<a class=\"listing-link\" href=\"" + schema.Name.ToLower() + "/content.htm\">" + iSection.ToString() + "." + iListSchema.ToString() + " " + schema.Name + "</a><br>");
                                }
                            }
                            htmSection.WriteLine("</p>");

                            htmSection.WriteLinkTo("chapter-" + iSection, 1);

                            htmSection.WriteFooter(Properties.Settings.Default.Footer);
                        }

                        // each schema
                        int iSchema = 0;
                        foreach (DocSchema schema in section.Schemas)
                        {
                            if (worker.CancellationPending)
                                return;

                            if (included == null || included.ContainsKey(schema))
                            {
                                iSchema++;

                                // ensure directory exists
                                System.IO.Directory.CreateDirectory(pathSchema + @"\" + schema.Name.ToLower() + @"\lexical\");

                                // create schema document
                                using (FormatHTM htmSchema = new FormatHTM(pathSchema + @"\" + schema.Name.ToLower() + @"\content.htm", mapEntity, mapSchema, included))
                                {
                                    {
                                        mapNumber.Add(schema, iSection.ToString() + "." + iSchema.ToString());

                                        htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"schema/" + schema.Name.ToLower() + "/content.htm\">" + iSection.ToString() + "." + iSchema.ToString() + " " + schema.Name + "</a>");

                                        // extra line between each schema
                                        htmSectionTOC.WriteLine("<tr><td>&nbsp;</td></tr>");
                                        htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a id=\"" + iSection.ToString() + "." + iSchema.ToString() + "\">" + iSection.ToString() + "." + iSchema.ToString() + "</a> <a class=\"listing-link\" href=\"" + schema.Name.ToLower() + "/content.htm\" target=\"info\">" + schema.Name + "</a></td></tr>\r\n");

                                        htmSchema.WriteHeader(schema.Name, iSection, iSchema, 0, 0, Properties.Settings.Default.Header);

                                        htmSchema.WriteScript(iSection, iSchema, 0, 0);

                                        htmSchema.WriteLine("<h2 class=\"std\">" + iSection.ToString() + "." + iSchema.ToString() + " " + schema.Name + "</h2>");

                                        int iSubSection = 1; // first subsection for schema semantic definition
                                        htmTOC.WriteTOC(2, iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Schema Definition");
                                        htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Schema Definition</td></tr>\r\n");
                                        htmSchema.WriteLine("<h3 class=\"std\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Schema Definition</h3>");

                                        schema.Documentation = UpdateNumbering(schema.Documentation, listFigures, listTables, schema);
                                        htmSchema.WriteDocumentationForISO(schema.Documentation, schema, Properties.Settings.Default.NoHistory);

                                        // each type
                                        if (schema.Types.Count > 0)
                                        {
                                            iSubSection++;

                                            htmTOC.WriteTOC(2, iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Types");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Types</td></tr>\r\n");
                                            int iType = 0;
                                            foreach (DocType type in schema.Types)
                                            {
                                                if (worker.CancellationPending)
                                                    return;

                                                if (type.Name.Equals("IfcNullStyle", StringComparison.OrdinalIgnoreCase) && schema.Name.Equals("IfcConstructionMgmtDomain", StringComparison.OrdinalIgnoreCase))
                                                {
                                                    // bug -- exclude
                                                }
                                                else if (included == null || included.ContainsKey(type))
                                                {
                                                    iType++;

                                                    string formatnum = iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iType.ToString();
                                                    mapNumber.Add(type, formatnum);

                                                    htmTOC.WriteTOC(3, "<a class=\"listing-link\" href=\"schema/" + mapSchema[type.Name].ToLower() + "/lexical/" + type.Name.ToLower() + ".htm\">" + formatnum.ToString() + " " + type.Name + "</a>");
                                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a id=\"" + formatnum + "\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iType.ToString() + "</a> <a class=\"listing-link\" href=\"" + mapSchema[type.Name].ToLower() + "/lexical/" + type.Name.ToLower() + ".htm\" target=\"info\">" + type.Name + "</a><td></tr>\r\n");


                                                    using (FormatHTM htmDef = new FormatHTM(pathSchema + @"\" + schema.Name.ToLower() + "\\lexical\\" + type.Name.ToLower() + ".htm", mapEntity, mapSchema, included))
                                                    {
                                                        htmDef.WriteHeader(type.Name, iSection, iSchema, iSubSection, iType, Properties.Settings.Default.Header);

                                                        htmDef.WriteScript(iSection, iSchema, iSubSection, iType);

                                                        htmDef.WriteLine("<h4 class=\"num\">" + type.Name + "</h4>");
                                                        htmDef.WriteLocalizedNames(type);
                                                        htmDef.WriteChangeLog(type, docProject);

                                                        htmDef.WriteLine("<section>");
                                                        htmDef.WriteLine("<h5 class=\"num\">Semantic definitions at the type</h5>");

                                                        if (type.Documentation != null)
                                                        {
                                                            type.Documentation = UpdateNumbering(type.Documentation, listFigures, listTables, type);
                                                        }

                                                        htmDef.WriteSummaryHeader("Type definition", true);
                                                        htmDef.WriteDocumentationForISO(type.Documentation, type, Properties.Settings.Default.NoHistory);
                                                        htmDef.WriteSummaryFooter();

                                                        if(type is DocEnumeration)
                                                        {
                                                            DocEnumeration docEnumeration = (DocEnumeration)type;

                                                            htmDef.WriteSummaryHeader("Enumeration definition", true);
                                                            htmDef.WriteLine("<table class=\"attributes\">");
                                                            htmDef.WriteLine("<tr><th>Constant</th><th>Description</th></tr>");
                                                            foreach (DocConstant docConstant in docEnumeration.Constants)
                                                            {
                                                                htmDef.Write("<tr><td>");
                                                                htmDef.Write(docConstant.Name);
                                                                htmDef.Write("</td><td>");
                                                                htmDef.Write(docConstant.Documentation);
                                                                htmDef.Write("</td></tr>");
                                                            }
                                                            htmDef.WriteLine("</table>");
                                                            htmDef.WriteSummaryFooter();
                                                        }
                                                        else if (type is DocSelect)
                                                        {
                                                            DocSelect docSelect = (DocSelect)type;

                                                            htmDef.WriteSummaryHeader("Select definition", true);
                                                            htmDef.WriteLine("<table class=\"attributes\">");
                                                            htmDef.WriteLine("<tr><th>Type</th><th>Description</th></tr>");
                                                            foreach (DocSelectItem docSelectItem in docSelect.Selects)
                                                            {
                                                                DocObject docRef = null;
                                                                if (mapEntity.TryGetValue(docSelectItem.Name, out docRef))
                                                                {
                                                                    if (included == null || included.ContainsKey(docRef))
                                                                    {
                                                                        htmDef.Write("<tr><td>");
                                                                        htmDef.WriteDefinition(docSelectItem.Name);
                                                                        //htmDef.Write(docSelectItem.Name);
                                                                        htmDef.Write("</td><td>");
                                                                        htmDef.Write(docSelectItem.Documentation);
                                                                        htmDef.Write("</td></tr>");
                                                                    }
                                                                }
                                                            }
                                                            htmDef.WriteLine("</table>");
                                                            htmDef.WriteSummaryFooter();
                                                        }

                                                        htmDef.WriteLine("</section>");


                                                        // where rules (for defined types)

                                                        if (type is DocDefined && ((DocDefined)type).WhereRules != null && ((DocDefined)type).WhereRules.Count > 0)
                                                        {
                                                            DocDefined entity = (DocDefined)type;

                                                            // formal propositions
                                                            htmDef.WriteSummaryHeader("Formal Propositions", true);

                                                            htmDef.WriteLine("<table class=\"propositions\">");
                                                            htmDef.WriteLine("<tr><th>Rule</th><th>Description</th></tr>");
                                                            foreach (DocWhereRule docAttr in entity.WhereRules)
                                                            {
                                                                htmDef.Write("<tr><td>");
                                                                htmDef.Write(docAttr.Name);
                                                                htmDef.Write("</td><td>");
                                                                if (docAttr.Documentation != null)
                                                                {
                                                                    htmDef.WriteDocumentationForISO(docAttr.Documentation, entity, Properties.Settings.Default.NoHistory);
                                                                }
                                                                htmDef.WriteLine("</td></tr>");
                                                            }
                                                            htmDef.WriteLine("</table>\r\n");

                                                            htmDef.WriteSummaryFooter();
                                                        }



                                                        htmDef.WriteLine("<section>");
                                                        htmDef.WriteLine("<h5 class=\"num\">Formal representations</h5>");

                                                        if (!Properties.Settings.Default.NoXsd)
                                                        {
                                                            htmDef.WriteSummaryHeader("XSD Specification", false);
                                                            htmDef.Write("<div class=\"xsd\"><code class=\"xsd\">");
                                                            if (type is DocSelect)
                                                            {
                                                                htmDef.WriteFormatted(FormatXSD.FormatSelect((DocSelect)type, mapEntity, included));
                                                            }
                                                            else if (type is DocEnumeration)
                                                            {
                                                                htmDef.WriteFormatted(FormatXSD.FormatEnum((DocEnumeration)type));
                                                            }
                                                            else if (type is DocDefined)
                                                            {
                                                                htmDef.WriteFormatted(FormatXSD.FormatDefined((DocDefined)type, mapEntity));
                                                            }
                                                            htmDef.Write("</code></div>");
                                                            htmDef.WriteSummaryFooter();
                                                        }

                                                        htmDef.WriteExpressTypeAndDocumentation(type, Properties.Settings.Default.NoHistory, Properties.Settings.Default.ExpressComments);

                                                        htmDef.WriteLine("</section>");

                                                        // write url for incoming page link
                                                        htmDef.WriteLinkTo(type);

                                                        htmDef.WriteFooter(Properties.Settings.Default.Footer);
                                                    }
                                                }
                                            }

                                        }

                                        // each entity
                                        if (schema.Entities.Count > 0)
                                        {
                                            iSubSection++;

                                            htmTOC.WriteTOC(2, iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Entities");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Entities</td></tr>\r\n");
                                            int iEntity = 0;
                                            foreach (DocEntity entity in schema.Entities)
                                            {
                                                if (worker.CancellationPending)
                                                    return;

                                                if (included == null || included.ContainsKey(entity))
                                                {
                                                    iEntity++;

                                                    string formatnum = iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iEntity.ToString();
                                                    mapNumber.Add(entity, formatnum);

                                                    htmTOC.WriteTOC(3, "<a class=\"listing-link\" href=\"schema/" + mapSchema[entity.Name].ToLower() + "/lexical/" + entity.Name.ToLower() + ".htm\">" + formatnum + " " + entity.Name + "</a>");
                                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a id=\"" + formatnum + "\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iEntity.ToString() + "</a> <a class=\"listing-link\" href=\"" + mapSchema[entity.Name].ToLower() + "/lexical/" + entity.Name.ToLower() + ".htm\" target=\"info\">" + entity.Name + "</a></td></tr>\r\n");

                                                    using (FormatHTM htmDef = new FormatHTM(pathSchema + @"\" + schema.Name.ToLower() + "\\lexical\\" + entity.Name.ToLower() + ".htm", mapEntity, mapSchema, included))
                                                    {
                                                        htmDef.WriteHeader(entity.Name, iSection, iSchema, iSubSection, iEntity, Properties.Settings.Default.Header);
                                                        htmDef.WriteScript(iSection, iSchema, iSubSection, iEntity);

                                                        htmDef.WriteLine("<h4 class=\"num\">" + entity.Name + "</h4>");
                                                        htmDef.WriteLocalizedNames(entity);
                                                        htmDef.WriteChangeLog(entity, docProject);
                                                        htmDef.WriteLine("<section>");
                                                        htmDef.WriteLine("<h5 class=\"num\">Semantic definitions at the entity</h5>");

                                                        string entitydocumentation = FormatEntityDescription(docProject, entity, listFigures, listTables);

                                                        htmDef.WriteSummaryHeader("Entity definition", true);
                                                        htmDef.WriteDocumentationForISO(entitydocumentation, entity, Properties.Settings.Default.NoHistory);
                                                        htmDef.WriteSummaryFooter();

                                                        if (entity.Attributes != null && entity.Attributes.Count > 0)
                                                        {
                                                            htmDef.WriteSummaryHeader("Attribute definitions", true);

                                                            htmDef.WriteLine("<table class=\"attributes\">");
                                                            htmDef.WriteLine("<tr><th>#</th><th>Attribute</th><th>Type</th><th>Cardinality</th><th>Description</th>");

                                                            if (views != null)
                                                            {
                                                                foreach (DocModelView docViewHeader in views)
                                                                {
                                                                    htmDef.Write("<th>");
                                                                    htmDef.Write(docViewHeader.Name.Substring(0, 1));
                                                                    htmDef.Write("</th>");
                                                                }
                                                            }
                                                            htmDef.WriteLine("</tr>");

                                                            int sequence = 0;

                                                            // count direct attributes of base classes
                                                            DocEntity docEntBase = entity;
                                                            DocObject docBase = null;
                                                            while(!String.IsNullOrEmpty(docEntBase.BaseDefinition) && mapEntity.TryGetValue(docEntBase.BaseDefinition, out docBase))
                                                            {
                                                                docEntBase = (DocEntity)docBase;
                                                                foreach(DocAttribute docAttrBase in docEntBase.Attributes)
                                                                {
                                                                    if (docAttrBase.Inverse == null && docAttrBase.Derived == null)
                                                                    {
                                                                        sequence++;
                                                                    }
                                                                }
                                                            }

                                                            htmDef.WriteEntityAttributes(entity, entity, views, dictionaryViews, ref sequence);

                                                            htmDef.WriteLine("</table>");

                                                            htmDef.WriteSummaryFooter();
                                                        }

                                                        if (entity.WhereRules != null && entity.WhereRules.Count > 0)
                                                        {
                                                            // avoid attributes without descriptions
                                                            int cDescs = 0;
                                                            foreach (DocWhereRule docAttr in entity.WhereRules)
                                                            {
                                                                if (docAttr.Documentation != null)
                                                                {
                                                                    cDescs++;
                                                                }
                                                            }

                                                            if (cDescs > 0)
                                                            {
                                                                // formal propositions
                                                                htmDef.WriteSummaryHeader("Formal Propositions", true);

                                                                htmDef.WriteLine("<table class=\"propositions\">");
                                                                htmDef.WriteLine("<tr><th>Rule</th><th>Description</th></tr>");
                                                                foreach (DocWhereRule docAttr in entity.WhereRules)
                                                                {
                                                                    htmDef.Write("<tr><td>");
                                                                    htmDef.Write(docAttr.Name);
                                                                    htmDef.Write("</td><td>");
                                                                    if (docAttr.Documentation != null)
                                                                    {
                                                                        htmDef.WriteDocumentationForISO(docAttr.Documentation, entity, Properties.Settings.Default.NoHistory);
                                                                    }
                                                                    htmDef.WriteLine("</td></tr>");
                                                                }
                                                                htmDef.WriteLine("</table>\r\n");

                                                                htmDef.WriteSummaryFooter();
                                                            }
                                                        }
                                                        
                                                        htmDef.WriteLine("</section>");

                                                        htmDef.WriteLine("<section>");
                                                        htmDef.WriteLine("<h5 class=\"num\">Inherited definitions from supertypes</h5>");

                                                        Dictionary<Rectangle, DocEntity> map = new Dictionary<Rectangle, DocEntity>();
                                                        using (Font font = new Font(FontFamily.GenericSansSerif, 8.0f))
                                                        {
                                                            using (Image img = FormatPNG.CreateInheritanceDiagramForEntity(docProject, included, entity, font, map))
                                                            {
                                                                img.Save(path + "\\diagrams\\" + entity.Name.ToLower() + ".png", System.Drawing.Imaging.ImageFormat.Png);
                                                            }
                                                        }

                                                        htmDef.WriteSummaryHeader("Entity inheritance", true);
                                                        htmDef.WriteLine("<img src=\"../../../diagrams/" + entity.Name.ToLower() + ".png\" usemap=\"#f\"/>");

                                                        htmDef.WriteLine("<map name=\"f\">");
                                                        foreach (Rectangle rc in map.Keys)
                                                        {
                                                            DocEntity docEntref = map[rc];
                                                            DocSchema docEntsch = docProject.GetSchemaOfDefinition(docEntref);

                                                            string hyperlink = "../../../schema/" + docEntsch.Name.ToLower() + "/lexical/" + docEntref.Name.ToLower() + ".htm";
                                                            htmDef.WriteLine("<area shape=\"rect\" coords=\"" + rc.Left + "," + rc.Top + "," + rc.Right + "," + rc.Bottom + "\" href=\"" + hyperlink + "\" alt=\"" + docEntref.Name + "\" />");
                                                        }
                                                        htmDef.WriteLine("</map>");
                                                        
                                                        htmDef.WriteSummaryFooter();

                                                        htmDef.WriteSummaryHeader("Attribute inheritance", false);

                                                        htmDef.WriteLine("<table class=\"attributes\">");
                                                        htmDef.Write("<tr><th>#</th><th>Attribute</th><th>Type</th><th>Cardinality</th><th>Description</th>");
                                                        if(views != null)
                                                        {
                                                            foreach(DocModelView docViewHeader in views)
                                                            {
                                                                htmDef.Write("<th>");
                                                                htmDef.Write(docViewHeader.Name.Substring(0, 1));
                                                                htmDef.Write("</th>");
                                                            }
                                                        }
                                                        htmDef.WriteLine("</tr>");

                                                        int sequenceX = 0;
                                                        htmDef.WriteEntityInheritance(entity, entity, views, dictionaryViews, ref sequenceX);

                                                        htmDef.WriteLine("</table>");

                                                        htmDef.WriteSummaryFooter();

                                                        //htmDef.WriteEntityInheritance(entity);

                                                        string conceptdocumentation = FormatEntityConcepts(docProject, entity, mapEntity, mapSchema, included, listFigures, listTables);
                                                        htmDef.WriteDocumentationForISO(conceptdocumentation, entity, Properties.Settings.Default.NoHistory);

                                                        if (docProject.Examples != null)
                                                        {
                                                            List<DocExample> listExample = new List<DocExample>();
                                                            foreach (DocExample docExample in docProject.Examples)
                                                            {
                                                                BuildExampleList(listExample, docExample, entity, included);
                                                            }
                                                            if (listExample.Count > 0)
                                                            {
                                                                htmDef.WriteLine("<section>");
                                                                htmDef.WriteLine("<h5 class=\"num\">Examples</h5>");
                                                                //htmDef.WriteSummaryHeader("Examples", true);
                                                                htmDef.WriteLine("<ul>");
                                                                foreach (DocExample docExample in listExample)
                                                                {
                                                                    if (docExample.Name != null)
                                                                    {
                                                                        htmDef.Write("<li><a href=\"../../../annex/annex-e/");
                                                                        htmDef.Write(docExample.Name.Replace(' ', '-').ToLower());
                                                                        htmDef.Write(".htm\">");
                                                                        htmDef.Write(docExample.Name);
                                                                        htmDef.Write("</a></li>");
                                                                        htmDef.WriteLine("");
                                                                    }
                                                                }
                                                                htmDef.WriteLine("</ul>");
                                                                //htmDef.WriteSummaryFooter();
                                                                htmDef.WriteLine("</section>");
                                                            }
                                                        }

                                                        htmDef.WriteLine("<section>");
                                                        htmDef.WriteLine("<h5 class=\"num\">Formal representations</h5>");

                                                        if (!Properties.Settings.Default.NoXsd)
                                                        {
                                                            htmDef.WriteSummaryHeader("XSD Specification", false);
                                                            htmDef.Write("<div class=\"xsd\"><code class=\"xsd\">");
                                                            htmDef.WriteFormatted(FormatXSD.FormatEntity(entity, mapEntity, included));
                                                            htmDef.Write("</code></div>");
                                                            htmDef.WriteSummaryFooter();
                                                        }

                                                        htmDef.WriteExpressEntityAndDocumentation(entity, Properties.Settings.Default.NoHistory, Properties.Settings.Default.ExpressComments);

                                                        htmDef.WriteLine("</section>");

                                                        // write url for incoming page link
                                                        htmDef.WriteLinkTo(entity);

                                                        htmDef.WriteFooter(Properties.Settings.Default.Footer);
                                                    }
                                                }
                                            }
                                        }

                                        // functions
                                        if (schema.Functions.Count > 0)
                                        {
                                            iSubSection++;

                                            htmTOC.WriteTOC(2, iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Functions");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Functions</td></tr>\r\n");
                                            int iEntity = 0;
                                            foreach (DocFunction entity in schema.Functions)
                                            {
                                                if (included == null || included.ContainsKey(entity))
                                                {
                                                    iEntity++;

                                                    string formatnum = iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iEntity.ToString();
                                                    mapNumber.Add(entity, formatnum);

                                                    htmTOC.WriteTOC(3, "<a class=\"listing-link\" href=\"schema/" + mapSchema[entity.Name].ToLower() + "/lexical/" + entity.Name.ToLower() + ".htm\">" + formatnum + " " + entity.Name + "</a>");
                                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a id=\"" + formatnum + "\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iEntity.ToString() + "</a> <a class=\"listing-link\" href=\"" + mapSchema[entity.Name].ToLower() + "/lexical/" + entity.Name.ToLower() + ".htm\" target=\"info\">" + entity.Name + "</a></td></tr>\r\n");

                                                    using (FormatHTM htmDef = new FormatHTM(pathSchema + @"\" + schema.Name.ToLower() + "\\lexical\\" + entity.Name.ToLower() + ".htm", mapEntity, mapSchema, included))
                                                    {
                                                        htmDef.WriteHeader(entity.Name, iSection, iSchema, iSubSection, iEntity, Properties.Settings.Default.Header);
                                                        htmDef.WriteScript(iSection, iSchema, iSubSection, iEntity);

                                                        htmDef.WriteLine("<h4 class=\"num\">" + entity.Name + "</h4>");

                                                        htmDef.WriteLine("<section>");
                                                        htmDef.WriteLine("<h5 class=\"num\">Semantic definitions at the function</h5>");

                                                        htmDef.WriteSummaryHeader("Function Definition", true);
                                                        htmDef.WriteLine("<p>");
                                                        htmDef.WriteDocumentationForISO(entity.Documentation, entity, Properties.Settings.Default.NoHistory);
                                                        htmDef.WriteLine("</p>");
                                                        htmDef.WriteSummaryFooter();

                                                        htmDef.WriteLine("</section>");

                                                        htmDef.WriteLine("<section>");
                                                        htmDef.WriteLine("<h5 class=\"num\">Formal representations</h5>");

                                                        htmDef.WriteSummaryHeader("EXPRESS Specification", true);
                                                        htmDef.WriteLine("<span class=\"express\">\r\n");
                                                        htmDef.WriteExpressFunction(entity);
                                                        htmDef.WriteLine("</span>\r\n");
                                                        htmDef.WriteSummaryFooter();

                                                        htmDef.WriteLine("</section>");

                                                        // write url for incoming page link
                                                        htmDef.WriteLinkTo(entity);

                                                        htmDef.WriteFooter(Properties.Settings.Default.Footer);
                                                    }
                                                }
                                            }
                                        }

                                        // rules
                                        if (schema.GlobalRules.Count > 0)
                                        {
                                            iSubSection++;

                                            htmTOC.WriteTOC(2, iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Rules");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Rules</td></tr>\r\n");
                                            int iEntity = 0;
                                            foreach (DocGlobalRule entity in schema.GlobalRules)
                                            {
                                                if (included == null || included.ContainsKey(entity))
                                                {
                                                    iEntity++;

                                                    string formatnum = iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iEntity.ToString();
                                                    mapNumber.Add(entity, formatnum);

                                                    htmTOC.WriteTOC(3, "<a class=\"listing-link\" href=\"schema/" + mapSchema[entity.Name].ToLower() + "/lexical/" + entity.Name.ToLower() + ".htm\">" + formatnum + " " + entity.Name + "</a>");
                                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a id=\"" + formatnum + "\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iEntity.ToString() + "</a> <a href=\"" + mapSchema[entity.Name].ToLower() + "/lexical/" + entity.Name.ToLower() + ".htm\" target=\"info\">" + entity.Name + "</a></td></tr>\r\n");

                                                    using (FormatHTM htmDef = new FormatHTM(pathSchema + @"\" + schema.Name.ToLower() + "\\lexical\\" + entity.Name.ToLower() + ".htm", mapEntity, mapSchema, included))
                                                    {
                                                        htmDef.WriteHeader(entity.Name, iSection, iSchema, iSubSection, iEntity, Properties.Settings.Default.Header);
                                                        htmDef.WriteScript(iSection, iSchema, iSubSection, iEntity);

                                                        htmDef.WriteLine("<h4 class=\"num\">" + entity.Name + "</h4>");

                                                        htmDef.WriteLine("<section>");
                                                        htmDef.WriteLine("<h5 class=\"num\">Semantic definitions at the global rule</h5>");

                                                        htmDef.WriteSummaryHeader("Global Rule Definition", true);
                                                        htmDef.WriteLine("<p>");
                                                        htmDef.WriteDocumentationForISO(entity.Documentation, entity, Properties.Settings.Default.NoHistory);
                                                        htmDef.WriteLine("</p>");
                                                        htmDef.WriteSummaryFooter();

                                                        htmDef.WriteLine("</section>");

                                                        htmDef.WriteLine("<section>");
                                                        htmDef.WriteLine("<h5 class=\"num\">Formal representations</h5>");

                                                        htmDef.WriteSummaryHeader("EXPRESS Specification", true);
                                                        htmDef.WriteLine("<span class=\"express\">\r\n");
                                                        htmDef.WriteExpressGlobalRule(entity);
                                                        htmDef.WriteLine("</span>\r\n");
                                                        htmDef.WriteSummaryFooter();

                                                        htmDef.WriteLine("</section>");

                                                        // write url for incoming page link
                                                        htmDef.WriteLinkTo(entity);

                                                        htmDef.WriteFooter(Properties.Settings.Default.Footer);
                                                    }
                                                }
                                            }
                                        }

                                        // property sets
                                        if (schema.PropertySets.Count > 0 || schema.PropertyEnums.Count > 0)
                                        {
                                            iSubSection++;

                                            htmTOC.WriteTOC(2, iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Property Sets");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Property Sets</td></tr>\r\n");
                                            int iPset = 0;
                                            foreach (DocPropertySet entity in schema.PropertySets)
                                            {
                                                if (worker.CancellationPending)
                                                    return;

                                                if (included == null || included.ContainsKey(entity))
                                                {
                                                    iPset++;

                                                    string formatnum = iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iPset.ToString();
                                                    mapNumber.Add(entity, formatnum);

                                                    htmTOC.WriteTOC(3, "<a class=\"listing-link\" href=\"schema/" + mapSchema[entity.Name].ToLower() + "/pset/" + entity.Name.ToLower() + ".htm\">" + formatnum + " " + entity.Name + "</a>");
                                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a id=\"" + formatnum + "\">" + formatnum + "</a> <a class=\"listing-link\" href=\"" + mapSchema[entity.Name].ToLower() + "/pset/" + entity.Name.ToLower() + ".htm\" target=\"info\">" + entity.Name + "</a></td></tr>\r\n");

                                                    using (FormatHTM htmDef = new FormatHTM(pathSchema + @"\" + schema.Name.ToLower() + "\\pset\\" + entity.Name.ToLower() + ".htm", mapEntity, mapSchema, included))
                                                    {
                                                        htmDef.WriteHeader(entity.Name, iSection, iSchema, iSubSection, iPset, Properties.Settings.Default.Header);
                                                        htmDef.WriteScript(iSection, iSchema, iSubSection, iPset);
                                                        htmDef.WriteLine("<h4 class=\"std\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iPset.ToString() + " " + entity.Name + "</h4>");

                                                        if (!String.IsNullOrEmpty(entity.ApplicableType))
                                                        {
                                                            htmDef.Write("<p>");
                                                            htmDef.WriteDefinition(entity.PropertySetType);
                                                            htmDef.WriteLine("/");

                                                            if (entity.ApplicableType != null && entity.ApplicableType.Contains("/"))
                                                            {
                                                                // break out, e.g. "IfcSensor/TEMPERATURESENSOR"
                                                                string[] applicableparts = entity.ApplicableType.Split('/');
                                                                for (int iapppart = 0; iapppart < applicableparts.Length; iapppart++)
                                                                {
                                                                    if (iapppart > 0)
                                                                    {
                                                                        htmDef.Write(" / ");
                                                                    }
                                                                    htmDef.WriteDefinition(applicableparts[iapppart]);
                                                                }
                                                            }
                                                            else
                                                            {
                                                                htmDef.WriteDefinition(entity.ApplicableType);
                                                            }
                                                            htmDef.Write("</p>");
                                                        }

                                                        // english by default
                                                        htmDef.WriteLine("<table>");

                                                        entity.Localization.Sort(); // ensure sorted
                                                        foreach (DocLocalization doclocal in entity.Localization)
                                                        {
                                                            string localname = doclocal.Name;
                                                            string localdesc = doclocal.Documentation;

                                                            string localid = doclocal.Locale.Substring(0, 2).ToLower();

                                                            if (localid.Equals("en", StringComparison.InvariantCultureIgnoreCase) && localdesc == null)
                                                            {
                                                                localdesc = entity.Documentation;
                                                            }

                                                            htmDef.WriteLine("<tr><td><img src=\"../../../img/locale-" + localid + ".png\" /></td><td><b> " + localname + ":</b> " + localdesc + "</td></tr>");
                                                        }

                                                        htmDef.WriteLine("</table>");

                                                        if (!Properties.Settings.Default.NoXml)
                                                        {
                                                            ////htmDef.WriteLine("<p><a href=\"http://lookup.bsdd.buildingsmart.com/api/4.0/IfdPSet/search/" + entity.Name + "\" target=\"ifd\"><img src=\"../../../img/external.png\" title=\"Link to IFD\"/> buildingSMART Data Dictionary</a></p>\r\n");
                                                            //http://lookup.bsdd.buildingsmart.com/api/4.0/IfdPSet/search/Pset_ActionRequest

                                                            // use guid
                                                            string guid = IfcGloballyUniqueId.Format(entity.Uuid);
                                                            htmDef.WriteLine("<p><a href=\"http://lookup.bsdd.buildingsmart.com/api/4.0/IfdPSet/" + guid + "/ifcVersion/2x4\" target=\"ifd\"><img border=\"0\" src=\"../../../img/external.png\" title=\"Link to IFD\"/> buildingSMART Data Dictionary</a></p>\r\n");

                                                            htmDef.WriteLine("<p><a href=\"../../../psd/" + entity.Name + ".xml\"><img border=\"0\" src=\"../../../img/diagram.png\" title=\"Link to PSD-XML\"/> PSD-XML</a></p>\r\n");
                                                        }

                                                        // write diagram if it exists
                                                        htmDef.WriteLine(FormatFigure(docProject, entity, null, entity.Name, listFigures));
                                                        htmDef.WriteProperties(entity.Properties);

                                                        // write url for incoming page link
                                                        htmDef.WriteLinkTo(entity);

                                                        htmDef.WriteFooter(Properties.Settings.Default.Footer);
                                                    }

                                                    // generate PSD listing
                                                    using (FormatXML formatPSD = new FormatXML(path + @"\psd\" + entity.Name + ".xml", typeof(PropertySetDef)))//, PropertySetDef.DefaultNamespace)) // full casing for compatibility with original files
                                                    {
                                                        formatPSD.Instance = Program.ExportPsd(entity, mapPropEnum);
                                                        formatPSD.Save();
                                                    }
                                                }
                                            }

                                            foreach (DocPropertyEnumeration entity in schema.PropertyEnums)
                                            {
                                                if (worker.CancellationPending)
                                                    return;

                                                if (included == null || included.ContainsKey(entity))
                                                {
                                                    iPset++;

                                                    string formatnum = iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iPset.ToString();
                                                    mapNumber.Add(entity, formatnum);

                                                    htmTOC.WriteTOC(3, "<a class=\"listing-link\" href=\"schema/" + mapSchema[entity.Name].ToLower() + "/pset/" + entity.Name.ToLower() + ".htm\">" + formatnum + " " + entity.Name + "</a>");
                                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a id=\"" + formatnum + "\">" + formatnum + "</a> <a class=\"listing-link\" href=\"" + mapSchema[entity.Name].ToLower() + "/pset/" + entity.Name.ToLower() + ".htm\" target=\"info\">" + entity.Name + "</a></td></tr>\r\n");

                                                    using (FormatHTM htmDef = new FormatHTM(pathSchema + @"\" + schema.Name.ToLower() + "\\pset\\" + entity.Name.ToLower() + ".htm", mapEntity, mapSchema, included))
                                                    {
                                                        htmDef.WriteHeader(entity.Name, iSection, iSchema, iSubSection, iPset, Properties.Settings.Default.Header);
                                                        htmDef.WriteScript(iSection, iSchema, iSubSection, iPset);
                                                        htmDef.WriteLine("<h4 class=\"std\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iPset.ToString() + " " + entity.Name + "</h4>");

                                                        // english by default
                                                        htmDef.WriteLine("<table>");

                                                        entity.Localization.Sort(); // ensure sorted
                                                        foreach (DocLocalization doclocal in entity.Localization)
                                                        {
                                                            if (doclocal.Locale != null && doclocal.Locale.Length > 2)
                                                            {
                                                                string localname = doclocal.Name;
                                                                string localdesc = doclocal.Documentation;

                                                                string localid = doclocal.Locale.Substring(0, 2).ToLower();

                                                                if (localid.Equals("en", StringComparison.InvariantCultureIgnoreCase) && localdesc == null)
                                                                {
                                                                    localdesc = entity.Documentation;
                                                                }

                                                                htmDef.WriteLine("<tr><td><img src=\"../../../img/locale-" + localid + ".png\" /></td><td><b> " + localname + ":</b> " + localdesc + "</td></tr>");
                                                            }
                                                        }

                                                        htmDef.WriteLine("</table>");

                                                        htmDef.WriteLine("<table class=\"gridtable\">");
                                                        htmDef.WriteLine("<tr><th>Name</th><th>Description</th></tr>");

                                                        bool showdefaultdesc = true;

                                                        foreach (DocPropertyConstant docprop in entity.Constants)
                                                        {
                                                            htmDef.WriteLine("<tr><td>" + docprop.Name + "</td><td>");

                                                            if (docprop.Localization.Count > 0)
                                                            {
                                                                htmDef.WriteLine("<table class=\"gridtable\">");
                                                                docprop.Localization.Sort();
                                                                foreach (DocLocalization doclocal in docprop.Localization)
                                                                {
                                                                    string localname = doclocal.Name;
                                                                    string localdesc = doclocal.Documentation;

                                                                    string localid = doclocal.Locale.Substring(0, 2).ToLower();

                                                                    if (localid.Equals("en", StringComparison.InvariantCultureIgnoreCase) && localdesc == null)
                                                                    {
                                                                        localdesc = docprop.Documentation;
                                                                        showdefaultdesc = false;
                                                                    }

                                                                    htmDef.WriteLine("<tr><td><img src=\"../../../img/locale-" + localid + ".png\" /></td><td><b>" + localname + "</b></td><td>" + localdesc + "</td></tr>");
                                                                }
                                                                htmDef.WriteLine("</table>");
                                                            }

                                                            if(showdefaultdesc)
                                                            {
                                                                htmDef.WriteLine(docprop.Documentation);
                                                            }

                                                            htmDef.WriteLine("</td></tr>");
                                                        }

                                                        htmDef.WriteLine("</table>");

                                                        // write url for incoming page link
                                                        htmDef.WriteLinkTo(entity);

                                                        htmDef.WriteFooter(Properties.Settings.Default.Footer);
                                                    }
                                                }
                                            }

                                        }


                                        // quantity sets (assume properties always exist for such schemas so always section 4)
                                        if (schema.QuantitySets.Count > 0)
                                        {
                                            iSubSection++;

                                            htmTOC.WriteTOC(2, iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Quantity Sets");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + " Quantity Sets</td></tr>\r\n");
                                            int iPset = 0;
                                            foreach (DocQuantitySet entity in schema.QuantitySets)
                                            {
                                                if (worker.CancellationPending)
                                                    return;

                                                if (included == null || included.ContainsKey(entity))
                                                {
                                                    iPset++;

                                                    string formatnum = iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iPset.ToString();
                                                    mapNumber.Add(entity, formatnum);

                                                    htmTOC.WriteTOC(3, "<a class=\"listing-link\" href=\"schema/" + mapSchema[entity.Name].ToLower() + "/qset/" + entity.Name.ToLower() + ".htm\">" + formatnum + " " + entity.Name + "</a>");
                                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a id=\"" + formatnum + "\">" + formatnum + "</a> <a class=\"listing-link\" href=\"" + mapSchema[entity.Name].ToLower() + "/qset/" + entity.Name.ToLower() + ".htm\" target=\"info\">" + entity.Name + "</a></td></tr>\r\n");

                                                    using (FormatHTM htmDef = new FormatHTM(pathSchema + @"\" + schema.Name.ToLower() + "\\qset\\" + entity.Name.ToLower() + ".htm", mapEntity, mapSchema, included))
                                                    {
                                                        htmDef.WriteHeader(entity.Name, iSection, iSchema, iSubSection, iPset, Properties.Settings.Default.Header);
                                                        htmDef.WriteScript(iSection, iSchema, iSubSection, iPset);
                                                        htmDef.WriteLine("<h4 class=\"std\">" + iSection.ToString() + "." + iSchema.ToString() + "." + iSubSection.ToString() + "." + iPset.ToString() + " " + entity.Name + "</h4>");

                                                        if (!String.IsNullOrEmpty(entity.ApplicableType))
                                                        {
                                                            htmDef.Write("<p>");

                                                            htmDef.WriteDefinition("QTO_TYPEDRIVENOVERRIDE");
                                                            htmDef.WriteLine("/");
                                                            htmDef.WriteDefinition(entity.ApplicableType);
                                                            htmDef.Write("</p>");
                                                        }

                                                        // english by default
                                                        htmDef.WriteLine("<table>");
                                                        entity.Localization.Sort(); // ensure sorted
                                                        foreach (DocLocalization doclocal in entity.Localization)
                                                        {
                                                            string localname = doclocal.Name;
                                                            string localdesc = doclocal.Documentation;
                                                            string localid = doclocal.Locale.Substring(0, 2).ToLower();

                                                            if (localid.Equals("en", StringComparison.InvariantCultureIgnoreCase) && localdesc == null)
                                                            {
                                                                localdesc = entity.Documentation;
                                                            }

                                                            htmDef.WriteLine("<tr valign=\"top\"><td><img src=\"../../../img/locale-" + localid + ".png\" title=\"Link to XML\"/></td><td><b>" + localname + "</b>: " + localdesc + "</td></tr>");
                                                        }

                                                        htmDef.WriteLine("</table>");

                                                        if (!Properties.Settings.Default.NoXml)
                                                        {
                                                            htmDef.WriteLine("<p><a href=\"../../../qto/" + entity.Name + ".xml\"><img border=\"0\" src=\"../../../img/diagram.png\" title=\"Link to QTO-XML\"/> QTO-XML</a></p>\r\n");
                                                        }

                                                        // write each quantity
                                                        htmDef.WriteLine("<table class=\"gridtable\">");
                                                        htmDef.WriteLine("<tr><th>Name</th><th>Type</th><th>Description</th>");
                                                        foreach (DocQuantity docprop in entity.Quantities)
                                                        {
                                                            htmDef.WriteLine("<tr><td>" + docprop.Name + "</td><td>");
                                                            htmDef.WriteDefinition(docprop.QuantityType.ToString());
                                                            htmDef.WriteLine("</td><td>");

                                                            bool showdefaultdesc = false;
                                                            if(docprop.Localization.Count > 0)
                                                            {
                                                                htmDef.WriteLine("<table class=\"gridtable\">");

                                                                docprop.Localization.Sort();
                                                                foreach (DocLocalization doclocal in docprop.Localization)
                                                                {
                                                                    string localname = doclocal.Name;
                                                                    string localdesc = doclocal.Documentation;

                                                                    string localid = doclocal.Locale.Substring(0, 2).ToLower();

                                                                    if (String.IsNullOrEmpty(localdesc) && localid.Equals("en", StringComparison.InvariantCultureIgnoreCase) && localdesc == null)
                                                                    {
                                                                        localdesc = docprop.Documentation;
                                                                        showdefaultdesc = false;
                                                                    }

                                                                    htmDef.WriteLine("<tr><td><img src=\"../../../img/locale-" + localid + ".png\" /></td><td><b>" + localname + "</b></td><td>" + localdesc + "</td></tr>");
                                                                }
                                                                htmDef.WriteLine("</table>");
                                                            }
                                                            if(showdefaultdesc)
                                                            {
                                                                htmDef.WriteLine(docprop.Documentation);
                                                            }

                                                            htmDef.WriteLine("</td></tr>");
                                                        }
                                                        htmDef.WriteLine("</table>");

                                                        // write url for incoming page link
                                                        htmDef.WriteLinkTo(entity);

                                                        htmDef.WriteFooter(Properties.Settings.Default.Footer);
                                                    }

                                                    // generate PSD listing
                                                    using (FormatXML formatPSD = new FormatXML(path + @"\qto\" + entity.Name + ".xml", typeof(QtoSetDef), QtoSetDef.DefaultNamespace)) // full casing for compatibility with original files
                                                    {
                                                        formatPSD.Instance = Program.ExportQto(entity);
                                                        formatPSD.Save();
                                                    }

                                                }
                                            }
                                        }
                                    }

                                    // v1.8: write links to express-g                                
                                    htmSchema.WriteLine(
                                    "<p><a href=\"../../annex/annex-d/" + MakeLinkName(schema) + "/index.htm\" ><img src=\"../../img/diagram.png\" style=\"border: 0px\" title=\"Link to EXPRESS-G diagram\" alt=\"Link to EXPRESS-G diagram\">&nbsp;EXPRESS-G diagram</a></p>");

                                    // link to this page
                                    htmSchema.WriteLinkTo(schema);

                                    htmSchema.WriteFooter(Properties.Settings.Default.Footer);
                                }
                            }
                        }

                        htmSectionTOC.WriteLine(
                            "</table>\r\n" +
                            "</div>\r\n" +
                            "</body>\r\n" +
                            "</html>\r\n");
                    }
                }

                int iAnnex = 0;
                char chAnnex = 'A';
                foreach (DocAnnex docannex in docProject.Annexes)
                {
                    worker.ReportProgress(++progressCurrent, docannex);

                    iAnnex--;
                    htmTOC.WriteTOC(0, "<a class=\"listing-link\" href=\"annex/annex-" + chAnnex.ToString().ToLower() + ".htm\">Annex " + chAnnex.ToString() + ". " + docannex.Name + "</a>");

                    // write the section page
                    using (FormatHTM htmSection = new FormatHTM(path + @"\annex\annex-" + chAnnex.ToString().ToLower() + @".htm", mapEntity, mapSchema, included))
                    {
                        htmSection.WriteHeader(docannex.Name, iAnnex, 0, 0, 0, Properties.Settings.Default.Header);
                        htmSection.WriteScript(iAnnex, 0, 0, 0);
                        htmSection.WriteLine("<h1 class=\"annex\">Annex " + chAnnex.ToString() + "</h1>");
                        if (chAnnex == 'A')
                        {
                            htmSection.WriteLine("<div align=\"center\">(normative)</div>");
                        }
                        else
                        {
                            htmSection.WriteLine("<div align=\"center\">(informative)</div>");
                        }
                        htmSection.WriteLine("<h1 class=\"annex\">" + docannex.Name + "</h1>");

                        // no numbering for annex currently... docannex.Documentation = UpdateNumbering(section.Documentation, ref iFigure, ref iTable);
                        htmSection.WriteDocumentationForISO(docannex.Documentation, docannex, Properties.Settings.Default.NoHistory);

                        // write listing of schemas
                        if (chAnnex == 'A')
                        {
                            // create page for model view
                            //htmSection.WriteComputerListing("IFC4", "ifc4", 0);

                            /*
                            DoExport(docProject, path + @"\annex\annex-a\default\ifc4.exp", null, null, instances, true);
                            DoExport(docProject, path + @"\annex\annex-a\default\ifcXML4.xsd", null, null, instances, true);
                            DoExport(docProject, path + @"\annex\annex-a\default\ifc4.ifc", null, null, instances, true);
                            DoExport(docProject, path + @"\annex\annex-a\default\ifc4.ifcxml", null, null, instances, true);

                            using (FormatHTM htmExpress = new FormatHTM(path + @"\annex\annex-a\default\ifc4.exp.htm", mapEntity, mapSchema, included))
                            {
                                htmExpress.UseAnchors = true;
                                htmExpress.WriteHeader("EXPRESS", 3);
                                htmExpress.WriteExpressSchema(docProject);
                                htmExpress.WriteFooter("");
                            }

                            using (FormatHTM htmXSD = new FormatHTM(path + @"\annex\annex-a\default\ifcXML4.xsd.htm", mapEntity, mapSchema, included))
                            {
                                string xsdcontent = null;
                                using (System.IO.StreamReader reader = new System.IO.StreamReader(path + @"\annex\annex-a\default\ifcXML4.xsd.txt"))
                                {
                                    xsdcontent = reader.ReadToEnd();
                                }

                                htmXSD.UseAnchors = false;
                                htmXSD.WriteHeader("XSD", 3);
                                htmXSD.Write("<span class=\"express\">");
                                htmXSD.WriteFormatted(xsdcontent);
                                htmXSD.Write("</span>");
                                htmXSD.WriteFooter("");
                            }
                             */
                        }
                        else if(chAnnex == 'C')
                        {
                            htmSection.WriteInheritanceMapping(docProject, views);
                        }

                        htmSection.WriteLinkTo("annex-" + chAnnex.ToString().ToLower(), 1);
                        htmSection.WriteFooter(Properties.Settings.Default.Footer);
                    }

                    using (FormatHTM htmSectionTOC = new FormatHTM(path + @"\annex\toc-" + chAnnex.ToString().ToLower() + ".htm", mapEntity, mapSchema, included))
                    {
                        htmSectionTOC.WriteLine(
                            "<html> \r\n" +
                            "<head> \r\n" +
                            "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"> \r\n" +
                            "<link rel=\"stylesheet\" type=\"text/css\" href=\"../ifc-styles.css\"> \r\n" +
                            "<title>Section Contents</title> \r\n" +
                            "</head> \r\n" +
                            "<body class=\"image\"> \r\n" +
                            "<div class=\"menu\">\r\n" +
                            "<table class=\"menu\" summary=\"Table of Contents\">\r\n");

                        // top level
                        htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">" + chAnnex + ". <a class=\"listing-link\" href=\"annex-" + chAnnex.ToString().ToLower() + ".htm\" target=\"info\" >" + docannex.Name + "</a></td></tr>\r\n");

                        switch (chAnnex)
                        {
                            case 'A':
                                // each MVD has specific schema
                                //if (Properties.Settings.Default.ConceptTables)
                                {
                                    int iCodeView = 0;
                                    foreach (DocModelView docModelView in docProject.ModelViews)
                                    {
                                        if ((included == null || included.ContainsKey(docModelView)) && !String.IsNullOrEmpty(docModelView.Code))
                                        {
                                            iCodeView++;
                                            htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"annex/annex-a/" + MakeLinkName(docModelView) + "/index.htm\" >A." + iCodeView.ToString() + " " + docModelView.Name + "</a>");

                                            htmSectionTOC.WriteLine("<tr><td>&nbsp;</td></tr>");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">A." + iCodeView.ToString() + " <a href=\"annex-a/" + MakeLinkName(docModelView) + "/index.htm\" target=\"info\" >" + docModelView.Name + "</a></td></tr>");

                                            // create page for model view
                                            string pathRoot = path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\index.htm";
                                            using (FormatHTM htmRoot = new FormatHTM(pathRoot, mapEntity, mapSchema, included))
                                            {
                                                htmRoot.WriteComputerListing(docModelView.Name, docModelView.Code, iCodeView);
                                            }

                                            // show filtered schemas for model views only if exchanges defined
                                            if (Properties.Settings.Default.ConceptTables)
                                            {
                                                DocModelView[] modelviews = docProject.GetViewInheritance(docModelView);

                                                DoExport(docProject, path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\" + docModelView.Code + ".exp", modelviews, locales, instances);
                                                DoExport(docProject, path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\" + docModelView.Code + ".xsd", modelviews, locales, instances);
                                                DoExport(docProject, path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\" + docModelView.Code + ".ifc", modelviews, locales, instances);
                                                DoExport(docProject, path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\" + docModelView.Code + ".ifcxml", modelviews, locales, instances);
                                                DoExport(docProject, path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\" + docModelView.Code + ".xml", modelviews, locales, instances);

                                                using (FormatHTM htmExpress = new FormatHTM(path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\" + docModelView.Code + ".exp.htm", mapEntity, mapSchema, included))
                                                {
                                                    htmExpress.UseAnchors = true;
                                                    htmExpress.WriteHeader("EXPRESS", 3);
                                                    htmExpress.WriteExpressSchema(docProject);
                                                    htmExpress.WriteFooter("");
                                                }

                                                // Future: write XSD with html markup...
                                                using (FormatHTM htmXSD = new FormatHTM(path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\" + docModelView.Code + ".xsd.htm", mapEntity, mapSchema, included))
                                                {
                                                    string xsdcontent = null;
                                                    using (System.IO.StreamReader reader = new System.IO.StreamReader(path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\" + docModelView.Code + ".xsd"))
                                                    {
                                                        xsdcontent = reader.ReadToEnd();
                                                    }

                                                    htmXSD.UseAnchors = false;
                                                    htmXSD.WriteHeader("XSD", 3);
                                                    htmXSD.WriteFormatted(xsdcontent);
                                                    htmXSD.WriteFooter("");
                                                }
                                            }

                                            DoExport(docProject, path + @"\annex\annex-a\" + MakeLinkName(docModelView) + @"\" + docModelView.Code + ".mvdxml", new DocModelView[] { docModelView }, locales, instances);

                                        }
                                    }
                                }
                                break;

                            case 'B':
                                // alphabetical listings
                                htmTOC.WriteTOC(1, "B.1 Definitions");
                                htmSectionTOC.WriteLine("<tr><td>&nbsp;</td></tr>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1 Definitions</td></tr>");

                                htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/alphabeticalorder_definedtypes.htm\" >B.1.1 Defined types</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1.1 <a href=\"annex-b/alphabeticalorder_definedtypes.htm\" target=\"info\" >Defined types</a></td></tr>");
                                htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/alphabeticalorder_enumtypes.htm\" >B.1.2 Enumeration types</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1.2 <a href=\"annex-b/alphabeticalorder_enumtypes.htm\" target=\"info\" >Enumeration types</a></td></tr>");
                                htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/alphabeticalorder_selecttypes.htm\" >B.1.3 Select types</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1.3 <a href=\"annex-b/alphabeticalorder_selecttypes.htm\" target=\"info\" >Select types</a></td></tr>");
                                htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/alphabeticalorder_entities.htm\" >B.1.4 Entities</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1.4 <a href=\"annex-b/alphabeticalorder_entities.htm\" target=\"info\" >Entities</a></td></tr>");
                                htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/alphabeticalorder_functions.htm\" >B.1.5 Functions</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1.5 <a href=\"annex-b/alphabeticalorder_functions.htm\" target=\"info\" >Functions</a></td></tr>");
                                htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/alphabeticalorder_rules.htm\" >B.1.6 Rules</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1.6 <a href=\"annex-b/alphabeticalorder_rules.htm\" target=\"info\" >Rules</a></td></tr>");
                                htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/alphabeticalorder_psets.htm\" >B.1.7 Property sets</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1.7 <a href=\"annex-b/alphabeticalorder_psets.htm\" target=\"info\" >Property sets</a></td></tr>");
                                htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/alphabeticalorder_qsets.htm\" >B.1.8 Quantity sets</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1.8 <a href=\"annex-b/alphabeticalorder_qsets.htm\" target=\"info\" >Quantity sets</a></td></tr>");

                                htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/alphabeticalorder_psets.htm\" >B.1.9 Individual properties</a>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B.1.9 <a href=\"annex-b/alphabeticalorder_properties.htm\" target=\"info\" >Individual properties</a></td></tr>");

                                // locales
                                int indexb = 1;
                                foreach (string locale in listLocale.Keys)
                                {
                                    indexb++;

                                    string localeheader = locale.ToUpper();
                                    if (locale == "zh")
                                    {
                                        localeheader += " [Chinese]"; // no language-generic info available
                                    }
                                    else
                                    {
                                        try
                                        {
                                            System.Globalization.CultureInfo cultureinfo = System.Globalization.CultureInfo.GetCultureInfo(locale);
                                            if (cultureinfo != null)
                                            {
                                                localeheader += " [" + cultureinfo.EnglishName + "]";
                                            }
                                        }
                                        catch
                                        {
                                        }
                                    }

                                    // each locale
                                    htmSectionTOC.WriteLine("<tr><td>&nbsp;</td></tr>");

                                    htmTOC.WriteTOC(1, "B." + indexb.ToString() + " " + localeheader);
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B." + indexb.ToString() + " " + localeheader + "</td></tr>");

                                    htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/" + locale.ToLower() + "/alphabeticalorder_definedtypes.htm\" >B." + indexb.ToString() + ".1 Defined types</a>");
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B." + indexb.ToString() + ".1 <a href=\"annex-b/" + locale.ToLower() + "/alphabeticalorder_definedtypes.htm\" target=\"info\" >Defined types</a></td></tr>");
                                    htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/" + locale.ToLower() + "/alphabeticalorder_enumtypes.htm\" >B." + indexb.ToString() + ".2 Enumeration types</a>");
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B." + indexb.ToString() + ".2 <a href=\"annex-b/" + locale.ToLower() + "/alphabeticalorder_enumtypes.htm\" target=\"info\" >Enumeration types</a></td></tr>");
                                    htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/" + locale.ToLower() + "/alphabeticalorder_selecttypes.htm\" >B." + indexb.ToString() + ".3 Select types</a>");
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B." + indexb.ToString() + ".3 <a href=\"annex-b/" + locale.ToLower() + "/alphabeticalorder_selecttypes.htm\" target=\"info\" >Select types</a></td></tr>");
                                    htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/" + locale.ToLower() + "/alphabeticalorder_entities.htm\" >B." + indexb.ToString() + ".4 Entities</a>");
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B." + indexb.ToString() + ".4 <a href=\"annex-b/" + locale.ToLower() + "/alphabeticalorder_entities.htm\" target=\"info\" >Entities</a></td></tr>");
                                    htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/" + locale.ToLower() + "/alphabeticalorder_functions.htm\" >B." + indexb.ToString() + ".5 Functions</a>");
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B." + indexb.ToString() + ".5 <a href=\"annex-b/" + locale.ToLower() + "/alphabeticalorder_functions.htm\" target=\"info\" >Functions</a></td></tr>");
                                    htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/" + locale.ToLower() + "/alphabeticalorder_rules.htm\" >B." + indexb.ToString() + ".6 Rules</a>");
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">B." + indexb.ToString() + ".6 <a href=\"annex-b/" + locale.ToLower() + "/alphabeticalorder_rules.htm\" target=\"info\" >Rules</a></td></tr>");

                                    /* no translations currently -- enable in future
                                    htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/" + locale.ToLower() + "/alphabeticalorder_psets.htm\" >B." + indexb.ToString() + ".7 Property sets</a>");
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a href=\"annex-b/" + locale.ToLower() + "/alphabeticalorder_psets.htm\" target=\"info\" >B." + indexb.ToString() + ".7 Property sets</a></td></tr>");
                                    htmTOC.WriteTOC(2, "<a class=\"listing-link\" href=\"annex/annex-b/" + locale.ToLower() + "/alphabeticalorder_qsets.htm\" >B." + indexb.ToString() + ".8 Quantity sets</a>");
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a href=\"annex-b/" + locale.ToLower() + "/alphabeticalorder_qsets.htm\" target=\"info\" >B." + indexb.ToString() + ".8 Quantity sets</a></td></tr>");
                                     */
                                }

                                // generate alphabetical listings
                                using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/alphabeticalorder_definedtypes.htm", mapEntity, mapSchema, included))
                                {
                                    htmAlpha1.WriteAlphabeticalListing<DocDefined>("Defined Types", path, "definedtypes");
                                }
                                using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/alphabeticalorder_enumtypes.htm", mapEntity, mapSchema, included))
                                {
                                    htmAlpha1.WriteAlphabeticalListing<DocEnumeration>("Enumeration Types", path, "enumtypes");
                                }
                                using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/alphabeticalorder_selecttypes.htm", mapEntity, mapSchema, included))
                                {
                                    htmAlpha1.WriteAlphabeticalListing<DocSelect>("Select Types", path, "selecttypes");
                                }
                                using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/alphabeticalorder_entities.htm", mapEntity, mapSchema, included))
                                {
                                    htmAlpha1.WriteAlphabeticalListing<DocEntity>("Entities", path, "entities");
                                }
                                using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/alphabeticalorder_functions.htm", mapEntity, mapSchema, included))
                                {
                                    htmAlpha1.WriteAlphabeticalListing<DocFunction>("Functions", path, "functions");
                                }
                                using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/alphabeticalorder_rules.htm", mapEntity, mapSchema, included))
                                {
                                    htmAlpha1.WriteAlphabeticalListing<DocGlobalRule>("Rules", path, "rules");
                                }
                                // no translations currently -- enable in future
                                using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/alphabeticalorder_psets.htm", mapEntity, mapSchema, included))
                                {
                                    htmAlpha1.WriteAlphabeticalListing<DocPropertySet>("Property Sets", path, "psets");
                                }
                                using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/alphabeticalorder_qsets.htm", mapEntity, mapSchema, included))
                                {
                                    htmAlpha1.WriteAlphabeticalListing<DocQuantitySet>("Quantity Sets", path, "qsets");
                                }
                                

                                // generate localized listings
                                foreach (string locale in listLocale.Keys)
                                {
                                    string code = listLocale[locale]; // null for default

                                    using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/" + locale + "/alphabeticalorder_definedtypes.htm", mapEntity, mapSchema, included))
                                    {
                                        htmAlpha1.WriteLocalizedListing<DocDefined>("Defined Types", code, path, "definedtypes");
                                    }
                                    using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/" + locale + "/alphabeticalorder_enumtypes.htm", mapEntity, mapSchema, included))
                                    {
                                        htmAlpha1.WriteLocalizedListing<DocEnumeration>("Enumeration Types", code, path, "enumtypes");
                                    }
                                    using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/" + locale + "/alphabeticalorder_selecttypes.htm", mapEntity, mapSchema, included))
                                    {
                                        htmAlpha1.WriteLocalizedListing<DocSelect>("Select Types", code, path, "selecttypes");
                                    }
                                    using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/" + locale + "/alphabeticalorder_entities.htm", mapEntity, mapSchema, included))
                                    {
                                        htmAlpha1.WriteLocalizedListing<DocEntity>("Entities", code, path, "entities");
                                    }
                                    using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/" + locale + "/alphabeticalorder_functions.htm", mapEntity, mapSchema, included))
                                    {
                                        htmAlpha1.WriteLocalizedListing<DocFunction>("Functions", code, path, "functions");
                                    }
                                    using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/" + locale + "/alphabeticalorder_rules.htm", mapEntity, mapSchema, included))
                                    {
                                        htmAlpha1.WriteLocalizedListing<DocGlobalRule>("Rules", code, path, "rules");
                                    }
                                    using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/" + locale + "/alphabeticalorder_psets.htm", mapEntity, mapSchema, included))
                                    {
                                        htmAlpha1.WriteLocalizedListing<DocPropertySet>("Property Sets", code, path, "psets");
                                    }
                                    using (FormatHTM htmAlpha1 = new FormatHTM(path + "/annex/annex-b/" + locale + "/alphabeticalorder_qsets.htm", mapEntity, mapSchema, included))
                                    {
                                        htmAlpha1.WriteLocalizedListing<DocQuantitySet>("Quantity Sets", code, path, "qsets");
                                    }

                                }
                                break;

                            case 'C':
                                // Inheritance listings

                                if (docProject.ModelViews != null)
                                {
                                    iView = 0;
                                    foreach (DocModelView docView in docProject.ModelViews)
                                    {
                                        if (included == null || included.ContainsKey(docView))
                                        {
                                            iView++;

                                            htmSectionTOC.WriteLine("<tr><td>&nbsp;</td></tr>");

                                            htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"annex/annex-c/" + MakeLinkName(docView) + "/index.htm\" >C." + iView + " " + docView.Name + "</a>");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">C." + iView + " <a href=\"annex-c/" + MakeLinkName(docView) + "/index.htm\" target=\"info\" >" + docView.Name + "</a></td></tr>");

                                            // diagram for view
                                            if (!Properties.Settings.Default.SkipDiagrams)
                                            {
                                                Dictionary<DocObject, bool> viewinclude = new Dictionary<DocObject, bool>();
                                                Dictionary<Rectangle, DocEntity> mapRectangle = new Dictionary<Rectangle, DocEntity>();
                                                docProject.RegisterObjectsInScope(docView, viewinclude);
                                                using (Image imgDiagram = FormatPNG.CreateInheritanceDiagram(docProject, viewinclude, docEntityRoot, null, new Font(FontFamily.GenericSansSerif, 8.0f), mapRectangle))
                                                {
                                                    using (FormatHTM htmCover = new FormatHTM(path + @"\annex\annex-c\" + MakeLinkName(docView) + @"\index.htm", mapEntity, mapSchema, included))
                                                    {
                                                        htmCover.WriteHeader(docView.Name, 3);
                                                        htmCover.WriteLine("<h2 class=\"std\">C." + iView + " " + docView.Name + " Inheritance</h2>");
                                                        htmCover.WriteLine("<img src=\"cover.png\" usemap=\"#f\"/>");
                                                        htmCover.WriteLine("<map name=\"f\">");

                                                        foreach (Rectangle rc in mapRectangle.Keys)
                                                        {
                                                            DocEntity docEntref = mapRectangle[rc];
                                                            DocSchema docEntsch = docProject.GetSchemaOfDefinition(docEntref);

                                                            string hyperlink = "../../../schema/" + docEntsch.Name.ToLower() + "/lexical/" + docEntref.Name.ToLower() + ".htm";
                                                            htmCover.WriteLine("<area shape=\"rect\" coords=\"" + rc.Left + "," + rc.Top + "," + rc.Right + "," + rc.Bottom + "\" href=\"" + hyperlink + "\" alt=\"" + docEntref.Name + "\" />");
                                                        }
                                                        htmCover.WriteLine("</map>");
                                                        htmCover.WriteLinkTo("inheritance-" + MakeLinkName(docView), 3);
                                                        htmCover.WriteFooter(String.Empty);

                                                        using (FormatHTM htmLink = new FormatHTM(path + "/link/inheritance-" + MakeLinkName(docView) + ".htm", mapEntity, mapSchema, included))
                                                        {
                                                            htmLink.WriteLinkPage("../annex/annex-c/" + DocumentationISO.MakeLinkName(docView) + "/index.htm");
                                                        }
                                                    }

                                                    // create image after (depends on directory being created first)
                                                    try
                                                    {
                                                        imgDiagram.Save(path + @"\annex\annex-c\" + MakeLinkName(docView) + @"\cover.png");
                                                    }
                                                    catch
                                                    {

                                                    }
                                                }
                                            }

                                                                                            

                                            // all entities
                                            htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"annex/annex-c/" + MakeLinkName(docView) + "/all.htm\" >C." + iView + ".1 All entities</a>");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">C." + iView + ".1 <a href=\"annex-c/" + MakeLinkName(docView) + "/all.htm\" target=\"info\" >All entities</a></td></tr>");
                                            using (FormatHTM htmInheritAll = new FormatHTM(path + "/annex/annex-c/" + MakeLinkName(docView) + "/all.htm", mapEntity, mapSchema, included))
                                            {
                                                htmInheritAll.WriteInheritanceListing(null, false, "All entities", docView, path, "all");
                                            }

                                            // specific inheritance
                                            htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"annex/annex-c/" + MakeLinkName(docView) + "/roots.htm\" >C." + iView + ".2 Rooted entities</a>");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">C." + iView + ".2 <a href=\"annex-c/" + MakeLinkName(docView) + "/roots.htm\" target=\"info\" >Rooted entities</a></td></tr>");
                                            using (FormatHTM htmInheritAll = new FormatHTM(path + "/annex/annex-c/" + MakeLinkName(docView) + "/roots.htm", mapEntity, mapSchema, included))
                                            {
                                                htmInheritAll.WriteInheritanceListing("IfcRoot", false, "Rooted entities", docView, path, "roots");
                                            }

                                            htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"annex/annex-c/" + MakeLinkName(docView) + "/types.htm\" >C." + iView + ".3 Object types</a>");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">C." + iView + ".3 <a href=\"annex-c/" + MakeLinkName(docView) + "/types.htm\" target=\"info\" >Object types</a></td></tr>");
                                            using (FormatHTM htmInheritAll = new FormatHTM(path + "/annex/annex-c/" + MakeLinkName(docView) + "/types.htm", mapEntity, mapSchema, included))
                                            {
                                                htmInheritAll.WriteInheritanceListing("IfcObject", true, "Object types", docView, path, "types");
                                            }

                                            htmSectionTOC.WriteLine("<tr><td>&nbsp;</td></tr>");
                                        
                                        }
                                    }
                                }
                                break;

                            case 'D':
                                // Diagrams

                                // Express-G diagrams
                                htmTOC.WriteTOC(1, "D.1 Schema diagrams");
                                htmSectionTOC.WriteLine("<tr><td>&nbsp;</td></tr>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">D.1 Schema diagrams</td></tr>");

                                for (int iSchemaSection = 5; iSchemaSection <= 8; iSchemaSection++)
                                {
                                    DocSection docSection = docProject.Sections[iSchemaSection - 1];

                                    int iDiagramSection = iSchemaSection - 4;

                                    htmTOC.WriteTOC(2, "D.1." + iDiagramSection + " " + docSection.Name);
                                    htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">D.1." + iDiagramSection + " " + docSection.Name + "</td></tr>");


                                    int iSchema = 0;
                                    for (int iSchemaIndex = 1; iSchemaIndex <= docSection.Schemas.Count; iSchemaIndex++)
                                    {
                                        DocSchema docSchema = docSection.Schemas[iSchemaIndex - 1];
                                        if (included == null || included.ContainsKey(docSchema))
                                        {
                                            iSchema++;

                                            htmTOC.WriteTOC(3, "<a class=\"listing-link\" href=\"annex/annex-d/" + MakeLinkName(docSchema) + "/index.htm\" >D.1." + iDiagramSection + "." + iSchema + " " + docSchema.Name + "</a>");
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">D.1." + iDiagramSection + "." + iSchema + " <a href=\"annex-d/" + MakeLinkName(docSchema) + "/index.htm\" target=\"info\" >" + docSchema.Name + "</a></td></tr>");

                                            // determine number of diagrams
                                            int iLastDiagram = docSchema.GetDiagramCount();

                                            // generate diagrams
                                            if (!Properties.Settings.Default.SkipDiagrams)
                                            {
                                                Image imageSchema = FormatPNG.CreateSchemaDiagram(docSchema, mapEntity);

                                                using (FormatHTM htmSchemaDiagram = new FormatHTM(path + "/annex/annex-d/" + MakeLinkName(docSchema) + "/index.htm", mapEntity, mapSchema, included))
                                                {
                                                    int iSub = 1;

                                                    htmSchemaDiagram.WriteHeader(docSection.Name, 3);
                                                    htmSchemaDiagram.WriteScript(iAnnex, iSub, iSection, 0);
                                                    htmSchemaDiagram.WriteLine("<h4 class=\"std\">D.1." + iDiagramSection + "." + iSchema + " " + docSchema.Name + "</h4>");

                                                    htmSchemaDiagram.WriteLine("<p>");

                                                    // write thumbnail links for each diagram
                                                    for (int iDiagram = 1; iDiagram <= iLastDiagram; iDiagram++)
                                                    {
                                                        string formatnumber = iDiagram.ToString("D4"); // 0001
                                                        htmSchemaDiagram.WriteLine("<a href=\"diagram_" + formatnumber + ".htm\">" +
                                                            "<img src=\"diagram_" + formatnumber + ".png\" width=\"300\" height=\"444\" /></a>"); // width=\"150\" height=\"222\"> 

                                                        // generate EXPRESS-G diagram
                                                        if (docSchema.DiagramPagesHorz != 0)
                                                        {
                                                            int pageY = (iDiagram - 1) / docSchema.DiagramPagesHorz;
                                                            int pageX = (iDiagram - 1) % docSchema.DiagramPagesHorz;
                                                            int pagePixelCX = CtlExpressG.PageX;
                                                            int pagePixelCY = CtlExpressG.PageY;
                                                            using (Image imagePage = new Bitmap(pagePixelCX, pagePixelCY))
                                                            {
                                                                using (Graphics g = Graphics.FromImage(imagePage))
                                                                {
                                                                    g.DrawImage(imageSchema, new Rectangle(0, 0, pagePixelCX, pagePixelCY), new Rectangle(pagePixelCX * pageX, pagePixelCY * pageY, pagePixelCX, pagePixelCY), GraphicsUnit.Pixel);
                                                                }
                                                                imagePage.Save(path + "/annex/annex-d/" + MakeLinkName(docSchema) + "/diagram_" + formatnumber + ".png");
                                                            }
                                                        }
                                                    }

                                                    htmSchemaDiagram.WriteLine("</p>");
                                                    htmSchemaDiagram.WriteFooter(Properties.Settings.Default.Footer);
                                                }


                                                double scale = 0.375; // hard-coded for now -- read from SCHEMATA.scale
                                                double pageCX = 1600; // hard-coded for now -- read from SCHEMATA.settings.page.width
                                                double pageCY = 2370; // hard-coded for now -- read from SCHEMATA.settings.page.height

                                                for (int iDiagram = 1; iDiagram <= iLastDiagram; iDiagram++)
                                                {
                                                    string formatnumber = iDiagram.ToString("D4");
                                                    using (FormatHTM htmSchema = new FormatHTM(path + "/annex/annex-d/" + MakeLinkName(docSchema) + "/diagram_" + formatnumber + ".htm", mapEntity, mapSchema, included))
                                                    {
                                                        htmSchema.WriteHeader(docSchema.Name, 3);
                                                        htmSchema.WriteScript(iAnnex, 1, iDiagramSection, iDiagram);

                                                        htmSchema.WriteLine("<h4 class=\"std\">");
                                                        if (iDiagram > 1)
                                                        {
                                                            htmSchema.Write("<a href=\"diagram_" + (iDiagram - 1).ToString("D4") + ".htm\"><img src=\"../../../img/navleft.png\" style=\"border: 0px\" /></a>");
                                                        }
                                                        else
                                                        {
                                                            // disabled
                                                            htmSchema.Write("<img src=\"../../../img/navleft.png\" style=\"border: 0px\" />");
                                                        }
                                                        if (iDiagram < iLastDiagram)
                                                        {
                                                            htmSchema.Write("<a href=\"diagram_" + (iDiagram + 1).ToString("D4") + ".htm\"><img src=\"../../../img/navright.png\" style=\"border: 0px\" /></a>");
                                                        }
                                                        else
                                                        {
                                                            // disabled
                                                            htmSchema.Write("<img src=\"../../../img/navright.png\" style=\"border: 0px\" />");
                                                        }
                                                        htmSchema.Write(" " + docSchema.Name + " (" + iDiagram + "/" + iLastDiagram + ")");
                                                        htmSchema.WriteLine("</h4>");

                                                        htmSchema.WriteLine("<img src=\"diagram_" + formatnumber + ".png\" usemap=\"#diagram\" >");
                                                        htmSchema.WriteLine("  <map name=\"diagram\" >");
                                                        foreach (DocType docType in docSchema.Types)
                                                        {
                                                            if ((included == null || included.ContainsKey(docType)) && docType.DiagramNumber == iDiagram && docType.DiagramRectangle != null)
                                                            {
                                                                double x0 = docType.DiagramRectangle.X % pageCX * scale;
                                                                double y0 = docType.DiagramRectangle.Y % pageCY * scale;
                                                                double x1 = docType.DiagramRectangle.X % pageCX * scale + docType.DiagramRectangle.Width % pageCX * scale;
                                                                double y1 = docType.DiagramRectangle.Y % pageCY * scale + docType.DiagramRectangle.Height % pageCY * scale;
                                                                string link = "../../../schema/" + mapSchema[docType.Name].ToLower() + "/lexical/" + docType.Name.ToLower() + ".htm";
                                                                htmSchema.WriteLine("    <area shape=\"rect\" coords=\"" + x0 + ", " + y0 + ", " + x1 + ", " + y1 + "\" alt=\"Navigate\" href=\"" + link + "\" />");
                                                            }
                                                        }
                                                        foreach (DocEntity docType in docSchema.Entities)
                                                        {
                                                            if ((included == null || included.ContainsKey(docType)) && docType.DiagramNumber == iDiagram && docType.DiagramRectangle != null)
                                                            {
                                                                double x0 = docType.DiagramRectangle.X % pageCX * scale;
                                                                double y0 = docType.DiagramRectangle.Y % pageCY * scale;
                                                                double x1 = docType.DiagramRectangle.X % pageCX * scale + docType.DiagramRectangle.Width % pageCX * scale;
                                                                double y1 = docType.DiagramRectangle.Y % pageCY * scale + docType.DiagramRectangle.Height % pageCY * scale;
                                                                string link = "../../../schema/" + mapSchema[docType.Name].ToLower() + "/lexical/" + docType.Name.ToLower() + ".htm";
                                                                htmSchema.WriteLine("    <area shape=\"rect\" coords=\"" + x0 + ", " + y0 + ", " + x1 + ", " + y1 + "\" alt=\"Navigate\" href=\"" + link + "\" />");
                                                            }
                                                        }
                                                        if (docSchema.PageTargets != null)
                                                        {
                                                            foreach (DocPageTarget docPageTarget in docSchema.PageTargets)
                                                            {
                                                                foreach (DocPageSource docPageSource in docPageTarget.Sources)
                                                                {
                                                                    if (docPageSource.DiagramNumber == iDiagram && docPageSource.DiagramRectangle != null)
                                                                    {
                                                                        double x0 = docPageSource.DiagramRectangle.X % pageCX * scale;
                                                                        double y0 = docPageSource.DiagramRectangle.Y % pageCY * scale;
                                                                        double x1 = docPageSource.DiagramRectangle.X % pageCX * scale + docPageSource.DiagramRectangle.Width % pageCX * scale;
                                                                        double y1 = docPageSource.DiagramRectangle.Y % pageCY * scale + docPageSource.DiagramRectangle.Height % pageCY * scale;
                                                                        string link = "diagram_" + docPageTarget.DiagramNumber.ToString("D4") + ".htm";
                                                                        htmSchema.WriteLine("    <area shape=\"rect\" coords=\"" + x0 + ", " + y0 + ", " + x1 + ", " + y1 + "\" alt=\"Navigate\" href=\"" + link + "\" />");
                                                                    }
                                                                }
                                                            }
                                                        }
                                                        if (docSchema.SchemaRefs != null)
                                                        {
                                                            foreach (DocSchemaRef docSchemaRef in docSchema.SchemaRefs)
                                                            {
                                                                foreach (DocDefinitionRef docDefinitionRef in docSchemaRef.Definitions)
                                                                {
                                                                    if (docDefinitionRef.DiagramNumber == iDiagram && docDefinitionRef.DiagramRectangle != null)
                                                                    {
                                                                        double x0 = docDefinitionRef.DiagramRectangle.X % pageCX * scale;
                                                                        double y0 = docDefinitionRef.DiagramRectangle.Y % pageCY * scale;
                                                                        double x1 = docDefinitionRef.DiagramRectangle.X % pageCX * scale + docDefinitionRef.DiagramRectangle.Width % pageCX * scale;
                                                                        double y1 = docDefinitionRef.DiagramRectangle.Y % pageCY * scale + docDefinitionRef.DiagramRectangle.Height % pageCY * scale;

                                                                        if (mapSchema.ContainsKey(docDefinitionRef.Name))
                                                                        {
                                                                            DocDefinition docDef = mapEntity[docDefinitionRef.Name] as DocDefinition;
                                                                            if (included == null || included.ContainsKey(docDef))
                                                                            {
                                                                                string link = "../../../schema/" + mapSchema[docDefinitionRef.Name].ToLower() + "/lexical/" + docDefinitionRef.Name.ToLower() + ".htm";
                                                                                htmSchema.WriteLine("    <area shape=\"rect\" coords=\"" + x0 + ", " + y0 + ", " + x1 + ", " + y1 + "\" alt=\"Navigate\" href=\"" + link + "\" />");
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                        htmSchema.WriteLine("  </map>");
                                                        htmSchema.WriteLine("</img>");
                                                        htmSchema.WriteFooter(Properties.Settings.Default.Footer);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }

                                // Instance diagrams
                                htmTOC.WriteTOC(1, "D.2 Instance diagrams");
                                htmSectionTOC.WriteLine("<tr><td>&nbsp;</td></tr>");
                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">D.2 Instance diagrams</td></tr>");

                                // D.1 -- schema diagrams - express-G
                                // D.1.1 -- core layer
                                // D.1.2 -- shared layer
                                // D.1.3 -- domain layer
                                // D.1.4 -- resource layer
                                // D.1.4.1~ schema

                                // D.2 -- instance diagrams
                                // D.2.1~  model view
                                // D.2.1.1~  entity

                                if (docProject.ModelViews != null)
                                {
                                    iView = 0;
                                    foreach (DocModelView docView in docProject.ModelViews)
                                    {
                                        if (included == null || included.ContainsKey(docView))
                                        {
                                            iView++;

                                            htmTOC.WriteTOC(2, "D.2." + iView.ToString() + " " + docView.Name);
                                            htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">D.2." + iView.ToString() + "<a href=\"annex-d/" + MakeLinkName(docView) + "/cover.htm\" target=\"info\"> " + docView.Name + "</a></td></tr>");


                                            Dictionary<DocObject, bool> viewinclude = new Dictionary<DocObject, bool>();
                                            Dictionary<Rectangle, DocEntity> mapRectangle = new Dictionary<Rectangle, DocEntity>();
                                            docProject.RegisterObjectsInScope(docView, viewinclude);
                                            using (FormatHTM htmCover = new FormatHTM(path + @"\annex\annex-d\" + MakeLinkName(docView) + @"\cover.htm", mapEntity, mapSchema, included))
                                            {
                                                htmCover.WriteHeader(docView.Name, 3);
                                                htmCover.WriteLine("<h3 class=\"std\">D.2." + iView + " " + docView.Name + " Diagrams</h3>");
                                                htmCover.WriteFooter(String.Empty);
                                            }

                                            // sort by entity name
                                            SortedList<string, DocConceptRoot> listEntity = new SortedList<string, DocConceptRoot>();
                                            foreach (DocConceptRoot docRoot in docView.ConceptRoots)
                                            {
                                                if (docRoot.ApplicableEntity != null)
                                                {
                                                    if (!listEntity.ContainsKey(docRoot.ApplicableEntity.Name)) // only one concept root per entity per view currently supported
                                                    {
                                                        listEntity.Add(docRoot.ApplicableEntity.Name, docRoot);
                                                    }
                                                }
                                            }

                                            // now generate
                                            int iRoot = 0;
                                            foreach (DocConceptRoot docRoot in listEntity.Values)
                                            {
                                                iRoot++;

                                                htmTOC.WriteTOC(3, "<a class=\"listing-link\" href=\"annex/annex-d/" + MakeLinkName(docView) + "/" + MakeLinkName(docRoot.ApplicableEntity) + ".htm\" >D.2." + iView.ToString() + "." + iRoot.ToString() + " " + docRoot.ApplicableEntity.Name + "</a>");
                                                htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">D.2." + iView.ToString() + "." + iRoot.ToString() + " <a href=\"annex-d/" + MakeLinkName(docView) + "/" + MakeLinkName(docRoot.ApplicableEntity) + ".htm\" target=\"info\">" + docRoot.ApplicableEntity.Name + "</a></td></tr>");

                                                string pathRoot = path + @"\annex\annex-d\" + MakeLinkName(docView) + @"\" + MakeLinkName(docRoot.ApplicableEntity) + ".htm";
                                                using (FormatHTM htmRoot = new FormatHTM(pathRoot, mapEntity, mapSchema, included))
                                                {
                                                    htmRoot.WriteHeader(docRoot.ApplicableEntity.Name, iAnnex, 2, 0, iView, Properties.Settings.Default.Header);
                                                    htmRoot.WriteScript(iAnnex, 2, iView, iRoot);
                                                    htmRoot.WriteLine("<h3 class=\"std\">D.2." + iView.ToString() + "." + iRoot.ToString() + " " + docRoot.ApplicableEntity.Name + "</h3>");

                                                    string diagram = FormatDiagram(docProject, docRoot.ApplicableEntity, docView, listFigures, mapEntity, mapSchema);
                                                    htmRoot.WriteLine(diagram);

                                                    htmRoot.WriteFooter(Properties.Settings.Default.Footer);
                                                }

                                            }
                                        }
                                    }
                                }                                
                                break;

                            case 'E':
                                if (docProject.Examples != null)
                                {
                                    List<DocXsdFormat> xsdFormatBase = new List<DocXsdFormat>();
                                    foreach(DocSection docSection in docProject.Sections)
                                    {
                                        foreach(DocSchema docSchema in docSection.Schemas)
                                        {
                                            foreach(DocEntity docEntity in docSchema.Entities)
                                            {
                                                foreach(DocAttribute docAttr in docEntity.Attributes)
                                                {
                                                    if(docAttr.XsdFormat != DocXsdFormatEnum.Default || docAttr.XsdTagless != null)
                                                    {
                                                        DocXsdFormat xsdformat = new DocXsdFormat();
                                                        xsdformat.Entity = docEntity.Name;
                                                        xsdformat.Attribute = docAttr.Name;
                                                        xsdformat.XsdFormat = docAttr.XsdFormat;
                                                        xsdformat.XsdTagless = docAttr.XsdTagless;
                                                        xsdFormatBase.Add(xsdformat);
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    List<int> indexpath = new List<int>();
                                    indexpath.Add(0);
                                    foreach(DocExample docExample in docProject.Examples)
                                    {
                                        Dictionary<string, Type> typemap = new Dictionary<string, Type>();
                                        Compiler compiler = new Compiler(docProject, docExample.Views.ToArray(), null);
                                        System.Reflection.Emit.AssemblyBuilder assembly = compiler.Assembly;
                                        try
                                        {
                                            Type[] types = assembly.GetTypes();
                                            foreach (Type t in types)
                                            {
                                                typemap.Add(t.Name.ToUpper(), t);
                                            }
                                        }
                                        catch
                                        {
                                            // schema could not be compiled according to definition
                                        }

                                        List<DocXsdFormat> listFormats = new List<DocXsdFormat>(xsdFormatBase);
                                        if (docExample.Views.Count > 0)
                                        {
                                            foreach (DocXsdFormat customformat in docExample.Views[0].XsdFormats)
                                            {
                                                listFormats.Add(customformat);
                                            }
                                        }

                                        GenerateExample(docExample, listFormats, path, indexpath, included, mapEntity, mapSchema, typemap, listFigures, listTables, htmTOC, htmSectionTOC);
                                    }
                                }
                                break;

                            case 'F':
                                if (docProject.ChangeSets != null)
                                {
                                    for (int iChangeset = 1; iChangeset <= docProject.ChangeSets.Count; iChangeset++)
                                    {
                                        DocChangeSet docChangeSet = docProject.ChangeSets[iChangeset - 1];

                                        // what's new page
                                        htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"annex/annex-f/" + MakeLinkName(docChangeSet) + "/index.htm\" >F." + iChangeset + " " + docChangeSet.Name + "</a>");
                                        htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\">F." + iChangeset + " <a href=\"annex-f/" + MakeLinkName(docChangeSet) + "/index.htm\" target=\"info\" >" + docChangeSet.Name + "</a></td></tr>");
                                        using (FormatHTM htmWhatsnew = new FormatHTM(path + @"\annex\annex-f\" + MakeLinkName(docChangeSet) + @"\index.htm", mapEntity, mapSchema, included))
                                        {
                                            htmWhatsnew.WriteHeader(docChangeSet.Name, 3);
                                            htmWhatsnew.WriteScript(iAnnex, iChangeset, 0, 0);
                                            htmWhatsnew.WriteLine("<h4 class=\"std\">F." + iChangeset + " " + docChangeSet.Name + "</h4>");
                                            htmWhatsnew.WriteDocumentationForISO(docChangeSet.Documentation, docChangeSet, false);
                                            htmWhatsnew.WriteLinkTo(MakeLinkName(docChangeSet), 3);
                                            htmWhatsnew.WriteFooter(Properties.Settings.Default.Footer);
                                        }

                                        // change log for entities
                                        htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"annex/annex-f/" + MakeLinkName(docChangeSet) + "/changelog.htm\" >F." + iChangeset + ".1 Entities</a>");
                                        htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a href=\"annex-f/" + MakeLinkName(docChangeSet) + "/changelog.htm\" target=\"info\" >F." + iChangeset + ".1 Entities</a></td></tr>");
                                        string pathChange = path + @"\annex\annex-f\" + MakeLinkName(docChangeSet) + @"\changelog.htm";
                                        using (FormatHTM htmChange = new FormatHTM(pathChange, mapEntity, mapSchema, included))
                                        {
                                            htmChange.WriteHeader(docChangeSet.Name, 3);
                                            htmChange.WriteScript(iAnnex, iChangeset, 1, 0);
                                            htmChange.WriteLine("<h4 class=\"std\">F." + iChangeset + ".1 Entities</h4>");

                                            htmChange.WriteLine("<table class=\"gridtable\">");
                                            htmChange.WriteLine("<tr>" +
                                                "<th>Item</th>" +
                                                "<th>SPF</th>" +
                                                "<th>XML</th>" +
                                                "<th>Change</th>" +
                                                "<th>Description</th>" +
                                                "</tr>");

                                            foreach (DocChangeAction docChangeItem in docChangeSet.ChangesEntities)
                                            {
                                                htmChange.WriteChangeItem(docChangeItem, 0);
                                            }

                                            htmChange.WriteLine("</table>");
                                            htmChange.WriteLinkTo(MakeLinkName(docChangeSet) + "-changelog", 3);
                                            htmChange.WriteFooter(Properties.Settings.Default.Footer);
                                        }

                                        // change log for properties
                                        htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"annex/annex-f/" + MakeLinkName(docChangeSet) + "/properties.htm\" >F." + iChangeset + ".2 Properties</a>");
                                        htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a href=\"annex-f/" + MakeLinkName(docChangeSet) + "/properties.htm\" target=\"info\" >F." + iChangeset + ".1 Properties</a></td></tr>");
                                        pathChange = path + @"\annex\annex-f\" + MakeLinkName(docChangeSet) + @"\properties.htm";
                                        using (FormatHTM htmChange = new FormatHTM(pathChange, mapEntity, mapSchema, included))
                                        {
                                            htmChange.WriteHeader(docChangeSet.Name, 3);
                                            htmChange.WriteScript(iAnnex, iChangeset, 1, 0);
                                            htmChange.WriteLine("<h4 class=\"std\">F." + iChangeset + ".2 Properties</h4>");

                                            htmChange.WriteLine("<table class=\"gridtable\">");
                                            htmChange.WriteLine("<tr>" +
                                                "<th>Item</th>" +
                                                "<th>SPF</th>" +
                                                "<th>XML</th>" +
                                                "<th>Change</th>" +
                                                "<th>Description</th>" +
                                                "</tr>");

                                            if (docChangeSet.ChangesProperties != null)
                                            {
                                                foreach (DocChangeAction docChangeItem in docChangeSet.ChangesProperties)
                                                {
                                                    htmChange.WriteChangeItem(docChangeItem, 0);
                                                }
                                            }

                                            htmChange.WriteLine("</table>");
                                            htmChange.WriteLinkTo(MakeLinkName(docChangeSet) + "-properties", 3);
                                            htmChange.WriteFooter(Properties.Settings.Default.Footer);
                                        }


                                        // change log for quantities
                                        htmTOC.WriteTOC(1, "<a class=\"listing-link\" href=\"annex/annex-f/" + MakeLinkName(docChangeSet) + "/quantities.htm\" >F." + iChangeset + ".3 Quantities</a>");
                                        htmSectionTOC.WriteLine("<tr class=\"std\"><td class=\"menu\"><a href=\"annex-f/" + MakeLinkName(docChangeSet) + "/quantities.htm\" target=\"info\" >F." + iChangeset + ".3 Quantities</a></td></tr>");
                                        pathChange = path + @"\annex\annex-f\" + MakeLinkName(docChangeSet) + @"\quantities.htm";
                                        using (FormatHTM htmChange = new FormatHTM(pathChange, mapEntity, mapSchema, included))
                                        {
                                            htmChange.WriteHeader(docChangeSet.Name, 3);
                                            htmChange.WriteScript(iAnnex, iChangeset, 1, 0);
                                            htmChange.WriteLine("<h4 class=\"std\">F." + iChangeset + ".3 Quantities</h4>");

                                            htmChange.WriteLine("<table class=\"gridtable\">");
                                            htmChange.WriteLine("<tr>" +
                                                "<th>Item</th>" +
                                                "<th>SPF</th>" +
                                                "<th>XML</th>" +
                                                "<th>Change</th>" +
                                                "<th>Description</th>" +
                                                "</tr>");

                                            if (docChangeSet.ChangesQuantities != null)
                                            {
                                                foreach (DocChangeAction docChangeItem in docChangeSet.ChangesQuantities)
                                                {
                                                    htmChange.WriteChangeItem(docChangeItem, 0);
                                                }
                                            }

                                            htmChange.WriteLine("</table>");
                                            htmChange.WriteLinkTo(MakeLinkName(docChangeSet) + "-quantities", 3);
                                            htmChange.WriteFooter(Properties.Settings.Default.Footer);
                                        }

                                    }
                                }
                                break;
                        }

                        htmSectionTOC.WriteLine(
                            "</table>\r\n" +
                            "</div>\r\n" +
                            "</body>\r\n" +
                            "</html>\r\n");
                    }

                    chAnnex++;
                }

                // bibliography
                try
                {
                    using (FormatHTM htmSection = new FormatHTM(path + @"\bibliography.htm", mapEntity, mapSchema, included))
                    {
                        htmSection.WriteHeader("Bibliography", 0);

                        htmSection.Write(
                            "\r\n" +
                            "<script type=\"text/javascript\">\r\n" +
                            "<!--\r\n" +
                            "    parent.index.location.replace(\"blank.htm\");\r\n" +
                            "//-->\r\n" +
                            "</script>\r\n");

                        htmSection.WriteLine("<h1>Bibliography</h1>");

                        htmSection.WriteLine("<dl>");
                        if (docProject.InformativeReferences != null)
                        {
                            foreach (DocReference docRef in docProject.InformativeReferences)
                            {
                                htmSection.WriteLine("<dt class=\"bibliographyreference\"><a id=\"" + MakeLinkName(docRef) + "\" id=\"" + MakeLinkName(docRef) + "\">" + docRef.Name + "</a>, <i>" + docRef.Documentation + "</i></dt>");
                                htmSection.WriteLine("<dd>&nbsp;</dd>");
                            }
                        }
                        htmSection.WriteLine("</dl>");

                        htmSection.WriteFooter(Properties.Settings.Default.Footer);
                    }
                }
                catch
                {
                    htmTOC.ToString();
                }

                htmTOC.WriteLine("</p>");


                // write figures
                htmTOC.WriteLine("<h1 class=\"std\">Figures</h1>");
                htmTOC.WriteLine("<p>");
                htmTOC.WriteContentRefs(listFigures, "Figure");
                htmTOC.WriteLine("</p>");

                htmTOC.WriteLine("<p></p>");

                // write tables
                htmTOC.WriteLine("<h1 class=\"std\">Tables</h1>");
                htmTOC.WriteLine("<p>");
                htmTOC.WriteContentRefs(listTables, "Table");
                htmTOC.WriteLine("</p>");

                htmTOC.WriteFooter(Properties.Settings.Default.Footer);
            }

            worker.ReportProgress(++progressCurrent, "Index");
            if (worker.CancellationPending)
                return;

            // generate index -- takes very long, so only run when changing
            SortedList<string, DocObject> listIndex = new SortedList<string, DocObject>();
            foreach (string key in mapEntity.Keys)
            {
                listIndex.Add(key, mapEntity[key]);
            }

            using (FormatHTM htmIndex = new FormatHTM(path + "/doc_index.htm", mapEntity, mapSchema, included)) // file name "doc_index" required by ISO
            {
                htmIndex.WriteHeader("Index", 0);

                htmIndex.Write(
                    "\r\n" +
                    "<script type=\"text/javascript\">\r\n" +
                    "<!--\r\n" +
                    "    parent.index.location.replace(\"blank.htm\");\r\n" +
                    "//-->\r\n" +
                    "</script>\r\n");

                htmIndex.WriteLine(
                    "<div class=\"not-numbered\">\r\n" +
                    "<h1 class=\"std\">Index</h1>\r\n" +
                    "<p class=\"std\">\r\n");

                foreach (string key in listIndex.Keys)
                {
                    DocObject obj = mapEntity[key];
                    if (included == null || included.ContainsKey(obj))
                    {
                        htmIndex.WriteLine("<b>" + key + "</b> ");

                        // build ordered list of references in documentation
                        SortedDictionary<string, string> mapRefs = new SortedDictionary<string, string>();
                        foreach (string refkey1 in listIndex.Keys)
                        {
                            string doc = mapEntity[refkey1].Documentation;
                            if (doc != null)// && key != refkey) // also include main ref for ISO
                            {
                                if (refkey1 == key || doc.Contains(key))
                                {
                                    DocObject refobj = (DocObject)mapEntity[refkey1];

                                    string refnumber = null;
                                    if (mapNumber != null && mapNumber.TryGetValue(refobj, out refnumber))
                                    {
                                        mapRefs.Add(refnumber, refkey1);
                                    }

                                }
                            }
                        }

                        // search references of terms in documentation
                        string comma = "";
                        foreach (string refnumber in mapRefs.Keys)
                        {
                            string refkey = mapRefs[refnumber];

                            DocObject refobj = (DocObject)mapEntity[refkey];
                            string display = refobj.Name;//refnumber; // new: use names for bSI; numbers for ISO

                            if (refobj is DocPropertySet || refobj is DocPropertyEnumeration)
                            {
                                htmIndex.Write(comma + "<a class=\"listing-link\" title=\"" + refobj.Name + "\" href=\"schema/" + mapSchema[refkey].ToLower() + "/pset/" + refobj.Name.ToLower() + ".htm\">" + display + "</a>");
                            }
                            else if (refobj is DocQuantitySet)
                            {
                                htmIndex.Write(comma + "<a class=\"listing-link\" title=\"" + refobj.Name + "\" href=\"schema/" + mapSchema[refkey].ToLower() + "/qset/" + refobj.Name.ToLower() + ".htm\">" + display + "</a>");
                            }
                            else
                            {
                                htmIndex.Write(comma + "<a class=\"listing-link\" title=\"" + refobj.Name + "\" href=\"schema/" + mapSchema[refkey].ToLower() + "/lexical/" + refobj.Name.ToLower() + ".htm\">" + display + "</a>");
                            }

                            comma = ", ";
                        }

                        htmIndex.WriteLine("<br />\r\n");
                    }
                }

                worker.ReportProgress(++progressCurrent, "Links");
                if (worker.CancellationPending)
                    return;

                // new: incoming links
                foreach(DocSection docLinkSection in docProject.Sections)
                {
                    int iSection = docProject.Sections.IndexOf(docLinkSection) + 1;
                    using (FormatHTM htmLink = new FormatHTM(path + "/link/chapter-" + iSection.ToString() + ".htm", mapEntity, mapSchema, included))
                    {
                        htmLink.WriteLinkPage("../schema/chapter-" + iSection.ToString() + ".htm");
                    }

                    foreach (DocSchema docLinkSchema in docLinkSection.Schemas)
                    {
                        using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docLinkSchema) + ".htm", mapEntity, mapSchema, included))
                        {
                            htmLink.WriteLinkPage("../schema/" + docLinkSchema.Name.ToLower() + "/content.htm");
                        }

                        foreach (DocEntity docLinkObj in docLinkSchema.Entities)
                        {
                            if (included == null || included.ContainsKey(docLinkObj))
                            {
                                using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docLinkObj) + ".htm", mapEntity, mapSchema, included))
                                {
                                    htmLink.WriteLinkPage("../schema/" + docLinkSchema.Name.ToLower() + "/lexical/" + MakeLinkName(docLinkObj) + ".htm");
                                }
                            }
                        }

                        foreach(DocType docLinkObj in docLinkSchema.Types)
                        {
                            if (included == null || included.ContainsKey(docLinkObj))
                            {
                                using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docLinkObj) + ".htm", mapEntity, mapSchema, included))
                                {
                                    htmLink.WriteLinkPage("../schema/" + docLinkSchema.Name.ToLower() + "/lexical/" + MakeLinkName(docLinkObj) + ".htm");
                                }
                            }
                        }

                        foreach (DocFunction docLinkObj in docLinkSchema.Functions)
                        {
                            if (included == null || included.ContainsKey(docLinkObj))
                            {
                                using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docLinkObj) + ".htm", mapEntity, mapSchema, included))
                                {
                                    htmLink.WriteLinkPage("../schema/" + docLinkSchema.Name.ToLower() + "/lexical/" + MakeLinkName(docLinkObj) + ".htm");
                                }
                            }
                        }

                        foreach (DocGlobalRule docLinkObj in docLinkSchema.GlobalRules)
                        {
                            if (included == null || included.ContainsKey(docLinkObj))
                            {
                                using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docLinkObj) + ".htm", mapEntity, mapSchema, included))
                                {
                                    htmLink.WriteLinkPage("../schema/" + docLinkSchema.Name.ToLower() + "/lexical/" + MakeLinkName(docLinkObj) + ".htm");
                                }
                            }
                        }

                        foreach (DocPropertySet docLinkObj in docLinkSchema.PropertySets)
                        {
                            if (included == null || included.ContainsKey(docLinkObj))
                            {
                                using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docLinkObj) + ".htm", mapEntity, mapSchema, included))
                                {
                                    htmLink.WriteLinkPage("../schema/" + docLinkSchema.Name.ToLower() + "/pset/" + MakeLinkName(docLinkObj) + ".htm");
                                }
                            }
                        }

                        foreach (DocPropertyEnumeration docLinkObj in docLinkSchema.PropertyEnums)
                        {
                            if (included == null || included.ContainsKey(docLinkObj))
                            {
                                using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docLinkObj) + ".htm", mapEntity, mapSchema, included))
                                {
                                    htmLink.WriteLinkPage("../schema/" + docLinkSchema.Name.ToLower() + "/pset/" + MakeLinkName(docLinkObj) + ".htm");
                                }
                            }
                        }

                        foreach (DocQuantitySet docLinkObj in docLinkSchema.QuantitySets)
                        {
                            if (included == null || included.ContainsKey(docLinkObj))
                            {
                                using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docLinkObj) + ".htm", mapEntity, mapSchema, included))
                                {
                                    htmLink.WriteLinkPage("../schema/" + docLinkSchema.Name.ToLower() + "/qset/" + MakeLinkName(docLinkObj) + ".htm");
                                }
                            }
                        }
                    }
                }

                char chAnnex = 'a';
                foreach(DocAnnex docAnnex in docProject.Annexes)
                {
                    using (FormatHTM htmLink = new FormatHTM(path + "/link/annex-" + chAnnex + ".htm", mapEntity, mapSchema, included))
                    {
                        htmLink.WriteLinkPage("../annex/annex-" + chAnnex + ".htm");
                    }

                    chAnnex++;
                }

                foreach(DocAnnotation docAnnot in docProject.Annotations)
                {
                    using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docAnnot) + ".htm", mapEntity, mapSchema, included))
                    {
                        htmLink.WriteLinkPage("../" + MakeLinkName(docAnnot) + ".htm");
                    }
                }

                foreach(DocChangeSet docChange in docProject.ChangeSets)
                {
                    using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docChange) + ".htm", mapEntity, mapSchema, included))
                    {
                        htmLink.WriteLinkPage("../annex/annex-f/" + MakeLinkName(docChange) + "/index.htm");
                    }
                    using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docChange) + "-changelog.htm", mapEntity, mapSchema, included))
                    {
                        htmLink.WriteLinkPage("../annex/annex-f/" + MakeLinkName(docChange) + "/changelog.htm");
                    }
                    using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docChange) + "-properties.htm", mapEntity, mapSchema, included))
                    {
                        htmLink.WriteLinkPage("../annex/annex-f/" + MakeLinkName(docChange) + "/properties.htm");
                    }
                    using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(docChange) + "-quantities.htm", mapEntity, mapSchema, included))
                    {
                        htmLink.WriteLinkPage("../annex/annex-f/" + MakeLinkName(docChange) + "/quantities.htm");
                    }
                }

                foreach(DocModelView docView in docProject.ModelViews)
                {
                    if (docView.Code != null)
                    {
                        using (FormatHTM htmLink = new FormatHTM(path + "/link/listing-" + docView.Code.ToLower() + ".htm", mapEntity, mapSchema, included))
                        {
                            htmLink.WriteLinkPage("../annex/annex-a/" + MakeLinkName(docView) + "/index.htm");
                        }
                    }
                }

#if false
                foreach (string key in listIndex.Keys)
                {
                    DocObject obj = mapEntity[key];
                    if (included == null || included.ContainsKey(obj))
                    {
                        string schemaname = null;
                        if (mapSchema.TryGetValue(obj.Name, out schemaname))
                        {
                            using (FormatHTM htmLink = new FormatHTM(path + "/link/" + MakeLinkName(obj) + ".htm", mapEntity, mapSchema, included))
                            {
                                string linkurl = "../schema/" + schemaname.ToLower() + "/lexical/" + MakeLinkName(obj) + ".htm";
                                if (obj is DocPropertySet || obj is DocPropertyEnumeration)
                                {
                                    linkurl = "../schema/" + schemaname.ToLower() + "/pset/" + MakeLinkName(obj) + ".htm";
                                }
                                else if (obj is DocQuantitySet)
                                {
                                    linkurl = "../schema/" + schemaname.ToLower() + "/qset/" + MakeLinkName(obj) + ".htm";
                                }

                                htmLink.WriteLinkPage(linkurl);
                            }
                        }
                    }
                }
#endif

                // write links for each concept template recursively
                List<DocTemplateDefinition> listLink = new List<DocTemplateDefinition>();
                foreach (DocTemplateDefinition docTemplate in docProject.Templates)
                {
                    listLink.Add(docTemplate);
                    GenerateTemplateLink(listLink, mapEntity, mapSchema, included);
                    listLink.Clear();
                }

                // write links for each example recursively
                List<DocExample> listLinkExample = new List<DocExample>();
                if (docProject.Examples != null)
                {
                    foreach (DocExample docTemplate in docProject.Examples)
                    {
                        listLinkExample.Add(docTemplate);
                        GenerateExampleLink(listLinkExample, mapEntity, mapSchema, included);
                        listLinkExample.Clear();
                    }
                }

                htmIndex.WriteLine("</p>");
                htmIndex.WriteFooter(Properties.Settings.Default.Footer);
            }
        }
Exemple #14
0
        public static void LoadAssembly(DocProject project, Assembly assem)
        {
            // look through classes of assembly
            foreach (Type t in assem.GetTypes())
            {
                if (t.Namespace != null)
                {
                    string[]   namespaceparts = t.Namespace.Split('.');
                    string     schema         = namespaceparts[namespaceparts.Length - 1];
                    DocSection docSection     = null;
                    if (t.Namespace.EndsWith("Resource"))
                    {
                        docSection = project.Sections[7];
                    }
                    else if (t.Namespace.EndsWith("Domain"))
                    {
                        docSection = project.Sections[6];
                    }
                    else if (t.Namespace.Contains("Shared"))
                    {
                        docSection = project.Sections[5];
                    }
                    else
                    {
                        docSection = project.Sections[4];                         // kernel, extensions
                    }

                    // find schema
                    DocSchema docSchema = null;
                    foreach (DocSchema docEachSchema in docSection.Schemas)
                    {
                        if (docEachSchema.Name.Equals(schema))
                        {
                            docSchema = docEachSchema;
                            break;
                        }
                    }

                    if (docSchema == null)
                    {
                        docSchema      = new DocSchema();
                        docSchema.Name = schema;
                        docSection.Schemas.Add(docSchema);
                        docSection.SortSection();
                    }

                    DocDefinition docDef = null;
                    if (t.IsEnum)
                    {
                        DocEnumeration docEnum = new DocEnumeration();
                        docSchema.Types.Add(docEnum);
                        docDef = docEnum;

                        System.Reflection.FieldInfo[] fields = t.GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
                        foreach (System.Reflection.FieldInfo field in fields)
                        {
                            DocConstant docConst = new DocConstant();
                            docEnum.Constants.Add(docConst);
                            docConst.Name = field.Name;

                            DescriptionAttribute[] attrs = (DescriptionAttribute[])field.GetCustomAttributes(typeof(DescriptionAttribute), false);
                            if (attrs.Length == 1)
                            {
                                docConst.Documentation = attrs[0].Description;
                            }
                        }
                    }
                    else if (t.IsValueType)
                    {
                        PropertyInfo[] fields = t.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                        if (fields.Length > 0)
                        {
                            Type typeField = fields[0].PropertyType;

                            DocDefined docDefined = new DocDefined();
                            docSchema.Types.Add(docDefined);
                            docDef = docDefined;
                            docDefined.DefinedType = FormatCSC.GetExpressType(typeField);

                            if (typeField.IsGenericType)
                            {
                                Type typeGeneric = typeField.GetGenericTypeDefinition();
                                typeField = typeField.GetGenericArguments()[0];
                                if (typeGeneric == typeof(ISet <>) ||
                                    typeGeneric == typeof(HashSet <>))
                                {
                                    docDefined.Aggregation = new DocAttribute();
                                    docDefined.Aggregation.AggregationType = (int)DocAggregationEnum.SET;
                                }
                                else if (typeGeneric == typeof(IList <>) ||
                                         typeGeneric == typeof(List <>))
                                {
                                    docDefined.Aggregation = new DocAttribute();
                                    docDefined.Aggregation.AggregationType = (int)DocAggregationEnum.LIST;
                                }
                            }

                            MaxLengthAttribute mxa = (MaxLengthAttribute)fields[0].GetCustomAttribute(typeof(MaxLengthAttribute));
                            if (mxa != null)
                            {
                                docDefined.Length = mxa.Length;
                            }
                        }
                    }
                    else if (t.IsInterface)
                    {
                        DocSelect docSelect = new DocSelect();
                        docSchema.Types.Add(docSelect);
                        docDef = docSelect;
                    }
                    else if (t.IsClass)
                    {
                        DocEntity docEntity = new DocEntity();
                        docSchema.Entities.Add(docEntity);
                        docDef = docEntity;

                        if (t.BaseType != null)
                        {
                            if (t.BaseType != typeof(object) && t.BaseType.Name != "SEntity")                             // back-compat for reflecting on IfcDoc types to generate Express
                            {
                                docEntity.BaseDefinition = t.BaseType.Name;
                            }
                        }

                        docEntity.IsAbstract = t.IsAbstract;

                        Dictionary <int, DocAttribute> attrsDirect  = new Dictionary <int, DocAttribute>();
                        List <DocAttribute>            attrsInverse = new List <DocAttribute>();
                        PropertyInfo[] fields = t.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | BindingFlags.DeclaredOnly);
                        foreach (PropertyInfo field in fields)
                        {
                            DocAttribute docAttr = new DocAttribute();
                            docAttr.Name = field.Name;

                            Type typeField = field.PropertyType;
                            if (typeField.IsGenericType)
                            {
                                Type typeGeneric = typeField.GetGenericTypeDefinition();
                                typeField = typeField.GetGenericArguments()[0];
                                if (typeGeneric == typeof(Nullable <>))
                                {
                                    docAttr.IsOptional = true;
                                }
                                else if (typeGeneric == typeof(ISet <>) ||
                                         typeGeneric == typeof(HashSet <>))
                                {
                                    docAttr.AggregationType = (int)DocAggregationEnum.SET;
                                }
                                else if (typeGeneric == typeof(IList <>) ||
                                         typeGeneric == typeof(List <>))
                                {
                                    docAttr.AggregationType = (int)DocAggregationEnum.LIST;
                                }
                            }

                            // primitives
                            docAttr.DefinedType = FormatCSC.GetExpressType(typeField);

                            MinLengthAttribute mla = (MinLengthAttribute)field.GetCustomAttribute(typeof(MinLengthAttribute));
                            if (mla != null)
                            {
                                docAttr.AggregationLower = mla.Length.ToString();
                            }

                            MaxLengthAttribute mxa = (MaxLengthAttribute)field.GetCustomAttribute(typeof(MaxLengthAttribute));
                            if (mxa != null)
                            {
                                docAttr.AggregationUpper = mxa.Length.ToString();
                            }

                            DescriptionAttribute da = (DescriptionAttribute)field.GetCustomAttribute(typeof(DescriptionAttribute));
                            if (da != null)
                            {
                                docAttr.Documentation = da.Description;
                            }

                            DataMemberAttribute dma = (DataMemberAttribute)field.GetCustomAttribute(typeof(DataMemberAttribute));
                            if (dma != null)
                            {
                                attrsDirect.Add(dma.Order, docAttr);

                                RequiredAttribute rqa = (RequiredAttribute)field.GetCustomAttribute(typeof(RequiredAttribute));
                                if (rqa == null)
                                {
                                    docAttr.IsOptional = true;
                                }

                                CustomValidationAttribute cva = (CustomValidationAttribute)field.GetCustomAttribute(typeof(CustomValidationAttribute));
                                if (cva != null)
                                {
                                    docAttr.IsUnique = true;
                                }
                            }
                            else
                            {
                                InversePropertyAttribute ipa = (InversePropertyAttribute)field.GetCustomAttribute(typeof(InversePropertyAttribute));
                                if (ipa != null)
                                {
                                    docAttr.Inverse = ipa.Property;
                                    attrsInverse.Add(docAttr);
                                }
                            }

                            // xml
                            XmlIgnoreAttribute xia = (XmlIgnoreAttribute)field.GetCustomAttribute(typeof(XmlIgnoreAttribute));
                            if (xia != null)
                            {
                                docAttr.XsdFormat = DocXsdFormatEnum.Hidden;
                            }
                            else
                            {
                                XmlElementAttribute xea = (XmlElementAttribute)field.GetCustomAttribute(typeof(XmlElementAttribute));
                                if (xea != null)
                                {
                                    if (!String.IsNullOrEmpty(xea.ElementName))
                                    {
                                        docAttr.XsdFormat = DocXsdFormatEnum.Element;
                                    }
                                    else
                                    {
                                        docAttr.XsdFormat = DocXsdFormatEnum.Attribute;
                                    }
                                }
                            }
                        }

                        foreach (DocAttribute docAttr in attrsDirect.Values)
                        {
                            docEntity.Attributes.Add(docAttr);
                        }

                        foreach (DocAttribute docAttr in attrsInverse)
                        {
                            docEntity.Attributes.Add(docAttr);
                        }

                        // get derived attributes based on properties
#if false
                        PropertyInfo[] props = t.GetProperties(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public);
                        foreach (PropertyInfo prop in props)
                        {
                            // if no backing field, then derived
                            FieldInfo field = t.GetField("_" + prop.Name, BindingFlags.NonPublic | BindingFlags.Instance);
                            if (field == null)
                            {
                                DocAttribute docDerived = new DocAttribute();
                                docDerived.Name = prop.Name;
                                docEntity.Attributes.Add(docDerived);
                            }
                        }
#endif
                    }

                    if (docDef != null)
                    {
                        docDef.Name = t.Name;
                        docDef.Uuid = t.GUID;
                    }

                    docSchema.SortTypes();
                    docSchema.SortEntities();
                }
            }

            // pass 2: hook up selects
            foreach (Type t in assem.GetTypes())
            {
                Type[] typeInterfaces = t.GetInterfaces();

                Type[] typeInherit = null;
                if (t.BaseType != null)
                {
                    typeInherit = t.BaseType.GetInterfaces();
                }

                if (typeInterfaces.Length > 0)
                {
                    foreach (Type typeI in typeInterfaces)
                    {
                        if (typeInherit == null || !typeInherit.Contains <Type>(typeI))
                        {
                            DocSelect docSelect = project.GetDefinition(typeI.Name) as DocSelect;
                            if (docSelect != null)
                            {
                                DocSelectItem docItem = new DocSelectItem();
                                docItem.Name = t.Name;
                                docSelect.Selects.Add(docItem);
                            }
                        }
                    }
                }
            }
        }
Exemple #15
0
        /// <summary>
        /// Loads all content from a folder hierarchy (overlaying anything already existing)
        /// </summary>
        /// <param name="project"></param>
        /// <param name="path"></param>
        public static void Load(DocProject project, string path)
        {
            // get all files within folder hierarchy
            string pathSchema         = path + @"\schemas";
            IEnumerable <string> en   = System.IO.Directory.EnumerateFiles(pathSchema, "*.cs", System.IO.SearchOption.AllDirectories);
            List <string>        list = new List <string>();

            foreach (string s in en)
            {
                list.Add(s);
            }
            string[] files = list.ToArray();

            Dictionary <string, string> options = new Dictionary <string, string> {
                { "CompilerVersion", "v4.0" }
            };

            Microsoft.CSharp.CSharpCodeProvider        prov  = new Microsoft.CSharp.CSharpCodeProvider(options);
            System.CodeDom.Compiler.CompilerParameters parms = new System.CodeDom.Compiler.CompilerParameters();
            parms.GenerateInMemory   = true;
            parms.GenerateExecutable = false;
            parms.ReferencedAssemblies.Add("System.dll");
            parms.ReferencedAssemblies.Add("System.Core.dll");
            parms.ReferencedAssemblies.Add("System.ComponentModel.dll");
            parms.ReferencedAssemblies.Add("System.ComponentModel.DataAnnotations.dll");
            parms.ReferencedAssemblies.Add("System.Data.dll");
            parms.ReferencedAssemblies.Add("System.Runtime.Serialization.dll");
            parms.ReferencedAssemblies.Add("System.Xml.dll");

            System.CodeDom.Compiler.CompilerResults results = prov.CompileAssemblyFromFile(parms, files);
            System.Reflection.Assembly assem = results.CompiledAssembly;

            // look through classes of assembly
            foreach (Type t in assem.GetTypes())
            {
                string[]   namespaceparts = t.Namespace.Split('.');
                string     schema         = namespaceparts[namespaceparts.Length - 1];
                DocSection docSection     = null;
                if (t.Namespace.EndsWith("Resource"))
                {
                    docSection = project.Sections[7];
                }
                else if (t.Namespace.EndsWith("Domain"))
                {
                    docSection = project.Sections[6];
                }
                else if (t.Namespace.Contains("Shared"))
                {
                    docSection = project.Sections[5];
                }
                else
                {
                    docSection = project.Sections[4]; // kernel, extensions
                }

                // find schema
                DocSchema docSchema = null;
                foreach (DocSchema docEachSchema in docSection.Schemas)
                {
                    if (docEachSchema.Name.Equals(schema))
                    {
                        docSchema = docEachSchema;
                        break;
                    }
                }

                if (docSchema == null)
                {
                    docSchema      = new DocSchema();
                    docSchema.Name = schema;
                    docSection.Schemas.Add(docSchema);
                    docSection.SortSchemas();
                }

                DocDefinition docDef = null;
                if (t.IsEnum)
                {
                    DocEnumeration docEnum = new DocEnumeration();
                    docSchema.Types.Add(docEnum);
                    docDef = docEnum;

                    System.Reflection.FieldInfo[] fields = t.GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
                    foreach (System.Reflection.FieldInfo field in fields)
                    {
                        DocConstant docConst = new DocConstant();
                        docEnum.Constants.Add(docConst);
                        docConst.Name = field.Name;

                        DescriptionAttribute[] attrs = (DescriptionAttribute[])field.GetCustomAttributes(typeof(DescriptionAttribute), false);
                        if (attrs.Length == 1)
                        {
                            docConst.Documentation = attrs[0].Description;
                        }
                    }
                }
                else if (t.IsValueType)
                {
                    DocDefined docDefined = new DocDefined();
                    docSchema.Types.Add(docDefined);
                    docDef = docDefined;

                    PropertyInfo[] fields = t.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                    docDefined.DefinedType = fields[0].PropertyType.Name;
                }
                else if (t.IsInterface)
                {
                    DocSelect docSelect = new DocSelect();
                    docSchema.Types.Add(docSelect);
                    docDef = docSelect;
                }
                else if (t.IsClass)
                {
                    DocEntity docEntity = new DocEntity();
                    docSchema.Entities.Add(docEntity);
                    docDef = docEntity;

                    if (t.BaseType != typeof(object))
                    {
                        docEntity.BaseDefinition = t.BaseType.Name;
                    }

                    if (!t.IsAbstract)
                    {
                        docEntity.EntityFlags = 0x20;
                    }

                    Dictionary <int, DocAttribute> attrsDirect  = new Dictionary <int, DocAttribute>();
                    List <DocAttribute>            attrsInverse = new List <DocAttribute>();
                    PropertyInfo[] fields = t.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
                    foreach (PropertyInfo field in fields)
                    {
                        DocAttribute docAttr = new DocAttribute();
                        docAttr.Name = field.Name.Substring(1);

                        Type typeField = field.PropertyType;
                        if (typeField.IsGenericType)
                        {
                            Type typeGeneric = typeField.GetGenericTypeDefinition();
                            typeField = typeField.GetGenericArguments()[0];
                            if (typeGeneric == typeof(Nullable <>))
                            {
                                docAttr.IsOptional = true;
                            }
                            else if (typeGeneric == typeof(ISet <>))
                            {
                                docAttr.AggregationType = (int)DocAggregationEnum.SET;
                            }
                            else if (typeGeneric == typeof(IList <>))
                            {
                                docAttr.AggregationType = (int)DocAggregationEnum.LIST;
                            }
                        }

                        docAttr.DefinedType = typeField.Name;


                        MinLengthAttribute mla = (MinLengthAttribute)field.GetCustomAttribute(typeof(MinLengthAttribute));
                        if (mla != null)
                        {
                            docAttr.AggregationLower = mla.Length.ToString();
                        }

                        MaxLengthAttribute mxa = (MaxLengthAttribute)field.GetCustomAttribute(typeof(MaxLengthAttribute));
                        if (mxa != null)
                        {
                            docAttr.AggregationUpper = mxa.Length.ToString();
                        }

                        PropertyInfo propinfo = t.GetProperty(docAttr.Name);
                        if (propinfo != null)
                        {
                            DescriptionAttribute da = (DescriptionAttribute)propinfo.GetCustomAttribute(typeof(DescriptionAttribute));
                            if (da != null)
                            {
                                docAttr.Documentation = da.Description;
                            }
                        }

                        DataMemberAttribute dma = (DataMemberAttribute)field.GetCustomAttribute(typeof(DataMemberAttribute));
                        if (dma != null)
                        {
                            attrsDirect.Add(dma.Order, docAttr);

                            RequiredAttribute rqa = (RequiredAttribute)field.GetCustomAttribute(typeof(RequiredAttribute));
                            if (rqa == null)
                            {
                                docAttr.IsOptional = true;
                            }

                            CustomValidationAttribute cva = (CustomValidationAttribute)field.GetCustomAttribute(typeof(CustomValidationAttribute));
                            if (cva != null)
                            {
                                docAttr.IsUnique = true;
                            }
                        }
                        else
                        {
                            InversePropertyAttribute ipa = (InversePropertyAttribute)field.GetCustomAttribute(typeof(InversePropertyAttribute));
                            if (ipa != null)
                            {
                                docAttr.Inverse = ipa.Property;
                                attrsInverse.Add(docAttr);
                            }
                        }

                        // xml
                        XmlIgnoreAttribute xia = (XmlIgnoreAttribute)field.GetCustomAttribute(typeof(XmlIgnoreAttribute));
                        if (xia != null)
                        {
                            docAttr.XsdFormat = DocXsdFormatEnum.Hidden;
                        }
                        else
                        {
                            XmlElementAttribute xea = (XmlElementAttribute)field.GetCustomAttribute(typeof(XmlElementAttribute));
                            if (xea != null)
                            {
                                if (!String.IsNullOrEmpty(xea.ElementName))
                                {
                                    docAttr.XsdFormat = DocXsdFormatEnum.Element;
                                }
                                else
                                {
                                    docAttr.XsdFormat = DocXsdFormatEnum.Attribute;
                                }
                            }
                        }
                    }

                    foreach (DocAttribute docAttr in attrsDirect.Values)
                    {
                        docEntity.Attributes.Add(docAttr);
                    }

                    foreach (DocAttribute docAttr in attrsInverse)
                    {
                        docEntity.Attributes.Add(docAttr);
                    }

                    // get derived attributes based on properties
                    PropertyInfo[] props = t.GetProperties(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public);
                    foreach (PropertyInfo prop in props)
                    {
                        // if no backing field, then derived
                        FieldInfo field = t.GetField("_" + prop.Name, BindingFlags.NonPublic | BindingFlags.Instance);
                        if (field == null)
                        {
                            DocAttribute docDerived = new DocAttribute();
                            docDerived.Name = prop.Name;
                            docEntity.Attributes.Add(docDerived);
                        }
                    }
                }

                if (docDef != null)
                {
                    docDef.Name = t.Name;
                    docDef.Uuid = t.GUID;
                }

                docSchema.SortTypes();
                docSchema.SortEntities();
            }

            // pass 2: hook up selects
            foreach (Type t in assem.GetTypes())
            {
                Type[] typeInterfaces = t.GetInterfaces();
                if (typeInterfaces.Length > 0)
                {
                    foreach (Type typeI in typeInterfaces)
                    {
                        DocSelect docSelect = project.GetDefinition(typeI.Name) as DocSelect;
                        if (docSelect != null)
                        {
                            DocSelectItem docItem = new DocSelectItem();
                            docItem.Name = t.Name;
                            docSelect.Selects.Add(docItem);
                        }
                    }
                }
            }

            // EXPRESS rules (eventually in C#, though .exp file snippets for now)
            en = System.IO.Directory.EnumerateFiles(pathSchema, "*.exp", System.IO.SearchOption.AllDirectories);
            foreach (string file in en)
            {
                string name = Path.GetFileNameWithoutExtension(file);
                string expr = null;
                using (StreamReader readExpr = new StreamReader(file, Encoding.UTF8))
                {
                    expr = readExpr.ReadToEnd();
                }

                if (name.Contains('-'))
                {
                    // where rule
                    string[] parts = name.Split('-');
                    if (parts.Length == 2)
                    {
                        DocWhereRule docWhere = new DocWhereRule();
                        docWhere.Name       = parts[1];
                        docWhere.Expression = expr;

                        DocDefinition docDef = project.GetDefinition(parts[0]);
                        if (docDef is DocEntity)
                        {
                            DocEntity docEnt = (DocEntity)docDef;
                            docEnt.WhereRules.Add(docWhere);
                        }
                        else if (docDef is DocDefined)
                        {
                            DocDefined docEnt = (DocDefined)docDef;
                            docEnt.WhereRules.Add(docWhere);
                        }
                        else if (docDef == null)
                        {
                            //... global rule...
                        }
                    }
                }
                else
                {
                    // function
                    string schema = Path.GetDirectoryName(file);
                    schema = Path.GetDirectoryName(schema);
                    schema = Path.GetFileName(schema);
                    DocSchema docSchema = project.GetSchema(schema);
                    if (docSchema != null)
                    {
                        DocFunction docFunction = new DocFunction();
                        docSchema.Functions.Add(docFunction);
                        docFunction.Name       = name;
                        docFunction.Expression = expr;
                    }
                }
            }

            // now, hook up html documentation
            en = System.IO.Directory.EnumerateFiles(pathSchema, "*.htm", System.IO.SearchOption.AllDirectories);
            foreach (string file in en)
            {
                string    name   = Path.GetFileNameWithoutExtension(file);
                DocObject docObj = null;
                if (name == "schema")
                {
                    string schema = Path.GetDirectoryName(file);
                    schema = Path.GetFileName(schema);
                    docObj = project.GetSchema(schema);
                }
                else if (name.Contains('-'))
                {
                    // where rule
                    string[] parts = name.Split('-');
                    if (parts.Length == 2)
                    {
                        DocDefinition docDef = project.GetDefinition(parts[0]);
                        if (docDef is DocEntity)
                        {
                            DocEntity docEnt = (DocEntity)docDef;
                            foreach (DocWhereRule docWhereRule in docEnt.WhereRules)
                            {
                                if (docWhereRule.Name.Equals(parts[1]))
                                {
                                    docObj = docWhereRule;
                                    break;
                                }
                            }
                        }
                        else if (docDef is DocDefined)
                        {
                            DocDefined docEnt = (DocDefined)docDef;
                            foreach (DocWhereRule docWhereRule in docEnt.WhereRules)
                            {
                                if (docWhereRule.Name.Equals(parts[1]))
                                {
                                    docObj = docWhereRule;
                                    break;
                                }
                            }
                        }
                    }
                }
                else
                {
                    docObj = project.GetDefinition(name);

                    if (docObj == null)
                    {
                        docObj = project.GetFunction(name);
                    }
                }

                if (docObj != null)
                {
                    using (StreamReader readHtml = new StreamReader(file, Encoding.UTF8))
                    {
                        docObj.Documentation = readHtml.ReadToEnd();
                    }
                }
            }

            // load schema diagrams
            en = System.IO.Directory.EnumerateFiles(pathSchema, "*.svg", System.IO.SearchOption.AllDirectories);
            foreach (string file in en)
            {
                string schema = Path.GetDirectoryName(file);
                schema = Path.GetFileName(schema);

                DocSchema docSchema = project.GetSchema(schema);
                if (docSchema != null)
                {
                    using (IfcDoc.Schema.SVG.SchemaSVG schemaSVG = new IfcDoc.Schema.SVG.SchemaSVG(file, docSchema, project))
                    {
                        schemaSVG.Load();
                    }
                }
            }

            // psets, qsets
            //...

            // exchanges
            en = System.IO.Directory.EnumerateFiles(path, "*.mvdxml", System.IO.SearchOption.AllDirectories);
            foreach (string file in en)
            {
                IfcDoc.Schema.MVD.SchemaMVD.Load(project, file);
            }

            // examples
            string pathExamples = path + @"\examples";

            if (Directory.Exists(pathExamples))
            {
                en = System.IO.Directory.EnumerateFiles(pathExamples, "*.htm", SearchOption.TopDirectoryOnly);
                foreach (string file in en)
                {
                    DocExample docExample = new DocExample();
                    docExample.Name = Path.GetFileNameWithoutExtension(file);
                    project.Examples.Add(docExample);

                    using (StreamReader reader = new StreamReader(file))
                    {
                        docExample.Documentation = reader.ReadToEnd();
                    }

                    string dirpath = file.Substring(0, file.Length - 4);
                    if (Directory.Exists(dirpath))
                    {
                        IEnumerable <string> suben = System.IO.Directory.EnumerateFiles(dirpath, "*.ifc", SearchOption.TopDirectoryOnly);
                        foreach (string ex in suben)
                        {
                            DocExample docEx = new DocExample();
                            docEx.Name = Path.GetFileNameWithoutExtension(ex);
                            docExample.Examples.Add(docEx);

                            // read the content of the file
                            using (FileStream fs = new FileStream(ex, FileMode.Open, FileAccess.Read))
                            {
                                docEx.File = new byte[fs.Length];
                                fs.Read(docEx.File, 0, docEx.File.Length);
                            }

                            // read documentation
                            string exdoc = ex.Substring(0, ex.Length - 4) + ".htm";
                            if (File.Exists(exdoc))
                            {
                                using (StreamReader reader = new StreamReader(exdoc))
                                {
                                    docEx.Documentation = reader.ReadToEnd();
                                }
                            }
                        }
                    }
                }
            }

            // localization
            en = System.IO.Directory.EnumerateFiles(path, "*.txt", System.IO.SearchOption.AllDirectories);
            foreach (string file in en)
            {
                using (FormatCSV format = new FormatCSV(file))
                {
                    try
                    {
                        format.Instance = project;
                        format.Load();
                    }
                    catch
                    {
                    }
                }
            }
        }
        /// <summary>
        /// Builds list of items in order, using inherited concepts.
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="template"></param>
        /// <param name="view"></param>
        private static DocTemplateItem[] FindTemplateItems(DocProject docProject, DocEntity entity, DocTemplateDefinition template, DocModelView view)
        {
            // inherited concepts first

            List<DocTemplateItem> listItems = new List<DocTemplateItem>();
            DocEntity basetype = entity;
            bool inherit = true;
            while (basetype != null)
            {
                // find templates for base
                foreach (DocModelView docView in docProject.ModelViews)
                {
                    if (view == docView || view.BaseView == docView.Name)
                    {
                        foreach (DocConceptRoot docRoot in docView.ConceptRoots)
                        {
                            if (docRoot.ApplicableEntity == basetype)
                            {
                                foreach (DocTemplateUsage eachusage in docRoot.Concepts)
                                {
                                    if (eachusage.Definition == template)
                                    {
                                        // found it

                                        string[] parameters = template.GetParameterNames();

                                        foreach (DocTemplateItem eachitem in eachusage.Items)
                                        {
                                            string[] values = new string[parameters.Length];
                                            for (int iparam = 0; iparam < parameters.Length; iparam++)
                                            {
                                                values[iparam] = eachitem.GetParameterValue(parameters[iparam]);
                                            }

                                            // new (IfcDoc 4.9d): only add if we don't override by parameters matching exactly
                                            bool include = true;
                                            foreach (DocTemplateItem existitem in listItems)
                                            {
                                                bool samevalues = true;

                                                for (int iparam = 0; iparam < parameters.Length; iparam++)
                                                {
                                                    string value = values[iparam];
                                                    string match = existitem.GetParameterValue(parameters[iparam]);
                                                    if (match != value || (match != null && !match.Equals(value, StringComparison.Ordinal)))
                                                    {
                                                        samevalues = false;
                                                        break;
                                                    }
                                                }

                                                if (samevalues)
                                                {
                                                    include = false;
                                                    break;
                                                }
                                            }

                                            if (include)
                                            {
                                                listItems.Add(eachitem);
                                            }
                                        }

                                        inherit = !eachusage.Override;
                                    }
                                }
                            }
                        }
                    }
                }

                // inherit concepts from supertypes unless overriding
                if (basetype.BaseDefinition != null && inherit)
                {
                    basetype = docProject.GetDefinition(basetype.BaseDefinition) as DocEntity;
                }
                else
                {
                    basetype = null;
                }
            }

            return listItems.ToArray();
        }
        private static string FormatField(DocProject docProject, string content, string fieldname, string fieldtype, string fieldvalue)
        {
            DocDefinition docDef = docProject.GetDefinition(fieldtype);

            // hyperlink to enumerators
            if (docDef is DocEnumeration)
            {
                // hyperlink to enumeration definition

                // replace it with hyperlink
                DocSchema docSchema = docProject.GetSchemaOfDefinition(docDef);
                string relative = @"../../";
                string hyperlink = relative + docSchema.Name.ToLower() + @"/lexical/" + docDef.Name.ToLower() + ".htm";
                string format = "<a href=\"" + hyperlink + "\">" + fieldvalue + "</a>";

                return content.Replace(fieldname, format);
            }
            else if (docDef is DocEntity)//fieldvalue != null && fieldvalue.StartsWith("Ifc") && docProject.GetDefinition(fieldvalue) != null)
            {
                // replace it with hyperlink
                DocSchema docSchema = docProject.GetSchemaOfDefinition(docDef);
                string relative = @"../../";
                string hyperlink = relative + docSchema.Name.ToLower() + @"/lexical/" + docDef.Name.ToLower() + ".htm";
                string format = "<a href=\"" + hyperlink + "\">" + fieldvalue + "</a>";

                return content.Replace(fieldname, format);
            }
            else //if (docDef == null)
            {
                // hyperlink to property set definition
                DocSchema docSchema = null;
                DocObject docObj = docProject.FindPropertySet(fieldvalue, out docSchema);
                if (docObj is DocPropertySet)
                {
                    string relative = @"../../";
                    string hyperlink = relative + docSchema.Name.ToLowerInvariant() + @"/pset/" + docObj.Name.ToLower() + ".htm"; // case-sensitive on linux -- need to make schema all lowercase
                    string format = "<a href=\"" + hyperlink + "\">" + fieldvalue + "</a>";
                    return content.Replace(fieldname, format);
                }
                else if (docObj is DocQuantitySet)
                {
                    string relative = @"../../";
                    string hyperlink = relative + docSchema.Name.ToLowerInvariant() + @"/qset/" + docObj.Name.ToLower() + ".htm"; // case-sentive on linux -- need to make schema all lowercase
                    string format = "<a href=\"" + hyperlink + "\">" + fieldvalue + "</a>";
                    return content.Replace(fieldname, format);
                }

                if (docObj == null)
                {
                    // simple replace -- hyperlink may markup value later
                    return content.Replace(fieldname, fieldvalue);
                }
            }
            /*
            else
            {
                // simple replace -- hyperlink may markup value later
                return content.Replace(fieldname, fieldvalue);
            }*/

            return content;
        }
        private static string FormatConceptTable(
            DocProject docProject,
            DocModelView docModelView,
            DocEntity entity,
            DocConceptRoot root,
            DocTemplateUsage usage,
            Dictionary<string, DocObject> mapEntity,
            Dictionary<string, string> mapSchema)
        {
            StringBuilder sb = new StringBuilder();

            DocTemplateItem[] listItems = FindTemplateItems(docProject, entity, usage.Definition, docModelView);

            if(listItems.Length == 0)
            {
                // scenario for referenced inner templates
                listItems = usage.Items.ToArray();
            }

            // new way with table
            DocModelRule[] parameters = usage.Definition.GetParameterRules();
            if (parameters != null && parameters.Length > 0 && listItems.Length > 0)
            {
                // check if descriptions are provided
                bool showdescriptions = false;
                foreach (DocTemplateItem item in listItems)
                {
                    if (item.Documentation != null)
                    {
                        showdescriptions = true;
                        break;
                    }
                }

                sb.AppendLine("<table class=\"gridtable\">");

                // header
                sb.Append("<tr>");
                foreach (DocModelRule parameter in parameters)
                {
                    sb.Append("<th><b>");
                    sb.Append(parameter.Identification);
                    sb.Append("</b></th>");
                }
                if (showdescriptions)
                {
                    sb.Append("<th><b>Description</b></th>");
                }
                sb.AppendLine("</tr>");

                // items
                foreach (DocTemplateItem item in listItems)
                {
                    sb.Append("<tr>");
                    foreach (DocModelRule parameter in parameters)
                    {
                        string value = item.GetParameterValue(parameter.Identification);
                        string schema = null;

                        if(parameter.Name.Equals("Columns"))
                        {
                            parameter.ToString();
                        }

                        sb.Append("<td>");
                        //if (value != null)
                        {
                            DocDefinition docDef = usage.Definition.GetParameterType(parameter.Identification, mapEntity);
                            if (docDef is DocEnumeration)
                            {
                                if(value != null)
                                {
                                    schema = mapSchema[docDef.Name];

                                    sb.Append("<a href=\"../../");
                                    sb.Append(schema.ToLower());
                                    sb.Append("/lexical/");
                                    sb.Append(docDef.Name.ToLower());
                                    sb.Append(".htm\">");
                                    sb.Append(value);
                                    sb.Append("</a>");
                                }
                            }
                            else if (docDef is DocEntity)
                            {
                                DocTemplateDefinition docTemplateInner = null;
                                if (parameter is DocModelRuleAttribute)
                                {
                                    DocModelRuleAttribute dma = (DocModelRuleAttribute)parameter;
                                    foreach(DocModelRule docInnerRule in dma.Rules)
                                    {
                                        if (docInnerRule is DocModelRuleEntity)
                                        {
                                            DocModelRuleEntity dme = (DocModelRuleEntity)docInnerRule;
                                            if (dme.References.Count == 1)
                                            {
                                                docTemplateInner = dme.References[0];

                                                DocTemplateUsage docConceptInner = item.GetParameterConcept(parameter.Identification, docTemplateInner);
                                                if (docConceptInner != null)
                                                {
                                                    string inner = FormatConceptTable(docProject, docModelView, (DocEntity)docDef, root, docConceptInner, mapEntity, mapSchema);
                                                    sb.Append("<a href=\"../../templates/" + MakeLinkName(docTemplateInner) + ".htm\">" + docTemplateInner.Name + "</a><br/>");
                                                    sb.Append(inner);
                                                }

                                            }
                                        }
                                    }
                                }

                                if (docTemplateInner == null && value != null && mapSchema.TryGetValue(value, out schema))
                                {
                                    if(value.StartsWith("Pset_"))
                                    {
                                        value.ToString();
                                    }

                                    sb.Append("<a href=\"../../");
                                    sb.Append(schema.ToLower());
                                    sb.Append("/lexical/");
                                    sb.Append(value.ToLower());
                                    sb.Append(".htm\">");
                                    sb.Append(value);
                                    sb.Append("</a>");
                                }
                                else if(docDef.Name.Equals("IfcReference"))
                                {
                                    // ...hyperlinks
                                    if(value != null)
                                    {
                                        string[] parts = value.Split('\\');
                                        foreach(string part in parts)
                                        {
                                            string[] tokens = part.Split('.');
                                            if (tokens.Length > 0)
                                            {
                                                sb.Append("\\");

                                                DocDefinition docToken = docProject.GetDefinition(tokens[0]);
                                                if (docToken != null)
                                                {
                                                    DocSchema docSchema = docProject.GetSchemaOfDefinition(docToken);
                                                    string relative = @"../../";
                                                    string hyperlink = relative + docSchema.Name.ToLower() + @"/lexical/" + docToken.Name.ToLower() + ".htm";
                                                    string format = "<a href=\"" + hyperlink + "\">" + tokens[0] + "</a>";
                                                    sb.Append(format);
                                                }

                                                if (tokens.Length > 1)
                                                {
                                                    sb.Append(".");
                                                    sb.Append(tokens[1]);
                                                }

                                                sb.Append("<br>");
                                            }
                                        }
                                    }
                                    //sb.Append(value);                                    
                                }
                                else if(value != null)
                                {
                                    sb.Append(value);
                                }
                            }
                            else if (docDef != null && value != null)
                            {
                                value = FormatField(docProject, value, value, docDef.Name, value);
                                sb.Append(value);
                            }
                            else if (value != null)
                            {
                                sb.Append(value);
                            }
                            else
                            {
                                sb.Append("&nbsp;");
                            }
                        }
                        /*
                        else
                        {
                            sb.Append("&nbsp;");
                        }*/
                        sb.Append("</td>");
                    }

                    if (showdescriptions)
                    {
                        sb.Append("<td>");
                        if (item.Documentation != null)
                        {
                            sb.Append(item.Documentation);
                        }
                        else
                        {
                            sb.Append("&nbsp;");
                        }
                        sb.Append("</td>");
                    }

                    sb.AppendLine("</tr>");
                }

                sb.AppendLine("</table>");
            }
            return sb.ToString();
        }
        public string FormatData(DocProject docProject, DocPublication docPublication, DocExchangeDefinition docExchange, Dictionary<string, DocObject> map, Dictionary<long, SEntity> instances, SEntity root, bool markup)
        {
            // load properties
            this.m_fullpropertynames.Clear();
            foreach(DocSection docSection in docProject.Sections)
            {
                foreach(DocSchema docSchema in docSection.Schemas)
                {
                    foreach(DocEntity docEntity in docSchema.Entities)
                    {
                        if(!docEntity.IsAbstract())
                        {
                            DocEntity docClass = docEntity;
                            while(docClass != null)
                            {
                                foreach(DocAttribute docAttr in docClass.Attributes)
                                {
                                    if (String.IsNullOrEmpty(docAttr.Derived) &&
                                        String.IsNullOrEmpty(docAttr.Inverse))
                                    {
                                        string row0 = docEntity.Name;
                                        string row1 = docAttr.Name;
                                        string row2 = docAttr.Name + "_" + docClass.Name;
                                        string row3 = "ENTITY";

                                        DocAggregationEnum docAggr = docAttr.GetAggregation();
                                        if(docAggr == DocAggregationEnum.SET)
                                        {
                                            row3 = "SET";
                                        }
                                        else if(docAggr == DocAggregationEnum.LIST)
                                        {
                                            row3 = "LIST";
                                        }

                                        this.m_fullpropertynames.Add(row1 + "_" + row0, new ObjectProperty(row0, row1, row2, row3));
                                    }
                                }

                                docClass = docProject.GetDefinition(docClass.BaseDefinition) as DocEntity;
                            }
                        }
                    }
                }
            }

            this.m_stream = new System.IO.MemoryStream();
            this.Instances = instances;
            this.Markup = markup;
            this.Save();

            this.m_stream.Position = 0;
            StreamReader reader = new StreamReader(this.m_stream);
            string content = reader.ReadToEnd();
            return content;
        }
Exemple #20
0
        internal static void ExportCnf(IfcDoc.Schema.CNF.configuration cnf, DocProject docProject, DocModelView[] docViews, Dictionary<DocObject, bool> included)
        {
            // configure general settings

            /*
              <cnf:option inheritance="true" exp-type="unspecified" concrete-attribute="attribute-content" entity-attribute="double-tag" tagless="unspecified" naming-convention="preserve-case" generate-keys="false"/>
              <cnf:schema targetNamespace="http://www.buildingsmart-tech.org/ifcXML/IFC4/final" embed-schema-items="true" elementFormDefault="qualified" attributeFormDefault="unqualified">
            <cnf:namespace prefix="ifc" alias="http://www.buildingsmart-tech.org/ifcXML/IFC4/final"/>
              </cnf:schema>
              <cnf:uosElement name="ifcXML"/>
              <cnf:type select="NUMBER" map="xs:double"/>
              <cnf:type select="BINARY" map="xs:hexBinary"/>
              <cnf:type select="IfcStrippedOptional" keep="false"/>
            */
            cnf.id = "IFC4";

            IfcDoc.Schema.CNF.option opt = new Schema.CNF.option();
            opt.inheritance = true;
            opt.exp_type = Schema.CNF.exp_type.unspecified;
            opt.concrete_attribute = Schema.CNF.exp_attribute_global.attribute_content;
            opt.entity_attribute = Schema.CNF.exp_attribute_global.double_tag;
            opt.tagless = Schema.CNF.boolean_or_unspecified.unspecified;
            opt.naming_convention = Schema.CNF.naming_convention.preserve_case;
            opt.generate_keys = false;
            cnf.option.Add(opt);

            IfcDoc.Schema.CNF.schema sch = new IfcDoc.Schema.CNF.schema();
            sch.targetNamespace = "http://www.buildingsmart-tech.org/ifcXML/IFC4/final"; //... make parameter...
            sch.embed_schema_items = true;
            sch.elementFormDefault = Schema.CNF.qual.qualified;
            sch.attributeFormDefault = Schema.CNF.qual.unqualified;

            IfcDoc.Schema.CNF._namespace ns = new Schema.CNF._namespace();
            ns.prefix = "ifc";
            ns.alias = "http://www.buildingsmart-tech.org/ifcXML/IFC4/final";
            sch._namespace = ns;

            cnf.schema.Add(sch);

            IfcDoc.Schema.CNF.uosElement uos = new Schema.CNF.uosElement();
            uos.name = "ifcXML";
            cnf.uosElement.Add(uos);

            IfcDoc.Schema.CNF.type typeNumber = new Schema.CNF.type();
            typeNumber.select = "NUMBER";
            typeNumber.map = "xs:double";
            cnf.type.Add(typeNumber);

            IfcDoc.Schema.CNF.type typeBinary = new Schema.CNF.type();
            typeBinary.select = "BINARY";
            typeBinary.map = "xs:hexBinary";
            cnf.type.Add(typeBinary);

            IfcDoc.Schema.CNF.type typeStripped = new Schema.CNF.type();
            typeStripped.select = "IfcStrippedOptional";
            typeStripped.keep = false;
            cnf.type.Add(typeStripped);

            SortedDictionary<string, IfcDoc.Schema.CNF.entity> mapEntity = new SortedDictionary<string, Schema.CNF.entity>();

            // export default configuration -- also export for Common Use Definitions (base view defined as itself to include everything)
            //if (docViews == null || docViews.Length == 0 || (docViews.Length == 1 && docViews[0].BaseView == docViews[0].Uuid.ToString()))
            {
                foreach (DocSection docSection in docProject.Sections)
                {
                    foreach (DocSchema docSchema in docSection.Schemas)
                    {
                        foreach(DocEntity docEntity in docSchema.Entities)
                        {
                            bool include = true; //... check if included in graph?
                            if (included != null && !included.ContainsKey(docEntity))
                            {
                                include = false;
                            }

                            if (include)
                            {
                                foreach (DocAttribute docAttr in docEntity.Attributes)
                                {
                                    if (docAttr.XsdFormat != DocXsdFormatEnum.Default || docAttr.XsdTagless == true)
                                    {
                                        IfcDoc.Schema.CNF.entity ent = null;
                                        if (!mapEntity.TryGetValue(docEntity.Name, out ent))
                                        {
                                            ent = new Schema.CNF.entity();
                                            ent.select = docEntity.Name;
                                            mapEntity.Add(docEntity.Name, ent);
                                        }

                                        ExportCnfAttribute(ent, docAttr, docAttr.XsdFormat, docAttr.XsdTagless);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // export view-specific configuration
            foreach (DocModelView docView in docViews)
            {
                foreach (DocXsdFormat format in docView.XsdFormats)
                {
                    DocEntity docEntity = docProject.GetDefinition(format.Entity) as DocEntity;
                    if (docEntity != null)
                    {
                        DocAttribute docAttr = null;
                        foreach (DocAttribute docEachAttr in docEntity.Attributes)
                        {
                            if (docEachAttr.Name != null && docEachAttr.Name.Equals(format.Attribute))
                            {
                                docAttr = docEachAttr;
                                break;
                            }
                        }

                        if (docAttr != null)
                        {
                            IfcDoc.Schema.CNF.entity ent = null;
                            if (!mapEntity.TryGetValue(docEntity.Name, out ent))
                            {
                                ent = new Schema.CNF.entity();
                                mapEntity.Add(docEntity.Name, ent);
                            }

                            ExportCnfAttribute(ent, docAttr, format.XsdFormat, format.XsdTagless);
                        }
                    }
                }
            }

            // add at end, such that sorted
            foreach(IfcDoc.Schema.CNF.entity ent in mapEntity.Values)
            {
                cnf.entity.Add(ent);
            }
        }
Exemple #21
0
        public static void Upload(DocProject docProject, BackgroundWorker worker, string baseurl, string username, string password, string parentid, DocModelView[] docViews)
        {
            string sessionid = Connect(docProject, worker, baseurl, username, password);

#if false
            if (docViews != null && docViews.Length > 0)
            {
                foreach (DocModelView docView in docViews)//docProject.ModelViews)
                {
                    // hack: only bridge view for now
                    if (docView.Name.Contains("Bridge"))
                    {
                        string codename = docView.Name;
                        if (!String.IsNullOrEmpty(docView.Code))
                        {
                            codename = docView.Code;
                        }

                        IfdBase ifdView = CreateConcept(baseurl, sessionid, docView, codename, docView.Name, IfdConceptTypeEnum.BAG);
                        //CreateRelationship(baseurl, sessionid, parentid, ifdView.guid, "COLLECTS"); // no top-level item for now

                        foreach (DocConceptRoot docRoot in docView.ConceptRoots)
                        {
                            if (docRoot.Name != null)
                            {
                                System.Diagnostics.Debug.WriteLine(docRoot.ToString());

                                IfdBase ifdRoot = CreateConcept(baseurl, sessionid, docRoot, docRoot.ApplicableEntity.Name, docRoot.Name, IfdConceptTypeEnum.SUBJECT);
                                CreateRelationship(baseurl, sessionid, ifdView.guid, ifdRoot.guid, IfdRelationshipTypeEnum.COLLECTS);

                                foreach (DocTemplateUsage docConc in docRoot.Concepts)
                                {
                                    UploadTemplateUsage(docProject, baseurl, sessionid, ifdRoot.guid, docConc);
                                }
                            }
                        }
                    }
                }
            }
            else
#endif
            {
                // build list of types referenced by property sets
                Dictionary <string, IfdBase> mapEntities = new Dictionary <string, IfdBase>();


                // core schema
                foreach (DocSection docSection in docProject.Sections)
                {
                    foreach (DocSchema docSchema in docSection.Schemas)
                    {
                        // only export objects that have associated property sets
                        foreach (DocPropertySet docPset in docSchema.PropertySets)
                        {
                            IfdBase ifdPset = CreateConcept(baseurl, sessionid, docPset, docPset.Name, docPset.Name, docPset.PropertySetType.ToString(), IfdConceptTypeEnum.BAG);
                            foreach (DocProperty docProp in docPset.Properties)
                            {
                                IfdBase ifdProp = CreateConcept(baseurl, sessionid, docProp, docProp.Name, docProp.Name, docProp.PropertyType.ToString(), IfdConceptTypeEnum.PROPERTY);
                                if (ifdProp != null)
                                {
                                    CreateRelationship(baseurl, sessionid, ifdPset.guid, ifdProp.guid, IfdRelationshipTypeEnum.COLLECTS);

                                    string paramval = docProp.PrimaryDataType;
                                    if (!String.IsNullOrEmpty(paramval))
                                    {
                                        DocDefinition docDef = docProject.GetDefinition(paramval);
                                        if (docDef != null)
                                        {
                                            // get the measure type
                                            IfdBase ifdType = SearchConcept(baseurl, sessionid, docDef.Name, IfdConceptTypeEnum.MEASURE);
                                            if (ifdType == null)
                                            {
                                                // create concept
                                                ifdType = CreateConcept(baseurl, sessionid, docDef, docDef.Name, docDef.Name, null, IfdConceptTypeEnum.MEASURE);

                                                // for enums, get enumerated type
                                                if (docProp.PropertyType == DocPropertyTemplateTypeEnum.P_ENUMERATEDVALUE)
                                                {
                                                    DocSchema docPropSchema            = null;
                                                    DocPropertyEnumeration docPropEnum = docProject.FindPropertyEnumeration(docProp.SecondaryDataType, out docPropSchema);
                                                    if (docPropEnum != null)
                                                    {
                                                        foreach (DocPropertyConstant docPropConst in docPropEnum.Constants)
                                                        {
                                                            IfdBase ifdConst = CreateConcept(baseurl, sessionid, docPropConst, docPropConst.Name, docPropConst.Name, null, IfdConceptTypeEnum.VALUE);
                                                            CreateRelationship(baseurl, sessionid, ifdType.guid, ifdConst.guid, IfdRelationshipTypeEnum.ASSIGNS_VALUES);
                                                        }
                                                    }
                                                }
                                            }
                                            CreateRelationship(baseurl, sessionid, ifdProp.guid, ifdType.guid, IfdRelationshipTypeEnum.ASSIGNS_MEASURES); // ??? fails for Pset_BuildingUse.NarrativeText / IfcText
                                        }
                                    }
                                }
                            }

                            // now link the property set to applicable type
                            DocEntity[] docEntities = docPset.GetApplicableTypeDefinitions(docProject);
                            if (docEntities != null && docEntities.Length > 0)
                            {
                                // only the first one matters
                                DocEntity docEnt = docEntities[0];
                                IfdBase   ifdEnt = null;
                                if (!mapEntities.TryGetValue(docEnt.Name, out ifdEnt))
                                {
                                    ifdEnt = CreateConcept(baseurl, sessionid, docEnt, docEnt.Name, docEnt.Name, null, IfdConceptTypeEnum.SUBJECT);
                                    mapEntities.Add(docEnt.Name, ifdEnt);

                                    // subtypes (predefined type)
                                    foreach (DocAttribute docAttr in docEnt.Attributes)
                                    {
                                        if (docAttr.Name.Equals("PredefinedType"))
                                        {
                                            DocEnumeration docEnum = docProject.GetDefinition(docAttr.DefinedType) as DocEnumeration;
                                            if (docEnum != null)
                                            {
                                                foreach (DocConstant docConst in docEnum.Constants)
                                                {
                                                    IfdBase ifdConst = CreateConcept(baseurl, sessionid, docConst, docConst.Name, docConst.Name, null, IfdConceptTypeEnum.SUBJECT);
                                                    CreateRelationship(baseurl, sessionid, ifdEnt.guid, ifdConst.guid, IfdRelationshipTypeEnum.SPECIALIZES);
                                                }
                                            }
                                        }
                                    }
                                }
                                CreateRelationship(baseurl, sessionid, ifdEnt.guid, ifdPset.guid, IfdRelationshipTypeEnum.ASSIGNS_COLLECTIONS); //!!! Fails with Forbidden!!! why???
                                // http://test.bsdd.buildingsmart.org/api/4.0/IfdRelationship/validrelations/SUBJECT/BAG indicates
                                // <ifdRelationshipTypeEnums>
                                //   <IfdRelationshipType xmlns="http://peregrine.catenda.no/objects">ASSIGNS_COLLECTIONS</IfdRelationshipType>
                                // </ifdRelationshipTypeEnums>
                            }
                        }

                        foreach (DocQuantitySet docPset in docSchema.QuantitySets)
                        {
                            IfdBase ifdPset = CreateConcept(baseurl, sessionid, docPset, docPset.Name, docPset.Name, "QTO_OCCURRENCEDRIVEN", IfdConceptTypeEnum.BAG);
                            foreach (DocQuantity docProp in docPset.Quantities)
                            {
                                IfdBase ifdProp = CreateConcept(baseurl, sessionid, docProp, docProp.Name, docProp.Name, docProp.QuantityType.ToString(), IfdConceptTypeEnum.PROPERTY);
                                if (ifdProp != null)
                                {
                                    CreateRelationship(baseurl, sessionid, ifdPset.guid, ifdProp.guid, IfdRelationshipTypeEnum.COLLECTS);

                                    string propclass = "IfcQuantityCount";
                                    switch (docProp.QuantityType)
                                    {
                                    case DocQuantityTemplateTypeEnum.Q_AREA:
                                        propclass = "IfcQuantityArea";
                                        break;

                                    case DocQuantityTemplateTypeEnum.Q_COUNT:
                                        propclass = "IfcQuantityCount";
                                        break;

                                    case DocQuantityTemplateTypeEnum.Q_LENGTH:
                                        propclass = "IfcQuantityLength";
                                        break;

                                    case DocQuantityTemplateTypeEnum.Q_TIME:
                                        propclass = "IfcQuantityTime";
                                        break;

                                    case DocQuantityTemplateTypeEnum.Q_VOLUME:
                                        propclass = "IfcQuantityVolume";
                                        break;

                                    case DocQuantityTemplateTypeEnum.Q_WEIGHT:
                                        propclass = "IfcQuantityWeight";
                                        break;
                                    }

                                    string paramval = propclass;
                                    if (!String.IsNullOrEmpty(paramval))
                                    {
                                        DocDefinition docDef = docProject.GetDefinition(paramval);
                                        if (docDef != null)
                                        {
                                            // get the measure type
                                            IfdBase ifdType = SearchConcept(baseurl, sessionid, docDef.Name, IfdConceptTypeEnum.MEASURE);
                                            if (ifdType == null)
                                            {
                                                // create concept
                                                ifdType = CreateConcept(baseurl, sessionid, docDef, docDef.Name, docDef.Name, null, IfdConceptTypeEnum.MEASURE);
                                            }
                                            CreateRelationship(baseurl, sessionid, ifdProp.guid, ifdType.guid, IfdRelationshipTypeEnum.ASSIGNS_MEASURES); // ??? fails for Pset_BuildingUse.NarrativeText / IfcText
                                        }
                                    }
                                }
                            }

                            // now link the property set to applicable type
                            DocEntity[] docEntities = docPset.GetApplicableTypeDefinitions(docProject);
                            if (docEntities != null && docEntities.Length > 0)
                            {
                                // only the first one matters
                                DocEntity docEnt = docEntities[0];
                                IfdBase   ifdEnt = null;
                                if (mapEntities.TryGetValue(docEnt.Name, out ifdEnt))
                                {
                                    CreateRelationship(baseurl, sessionid, ifdEnt.guid, ifdPset.guid, IfdRelationshipTypeEnum.ASSIGNS_COLLECTIONS);
                                }
                            }
                        }
                    }
                }
            }
        }