private Section _formatClassSection(BplDocumentationTopic topic) {
         var bplClass = topic.Class;
         var section = new Section();
         Action<Block> add = block => { if (block != null) section.Blocks.Add(block); };

         var title = topic.Title;
         if (bplClass.IsObsolete) {
            title += " (OBSOLETE)";
         }

         add(_formatStyledParagraph("@TopicHeader", title));
         var markup = topic.Content;
         add(_formatSummary("@TopicSummary", markup));
         add(_formatClassSynopsis(bplClass));

         var operation = bplClass.Operation;
         if (operation != null) {
            add(_formatPropertiesTable("Input", operation.Input));
            add(_formatPropertiesTable("Output", operation.Output));
         } else {
            add(_formatPropertiesTable("Properties", bplClass));
         }
         
         if (OutputOptions.Has(BplDocumentationOptions.ShowBinaryLayout)) {
            add(_formatBinaryLayout("Binary Layout", bplClass));
         }

         add(_formatRemarks(null, markup));
         
         if (operation != null && operation.Failures != null) {
            add(_formatHyperlinksGroup("Failures", operation.Failures));
         }
         
         add(_formatHyperlinksGroup("See Also", bplClass.UsedBy.Select(p => p.Class)));

         return section;
      }
      private Section _formatPrimitiveSection(BplDocumentationTopic topic) {
         var primitive = topic.Primitive;
         var section = new Section();
         Action<Block> add = block => { if (block != null) section.Blocks.Add(block); };
         add(_formatStyledParagraph("@TopicHeader", topic.Title));

         var markup = topic.Content;
         add(_formatSummary("@TopicSummary", markup));
         add(_formatPrimitiveSynopsis(primitive));

         if (primitive.IsEnum) {
            var table = new TableData(100, 250, "Auto");
            table.Add("Value", "Name", "Description");
            var enumType = primitive.UnderlyingType;
            foreach (var field in enumType.GetFields()) {
               if (field.IsSpecialName) continue;
               var enumName = field.Name;
               var enumValue = Convert.ToInt64(field.GetValue(null));
               var enumDescr = _formatDescription(field.ToCref());
               table.Add(enumValue.ToString(), enumName, enumDescr);
            }
            add(_formatHeaderedTable(table));
         }

         add(_formatHyperlinksGroup("Used By", primitive.UsedBy.Select(p => p.Class)));

         return section;
      }
      private Section _formatNamespaceSection(BplDocumentationTopic topic) {
         var bplNamespace = topic.Namespace;
         var section = new Section();
         Action<Block> add = block => { if (block != null) section.Blocks.Add(block); };

         var synopsis = new TableData(140, "Auto");
         synopsis.Add("Library:", _formatHyperlink(bplNamespace.Library));
         synopsis.Add("Version:", bplNamespace.Version.ToString());
         var contents = _formatNamespaceContents("Class", bplNamespace);

         add(_formatStyledParagraph("@TopicHeader", topic.Title));
         add(_formatPlainTable(synopsis));
         add(contents);

         return section;
      }
      private Section _formatGlossarySection(BplDocumentationTopic topic) {
         var section = new Section();
         Action<Block> add = block => { if (block != null) section.Blocks.Add(block); };

         var table = new TableData(250, "Auto");
         IEnumerable<BplPrimitive> primitives = null;
         if (topic.Name == "Primitives") {
            table.Add("Primitive", "Description");
            primitives = BplLanguage.Primitives.Where(p => p.IsBrowsable && !p.IsArray && !p.IsNullable && !p.IsEnum);
         } else if (topic.Name == "Enumerations") {
            table.Add("Enumeration", "Description");
            primitives = BplLanguage.Primitives.Where(p => p.IsBrowsable && p.IsEnum);
         } else {
            return null;
         }

         add(_formatStyledParagraph("@TopicHeader", topic.Title));
         foreach (var primitive in primitives.OrderBy(p => p.Name)) {
            var name = _formatHyperlink(primitive);
            var desc = _formatDescription(primitive.ToCref());
            table.Add(name, desc);
         }
         if (table.RowCount > 1) {
            add(_formatHeaderedTable(table));
         }

         return section;
      }
      private Section _formatLibrarySection(BplDocumentationTopic topic) {
         var bplLibrary = topic.Library;
         var section = new Section();
         Action<Block> add = block => { if (block != null) section.Blocks.Add(block); };

         var synopsis = new TableData(140, "Auto");
         synopsis.Add("Assembly:", bplLibrary.Assembly.GetName().Name + ".dll");
         synopsis.Add("Version:", bplLibrary.Version.ToString());

         add(_formatStyledParagraph("@TopicHeader", topic.Title));
         add(_formatPlainTable(synopsis));
         foreach (var bplNamespace in bplLibrary.Namespaces.OrderBy(ns => ns.Name)) {
            var contents = _formatNamespaceContents("Class", bplNamespace);
            if (contents != null) {
               add(_formatStyledParagraph("@SubTitle", bplNamespace.Name));
               add(contents);
            }
         }
         return section;
      }