diff --git a/README.adoc b/README.adoc
index 8d0222a..9def6b0 100644
--- a/README.adoc
+++ b/README.adoc
@@ -1,4 +1,4 @@
-= RelatonBib
+= Relaton::Bib
 
 image:https://img.shields.io/gem/v/relaton-bib.svg["Gem Version", link="https://rubygems.org/gems/relaton-bib"]
 image:https://github.com/relaton/relaton-bib/workflows/rake/badge.svg["Build Status", link="https://github.com/relaton/relaton-bib/actions?workflow=rake"]
@@ -6,7 +6,7 @@ image:https://codeclimate.com/github/relaton/relaton-bib/badges/gpa.svg["Code Cl
 image:https://img.shields.io/github/issues-pr-raw/relaton/relaton-bib.svg["Pull Requests", link="https://github.com/relaton/relaton-bib/pulls"]
 image:https://img.shields.io/github/commits-since/relaton/relaton-bib/latest.svg["Commits since latest",link="https://github.com/relaton/relaton-bib/releases"]
 
-RelatonBib is a Ruby gem that implements the https://github.com/metanorma/relaton-models#bibliography-uml-models[BibliographicItem model].
+Relaton::Bib is a Ruby gem that implements the https://github.com/metanorma/relaton-models#bibliography-uml-models[BibliographicItem model].
 
 == Installation
 
@@ -27,23 +27,34 @@ Or install it yourself as:
 
 == Usage
 
-=== Create bibliographic item
+=== Configuration
+
+Configuration is optional. The available option is `logger` which is a `Logger` instance. By default, the logger is `Logger.new($stderr)` with `Logger::WARN` level. To change the logger level, use `Relaton::Bib.configure` block.
 
 [source,ruby]
 ----
 require 'relaton_bib'
 => true
 
+Relaton::Bib.configure do |config|
+  config.logger.level = Logger::DEBUG
+end
+----
+
+=== Create bibliographic item
+
+[source,ruby]
+----
 hash = YAML.load_file "spec/examples/bib_item.yml"
 => {"id"=>"ISOTC211",
 "fetched"=>"2022-05-02",
  "title"=>["Geographic information", {"content"=>"Information géographique", "language"=>"fr", "script"=>"Latn"}],
  ...
 
-item = RelatonBib::BibliographicItem.from_hash(hash)
-=> #<RelatonBib::BibliographicItem:0x00007f962f030710
+item = Relaton::Bib::Item.from_hash(hash)
+=> #<Relaton::Bib::Item:0x00007f962f030710
  @abstract=
-  [#<RelatonBib::FormattedString:0x00007f962f02acc0
+  [#<Relaton::Bib::FormattedString:0x00007f962f02acc0
 ...
 ----
 
@@ -52,24 +63,24 @@ item = RelatonBib::BibliographicItem.from_hash(hash)
 [source,ruby]
 ----
 item.title
-=> #<RelatonBib::TypedTitleStringCollection:0x00007fea821ec6b0
+=> #<Relaton::Bib::TitleCollection:0x00007fea821ec6b0
  @array=
-  [#<RelatonBib::TypedTitleString:0x00007fea821ecb60
-    @title=#<RelatonBib::FormattedString:0x00007fea821eca70 @content="Geographic information", @format="text/plain", @language=nil, @script=nil>,
+  [#<Relaton::Bib::Title:0x00007fea821ecb60
+    @title=#<Relaton::Bib::FormattedString:0x00007fea821eca70 @content="Geographic information", @format="text/plain", @language=nil, @script=nil>,
     @type="title-main">,
-   #<RelatonBib::TypedTitleString:0x00007fea821ec8b8
-    @title=#<RelatonBib::FormattedString:0x00007fea821ec818 @content="Geographic information", @format="text/plain", @language=nil, @script=nil>,
+   #<Relaton::Bib::Title:0x00007fea821ec8b8
+    @title=#<Relaton::Bib::FormattedString:0x00007fea821ec818 @content="Geographic information", @format="text/plain", @language=nil, @script=nil>,
     @type="main">,
-   #<RelatonBib::TypedTitleString:0x00007fea821ec610
+   #<Relaton::Bib::Title:0x00007fea821ec610
     @title=
-     #<RelatonBib::FormattedString:0x00007fea821ec570 @content="Information géographique", @format="text/plain", @language=["fr"], @script=["Latn"]>,
+     #<Relaton::Bib::FormattedString:0x00007fea821ec570 @content="Information géographique", @format="text/plain", @language=["fr"], @script=["Latn"]>,
     @type=nil>]>
 
 item.title lang: "fr"
-=> #<RelatonBib::TypedTitleStringCollection:0x00007fea8222d908
+=> #<Relaton::Bib::TitleCollection:0x00007fea8222d908
  @array=
-  [#<RelatonBib::TypedTitleString:0x00007fea821ec610
-    @title=#<RelatonBib::FormattedString:0x00007fea821ec570 @content="Information géographique", @format="text/plain", @language=["fr"], @script=["Latn"]>,
+  [#<Relaton::Bib::Title:0x00007fea821ec610
+    @title=#<Relaton::Bib::FormattedString:0x00007fea821ec570 @content="Information géographique", @format="text/plain", @language=["fr"], @script=["Latn"]>,
     @type=nil>]>
 ----
 
@@ -78,12 +89,12 @@ item.title lang: "fr"
 [source,ruby]
 ----
 item.abstract
-=> [#<RelatonBib::FormattedString:0x00007fea82236828
+=> [#<Relaton::Bib::FormattedString:0x00007fea82236828
   @content="<p>ISO 19115-1:2014 defines the schema required for ...</p>",
   @format="text/html",
   @language=["en"],
   @script=["Latn"]>,
- #<RelatonBib::FormattedString:0x00007fea82236670
+ #<Relaton::Bib::FormattedString:0x00007fea82236670
   @content="L'ISO 19115-1:2014 définit le schéma requis pour ...",
   @format="text/plain",
   @language=["fr"],
@@ -191,8 +202,8 @@ hash = YAML.load_file 'spec/examples/bib_item.yml'
 => {"id"=>"ISOTC211"
 ...
 
-RelatonBib::BibliographicItem.from_hash hash
-=> #<RelatonBib::BibliographicItem:0x007ff1524f8c88
+Relaton::Bib::Item.from_hash hash
+=> #<Relaton::Bib::Item:0x007ff1524f8c88
 ...
 ----
 
@@ -203,8 +214,8 @@ RelatonBib::BibliographicItem.from_hash hash
 bibxml = File.read "spec/examples/rfc.xml"
 => <reference anchor=...
 
-RelatonBib::BibXMLParser.parse bibxml
-=> #<RelatonBib::BibliographicItem:0x00007f9d0c75b268
+Relaton::Bib::BibXMLParser.parse bibxml
+=> #<Relaton::Bib::Item:0x00007f9d0c75b268
 ...
 ----
 
@@ -226,9 +237,9 @@ item.to_hash
 
 [source,ruby]
 ----
-RelatonBib::BibtexParser.from_bibtex File.read('spec/examples/techreport.bib')
+Relaton::Bib::BibtexParser.from_bibtex File.read('spec/examples/techreport.bib')
 => {"ISOTC211"=>
-  #<RelatonBib::BibliographicItem:0x007fedee0a2ab0
+  #<Relaton::Bib::Item:0x007fedee0a2ab0
   ...
 ----
 
diff --git a/bin/console b/bin/console
index 4db53c8..809a174 100755
--- a/bin/console
+++ b/bin/console
@@ -1,7 +1,7 @@
 #!/usr/bin/env ruby
 
 require "bundler/setup"
-require "relaton_bib"
+require "relaton/bib"
 
 # You can add fixtures and/or initialization code here to make experimenting
 # with your gem easier. You can also use a different console, if you like.
diff --git a/grammars/basicdoc.rng b/grammars/basicdoc.rng
index 5a96d4a..08b0241 100644
--- a/grammars/basicdoc.rng
+++ b/grammars/basicdoc.rng
@@ -1,18 +1,28 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+<grammar xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <define name="document">
+    <a:documentation>Document</a:documentation>
     <element name="document">
       <optional>
-        <attribute name="identifier"/>
+        <attribute name="identifier">
+          <a:documentation>A globally unique identifier for the document in an agreed identifier schema. The identifier is to be used for tracking interactions with the document without depending on formal document registries; it would be exemplified by a GUID, rather than a document registry identifier such as "`ISO 639`", which belongs to `bibdata`</a:documentation>
+        </attribute>
       </optional>
-      <ref name="bibdata"/>
-      <ref name="sections"/>
+      <ref name="bibdata">
+        <a:documentation>A bibliographic description, capturing bibliographic metadata about the document itself, including authors, title, and date of production</a:documentation>
+      </ref>
+      <ref name="sections">
+        <a:documentation>Hierarchically arranged units of textual content within the document</a:documentation>
+      </ref>
       <zeroOrMore>
-        <ref name="references"/>
+        <ref name="references">
+          <a:documentation>Bibliographic content</a:documentation>
+        </ref>
       </zeroOrMore>
     </element>
   </define>
   <define name="bibdata">
+    <a:documentation>Bibliographic description of a document, used as metadata, expressed in the Relaton model</a:documentation>
     <element name="bibdata">
       <ref name="BibData"/>
     </element>
@@ -25,51 +35,71 @@
     </element>
   </define>
   <define name="section">
+    <a:documentation>Section: groups of blocks within text, which can also contain other sections</a:documentation>
     <element name="section">
       <ref name="Basic-Section"/>
       <zeroOrMore>
-        <ref name="section"/>
+        <ref name="section">
+          <a:documentation>Sections contained within the current section. The relation is recursive,
+so the hierarchical arrangement of sections can be arbitrarily deep</a:documentation>
+        </ref>
       </zeroOrMore>
     </element>
   </define>
+  <define name="LanguageType">
+    <a:documentation>Two-letter language code taken from ISO 639, indicating the language in which the content is written</a:documentation>
+    <text/>
+  </define>
+  <define name="ScriptType">
+    <a:documentation>Four-letter script code taken from ISO 15924, indicating the script in which the content is written</a:documentation>
+    <text/>
+  </define>
+  <define name="LocaleType">
+    <a:documentation>(Two-letter) Country and country subdivisions identifier taken from ISO 3166, indicating the locale in which the content is written</a:documentation>
+    <text/>
+  </define>
   <define name="Basic-Section">
+    <a:documentation>Group of blocks within text, which is a leaf node in the hierarchical organisation of text (does not contain any sections of its own)</a:documentation>
+    <ref name="Basic-Section-Attributes"/>
     <optional>
-      <attribute name="id">
-        <data type="ID"/>
-      </attribute>
-    </optional>
-    <optional>
-      <attribute name="language"/>
-    </optional>
-    <optional>
-      <attribute name="script"/>
-    </optional>
-    <optional>
-      <ref name="section-title"/>
+      <ref name="section-title">
+        <a:documentation>Title of the section</a:documentation>
+      </ref>
     </optional>
     <zeroOrMore>
-      <ref name="BasicBlock"/>
+      <ref name="BasicBlock">
+        <a:documentation>Blocks, containing the textual content of the section
+(but excluding subsections, which are only present in Hierarchical Sections)</a:documentation>
+      </ref>
     </zeroOrMore>
   </define>
+  <define name="Basic-Section-Attributes">
+    <ref name="OptionalId"/>
+    <ref name="LocalizedStringAttributes"/>
+  </define>
   <define name="references">
+    <a:documentation>Sections containing zero or more bibliographical items (as described in Relaton), along with any prefatory text</a:documentation>
     <element name="references">
+      <ref name="OptionalId"/>
       <optional>
-        <attribute name="id">
-          <data type="ID"/>
-        </attribute>
-      </optional>
-      <optional>
-        <ref name="section-title"/>
+        <ref name="section-title">
+          <a:documentation>Title of section</a:documentation>
+        </ref>
       </optional>
       <zeroOrMore>
-        <ref name="BasicBlock"/>
+        <ref name="BasicBlock">
+          <a:documentation>Prefatory text</a:documentation>
+        </ref>
       </zeroOrMore>
       <zeroOrMore>
-        <ref name="bibitem"/>
+        <ref name="bibitem">
+          <a:documentation>Bibliographical items included in the References section</a:documentation>
+        </ref>
       </zeroOrMore>
     </element>
   </define>
   <define name="section-title">
+    <a:documentation>Title of a section</a:documentation>
     <element name="title">
       <zeroOrMore>
         <ref name="TextElement"/>
@@ -77,6 +107,7 @@
     </element>
   </define>
   <define name="BasicBlock">
+    <a:documentation>Block of textual content</a:documentation>
     <choice>
       <ref name="paragraph-with-footnote"/>
       <ref name="table"/>
@@ -98,18 +129,39 @@
       <ref name="amend"/>
     </choice>
   </define>
+  <define name="BasicBlockNoId">
+    <a:documentation>Block of textual content: optional ID attributes (for use in Relaton, metadata)</a:documentation>
+    <choice>
+      <ref name="paragraph-with-footnote-no-id"/>
+      <ref name="table-no-id"/>
+      <ref name="formula-no-id"/>
+      <ref name="admonition-no-id"/>
+      <ref name="ol-no-id"/>
+      <ref name="ul-no-id"/>
+      <ref name="dl-no-id"/>
+      <ref name="figure-no-id"/>
+      <ref name="quote-no-id"/>
+      <ref name="sourcecode-no-id"/>
+      <ref name="example-no-id"/>
+      <ref name="review"/>
+      <ref name="pre-no-id"/>
+      <ref name="note-no-id"/>
+      <ref name="pagebreak"/>
+      <ref name="hr"/>
+      <ref name="bookmark"/>
+      <ref name="amend"/>
+    </choice>
+  </define>
   <define name="amend">
+    <a:documentation>Block describing a change in a document, intended for human readers</a:documentation>
     <element name="amend">
       <ref name="AmendType"/>
     </element>
   </define>
   <define name="AmendType">
-    <optional>
-      <attribute name="id">
-        <data type="ID"/>
-      </attribute>
-    </optional>
+    <ref name="OptionalId"/>
     <attribute name="change">
+      <a:documentation>The type of change described in this block</a:documentation>
       <choice>
         <value>add</value>
         <value>modify</value>
@@ -118,16 +170,26 @@
       </choice>
     </attribute>
     <optional>
-      <attribute name="path"/>
+      <attribute name="path">
+        <a:documentation>The span within location where the change applies to,
+if location defines a container larger than the scope of the change</a:documentation>
+      </attribute>
     </optional>
     <optional>
-      <attribute name="path_end"/>
+      <attribute name="path_end">
+        <a:documentation>The end of the span within location where the change applies to,
+if location defines a container larger than the scope of the change.
+Applicable to modify and delete</a:documentation>
+      </attribute>
     </optional>
     <optional>
-      <attribute name="title"/>
+      <attribute name="title">
+        <a:documentation>Optional caption of this block</a:documentation>
+      </attribute>
     </optional>
     <optional>
       <element name="location">
+        <a:documentation>The location(s) in the original document which have undergone the change described in this block</a:documentation>
         <zeroOrMore>
           <choice>
             <ref name="locality"/>
@@ -138,6 +200,7 @@
     </optional>
     <optional>
       <element name="description">
+        <a:documentation>Description of the change described in this block</a:documentation>
         <zeroOrMore>
           <ref name="BasicBlock"/>
         </zeroOrMore>
@@ -145,27 +208,33 @@
     </optional>
     <optional>
       <element name="newcontent">
-        <optional>
-          <attribute name="id">
-            <data type="ID"/>
-          </attribute>
-        </optional>
+        <a:documentation>New content to be added to the document; applicable to add and modify</a:documentation>
+        <ref name="OptionalId"/>
         <zeroOrMore>
           <ref name="BasicBlock"/>
         </zeroOrMore>
       </element>
     </optional>
     <zeroOrMore>
-      <ref name="classification"/>
+      <ref name="classification">
+        <a:documentation>Classification of the change</a:documentation>
+      </ref>
     </zeroOrMore>
     <zeroOrMore>
-      <ref name="contributor"/>
+      <ref name="contributor">
+        <a:documentation>Contributor responsible for the change</a:documentation>
+      </ref>
     </zeroOrMore>
   </define>
   <define name="classification">
+    <a:documentation>Key-value classification of an entity</a:documentation>
     <element name="classification">
-      <ref name="classification_tag"/>
-      <ref name="classification_value"/>
+      <ref name="classification_tag">
+        <a:documentation>Key for the classification</a:documentation>
+      </ref>
+      <ref name="classification_value">
+        <a:documentation>Value for the classification</a:documentation>
+      </ref>
     </element>
   </define>
   <define name="classification_tag">
@@ -179,11 +248,18 @@
     </element>
   </define>
   <define name="paragraph">
+    <a:documentation>Default block of textual content. 
+Unlike the case for other document models, paragraphs _cannot_
+contain other blocks, such as lists, tables, or figures: they are modelled as a basic building block of text
+Does not contain foonotes. While most paragraphs in a document can contain footnotes (paragraph-with-footnote),
+the distinction is necessary, as footnotes are not appropriate for all instances of paragraph content 
+in a document (e.g. sourcecode annotations)</a:documentation>
     <element name="p">
       <ref name="ParagraphType"/>
     </element>
   </define>
   <define name="Alignments">
+    <a:documentation>The alignment of the paragraph against the margins of the document</a:documentation>
     <choice>
       <value>left</value>
       <value>right</value>
@@ -191,133 +267,298 @@
       <value>justified</value>
     </choice>
   </define>
-  <define name="ParagraphType">
+  <define name="RequiredId">
+    <a:documentation>Mandatory anchor of element, to be used for cross-references within the document</a:documentation>
     <attribute name="id">
       <data type="ID"/>
     </attribute>
+  </define>
+  <define name="OptionalId">
+    <a:documentation>Optional anchor of element</a:documentation>
+    <optional>
+      <attribute name="id">
+        <data type="ID"/>
+      </attribute>
+    </optional>
+  </define>
+  <define name="ParagraphAttributes">
     <optional>
       <attribute name="align">
+        <a:documentation>The alignment of the paragraph against the margins of the document</a:documentation>
         <ref name="Alignments"/>
       </attribute>
     </optional>
+  </define>
+  <define name="ParagraphType">
+    <ref name="RequiredId"/>
+    <ref name="ParagraphAttributes"/>
+    <ref name="ParagraphBody"/>
+  </define>
+  <define name="ParagraphBody">
+    <a:documentation>Inline elements constituting the content of the paragraph, excluding footnotes</a:documentation>
     <zeroOrMore>
-      <ref name="TextElement"/>
+      <ref name="TextElement">
+        <a:documentation>Inline elements constituting the content of the paragraph</a:documentation>
+      </ref>
     </zeroOrMore>
     <zeroOrMore>
-      <ref name="note"/>
+      <ref name="note">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
+  <define name="ParagraphFnBody">
+    <a:documentation>Inline elements constituting the content of the paragraph, including footnotes</a:documentation>
+    <zeroOrMore>
+      <choice>
+        <ref name="TextElement">
+          <a:documentation>Inline elements constituting the content of the paragraph</a:documentation>
+        </ref>
+        <ref name="fn">
+          <a:documentation>Footnotes interspersed with paragraph content</a:documentation>
+        </ref>
+      </choice>
+    </zeroOrMore>
+    <zeroOrMore>
+      <ref name="note">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
     </zeroOrMore>
   </define>
+  <define name="paragraph-no-id">
+    <a:documentation>Paragraph containing no footnotes: optional ID attributes (for use in Relaton, metadata) </a:documentation>
+    <element name="p">
+      <ref name="OptionalId"/>
+      <ref name="ParagraphAttributes"/>
+      <ref name="ParagraphBody"/>
+    </element>
+  </define>
   <define name="paragraph-with-footnote">
+    <a:documentation>A paragraph which may contain footnotes.</a:documentation>
     <element name="p">
-      <attribute name="id">
-        <data type="ID"/>
-      </attribute>
-      <optional>
-        <attribute name="align">
-          <ref name="Alignments"/>
-        </attribute>
-      </optional>
-      <zeroOrMore>
-        <choice>
-          <ref name="TextElement"/>
-          <ref name="fn"/>
-        </choice>
-      </zeroOrMore>
-      <zeroOrMore>
-        <ref name="note"/>
-      </zeroOrMore>
+      <ref name="RequiredId"/>
+      <ref name="ParagraphAttributes"/>
+      <ref name="ParagraphFnBody"/>
+    </element>
+  </define>
+  <define name="paragraph-with-footnote-no-id">
+    <a:documentation>A paragraph which may contain footnotes: optional ID attributes (for use in Relaton, metadata)</a:documentation>
+    <element name="p">
+      <ref name="OptionalId"/>
+      <ref name="ParagraphAttributes"/>
+      <ref name="ParagraphFnBody"/>
     </element>
   </define>
   <define name="note">
+    <a:documentation>Note block</a:documentation>
     <element name="note">
-      <attribute name="id">
-        <data type="ID"/>
-      </attribute>
-      <oneOrMore>
-        <ref name="paragraph"/>
-      </oneOrMore>
+      <ref name="RequiredId"/>
+      <ref name="NoteAttributes"/>
+      <ref name="NoteBody"/>
+    </element>
+  </define>
+  <define name="note-no-id">
+    <a:documentation>Note block: optional ID attributes (for use in Relaton, metadata)</a:documentation>
+    <element name="note">
+      <ref name="OptionalId"/>
+      <ref name="NoteAttributes"/>
+      <ref name="NoteNoIdBody"/>
     </element>
   </define>
+  <define name="NoteAttributes">
+    <ref name="NumberingAttributes"/>
+  </define>
+  <define name="NoteBody">
+    <oneOrMore>
+      <ref name="paragraph"/>
+    </oneOrMore>
+  </define>
+  <define name="NoteNoIdBody">
+    <oneOrMore>
+      <ref name="paragraph-no-id"/>
+    </oneOrMore>
+  </define>
   <define name="review">
+    <a:documentation>Block intended to capture reviewer comments about some text in the document</a:documentation>
     <element name="review">
-      <attribute name="id">
-        <data type="ID"/>
+      <ref name="RequiredId"/>
+      <attribute name="reviewer">
+        <a:documentation>The party who has offered the comment</a:documentation>
       </attribute>
-      <attribute name="reviewer"/>
       <optional>
-        <attribute name="type"/>
+        <attribute name="type">
+          <a:documentation>The type of reviewer comment</a:documentation>
+        </attribute>
       </optional>
       <optional>
         <attribute name="date">
+          <a:documentation>The date when the comment was made</a:documentation>
           <data type="dateTime"/>
         </attribute>
       </optional>
       <optional>
         <attribute name="from">
+          <a:documentation>Identifier for the start of the text or point in the text to which the comment applies.
+If not provided, the comment applies in the vicinity of the place it has been inserted into the text</a:documentation>
           <data type="IDREF"/>
         </attribute>
       </optional>
       <optional>
         <attribute name="to">
+          <a:documentation>Identifier for the end of the text to which the comment applies</a:documentation>
           <data type="IDREF"/>
         </attribute>
       </optional>
       <oneOrMore>
-        <ref name="paragraph"/>
+        <ref name="paragraph">
+          <a:documentation>Reviewer comments content</a:documentation>
+        </ref>
       </oneOrMore>
     </element>
   </define>
+  <define name="NumberingAttributes">
+    <optional>
+      <attribute name="unnumbered">
+        <a:documentation>Do not number this block in rendering</a:documentation>
+        <data type="boolean"/>
+      </attribute>
+    </optional>
+    <optional>
+      <attribute name="subsequence">
+        <a:documentation>Define a subsequence for numbering of this block; e.g. if this block would be numbered
+as 7, but it has a subsequence value of XYZ, this block, and all consecutive blocks
+of the same class and with the same subsequence value, will be numbered consecutively
+with the same number and in a subsequence: 7a, 7b, 7c etc</a:documentation>
+      </attribute>
+    </optional>
+  </define>
   <define name="formula">
+    <a:documentation>Block containing a mathematical expression or other formulas</a:documentation>
     <element name="formula">
-      <attribute name="id">
-        <data type="ID"/>
-      </attribute>
-      <optional>
-        <attribute name="unnumbered">
-          <data type="boolean"/>
-        </attribute>
-      </optional>
-      <optional>
-        <attribute name="subsequence"/>
-      </optional>
-      <optional>
-        <attribute name="inequality">
-          <data type="boolean"/>
-        </attribute>
-      </optional>
-      <ref name="stem"/>
-      <optional>
-        <ref name="dl"/>
-      </optional>
-      <zeroOrMore>
-        <ref name="note"/>
-      </zeroOrMore>
+      <ref name="RequiredId"/>
+      <ref name="FormulaAttributes"/>
+      <ref name="FormulaBody"/>
+    </element>
+  </define>
+  <define name="formula-no-id">
+    <a:documentation>Block containing a mathematical expression or other formulas: optional ID attributes (for use in Relaton, metadata)</a:documentation>
+    <element name="formula">
+      <ref name="OptionalId"/>
+      <ref name="FormulaAttributes"/>
+      <ref name="FormulaNoIdBody"/>
     </element>
   </define>
+  <define name="FormulaAttributes">
+    <ref name="NumberingAttributes"/>
+    <optional>
+      <attribute name="inequality">
+        <a:documentation>Indication that the formula is to be labelled as an Inequality, if inequalities are differentiated from equations</a:documentation>
+        <data type="boolean"/>
+      </attribute>
+    </optional>
+  </define>
+  <define name="FormulaBody">
+    <ref name="stem">
+      <a:documentation>The content of the formula, as a mathematical expression</a:documentation>
+    </ref>
+    <optional>
+      <ref name="dl">
+        <a:documentation>A definitions list defining any symbols used in the formula</a:documentation>
+      </ref>
+    </optional>
+    <zeroOrMore>
+      <ref name="note">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
+  <define name="FormulaNoIdBody">
+    <ref name="stem">
+      <a:documentation>The content of the formula, as a mathematical expression</a:documentation>
+    </ref>
+    <optional>
+      <ref name="dl-no-id">
+        <a:documentation>A definitions list defining any symbols used in the formula</a:documentation>
+      </ref>
+    </optional>
+    <zeroOrMore>
+      <ref name="note-no-id">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
   <define name="quote">
+    <a:documentation>Block quotation, containing extensive textual content originally authored outside of the current document</a:documentation>
     <element name="quote">
-      <attribute name="id">
-        <data type="ID"/>
-      </attribute>
-      <optional>
-        <attribute name="alignment">
-          <ref name="Alignments"/>
-        </attribute>
-      </optional>
-      <optional>
-        <ref name="quote-source"/>
-      </optional>
-      <optional>
-        <ref name="quote-author"/>
-      </optional>
-      <oneOrMore>
-        <ref name="paragraph-with-footnote"/>
-      </oneOrMore>
-      <zeroOrMore>
-        <ref name="note"/>
-      </zeroOrMore>
+      <ref name="RequiredId"/>
+      <ref name="QuoteAttributes"/>
+      <ref name="QuoteBody"/>
+    </element>
+  </define>
+  <define name="quote-no-id">
+    <a:documentation>Block quotation: optional ID attributes (for use in Relaton, metadata)</a:documentation>
+    <element name="quote">
+      <ref name="OptionalId"/>
+      <ref name="QuoteAttributes"/>
+      <ref name="QuoteNoIdBody"/>
     </element>
   </define>
+  <define name="QuoteAttributes">
+    <optional>
+      <attribute name="alignment">
+        <a:documentation>The alignment of the quote against the margins of the document</a:documentation>
+        <ref name="Alignments"/>
+      </attribute>
+    </optional>
+  </define>
+  <define name="QuoteBody">
+    <optional>
+      <ref name="quote-source">
+        <a:documentation>Bibliographic citation for the quotation</a:documentation>
+      </ref>
+    </optional>
+    <optional>
+      <ref name="quote-author">
+        <a:documentation>Author of the quotation. The `author` attribute of the quotation is redundant with `source`,
+since it restates information about the author that should be recoverable from the `source` citation.
+It is included for convenience, in case processing the citation to extract the author is prohibitive for rendering tools</a:documentation>
+      </ref>
+    </optional>
+    <oneOrMore>
+      <ref name="paragraph-with-footnote">
+        <a:documentation>Content of quote</a:documentation>
+      </ref>
+    </oneOrMore>
+    <zeroOrMore>
+      <ref name="note">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
+  <define name="QuoteNoIdBody">
+    <optional>
+      <ref name="quote-source">
+        <a:documentation>Bibliographic citation for the quotation</a:documentation>
+      </ref>
+    </optional>
+    <optional>
+      <ref name="quote-author">
+        <a:documentation>Author of the quotation. The `author` attribute of the quotation is redundant with `source`,
+since it restates information about the author that should be recoverable from the `source` citation.
+It is included for convenience, in case processing the citation to extract the author is prohibitive for rendering tools</a:documentation>
+      </ref>
+    </optional>
+    <oneOrMore>
+      <ref name="paragraph-with-footnote-no-id">
+        <a:documentation>Content of quote</a:documentation>
+      </ref>
+    </oneOrMore>
+    <zeroOrMore>
+      <ref name="note-no-id">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
   <define name="quote-source">
     <element name="source">
       <ref name="erefType"/>
@@ -329,110 +570,245 @@
     </element>
   </define>
   <define name="sourcecode">
+    <a:documentation>Block containing computer code or comparable text</a:documentation>
     <element name="sourcecode">
-      <attribute name="id">
-        <data type="ID"/>
-      </attribute>
-      <optional>
-        <attribute name="unnumbered">
-          <data type="boolean"/>
-        </attribute>
-      </optional>
-      <optional>
-        <attribute name="subsequence"/>
-      </optional>
-      <optional>
-        <attribute name="lang"/>
-      </optional>
-      <optional>
-        <ref name="tname"/>
-      </optional>
-      <oneOrMore>
-        <choice>
-          <text/>
-          <ref name="callout"/>
-        </choice>
-      </oneOrMore>
-      <zeroOrMore>
-        <ref name="annotation"/>
-      </zeroOrMore>
-      <zeroOrMore>
-        <ref name="note"/>
-      </zeroOrMore>
+      <ref name="RequiredId"/>
+      <ref name="SourceAttributes"/>
+      <ref name="SourceBody"/>
+    </element>
+  </define>
+  <define name="sourcecode-no-id">
+    <a:documentation>Block containing computer code or comparable text: optional ID attributes (for use in Relaton, metadata)</a:documentation>
+    <element name="sourcecode">
+      <ref name="OptionalId"/>
+      <ref name="SourceAttributes"/>
+      <ref name="SourceNoIdBody"/>
     </element>
   </define>
+  <define name="SourceAttributes">
+    <ref name="NumberingAttributes"/>
+    <optional>
+      <attribute name="lang">
+        <a:documentation>The computer language or other notational convention that the source code is expressed in</a:documentation>
+      </attribute>
+    </optional>
+  </define>
+  <define name="SourceBody">
+    <optional>
+      <ref name="tname">
+        <a:documentation>The caption of the block</a:documentation>
+      </ref>
+    </optional>
+    <oneOrMore>
+      <choice>
+        <text>
+          <a:documentation>The computer code or other such text presented in the block, as a single unformatted string. 
+(The string should be treated as pre-formatted text, with whitespace treated as significant)</a:documentation>
+        </text>
+        <ref name="callout">
+          <a:documentation>Zero or more cross-references; these are intended to be embedded within the content string, and link to annotations</a:documentation>
+        </ref>
+      </choice>
+    </oneOrMore>
+    <zeroOrMore>
+      <ref name="annotation">
+        <a:documentation>Annotations to the source code; each annotation consists of zero or more paragraphs,
+and is intended to be referenced by a callout within the source code</a:documentation>
+      </ref>
+    </zeroOrMore>
+    <zeroOrMore>
+      <ref name="note">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
+  <define name="SourceNoIdBody">
+    <optional>
+      <ref name="tname">
+        <a:documentation>The caption of the block</a:documentation>
+      </ref>
+    </optional>
+    <oneOrMore>
+      <choice>
+        <text>
+          <a:documentation>The computer code or other such text presented in the block, as a single unformatted string. 
+(The string should be treated as pre-formatted text, with whitespace treated as significant)</a:documentation>
+        </text>
+        <ref name="callout">
+          <a:documentation>Zero or more cross-references; these are intended to be embedded within the content string, and link to annotations</a:documentation>
+        </ref>
+      </choice>
+    </oneOrMore>
+    <zeroOrMore>
+      <ref name="annotation">
+        <a:documentation>Annotations to the source code; each annotation consists of zero or more paragraphs,
+and is intended to be referenced by a callout within the source code</a:documentation>
+      </ref>
+    </zeroOrMore>
+    <zeroOrMore>
+      <ref name="note-no-id">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
   <define name="pre">
+    <a:documentation>Pre-formatted block. Wrapper for text to be rendered with fixed-width typeface, and preserving spaces including line breaks. 
+They are intended for a restricted number of functions, most typically ASCII Art (which is still in prominent use in some 
+standards documents), and computer output. In most cases, sourcecode blocks are more appropriate in markup, 
+as it is more clearly motivated semantically</a:documentation>
     <element name="pre">
-      <attribute name="id">
-        <data type="ID"/>
-      </attribute>
-      <optional>
-        <attribute name="alt"/>
-      </optional>
-      <optional>
-        <ref name="tname"/>
-      </optional>
-      <text/>
-      <zeroOrMore>
-        <ref name="note"/>
-      </zeroOrMore>
+      <ref name="RequiredId"/>
+      <ref name="PreAttributes"/>
+      <ref name="PreBody"/>
+    </element>
+  </define>
+  <define name="pre-no-id">
+    <a:documentation>Pre-formatted block: optional ID attributes (for use in Relaton, metadata)</a:documentation>
+    <element name="pre">
+      <ref name="OptionalId"/>
+      <ref name="PreAttributes"/>
+      <ref name="PreNoIdBody"/>
     </element>
   </define>
+  <define name="PreAttributes">
+    <optional>
+      <attribute name="alt">
+        <a:documentation>Accessible description of the preformatted text</a:documentation>
+      </attribute>
+    </optional>
+  </define>
+  <define name="PreBody">
+    <optional>
+      <ref name="tname">
+        <a:documentation>The caption of the block</a:documentation>
+      </ref>
+    </optional>
+    <text>
+      <a:documentation>The pre-formatted text presented in the block, as a single unformatted string. (Whitespace is treated as significant)</a:documentation>
+    </text>
+    <zeroOrMore>
+      <ref name="note">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
+  <define name="PreNoIdBody">
+    <optional>
+      <ref name="tname">
+        <a:documentation>The caption of the block</a:documentation>
+      </ref>
+    </optional>
+    <text>
+      <a:documentation>The pre-formatted text presented in the block, as a single unformatted string. (Whitespace is treated as significant)</a:documentation>
+    </text>
+    <zeroOrMore>
+      <ref name="note-no-id">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
   <define name="table">
+    <a:documentation>Tabular arrangement of text</a:documentation>
     <element name="table">
-      <attribute name="id">
-        <data type="ID"/>
-      </attribute>
-      <optional>
-        <attribute name="unnumbered">
-          <data type="boolean"/>
-        </attribute>
-      </optional>
-      <optional>
-        <attribute name="subsequence"/>
-      </optional>
-      <optional>
-        <attribute name="alt"/>
-      </optional>
-      <optional>
-        <attribute name="summary"/>
-      </optional>
-      <optional>
-        <attribute name="uri">
-          <data type="anyURI"/>
-        </attribute>
-      </optional>
-      <optional>
-        <ref name="tname"/>
-      </optional>
-      <optional>
-        <ref name="thead"/>
-      </optional>
-      <ref name="tbody"/>
-      <optional>
-        <ref name="tfoot"/>
-      </optional>
-      <zeroOrMore>
-        <ref name="table-note"/>
-      </zeroOrMore>
-      <optional>
-        <ref name="dl"/>
-      </optional>
+      <ref name="RequiredId"/>
+      <ref name="TableAttributes"/>
+      <ref name="TableBody"/>
     </element>
   </define>
+  <define name="table-no-id">
+    <a:documentation>Tabular arrangement of text: optional ID attributes recursively (for use in Relaton, metadata)</a:documentation>
+    <element name="table">
+      <ref name="OptionalId"/>
+      <ref name="TableAttributes"/>
+      <ref name="TableNoIdBody"/>
+    </element>
+  </define>
+  <define name="TableAttributes">
+    <ref name="NumberingAttributes"/>
+    <optional>
+      <attribute name="alt">
+        <a:documentation>Accessible description of the tabular text, in case the table cannot be rendered accessibly (HTML 5)</a:documentation>
+      </attribute>
+    </optional>
+    <optional>
+      <attribute name="summary">
+        <a:documentation>Alternative more extensive summary of table to be provided for accessibility purposes, 
+in case the table cannot be rendered accessibly (HTML 5)</a:documentation>
+      </attribute>
+    </optional>
+    <optional>
+      <attribute name="uri">
+        <a:documentation>Online location of content of table (in case the table is available as a separate external document) (HTML 5)</a:documentation>
+        <data type="anyURI"/>
+      </attribute>
+    </optional>
+  </define>
+  <define name="TableBody">
+    <a:documentation>Elements of table</a:documentation>
+    <optional>
+      <ref name="tname">
+        <a:documentation>Caption for the table</a:documentation>
+      </ref>
+    </optional>
+    <optional>
+      <ref name="thead">
+        <a:documentation>Table rows constituting the table header</a:documentation>
+      </ref>
+    </optional>
+    <ref name="tbody">
+      <a:documentation>Table rows constituting the table body</a:documentation>
+    </ref>
+    <optional>
+      <ref name="tfoot">
+        <a:documentation>Table rows constituting the table footer</a:documentation>
+      </ref>
+    </optional>
+    <optional>
+      <ref name="dl">
+        <a:documentation>Definitions list defining any symbols used in the table</a:documentation>
+      </ref>
+    </optional>
+    <zeroOrMore>
+      <ref name="table-note">
+        <a:documentation>Notes specific to this block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
+  <define name="TableNoIdBody">
+    <a:documentation>Elements of table: optional ID attributes recursively (for use in Relaton, metadata)</a:documentation>
+    <optional>
+      <ref name="tname">
+        <a:documentation>Caption for the table</a:documentation>
+      </ref>
+    </optional>
+    <optional>
+      <ref name="thead-no-id">
+        <a:documentation>Table rows constituting the table header</a:documentation>
+      </ref>
+    </optional>
+    <ref name="tbody-no-id">
+      <a:documentation>Table rows constituting the table body</a:documentation>
+    </ref>
+    <optional>
+      <ref name="tfoot-no-id">
+        <a:documentation>Table rows constituting the table footer</a:documentation>
+      </ref>
+    </optional>
+    <optional>
+      <ref name="dl-no-id">
+        <a:documentation>Definitions list defining any symbols used in the table</a:documentation>
+      </ref>
+    </optional>
+    <zeroOrMore>
+      <ref name="table-note-no-id">
+        <a:documentation>Notes specific to this block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
   <define name="tname">
     <element name="name">
       <oneOrMore>
-        <choice>
-          <ref name="PureTextElement"/>
-          <ref name="eref"/>
-          <ref name="stem"/>
-          <ref name="keyword"/>
-          <ref name="xref"/>
-          <ref name="hyperlink"/>
-          <ref name="index"/>
-          <ref name="index-xref"/>
-        </choice>
+        <ref name="NestedTextElement"/>
       </oneOrMore>
     </element>
   </define>
@@ -441,11 +817,21 @@
       <ref name="tr"/>
     </element>
   </define>
+  <define name="thead-no-id">
+    <element name="thead">
+      <ref name="tr-no-id"/>
+    </element>
+  </define>
   <define name="tfoot">
     <element name="tfoot">
       <ref name="tr"/>
     </element>
   </define>
+  <define name="tfoot-no-id">
+    <element name="tfoot">
+      <ref name="tr-no-id"/>
+    </element>
+  </define>
   <define name="tbody">
     <element name="tbody">
       <oneOrMore>
@@ -453,209 +839,409 @@
       </oneOrMore>
     </element>
   </define>
+  <define name="tbody-no-id">
+    <element name="tbody">
+      <oneOrMore>
+        <ref name="tr-no-id"/>
+      </oneOrMore>
+    </element>
+  </define>
   <define name="table-note">
     <element name="note">
       <ref name="paragraph"/>
     </element>
   </define>
+  <define name="table-note-no-id">
+    <element name="note">
+      <ref name="paragraph-no-id"/>
+    </element>
+  </define>
   <define name="tr">
+    <a:documentation>Sequence of cells to be displayed as a row in a table</a:documentation>
+    <element name="tr">
+      <oneOrMore>
+        <choice>
+          <ref name="td">
+            <a:documentation>Data cells in a table row</a:documentation>
+          </ref>
+          <ref name="th">
+            <a:documentation>Header cells in a table row</a:documentation>
+          </ref>
+        </choice>
+      </oneOrMore>
+    </element>
+  </define>
+  <define name="tr-no-id">
+    <a:documentation>Sequence of cells to be displayed as a row in a table: optional ID attributes recursively (for use in Relaton, metadata)</a:documentation>
     <element name="tr">
       <oneOrMore>
         <choice>
-          <ref name="td"/>
-          <ref name="th"/>
+          <ref name="td-no-id"/>
+          <ref name="th-no-id"/>
         </choice>
       </oneOrMore>
     </element>
   </define>
   <define name="td">
+    <a:documentation>Textual content constituting a basic building block of a table: data cell</a:documentation>
     <element name="td">
-      <optional>
-        <attribute name="colspan"/>
-      </optional>
-      <optional>
-        <attribute name="rowspan"/>
-      </optional>
-      <optional>
-        <attribute name="align">
-          <choice>
-            <value>left</value>
-            <value>right</value>
-            <value>center</value>
-          </choice>
-        </attribute>
-      </optional>
-      <optional>
-        <attribute name="valign">
-          <choice>
-            <value>top</value>
-            <value>middle</value>
-            <value>bottom</value>
-            <value>baseline</value>
-          </choice>
-        </attribute>
-      </optional>
-      <choice>
-        <zeroOrMore>
-          <ref name="TextElement"/>
-        </zeroOrMore>
-        <oneOrMore>
-          <ref name="paragraph-with-footnote"/>
-        </oneOrMore>
-      </choice>
+      <ref name="TdAttributes"/>
+      <ref name="TdBody"/>
     </element>
   </define>
-  <define name="th">
-    <element name="th">
-      <optional>
-        <attribute name="colspan"/>
-      </optional>
-      <optional>
-        <attribute name="rowspan"/>
-      </optional>
-      <optional>
-        <attribute name="align">
-          <choice>
-            <value>left</value>
-            <value>right</value>
-            <value>center</value>
-          </choice>
-        </attribute>
-      </optional>
-      <optional>
-        <attribute name="valign">
-          <choice>
-            <value>top</value>
-            <value>middle</value>
-            <value>bottom</value>
-            <value>baseline</value>
-          </choice>
-        </attribute>
-      </optional>
-      <choice>
-        <zeroOrMore>
-          <ref name="TextElement"/>
-        </zeroOrMore>
-        <oneOrMore>
-          <ref name="paragraph-with-footnote"/>
-        </oneOrMore>
-      </choice>
+  <define name="td-no-id">
+    <a:documentation>Data cell: optional ID attributes recursively (for use in Relaton, metadata)</a:documentation>
+    <element name="td">
+      <ref name="TdAttributes"/>
+      <ref name="TdNoIdBody"/>
     </element>
   </define>
-  <define name="example">
-    <element name="example">
-      <attribute name="id">
-        <data type="ID"/>
+  <define name="TdAttributes">
+    <optional>
+      <attribute name="colspan">
+        <a:documentation>Number of columns in the underlying table grid which the cell spans</a:documentation>
       </attribute>
-      <optional>
-        <attribute name="unnumbered">
-          <data type="boolean"/>
-        </attribute>
-      </optional>
-      <optional>
-        <attribute name="subsequence"/>
-      </optional>
-      <optional>
-        <ref name="tname"/>
-      </optional>
-      <oneOrMore>
+    </optional>
+    <optional>
+      <attribute name="rowspan">
+        <a:documentation>Number of rows in the underlying table grid which the cell spans</a:documentation>
+      </attribute>
+    </optional>
+    <optional>
+      <attribute name="align">
+        <a:documentation>Horizontal textual alignment of the cell against the underlying table grid</a:documentation>
         <choice>
-          <ref name="formula"/>
-          <ref name="ul"/>
-          <ref name="ol"/>
-          <ref name="dl"/>
-          <ref name="quote"/>
-          <ref name="sourcecode"/>
-          <ref name="paragraph-with-footnote"/>
+          <value>left</value>
+          <value>right</value>
+          <value>center</value>
         </choice>
+      </attribute>
+    </optional>
+    <optional>
+      <attribute name="valign">
+        <a:documentation>Vertical alignment of the cell against the underlying table grid</a:documentation>
+        <choice>
+          <value>top</value>
+          <value>middle</value>
+          <value>bottom</value>
+          <value>baseline</value>
+        </choice>
+      </attribute>
+    </optional>
+  </define>
+  <define name="TdBody">
+    <choice>
+      <zeroOrMore>
+        <group>
+          <a:documentation>Table cell is a block</a:documentation>
+          <ref name="TextElement"/>
+        </group>
+      </zeroOrMore>
+      <oneOrMore>
+        <ref name="paragraph-with-footnote">
+          <a:documentation>Table cell contains a block</a:documentation>
+        </ref>
       </oneOrMore>
+    </choice>
+  </define>
+  <define name="TdNoIdBody">
+    <choice>
       <zeroOrMore>
-        <ref name="note"/>
+        <group>
+          <a:documentation>Table cell is a block</a:documentation>
+          <ref name="TextElement"/>
+        </group>
       </zeroOrMore>
+      <oneOrMore>
+        <ref name="paragraph-with-footnote-no-id">
+          <a:documentation>Table cell contains a block</a:documentation>
+        </ref>
+      </oneOrMore>
+    </choice>
+  </define>
+  <define name="th">
+    <a:documentation>Textual content constituting a basic building block of a table, treated as a header: header cell</a:documentation>
+    <element name="th">
+      <ref name="ThAttributes"/>
+      <ref name="ThBody"/>
+    </element>
+  </define>
+  <define name="th-no-id">
+    <a:documentation>Header cell: optional ID attributes recursively (for use in Relaton, metadata)</a:documentation>
+    <element name="th">
+      <ref name="ThAttributes"/>
+      <ref name="ThNoIdBody"/>
+    </element>
+  </define>
+  <define name="ThAttributes">
+    <ref name="TdAttributes"/>
+  </define>
+  <define name="ThBody">
+    <ref name="TdBody"/>
+  </define>
+  <define name="ThNoIdBody">
+    <ref name="TdNoIdBody"/>
+  </define>
+  <define name="example">
+    <a:documentation>Block containing an example illustrating a claim made in the main flow of text</a:documentation>
+    <element name="example">
+      <ref name="RequiredId"/>
+      <ref name="ExampleAttributes"/>
+      <ref name="ExampleBody"/>
+    </element>
+  </define>
+  <define name="example-no-id">
+    <a:documentation>Example block: optional ID attributes recursively (for use in Relaton, metadata)</a:documentation>
+    <element name="example">
+      <ref name="OptionalId"/>
+      <ref name="ExampleAttributes"/>
+      <ref name="ExampleNoIdBody"/>
     </element>
   </define>
+  <define name="ExampleAttributes">
+    <ref name="NumberingAttributes"/>
+  </define>
+  <define name="ExampleBody">
+    <optional>
+      <ref name="tname">
+        <a:documentation>The caption of the example</a:documentation>
+      </ref>
+    </optional>
+    <oneOrMore>
+      <choice>
+        <a:documentation>Content of the example</a:documentation>
+        <ref name="formula"/>
+        <ref name="ul"/>
+        <ref name="ol"/>
+        <ref name="dl"/>
+        <ref name="quote"/>
+        <ref name="sourcecode"/>
+        <ref name="paragraph-with-footnote"/>
+      </choice>
+    </oneOrMore>
+    <zeroOrMore>
+      <ref name="note">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
+  <define name="ExampleNoIdBody">
+    <optional>
+      <ref name="tname">
+        <a:documentation>The caption of the example</a:documentation>
+      </ref>
+    </optional>
+    <oneOrMore>
+      <choice>
+        <a:documentation>Content of the example</a:documentation>
+        <ref name="formula-no-id"/>
+        <ref name="ul-no-id"/>
+        <ref name="ol-no-id"/>
+        <ref name="dl-no-id"/>
+        <ref name="quote-no-id"/>
+        <ref name="sourcecode-no-id"/>
+        <ref name="paragraph-with-footnote-no-id"/>
+      </choice>
+    </oneOrMore>
+    <zeroOrMore>
+      <ref name="note-no-id">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
   <define name="admonition">
+    <a:documentation>A sidebar block outside of the main flow of text, conveying particular warnings or supplementary text to the reader</a:documentation>
     <element name="admonition">
-      <attribute name="type">
-        <ref name="AdmonitionType"/>
+      <ref name="RequiredId"/>
+      <ref name="AdmonitionAttributes"/>
+      <ref name="AdmonitionBody"/>
+    </element>
+  </define>
+  <define name="admonition-no-id">
+    <a:documentation>A sidebar block outside of the main flow of text: optional ID attributes recursively (for use in Relaton, metadata)</a:documentation>
+    <element name="admonition">
+      <ref name="OptionalId"/>
+      <ref name="AdmonitionAttributes"/>
+      <ref name="AdmonitionNoIdBody"/>
+    </element>
+  </define>
+  <define name="AdmonitionAttributes">
+    <attribute name="type">
+      <a:documentation>Subclass of admonition determining how it is to be rendered. 
+Distinct admonition types are often associated with distinct icons or rendering</a:documentation>
+      <ref name="AdmonitionType"/>
+    </attribute>
+    <optional>
+      <attribute name="class">
+        <a:documentation>Subclass of admonition, allowing different runs of admonitions to be labelled
+and auto-numbered differently, even if they are of the same type.
+Typically is a subclass of an admonition type</a:documentation>
       </attribute>
-      <optional>
-        <attribute name="class"/>
-      </optional>
-      <attribute name="id">
-        <data type="ID"/>
+    </optional>
+    <optional>
+      <attribute name="uri">
+        <a:documentation>Location where the content of the admonition is accessible as an external document</a:documentation>
+        <data type="anyURI"/>
       </attribute>
-      <optional>
-        <attribute name="uri">
-          <data type="anyURI"/>
-        </attribute>
-      </optional>
-      <optional>
-        <ref name="tname"/>
-      </optional>
-      <zeroOrMore>
-        <ref name="paragraph-with-footnote"/>
-      </zeroOrMore>
-      <zeroOrMore>
-        <ref name="note"/>
-      </zeroOrMore>
-    </element>
+    </optional>
+  </define>
+  <define name="AdmonitionBody">
+    <optional>
+      <ref name="tname">
+        <a:documentation>Caption of admonition</a:documentation>
+      </ref>
+    </optional>
+    <zeroOrMore>
+      <ref name="paragraph-with-footnote">
+        <a:documentation>Admonition content</a:documentation>
+      </ref>
+    </zeroOrMore>
+    <zeroOrMore>
+      <ref name="note">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
+  <define name="AdmonitionNoIdBody">
+    <optional>
+      <ref name="tname">
+        <a:documentation>Caption of admonition</a:documentation>
+      </ref>
+    </optional>
+    <zeroOrMore>
+      <ref name="paragraph-with-footnote-no-id">
+        <a:documentation>Admonition content</a:documentation>
+      </ref>
+    </zeroOrMore>
+    <zeroOrMore>
+      <ref name="note-no-id">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
   </define>
   <define name="AdmonitionType">
+    <a:documentation>Subclass of admonition determining how it is to be rendered</a:documentation>
     <choice>
       <value>warning</value>
+      <a:documentation>Warning to reader, note of risk to be avoided</a:documentation>
       <value>note</value>
+      <a:documentation>Supplementary, explanatory information</a:documentation>
       <value>tip</value>
+      <a:documentation>Instructive information to assist in the fulfilment of tasks related to content</a:documentation>
       <value>important</value>
+      <a:documentation>Note to reader of something crucial to be borne in mind</a:documentation>
       <value>caution</value>
+      <a:documentation>Caution to reader, note of potential surprise or difficulty</a:documentation>
     </choice>
   </define>
   <define name="figure">
+    <a:documentation>Block containing a figure: a visual rather than textual asset, possibly with accompanying text</a:documentation>
     <element name="figure">
-      <attribute name="id">
-        <data type="ID"/>
+      <ref name="RequiredId"/>
+      <ref name="FigureAttributes"/>
+      <ref name="FigureBody"/>
+    </element>
+  </define>
+  <define name="figure-no-id">
+    <a:documentation>Block containing a figure: optional ID attributes recursively (for use in Relaton, metadata)</a:documentation>
+    <element name="figure">
+      <ref name="OptionalId"/>
+      <ref name="FigureAttributes"/>
+      <ref name="FigureNoIdBody"/>
+    </element>
+  </define>
+  <define name="FigureAttributes">
+    <ref name="NumberingAttributes"/>
+    <optional>
+      <attribute name="class">
+        <a:documentation>The semantic category of the figure. This is to allow different classes of figure (e.g. _Plate_, _Chart_, _Diagram_) 
+to be auto-numbered and captioned differently</a:documentation>
       </attribute>
-      <optional>
-        <attribute name="unnumbered">
-          <data type="boolean"/>
-        </attribute>
-      </optional>
-      <optional>
-        <attribute name="subsequence"/>
-      </optional>
-      <optional>
-        <attribute name="class"/>
-      </optional>
-      <optional>
-        <ref name="source"/>
-      </optional>
-      <optional>
-        <ref name="tname"/>
-      </optional>
-      <choice>
-        <ref name="image"/>
-        <ref name="video"/>
-        <ref name="audio"/>
-        <ref name="pre"/>
-        <oneOrMore>
-          <ref name="paragraph-with-footnote"/>
-        </oneOrMore>
-        <zeroOrMore>
-          <ref name="figure"/>
-        </zeroOrMore>
-      </choice>
+    </optional>
+  </define>
+  <define name="FigureBody">
+    <optional>
+      <ref name="tname">
+        <a:documentation>The caption of the block</a:documentation>
+      </ref>
+    </optional>
+    <choice>
+      <a:documentation>Content of the figure</a:documentation>
+      <ref name="image"/>
+      <ref name="video"/>
+      <ref name="audio"/>
+      <ref name="pre"/>
+      <oneOrMore>
+        <ref name="paragraph-with-footnote"/>
+      </oneOrMore>
       <zeroOrMore>
-        <ref name="fn"/>
+        <ref name="figure"/>
       </zeroOrMore>
-      <optional>
-        <ref name="dl"/>
-      </optional>
+    </choice>
+    <zeroOrMore>
+      <ref name="fn">
+        <a:documentation>Footnotes specific to the figure</a:documentation>
+      </ref>
+    </zeroOrMore>
+    <optional>
+      <ref name="dl">
+        <a:documentation>An optional definitions list defining any symbols used in the figure</a:documentation>
+      </ref>
+    </optional>
+    <zeroOrMore>
+      <ref name="note">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+    <optional>
+      <ref name="source">
+        <a:documentation>A URI or other reference intended to link to an externally hosted image (or equivalent)</a:documentation>
+      </ref>
+    </optional>
+  </define>
+  <define name="FigureNoIdBody">
+    <optional>
+      <ref name="source">
+        <a:documentation>A URI or other reference intended to link to an externally hosted image (or equivalent)</a:documentation>
+      </ref>
+    </optional>
+    <optional>
+      <ref name="tname">
+        <a:documentation>The caption of the block</a:documentation>
+      </ref>
+    </optional>
+    <choice>
+      <a:documentation>Content of the figure</a:documentation>
+      <ref name="image-no-id"/>
+      <ref name="video-no-id"/>
+      <ref name="audio-no-id"/>
+      <ref name="pre-no-id"/>
+      <oneOrMore>
+        <ref name="paragraph-with-footnote-no-id"/>
+      </oneOrMore>
       <zeroOrMore>
-        <ref name="note"/>
+        <ref name="figure-no-id"/>
       </zeroOrMore>
-    </element>
+    </choice>
+    <zeroOrMore>
+      <ref name="fn">
+        <a:documentation>Footnotes specific to the figure</a:documentation>
+      </ref>
+    </zeroOrMore>
+    <optional>
+      <ref name="dl-no-id">
+        <a:documentation>An optional definitions list defining any symbols used in the figure</a:documentation>
+      </ref>
+    </optional>
+    <zeroOrMore>
+      <ref name="note-no-id">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
   </define>
   <define name="TextElement">
+    <a:documentation>Any inline element containing text and associated formatting information.
+Includes inline elements that are identifiers or references to identifiers</a:documentation>
     <choice>
       <text/>
       <ref name="em"/>
@@ -682,69 +1268,91 @@
     </choice>
   </define>
   <define name="PureTextElement">
+    <a:documentation>Inline element containing text and associated formatting information,
+but which does not contain any associated identifiers or references to identifiers.
+Restricted recursively to contain only other such inline elements with no identifiers or references to identifiers</a:documentation>
     <choice>
       <text/>
-      <ref name="em"/>
-      <ref name="strong"/>
+      <ref name="pure_em"/>
+      <ref name="pure_strong"/>
       <ref name="sub"/>
       <ref name="sup"/>
-      <ref name="tt"/>
-      <ref name="underline"/>
-      <ref name="strike"/>
-      <ref name="smallcap"/>
+      <ref name="pure_tt"/>
+      <ref name="pure_underline"/>
+      <ref name="pure_strike"/>
+      <ref name="pure_smallcap"/>
       <ref name="br"/>
     </choice>
   </define>
+  <define name="NestedTextElement">
+    <a:documentation>Contents of TextElement tags: leaves out tags that should occur only at top level of block: bookmark image hr pagebreak</a:documentation>
+    <choice>
+      <ref name="PureTextElement"/>
+      <ref name="stem"/>
+      <ref name="eref"/>
+      <ref name="xref"/>
+      <ref name="hyperlink"/>
+      <ref name="index"/>
+      <ref name="index-xref"/>
+      <ref name="ruby"/>
+      <ref name="keyword"/>
+    </choice>
+  </define>
   <define name="source">
     <element name="source">
       <ref name="TypedUri"/>
     </element>
   </define>
   <define name="em">
+    <a:documentation>Emphasised text. Corresponds to HTML `em`, `i`</a:documentation>
     <element name="em">
       <zeroOrMore>
-        <choice>
-          <ref name="PureTextElement"/>
-          <ref name="stem"/>
-          <ref name="eref"/>
-          <ref name="xref"/>
-          <ref name="hyperlink"/>
-          <ref name="index"/>
-          <ref name="index-xref"/>
-        </choice>
+        <ref name="NestedTextElement"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="pure_em">
+    <a:documentation>Emphasised text for PureTextElement</a:documentation>
+    <element name="em">
+      <zeroOrMore>
+        <ref name="PureTextElement"/>
       </zeroOrMore>
     </element>
   </define>
   <define name="strong">
+    <a:documentation>Strong text. Corresponds to HTML `strong`, `b`</a:documentation>
     <element name="strong">
       <zeroOrMore>
-        <choice>
-          <ref name="PureTextElement"/>
-          <ref name="stem"/>
-          <ref name="eref"/>
-          <ref name="xref"/>
-          <ref name="hyperlink"/>
-          <ref name="index"/>
-          <ref name="index-xref"/>
-        </choice>
+        <ref name="NestedTextElement"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="pure_strong">
+    <a:documentation>Strong text for PureTextElement</a:documentation>
+    <element name="strong">
+      <zeroOrMore>
+        <ref name="PureTextElement"/>
       </zeroOrMore>
     </element>
   </define>
   <define name="tt">
+    <a:documentation>Monospace text. Corresponds to HTML `tt`, `code`</a:documentation>
     <element name="tt">
       <zeroOrMore>
-        <choice>
-          <ref name="PureTextElement"/>
-          <ref name="eref"/>
-          <ref name="xref"/>
-          <ref name="hyperlink"/>
-          <ref name="index"/>
-          <ref name="index-xref"/>
-        </choice>
+        <ref name="NestedTextElement"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="pure_tt">
+    <a:documentation>Monospace text for PureTextElement</a:documentation>
+    <element name="tt">
+      <zeroOrMore>
+        <ref name="PureTextElement"/>
       </zeroOrMore>
     </element>
   </define>
   <define name="keyword">
+    <a:documentation>Keyword text</a:documentation>
     <element name="keyword">
       <zeroOrMore>
         <choice>
@@ -756,6 +1364,7 @@
     </element>
   </define>
   <define name="sub">
+    <a:documentation>Subscript text. Corresponds to HTML `sub`</a:documentation>
     <element name="sub">
       <zeroOrMore>
         <ref name="PureTextElement"/>
@@ -763,6 +1372,7 @@
     </element>
   </define>
   <define name="sup">
+    <a:documentation>Superscript text. Corresponds to HTML `sup`</a:documentation>
     <element name="sup">
       <zeroOrMore>
         <ref name="PureTextElement"/>
@@ -770,17 +1380,36 @@
     </element>
   </define>
   <define name="strike">
+    <a:documentation>Strikethrough text. Corresponds to HTML 4 `s`</a:documentation>
     <element name="strike">
       <zeroOrMore>
-        <choice>
-          <ref name="PureTextElement"/>
-          <ref name="index"/>
-          <ref name="index-xref"/>
-        </choice>
+        <ref name="NestedTextElement"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="pure_strike">
+    <a:documentation>Strikethrough for PureTextElement</a:documentation>
+    <element name="strike">
+      <zeroOrMore>
+        <ref name="PureTextElement"/>
       </zeroOrMore>
     </element>
   </define>
   <define name="underline">
+    <a:documentation>Underlined text. Corresponds to HTML 4 `u`</a:documentation>
+    <element name="underline">
+      <optional>
+        <attribute name="style">
+          <a:documentation>CSS style to apply to underline (intended for text-decoration-style attribute keyword values: solid double dotted dashed wavy)</a:documentation>
+        </attribute>
+      </optional>
+      <zeroOrMore>
+        <ref name="NestedTextElement"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="pure_underline">
+    <a:documentation>Underlined text for PureTextElement</a:documentation>
     <element name="underline">
       <optional>
         <attribute name="style"/>
@@ -791,6 +1420,15 @@
     </element>
   </define>
   <define name="smallcap">
+    <a:documentation>Small caps text</a:documentation>
+    <element name="smallcap">
+      <zeroOrMore>
+        <ref name="NestedTextElement"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="pure_smallcap">
+    <a:documentation>Small caps text for PureTextElement</a:documentation>
     <element name="smallcap">
       <zeroOrMore>
         <ref name="PureTextElement"/>
@@ -798,252 +1436,320 @@
     </element>
   </define>
   <define name="ruby">
+    <a:documentation>Text with Ruby annotations in East Asian languages. Corresponds to HTML `ruby`</a:documentation>
     <element name="ruby">
       <choice>
-        <ref name="ruby_pronunciation"/>
-        <ref name="ruby_annotation"/>
+        <ref name="ruby_pronunciation">
+          <a:documentation>Ruby annotation giving pronunciation</a:documentation>
+        </ref>
+        <ref name="ruby_annotation">
+          <a:documentation>Ruby annotation giving other (semantic) information</a:documentation>
+        </ref>
       </choice>
       <choice>
-        <text/>
-        <ref name="ruby"/>
+        <text>
+          <a:documentation>Ruby annotated text which contains no further annotations</a:documentation>
+        </text>
+        <ref name="ruby">
+          <a:documentation>Ruby annotated text which itself contains other Ruby annotations</a:documentation>
+        </ref>
       </choice>
     </element>
   </define>
   <define name="ruby_pronunciation">
+    <a:documentation>Ruby annotation giving pronunciation of text</a:documentation>
     <element name="pronunciation">
-      <attribute name="value"/>
-      <optional>
-        <attribute name="script"/>
-      </optional>
-      <optional>
-        <attribute name="lang"/>
-      </optional>
+      <attribute name="value">
+        <a:documentation>Ruby annotation value</a:documentation>
+      </attribute>
+      <ref name="LocalizedStringAttributes"/>
     </element>
   </define>
   <define name="ruby_annotation">
+    <a:documentation>Ruby annotation giving information other than pronunciation of text</a:documentation>
     <element name="annotation">
-      <attribute name="value"/>
-      <optional>
-        <attribute name="script"/>
-      </optional>
-      <optional>
-        <attribute name="lang"/>
-      </optional>
+      <attribute name="value">
+        <a:documentation>Ruby annotation value</a:documentation>
+      </attribute>
+      <ref name="LocalizedStringAttributes"/>
     </element>
   </define>
   <define name="br">
+    <a:documentation>Line break</a:documentation>
     <element name="br">
       <empty/>
     </element>
   </define>
   <define name="hr">
+    <a:documentation>Horizontal rule</a:documentation>
     <element name="hr">
       <empty/>
     </element>
   </define>
   <define name="pagebreak">
+    <a:documentation>Page break. Only applicable in paged layouts (e.g. PDF, Word), and not flow layouts (e.g. HTML)</a:documentation>
     <element name="pagebreak">
       <empty/>
     </element>
   </define>
   <define name="index">
+    <a:documentation>Index term, defined as applying to the location in the text where the index element appears, as a milestone</a:documentation>
     <element name="index">
       <optional>
         <attribute name="to">
+          <a:documentation>A reference to an anchor element (typically a bookmark), 
+to indicate that the index range covers a range of locations between the current index element and the `to` anchor</a:documentation>
           <data type="IDREF"/>
         </attribute>
       </optional>
-      <element name="primary">
-        <oneOrMore>
-          <ref name="PureTextElement"/>
-        </oneOrMore>
-      </element>
-      <optional>
-        <element name="secondary">
-          <oneOrMore>
-            <ref name="PureTextElement"/>
-          </oneOrMore>
-        </element>
-      </optional>
-      <optional>
-        <element name="tertiary">
-          <oneOrMore>
-            <ref name="PureTextElement"/>
-          </oneOrMore>
-        </element>
-      </optional>
+      <ref name="index-primary">
+        <a:documentation>Primary index term to be recorded at the current location</a:documentation>
+      </ref>
+      <ref name="index-secondary">
+        <a:documentation>Secondary index term to be recorded at the current location</a:documentation>
+      </ref>
+      <ref name="index-tertiary">
+        <a:documentation>Tertiary index term to be recorded at the current </a:documentation>
+      </ref>
     </element>
   </define>
   <define name="index-xref">
+    <a:documentation>A reference to an index term, cross-referenced within an index as an
+alternative index entry, either as a "see" or a "see also" cross-reference.
+The text in the inline element is the primary index term to be be cross-referenced</a:documentation>
     <element name="index-xref">
       <attribute name="also">
+        <a:documentation>The cross-reference is to be treated as "see also" rather than as "see"</a:documentation>
         <data type="boolean"/>
       </attribute>
-      <element name="primary">
-        <oneOrMore>
-          <ref name="PureTextElement"/>
-        </oneOrMore>
-      </element>
-      <optional>
-        <element name="secondary">
-          <oneOrMore>
-            <ref name="PureTextElement"/>
-          </oneOrMore>
-        </element>
-      </optional>
-      <optional>
-        <element name="tertiary">
-          <oneOrMore>
-            <ref name="PureTextElement"/>
-          </oneOrMore>
-        </element>
-      </optional>
+      <ref name="index-primary">
+        <a:documentation>The primary index term to be cross-referenced</a:documentation>
+      </ref>
+      <ref name="index-secondary">
+        <a:documentation>The secondary index term to be cross-referenced</a:documentation>
+      </ref>
+      <ref name="index-tertiary">
+        <a:documentation>The tertiary index term to be cross-referenced</a:documentation>
+      </ref>
       <element name="target">
+        <a:documentation>The index term to be cross-referenced to</a:documentation>
         <oneOrMore>
           <ref name="PureTextElement"/>
         </oneOrMore>
       </element>
     </element>
   </define>
-  <!-- bare ID element, used for referencing arbitrary spans of text -->
+  <define name="index-primary">
+    <element name="primary">
+      <oneOrMore>
+        <ref name="PureTextElement"/>
+      </oneOrMore>
+    </element>
+  </define>
+  <define name="index-secondary">
+    <element name="secondary">
+      <oneOrMore>
+        <ref name="PureTextElement"/>
+      </oneOrMore>
+    </element>
+  </define>
+  <define name="index-tertiary">
+    <element name="tertiary">
+      <oneOrMore>
+        <ref name="PureTextElement"/>
+      </oneOrMore>
+    </element>
+  </define>
   <define name="bookmark">
+    <a:documentation>Anchors within a block under the BasicDocument model cannot span across a number of inline elements; 
+bookmarks are intended as point anchors. For that reason, the Review block has a starting reference and an optional ending reference, 
+which can be bookmarks as well as block or section references</a:documentation>
     <element name="bookmark">
-      <attribute name="id">
-        <data type="ID"/>
-      </attribute>
+      <ref name="RequiredId"/>
       <empty/>
     </element>
   </define>
   <define name="ReferenceFormat">
+    <a:documentation>The type of Reference Element, prescribing how it is to be rendered</a:documentation>
     <choice>
       <value>external</value>
+      <a:documentation>Reference to an external document</a:documentation>
       <value>inline</value>
+      <a:documentation>Reference to another element in the same document</a:documentation>
       <value>footnote</value>
+      <a:documentation>Inline reference to a block to be rendered as a footnote</a:documentation>
       <value>callout</value>
+      <a:documentation>Inline reference to a block to be referenced as a sourcecode callout</a:documentation>
     </choice>
   </define>
   <define name="eref">
+    <a:documentation>An external reference to a bibliographic entity</a:documentation>
     <element name="eref">
       <ref name="erefType"/>
     </element>
   </define>
   <define name="erefType">
+    <ref name="erefAttributes"/>
+    <ref name="CitationType">
+      <a:documentation>Reference cross-reference: modelled as cross-reference to the corresponding bibliographical item in a References section</a:documentation>
+    </ref>
+    <ref name="ErefBody">
+      <a:documentation>The textual content of the element. The `text` is what we wish to show the link as (e.g., the "content" of `&lt;xx&gt;my link text&lt;/xx&gt;`)</a:documentation>
+    </ref>
+  </define>
+  <define name="erefAttributes">
     <optional>
       <attribute name="normative">
+        <a:documentation>Whether the reference is to be treated as normative or informative, particularly in the context of normative documents such as standards</a:documentation>
         <data type="boolean"/>
       </attribute>
     </optional>
-    <attribute name="citeas"/>
-    <attribute name="type">
-      <ref name="ReferenceFormat"/>
+    <attribute name="citeas">
+      <a:documentation>Form that the bibliographic citation should take when it is rendered</a:documentation>
     </attribute>
     <optional>
-      <attribute name="alt"/>
+      <attribute name="type">
+        <a:documentation>The type of Reference Element, prescribing how it is to be rendered</a:documentation>
+        <ref name="ReferenceFormat"/>
+      </attribute>
+    </optional>
+    <optional>
+      <attribute name="alt">
+        <a:documentation>Alternate text, used for accessibility</a:documentation>
+      </attribute>
     </optional>
-    <ref name="CitationType"/>
-    <oneOrMore>
-      <ref name="PureTextElement"/>
-    </oneOrMore>
   </define>
   <define name="hyperlink">
+    <a:documentation>A reference to an external document or resource</a:documentation>
     <element name="link">
-      <attribute name="target">
-        <data type="anyURI"/>
-      </attribute>
+      <ref name="HyperlinkAttributes"/>
+      <oneOrMore>
+        <ref name="PureTextElement">
+          <a:documentation>The textual content of the element. The `text` is what we wish to show the link as (e.g., the "content" of `&lt;xx&gt;my link text&lt;/xx&gt;`)</a:documentation>
+        </ref>
+      </oneOrMore>
+    </element>
+  </define>
+  <define name="HyperlinkAttributes">
+    <attribute name="target">
+      <a:documentation>The location or online identifier of the external document or resource</a:documentation>
+      <data type="anyURI"/>
+    </attribute>
+    <optional>
       <attribute name="type">
+        <a:documentation>The type of Reference Element, prescribing how it is to be rendered</a:documentation>
         <ref name="ReferenceFormat"/>
       </attribute>
-      <optional>
-        <attribute name="alt"/>
-      </optional>
-      <oneOrMore>
-        <ref name="PureTextElement"/>
-      </oneOrMore>
-    </element>
+    </optional>
+    <optional>
+      <attribute name="alt">
+        <a:documentation>Alternate text, used for accessibility</a:documentation>
+      </attribute>
+    </optional>
   </define>
   <define name="xref">
+    <a:documentation>Inline element, which references an identifier of a document, a block in a document, or an element in a document</a:documentation>
     <element name="xref">
-      <attribute name="target">
-        <data type="IDREF"/>
-      </attribute>
+      <ref name="XrefAttributes"/>
+      <ref name="XrefBody"/>
+    </element>
+  </define>
+  <define name="XrefAttributes">
+    <attribute name="target">
+      <a:documentation>The identifier of a section, block or inlined element being referenced</a:documentation>
+      <data type="IDREF"/>
+    </attribute>
+    <optional>
       <attribute name="type">
+        <a:documentation>The type of Reference Element, prescribing how it is to be rendered</a:documentation>
         <ref name="ReferenceFormat"/>
       </attribute>
-      <optional>
-        <attribute name="alt"/>
-      </optional>
-      <oneOrMore>
-        <ref name="PureTextElement"/>
-      </oneOrMore>
-    </element>
+    </optional>
+    <optional>
+      <attribute name="alt">
+        <a:documentation>Alternate text, used for accessibility</a:documentation>
+      </attribute>
+    </optional>
+  </define>
+  <define name="XrefBody">
+    <oneOrMore>
+      <ref name="PureTextElement">
+        <a:documentation>The textual content of the element. The `text` is what we wish to show the link as (e.g., the "content" of `&lt;xx&gt;my link text&lt;/xx&gt;`)</a:documentation>
+      </ref>
+    </oneOrMore>
+  </define>
+  <define name="ErefBody">
+    <oneOrMore>
+      <ref name="PureTextElement">
+        <a:documentation>The textual content of the element. The `text` is what we wish to show the link as (e.g., the "content" of `&lt;xx&gt;my link text&lt;/xx&gt;`)</a:documentation>
+      </ref>
+    </oneOrMore>
   </define>
   <define name="fn">
+    <a:documentation>Inline reference to a paragraph or paragraphs, appearing as a footnote.
+The target of a footnote is the location it is embedded in within the text</a:documentation>
     <element name="fn">
-      <attribute name="reference"/>
+      <attribute name="reference">
+        <a:documentation>The number of the footnote, used to identify it visually</a:documentation>
+      </attribute>
       <oneOrMore>
-        <ref name="paragraph"/>
+        <ref name="paragraph">
+          <a:documentation>The content of the footnote</a:documentation>
+        </ref>
       </oneOrMore>
     </element>
   </define>
-  <!--
-    This is xref with fixed @type="footnote", and @target built in as paragraph+
-    @reference replaces ReferenceElement/text
-    so <fn reference="2"><p>This is a footnote</p></fn>
-    corresponds to 
-    <eref type="footnote" target="fn2">2</xref> <p id="fn2">This is a footnote</p>
-  -->
   <define name="callout">
+    <a:documentation>Inline reference to a paragraph or paragraphs, appearing as annotation of source code</a:documentation>
     <element name="callout">
       <attribute name="target">
+        <a:documentation>The target of the callout is understood to be the location of the callout within the source code; 
+the extent of the target is not expressed overtly</a:documentation>
         <data type="IDREF"/>
       </attribute>
-      <text/>
+      <text>
+        <a:documentation>The label of the callout, used to identify its target within the source code</a:documentation>
+      </text>
     </element>
   </define>
-  <!--
-    This is xref with fixed @type="callout"; the target by convention is in an annotation in the same source code snippet
-    so <callout target="xyz">1</callout>
-    corresponds to <xref type="callout" target="xyz">1</xref>
-  -->
   <define name="image">
+    <a:documentation>Container for image content</a:documentation>
     <element name="image">
-      <ref name="Image"/>
+      <ref name="RequiredId"/>
+      <ref name="ImageAttributes"/>
     </element>
   </define>
-  <define name="Image">
-    <attribute name="id">
-      <data type="ID"/>
-    </attribute>
-    <attribute name="src">
-      <data type="anyURI"/>
-    </attribute>
-    <attribute name="mimetype"/>
-    <optional>
-      <attribute name="filename"/>
-    </optional>
+  <define name="image-no-id">
+    <a:documentation>Container for image content: optional ID attributes recursively (for use in Relaton, metadata)</a:documentation>
+    <element name="image">
+      <ref name="OptionalId"/>
+      <ref name="ImageAttributes"/>
+    </element>
+  </define>
+  <define name="ImageAttributes">
+    <ref name="MediaAttributes"/>
+    <ref name="MediaAccessibilityAttributes"/>
     <optional>
       <attribute name="width">
+        <a:documentation>Height of image</a:documentation>
         <ref name="ImageSize"/>
       </attribute>
     </optional>
     <optional>
       <attribute name="height">
+        <a:documentation>Width of image</a:documentation>
         <ref name="ImageSize"/>
       </attribute>
     </optional>
-    <optional>
-      <attribute name="alt"/>
-    </optional>
-    <optional>
-      <attribute name="title"/>
-    </optional>
-    <optional>
-      <attribute name="longdesc">
-        <data type="anyURI"/>
-      </attribute>
-    </optional>
+  </define>
+  <define name="MIMEType">
+    <a:documentation>MIME encoding of media type</a:documentation>
+    <text/>
   </define>
   <define name="ImageSize">
+    <a:documentation>Legal values for image height and width.
+Attributes are realised as a real number, with optional percent sign,
+or as the string "auto"</a:documentation>
     <choice>
       <data type="string">
         <param name="pattern">\d+([.]\d+)?(%?)</param>
@@ -1052,177 +1758,328 @@
     </choice>
   </define>
   <define name="video">
+    <a:documentation>Container for video content</a:documentation>
     <element name="video">
-      <attribute name="id">
-        <data type="ID"/>
+      <ref name="RequiredId"/>
+      <ref name="VideoAttributes"/>
+      <ref name="VideoBody"/>
+    </element>
+  </define>
+  <define name="video-no-id">
+    <a:documentation>Container for video content: optional ID attributes recursively (for use in Relaton, metadata)</a:documentation>
+    <element name="video">
+      <ref name="OptionalId"/>
+      <ref name="VideoAttributes"/>
+      <ref name="VideoBody"/>
+    </element>
+  </define>
+  <define name="VideoAttributes">
+    <ref name="MediaAttributes"/>
+    <ref name="MediaAccessibilityAttributes"/>
+    <optional>
+      <attribute name="width">
+        <a:documentation>Width of video</a:documentation>
+        <ref name="ImageSize"/>
       </attribute>
-      <attribute name="src">
-        <data type="anyURI"/>
+    </optional>
+    <optional>
+      <attribute name="height">
+        <a:documentation>Height of video</a:documentation>
+        <ref name="ImageSize"/>
       </attribute>
-      <attribute name="mimetype"/>
-      <optional>
-        <attribute name="filename"/>
-      </optional>
-      <optional>
-        <attribute name="width">
-          <choice>
-            <data type="int"/>
-            <value>auto</value>
-          </choice>
-        </attribute>
-      </optional>
-      <optional>
-        <attribute name="height">
-          <choice>
-            <data type="int"/>
-            <value>auto</value>
-          </choice>
-        </attribute>
-      </optional>
-      <optional>
-        <attribute name="alt"/>
-      </optional>
-      <optional>
-        <attribute name="title"/>
-      </optional>
-      <optional>
-        <attribute name="longdesc">
-          <data type="anyURI"/>
-        </attribute>
-      </optional>
-      <zeroOrMore>
-        <ref name="altsource"/>
-      </zeroOrMore>
-    </element>
+    </optional>
+  </define>
+  <define name="VideoBody">
+    <zeroOrMore>
+      <ref name="altsource">
+        <a:documentation>Alternative files to use as media</a:documentation>
+      </ref>
+    </zeroOrMore>
   </define>
   <define name="audio">
+    <a:documentation>Container for audio content</a:documentation>
     <element name="audio">
-      <attribute name="id">
-        <data type="ID"/>
-      </attribute>
-      <attribute name="src">
-        <data type="anyURI"/>
-      </attribute>
-      <attribute name="mimetype"/>
-      <optional>
-        <attribute name="filename"/>
-      </optional>
-      <optional>
-        <attribute name="alt"/>
-      </optional>
-      <optional>
-        <attribute name="title"/>
-      </optional>
-      <optional>
-        <attribute name="longdesc">
-          <data type="anyURI"/>
-        </attribute>
-      </optional>
-      <zeroOrMore>
-        <ref name="altsource"/>
-      </zeroOrMore>
+      <ref name="RequiredId"/>
+      <ref name="AudioAttributes"/>
+      <ref name="AudioBody"/>
+    </element>
+  </define>
+  <define name="audio-no-id">
+    <a:documentation>Container for audio content: optional ID attributes recursively (for use in Relaton, metadata)</a:documentation>
+    <element name="audio">
+      <ref name="OptionalId"/>
+      <ref name="AudioAttributes"/>
+      <ref name="AudioBody"/>
     </element>
   </define>
+  <define name="AudioAttributes">
+    <ref name="MediaAttributes"/>
+    <ref name="MediaAccessibilityAttributes"/>
+  </define>
+  <define name="AudioBody">
+    <zeroOrMore>
+      <ref name="altsource">
+        <a:documentation>Alternative files to use as media</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
   <define name="altsource">
+    <a:documentation>Alternative file to use as media</a:documentation>
     <element name="altsource">
-      <attribute name="src">
+      <ref name="MediaAttributes"/>
+    </element>
+  </define>
+  <define name="MediaAttributes">
+    <attribute name="src">
+      <a:documentation>URI of the media file</a:documentation>
+      <data type="anyURI"/>
+    </attribute>
+    <attribute name="mimetype">
+      <a:documentation>Type of the media file, in MIME</a:documentation>
+      <ref name="MIMEType"/>
+    </attribute>
+    <optional>
+      <attribute name="filename">
+        <a:documentation>File name corresponding to the media, to which the media can be extracted if it is represented inline
+(e.g. in Base64 encoding in the URI)</a:documentation>
+      </attribute>
+    </optional>
+  </define>
+  <define name="MediaAccessibilityAttributes">
+    <optional>
+      <attribute name="alt">
+        <a:documentation>Alternate text, supplied for accessibility</a:documentation>
+      </attribute>
+    </optional>
+    <optional>
+      <attribute name="title">
+        <a:documentation>Title, supplied for accessibility</a:documentation>
+      </attribute>
+    </optional>
+    <optional>
+      <attribute name="longdesc">
+        <a:documentation>URI pointing to more extensive alternate text description, supplied for accessibility</a:documentation>
         <data type="anyURI"/>
       </attribute>
-      <attribute name="mimetype"/>
-      <optional>
-        <attribute name="filename"/>
-      </optional>
-    </element>
+    </optional>
   </define>
   <define name="stem">
+    <a:documentation>Mathematically formatted text</a:documentation>
     <element name="stem">
-      <attribute name="type">
-        <choice>
-          <value>MathML</value>
-          <value>AsciiMath</value>
-        </choice>
-      </attribute>
+      <ref name="StemAttributes"/>
       <oneOrMore>
         <choice>
+          <a:documentation>The content of the mathematically formatted text</a:documentation>
           <text/>
           <ref name="AnyElement"/>
         </choice>
       </oneOrMore>
     </element>
   </define>
+  <define name="StemAttributes">
+    <attribute name="type">
+      <a:documentation>The notation used to mathematically format the text</a:documentation>
+      <choice>
+        <value>MathML</value>
+        <value>AsciiMath</value>
+        <value>LaTeX</value>
+      </choice>
+    </attribute>
+  </define>
   <define name="annotation">
     <element name="annotation">
-      <attribute name="id">
-        <data type="ID"/>
-      </attribute>
-      <ref name="paragraph"/>
+      <ref name="RequiredId"/>
+      <oneOrMore>
+        <ref name="paragraph"/>
+      </oneOrMore>
     </element>
   </define>
   <define name="ul">
+    <a:documentation>Unordered list block</a:documentation>
     <element name="ul">
-      <attribute name="id">
-        <data type="ID"/>
-      </attribute>
-      <oneOrMore>
-        <ref name="li"/>
-      </oneOrMore>
-      <zeroOrMore>
-        <ref name="note"/>
-      </zeroOrMore>
+      <ref name="RequiredId"/>
+      <ref name="UlAttributes"/>
+      <ref name="UlBody"/>
+    </element>
+  </define>
+  <define name="ul-no-id">
+    <a:documentation>Unordered list block: optional ID attributes recursively (for use in Relaton, metadata)</a:documentation>
+    <element name="ul">
+      <ref name="OptionalId"/>
+      <ref name="UlAttributes"/>
+      <ref name="UlNoIdBody"/>
     </element>
   </define>
+  <define name="UlAttributes">
+    <empty/>
+  </define>
+  <define name="UlBody">
+    <oneOrMore>
+      <ref name="li">
+        <a:documentation>List items</a:documentation>
+      </ref>
+    </oneOrMore>
+    <zeroOrMore>
+      <ref name="note">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
+  <define name="UlNoIdBody">
+    <oneOrMore>
+      <ref name="li-no-id">
+        <a:documentation>List items</a:documentation>
+      </ref>
+    </oneOrMore>
+    <zeroOrMore>
+      <ref name="note-no-id">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
   <define name="li">
+    <a:documentation>Item in a list block</a:documentation>
     <element name="li">
-      <optional>
-        <attribute name="id">
-          <data type="ID"/>
-        </attribute>
-      </optional>
-      <oneOrMore>
-        <ref name="paragraph-with-footnote"/>
-      </oneOrMore>
+      <ref name="OptionalId"/>
+      <ref name="LiAttributes"/>
+      <ref name="LiBody"/>
+    </element>
+  </define>
+  <define name="li-no-id">
+    <a:documentation>Item in a list block: optional ID attributes recursively (for use in Relaton, metadata)</a:documentation>
+    <element name="li">
+      <ref name="OptionalId"/>
+      <ref name="LiAttributes"/>
+      <ref name="LiNoIdBody"/>
     </element>
   </define>
+  <define name="LiAttributes">
+    <empty/>
+  </define>
+  <define name="LiBody">
+    <oneOrMore>
+      <ref name="paragraph-with-footnote"/>
+    </oneOrMore>
+  </define>
+  <define name="LiNoIdBody">
+    <oneOrMore>
+      <ref name="paragraph-with-footnote-no-id"/>
+    </oneOrMore>
+  </define>
   <define name="ol">
+    <a:documentation>Ordered list, with numbering applied to the list items</a:documentation>
     <element name="ol">
-      <attribute name="id">
-        <data type="ID"/>
-      </attribute>
-      <attribute name="type">
-        <choice>
-          <value>roman</value>
-          <value>alphabet</value>
-          <value>arabic</value>
-          <value>roman_upper</value>
-          <value>alphabet_upper</value>
-        </choice>
-      </attribute>
-      <optional>
-        <attribute name="start"/>
-      </optional>
-      <oneOrMore>
-        <ref name="li"/>
-      </oneOrMore>
-      <zeroOrMore>
-        <ref name="note"/>
-      </zeroOrMore>
+      <ref name="RequiredId"/>
+      <ref name="OlAttributes"/>
+      <ref name="OlBody"/>
+    </element>
+  </define>
+  <define name="ol-no-id">
+    <a:documentation>Ordered list: optional ID attributes recursively (for use in Relaton, metadata)</a:documentation>
+    <element name="ol">
+      <ref name="OptionalId"/>
+      <ref name="OlAttributes"/>
+      <ref name="OlNoIdBody"/>
     </element>
   </define>
+  <define name="OlAttributes">
+    <attribute name="type">
+      <a:documentation>Type of numbering to be applied to the list items</a:documentation>
+      <choice>
+        <value>roman</value>
+        <value>alphabet</value>
+        <value>arabic</value>
+        <value>roman_upper</value>
+        <value>alphabet_upper</value>
+      </choice>
+    </attribute>
+    <optional>
+      <attribute name="start">
+        <a:documentation>Starting value for numbering of the list items; is a number, regardless of the type,
+and is mapped to the ordinal represented in the type</a:documentation>
+      </attribute>
+    </optional>
+  </define>
+  <define name="OlBody">
+    <oneOrMore>
+      <ref name="li">
+        <a:documentation>List item</a:documentation>
+      </ref>
+    </oneOrMore>
+    <zeroOrMore>
+      <ref name="note">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
+  <define name="OlNoIdBody">
+    <oneOrMore>
+      <ref name="li-no-id">
+        <a:documentation>List item</a:documentation>
+      </ref>
+    </oneOrMore>
+    <zeroOrMore>
+      <ref name="note-no-id">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
   <define name="dl">
+    <a:documentation>Definition list, composed of definitions rather than list items</a:documentation>
     <element name="dl">
-      <attribute name="id">
-        <data type="ID"/>
-      </attribute>
-      <oneOrMore>
-        <ref name="dt"/>
-        <ref name="dd"/>
-      </oneOrMore>
-      <zeroOrMore>
-        <ref name="note"/>
-      </zeroOrMore>
+      <ref name="RequiredId"/>
+      <ref name="DlAttributes"/>
+      <ref name="DlBody"/>
+    </element>
+  </define>
+  <define name="dl-no-id">
+    <a:documentation>Definition list: optional ID attributes recursively (for use in Relaton, metadata)</a:documentation>
+    <element name="dl">
+      <ref name="OptionalId"/>
+      <ref name="DlNoIdBody"/>
     </element>
   </define>
+  <define name="DlAttributes">
+    <empty/>
+  </define>
+  <define name="DlBody">
+    <oneOrMore>
+      <group>
+        <a:documentation>Entry-Definition pair used to constitute a definition list</a:documentation>
+        <ref name="dt">
+          <a:documentation>Entry being defined in the definition</a:documentation>
+        </ref>
+        <ref name="dd">
+          <a:documentation>Definition of the entry</a:documentation>
+        </ref>
+      </group>
+    </oneOrMore>
+    <zeroOrMore>
+      <ref name="note">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
+  <define name="DlNoIdBody">
+    <oneOrMore>
+      <group>
+        <a:documentation>Entry-Definition pair used to constitute a definition list</a:documentation>
+        <ref name="dt">
+          <a:documentation>Entry being defined in the definition</a:documentation>
+        </ref>
+        <ref name="dd-no-id">
+          <a:documentation>Definition of the entry</a:documentation>
+        </ref>
+      </group>
+    </oneOrMore>
+    <zeroOrMore>
+      <ref name="note-no-id">
+        <a:documentation>Notes whose scope is the current block</a:documentation>
+      </ref>
+    </zeroOrMore>
+  </define>
   <define name="dt">
+    <a:documentation>Entry in a definition list</a:documentation>
     <element name="dt">
       <zeroOrMore>
         <ref name="TextElement"/>
@@ -1230,10 +2087,19 @@
     </element>
   </define>
   <define name="dd">
+    <a:documentation>Definition in a definition list</a:documentation>
     <element name="dd">
       <zeroOrMore>
         <ref name="paragraph-with-footnote"/>
       </zeroOrMore>
     </element>
   </define>
+  <define name="dd-no-id">
+    <a:documentation>Definition in a definition list: optional ID attributes recursively (for use in Relaton, metadata)</a:documentation>
+    <element name="dd">
+      <zeroOrMore>
+        <ref name="paragraph-with-footnote-no-id"/>
+      </zeroOrMore>
+    </element>
+  </define>
 </grammar>
diff --git a/grammars/biblio-standoc.rng b/grammars/biblio-standoc.rng
index 2373865..6588af6 100644
--- a/grammars/biblio-standoc.rng
+++ b/grammars/biblio-standoc.rng
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<grammar xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns="http://relaxng.org/ns/structure/1.0">
   <!--
     Add-ons to biblio.rnc for standoc model: defines the extension point BibDataExtensionType
     of relaton
@@ -9,19 +9,23 @@
   -->
   <include href="biblio.rng">
     <define name="BibData">
+      <a:documentation>The bibliographic description of a standardisation document</a:documentation>
       <ref name="StandardBibliographicItem"/>
       <optional>
-        <ref name="ext"/>
+        <ref name="ext">
+          <a:documentation>The extension point of the bibliographic description of a standardisation document</a:documentation>
+        </ref>
       </optional>
     </define>
     <define name="docrelation">
+      <a:documentation>Update to StandardReducedBibliographicItem</a:documentation>
       <element name="relation">
         <attribute name="type">
           <ref name="DocRelationType"/>
         </attribute>
         <optional>
           <element name="description">
-            <ref name="FormattedString"/>
+            <ref name="LocalizedMarkedUpString"/>
           </element>
         </optional>
         <element name="bibitem">
@@ -47,34 +51,58 @@
     </define>
   </include>
   <define name="ext">
+    <a:documentation>The extension point of the bibliographic description of a standardisation document</a:documentation>
     <element name="ext">
       <ref name="BibDataExtensionType"/>
     </element>
   </define>
   <define name="BibDataExtensionType">
     <optional>
-      <attribute name="schema-version"/>
+      <attribute name="schema-version">
+        <a:documentation>The version of the flavour-specific schema that this extension point conforms to</a:documentation>
+      </attribute>
     </optional>
-    <ref name="doctype"/>
+    <ref name="doctype">
+      <a:documentation>Classification of the standardisation document that is treated as a distinct series by the
+standards defining organization, and that is rendered in a distinct manner</a:documentation>
+    </ref>
     <optional>
-      <ref name="docsubtype"/>
+      <ref name="docsubtype">
+        <a:documentation>Subclass of the standardisation document, that is treated or processed differently
+from other documents in the same doctype</a:documentation>
+      </ref>
     </optional>
+    <ref name="flavor">
+      <a:documentation>Flavour of Metanorma used to process this document</a:documentation>
+    </ref>
     <optional>
-      <ref name="editorialgroup"/>
+      <ref name="editorialgroup">
+        <a:documentation>Groups associated with the production of the standards document, typically within
+a standards definition organization</a:documentation>
+      </ref>
     </optional>
     <zeroOrMore>
-      <ref name="ics"/>
+      <ref name="ics">
+        <a:documentation>Classification of the document contents taken from the International Classification of Standards</a:documentation>
+      </ref>
     </zeroOrMore>
     <zeroOrMore>
-      <ref name="structuredidentifier"/>
+      <ref name="structuredidentifier">
+        <a:documentation>Representation of the identifier for the standardisation document, giving its individual semantic components</a:documentation>
+      </ref>
     </zeroOrMore>
   </define>
   <define name="doctype">
+    <a:documentation>Classification of the standardisation document</a:documentation>
     <element name="doctype">
       <optional>
-        <attribute name="abbreviation"/>
+        <attribute name="abbreviation">
+          <a:documentation>Standard abbreviation for the doctype value used by the standards defining organization</a:documentation>
+        </attribute>
       </optional>
-      <ref name="DocumentType"/>
+      <ref name="DocumentType">
+        <a:documentation>Name of the doctype</a:documentation>
+      </ref>
     </element>
   </define>
   <define name="DocumentType">
@@ -88,105 +116,153 @@
   <define name="DocumentSubtype">
     <text/>
   </define>
+  <define name="flavor">
+    <element name="flavor">
+      <ref name="MetanormaFlavor"/>
+    </element>
+  </define>
+  <define name="MetanormaFlavor">
+    <a:documentation>This is in fact an enum, as of this writing: standoc iso generic ietf ieee itu nist ogc csa cc iho ribose jis iec bsi bipm plateau.
+However we prefer not to hardcode it, given ongoing extension.</a:documentation>
+    <text/>
+  </define>
   <define name="editorialgroup">
+    <a:documentation>A group associated with the production of the standards document, typically within
+a standards definition organization</a:documentation>
     <element name="editorialgroup">
       <oneOrMore>
-        <ref name="technical-committee"/>
+        <ref name="technical-committee">
+          <a:documentation>A technical committee associated with the production of the standards document</a:documentation>
+        </ref>
       </oneOrMore>
     </element>
   </define>
   <define name="technical-committee">
+    <a:documentation>Technical committee associated with the production of a standards document</a:documentation>
     <element name="technical-committee">
       <ref name="IsoWorkgroup"/>
     </element>
   </define>
   <define name="IsoWorkgroup">
     <optional>
-      <attribute name="number"/>
+      <attribute name="number">
+        <a:documentation>Numeric identifier of the technical committee</a:documentation>
+      </attribute>
     </optional>
     <optional>
-      <attribute name="type"/>
+      <attribute name="type">
+        <a:documentation>Type of the technical committee, used in identifying the technical committee</a:documentation>
+      </attribute>
     </optional>
     <optional>
-      <attribute name="identifier"/>
+      <attribute name="identifier">
+        <a:documentation>Non-numeric, complete identifier of the technical committee</a:documentation>
+      </attribute>
     </optional>
     <optional>
-      <attribute name="prefix"/>
+      <attribute name="prefix">
+        <a:documentation>Disambiguating prefix added to number to form the identifier of the technical committee,
+typically indicating its type</a:documentation>
+      </attribute>
     </optional>
-    <text/>
+    <text>
+      <a:documentation>Name of the technical committee</a:documentation>
+    </text>
   </define>
   <define name="ics">
+    <a:documentation>Classification taken from the International Classification of Standards. 
+ICS is defined by ISO here -- https://www.iso.org/publication/PUB100033.html</a:documentation>
     <element name="ics">
       <element name="code">
+        <a:documentation>Classification code taken from the ICS</a:documentation>
         <text/>
       </element>
       <optional>
         <element name="text">
+          <a:documentation>Text string associated with the classification code</a:documentation>
           <text/>
         </element>
       </optional>
     </element>
   </define>
   <define name="structuredidentifier">
+    <a:documentation>Representation of the identifier for a standardisation document, giving its individual semantic components</a:documentation>
     <element name="structuredidentifier">
       <optional>
-        <attribute name="type"/>
+        <attribute name="type">
+          <a:documentation>Representation in the identifier of the type of standard document, corresponds to bibitem/ext/doctype</a:documentation>
+        </attribute>
       </optional>
       <oneOrMore>
         <element name="agency">
+          <a:documentation>Representation in the identifier of the agency responsible for the standard document</a:documentation>
           <text/>
         </element>
       </oneOrMore>
       <optional>
         <element name="class">
+          <a:documentation>Representation in the identifier of the class of standard document (as a subclass of the document type),
+corresponds to bibitem/item/docsubtype</a:documentation>
           <text/>
         </element>
       </optional>
       <element name="docnumber">
+        <a:documentation>Representation in the identifier of the (typically numeric) component uniquely identifying the document
+or standard. If a document includes parts or supplements, the docnumber identifies the document as whole,
+and not those document components</a:documentation>
         <text/>
       </element>
       <optional>
         <element name="partnumber">
+          <a:documentation>Representation in the identifier of the document part, if this is a document part. May be compound</a:documentation>
           <text/>
         </element>
       </optional>
       <optional>
         <element name="edition">
+          <a:documentation>Representation in the identifier of the document edition, if this is a published document</a:documentation>
           <text/>
         </element>
       </optional>
       <optional>
         <element name="version">
+          <a:documentation>Representation in the identifier of the document version, which can include document drafts</a:documentation>
           <text/>
         </element>
       </optional>
       <optional>
         <element name="supplementtype">
+          <a:documentation>Representation in the identifier of the type of document supplement, if this is a document supplement</a:documentation>
           <text/>
         </element>
       </optional>
       <optional>
         <element name="supplementnumber">
+          <a:documentation>Representation in the identifier of the document supplement, if this is a document supplement</a:documentation>
           <text/>
         </element>
       </optional>
       <optional>
         <element name="amendment">
+          <a:documentation>Representation in the identifier of the document amendment, if this is a document amendment</a:documentation>
           <text/>
         </element>
       </optional>
       <optional>
         <element name="corrigendum">
+          <a:documentation>Representation in the identifier of the document corrigendum, if this is a document corrigendum</a:documentation>
           <text/>
         </element>
       </optional>
       <optional>
         <element name="language">
+          <a:documentation>Representation in the identifier of the language of the document</a:documentation>
           <text/>
         </element>
       </optional>
       <optional>
         <element name="year">
+          <a:documentation>Representation in the identifier of the year of publication or issuance of the document</a:documentation>
           <text/>
         </element>
       </optional>
@@ -195,13 +271,17 @@
   <define name="StandardBibliographicItem">
     <ref name="BibliographicItem"/>
     <zeroOrMore>
-      <ref name="amend"/>
+      <ref name="amend">
+        <a:documentation>Description of changes specific to this document</a:documentation>
+      </ref>
     </zeroOrMore>
   </define>
   <define name="StandardReducedBibliographicItem">
     <ref name="ReducedBibliographicItem"/>
     <zeroOrMore>
-      <ref name="amend"/>
+      <ref name="amend">
+        <a:documentation>Description of changes specific to this document</a:documentation>
+      </ref>
     </zeroOrMore>
   </define>
 </grammar>
diff --git a/grammars/biblio.rng b/grammars/biblio.rng
index f18d67c..2b81353 100644
--- a/grammars/biblio.rng
+++ b/grammars/biblio.rng
@@ -24,44 +24,62 @@
     Somewhat dumbed down for XSD regex:
   -->
   <define name="ISO8601DateTime">
+    <a:documentation>Date/Time conforming with ISO 8601</a:documentation>
     <data type="string">
       <param name="pattern">([\+\-]?\d{4})((-?)((0[1-9]|1[0-2])((-?)([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([\.,]\d+)?)?((:?)[0-5]\d([.,]\d+)?)?([zZ]|([\+\-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?</param>
     </data>
   </define>
   <define name="ISO8601Date">
+    <a:documentation>Date conforming with ISO 8601</a:documentation>
     <data type="string">
       <param name="pattern">([\+\-]?\d{4})((-?)((0[1-9]|1[0-2])((-?)([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6]))))?</param>
     </data>
   </define>
-  <!-- start = bibitem -->
   <define name="BibData">
     <ref name="BibliographicItem"/>
   </define>
   <define name="status">
+    <a:documentation>The publication or preparation status of a document</a:documentation>
     <element name="status">
-      <ref name="stage"/>
+      <ref name="stage">
+        <a:documentation>The stage of the document status, e.g. "Published", "Unpublished", "Committee Draft", "Preprint"</a:documentation>
+      </ref>
       <optional>
-        <ref name="substage"/>
+        <ref name="substage">
+          <a:documentation>The substage of the document status. These are used particularly in Standards Defining Organizations</a:documentation>
+        </ref>
       </optional>
       <optional>
-        <ref name="iteration"/>
+        <ref name="iteration">
+          <a:documentation>The iteration of the given status that the document is currently in (e.g. "3" for a third draft)</a:documentation>
+        </ref>
       </optional>
     </element>
   </define>
   <define name="stage">
+    <a:documentation>The stage of the document status, e.g. "Published", "Unpublished", "Committee Draft", "Preprint"</a:documentation>
     <element name="stage">
       <optional>
-        <attribute name="abbreviation"/>
+        <attribute name="abbreviation">
+          <a:documentation>A canonical abbreviation of the document stage</a:documentation>
+        </attribute>
       </optional>
-      <text/>
+      <text>
+        <a:documentation>The name of the document stage</a:documentation>
+      </text>
     </element>
   </define>
   <define name="substage">
+    <a:documentation>The substage of the document status. These are used particularly in Standards Defining Organizations</a:documentation>
     <element name="substage">
       <optional>
-        <attribute name="abbreviation"/>
+        <attribute name="abbreviation">
+          <a:documentation>A canonical abbreviation of the document substage</a:documentation>
+        </attribute>
       </optional>
-      <text/>
+      <text>
+        <a:documentation>The name of the documen substage</a:documentation>
+      </text>
     </element>
   </define>
   <define name="iteration">
@@ -71,87 +89,84 @@
   </define>
   <define name="language">
     <element name="language">
-      <text/>
+      <ref name="LanguageType"/>
     </element>
   </define>
   <define name="locale">
-    <a:documentation>ISO-639</a:documentation>
     <element name="locale">
-      <text/>
+      <ref name="LocaleType"/>
     </element>
   </define>
   <define name="script">
-    <a:documentation>ISO-3166</a:documentation>
     <element name="script">
-      <text/>
+      <ref name="ScriptType"/>
     </element>
   </define>
   <define name="edition">
-    <a:documentation>ISO-15924: Latn</a:documentation>
+    <a:documentation>Edition of a bibliographic item</a:documentation>
     <element name="edition">
       <optional>
-        <attribute name="number"/>
+        <attribute name="number">
+          <a:documentation>Number of edition.
+NOTE: The number attribute can be used to represent the numeric equivalent of the edition string</a:documentation>
+        </attribute>
       </optional>
-      <text/>
+      <text>
+        <a:documentation>Formatted, human-readable edition string</a:documentation>
+      </text>
     </element>
   </define>
-  <define name="LocalizedString1">
+  <define name="LocalizedStringAttributes">
+    <a:documentation>multiple values are comma-delimited</a:documentation>
     <optional>
-      <!-- multiple languages and scripts possible: comma delimit them if so -->
-      <attribute name="language"/>
+      <attribute name="language">
+        <ref name="LanguageType"/>
+      </attribute>
     </optional>
     <optional>
-      <attribute name="locale"/>
+      <attribute name="locale">
+        <ref name="LocaleType"/>
+      </attribute>
     </optional>
     <optional>
-      <attribute name="script"/>
+      <attribute name="script">
+        <ref name="ScriptType"/>
+      </attribute>
     </optional>
-    <text/>
   </define>
   <define name="LocalizedString">
-    <choice>
-      <ref name="LocalizedString1"/>
-      <oneOrMore>
-        <element name="variant">
-          <ref name="LocalizedString1"/>
-        </element>
-      </oneOrMore>
-    </choice>
+    <ref name="LocalizedStringAttributes"/>
+    <text/>
   </define>
+  <!--
+    LocalizedString =
+     LocalizedStringAttributes,
+     text
+    
+    LocalizedString =
+     LocalizedString1 |
+     element variant { LocalizedString1 }+
+  -->
+  <define name="LocalizedMarkedUpString">
+    <ref name="LocalizedStringAttributes"/>
+    <oneOrMore>
+      <ref name="PureTextElement"/>
+    </oneOrMore>
+  </define>
+  <!--
+    LocalizedMarkedUpString =
+    LocalizedMarkedUpString1 |
+    Variants of the string, with the same content, but in different language, script, or format
+    element variant { LocalizedMarkedUpString1 }+
+  -->
   <!--
     Unlike UML, change type to format: type is overloaded
     Would be need if plain were default value and could omit the attribute
     Added LocalizedStringOrXsAny
   -->
-  <define name="FormattedString">
-    <optional>
-      <!-- attribute format { ( "plain" | "html" | "docbook" | "tei" | "asciidoc" | "markdown" ) }?, -->
-      <attribute name="format">
-        <choice>
-          <value>text/plain</value>
-          <value>text/html</value>
-          <value>application/docbook+xml</value>
-          <value>application/tei+xml</value>
-          <value>text/x-asciidoc</value>
-          <value>text/markdown</value>
-          <value>application/x-metanorma+xml</value>
-          <text/>
-        </choice>
-      </attribute>
-    </optional>
-    <ref name="LocalizedStringOrXsAny"/>
-  </define>
-  <define name="LocalizedStringOrXsAny1">
-    <optional>
-      <!-- multiple languages and scripts possible: comma delimit them if so -->
-      <attribute name="language"/>
-    </optional>
-    <optional>
-      <attribute name="locale"/>
-    </optional>
-    <optional>
-      <attribute name="script"/>
-    </optional>
+  <!-- LocalizedStringOrXsAny1 = -->
+  <define name="LocalizedStringOrXsAny">
+    <ref name="LocalizedStringAttributes"/>
     <oneOrMore>
       <choice>
         <text/>
@@ -159,27 +174,43 @@
       </choice>
     </oneOrMore>
   </define>
-  <define name="LocalizedStringOrXsAny">
-    <choice>
-      <ref name="LocalizedStringOrXsAny1"/>
-      <oneOrMore>
-        <element name="variant">
-          <ref name="LocalizedStringOrXsAny1"/>
-        </element>
-      </oneOrMore>
-    </choice>
-  </define>
+  <!--
+    LocalizedStringOrXsAny =
+     LocalizedStringOrXsAny1 |
+     element variant { LocalizedStringOrXsAny1 }+
+  -->
   <define name="contributor">
+    <a:documentation>String which is formatted according to conventions specified in a named MIME type </a:documentation>
+    <!-- FormattedString = -->
+    <a:documentation>MIME type for string (defailts to text/plain). 
+NOTE: `docbook`, `AsciiDoc`, `Metanorma` are not registered IANA Media Types</a:documentation>
+    <!--
+      attribute format { 
+      "text/plain" | "text/html" | "application/docbook+xml" |
+      "application/tei+xml" | "text/x-asciidoc" | "text/markdown" | "application/x-metanorma+xml" | text 
+      }?,
+    -->
+    <a:documentation>String</a:documentation>
+    <!-- LocalizedStringOrXsAny -->
+    <a:documentation>Description of a contributor to the production of the bibliographic item</a:documentation>
     <element name="contributor">
       <oneOrMore>
-        <ref name="role"/>
+        <ref name="role">
+          <a:documentation>A description of the role of the contributor in the production of the bibliographic item</a:documentation>
+        </ref>
       </oneOrMore>
-      <ref name="ContributorInfo"/>
+      <ref name="ContributorInfo">
+        <a:documentation>The contributor involved in the production of the bibliographic item.
+May be either a person or an organization</a:documentation>
+      </ref>
     </element>
   </define>
   <define name="role">
+    <a:documentation>A description of the role of the contributor in the production of a bibliographic item</a:documentation>
     <element name="role">
       <attribute name="type">
+        <a:documentation>The broad class of role of the contributor. Mandatory in order to enforce orderly management of contributors.
+Detailed in https://www.relaton.org/model/creator/</a:documentation>
         <choice>
           <value>author</value>
           <value>performer</value>
@@ -196,7 +227,9 @@
         </choice>
       </attribute>
       <zeroOrMore>
-        <ref name="roledescription"/>
+        <ref name="roledescription">
+          <a:documentation>A more detailed description of the role of the contributor</a:documentation>
+        </ref>
       </zeroOrMore>
     </element>
   </define>
@@ -208,29 +241,41 @@
   </define>
   <define name="roledescription">
     <element name="description">
-      <ref name="FormattedString"/>
+      <ref name="LocalizedMarkedUpString"/>
     </element>
   </define>
   <define name="person">
+    <a:documentation>Person associated with a bibliographic item</a:documentation>
     <element name="person">
       <optional>
-        <ref name="fullname"/>
+        <ref name="fullname">
+          <a:documentation>The name of the person</a:documentation>
+        </ref>
       </optional>
       <zeroOrMore>
-        <ref name="credential"/>
+        <ref name="credential">
+          <a:documentation>Credentials given for the person postnominally, e.g. "PhD"</a:documentation>
+        </ref>
       </zeroOrMore>
       <zeroOrMore>
-        <ref name="affiliation"/>
+        <ref name="affiliation">
+          <a:documentation>The affiliation of the person within an organization</a:documentation>
+        </ref>
       </zeroOrMore>
       <zeroOrMore>
-        <ref name="person-identifier"/>
-      </zeroOrMore>
-      <zeroOrMore>
-        <ref name="contact"/>
+        <ref name="person-identifier">
+          <a:documentation>An identifier of the person according to an international identifier scheme</a:documentation>
+        </ref>
       </zeroOrMore>
+      <optional>
+        <ref name="contact">
+          <a:documentation>Contact information for the person, including URI, address, phone number, and email</a:documentation>
+        </ref>
+      </optional>
     </element>
   </define>
   <define name="fullname">
+    <a:documentation>The name of a person</a:documentation>
     <element name="name">
       <ref name="FullNameType"/>
     </element>
@@ -242,31 +287,56 @@
   </define>
   <define name="FullNameType">
     <optional>
-      <ref name="name_abbreviation"/>
+      <ref name="name_abbreviation">
+        <a:documentation>The initials of the person, used as an abbreviation for the person, and including the
+surname. Can be used instead of the complete name. Distinct from formatted-initials,
+which are the initials only of the forenames of the person</a:documentation>
+      </ref>
     </optional>
-    <choice>
-      <group>
-        <zeroOrMore>
-          <ref name="prefix"/>
-        </zeroOrMore>
-        <zeroOrMore>
-          <ref name="forename"/>
-        </zeroOrMore>
-        <optional>
-          <ref name="formatted-initials"/>
-        </optional>
-        <ref name="surname"/>
-        <zeroOrMore>
-          <ref name="addition"/>
-        </zeroOrMore>
-      </group>
-      <ref name="completeName"/>
-    </choice>
+    <group>
+      <zeroOrMore>
+        <ref name="prefix">
+          <a:documentation>A prefixed addition to the name of the person, such as "Dr"</a:documentation>
+        </ref>
+      </zeroOrMore>
+      <zeroOrMore>
+        <ref name="forename">
+          <a:documentation>A forename or given name of the person. Includes middle names</a:documentation>
+        </ref>
+      </zeroOrMore>
+      <optional>
+        <ref name="formatted-initials">
+          <a:documentation>The initials of the person, as a formatted string, including punctuation, dropping
+punctuation as desired, and including hyphens where necessary. For example,
+the initial set for Jean-Paul would be J, P; the formatted initials would be "J.-P."
+or "J-P.". Can be used instead of forenames</a:documentation>
+        </ref>
+      </optional>
+      <optional>
+        <ref name="surname">
+          <a:documentation>The surname, family name, or equivalent of the person</a:documentation>
+        </ref>
+      </optional>
+      <zeroOrMore>
+        <ref name="addition">
+          <a:documentation>A suffixed addition to the name of the person, such as "Jr"</a:documentation>
+        </ref>
+      </zeroOrMore>
+      <optional>
+        <ref name="completeName">
+          <a:documentation>A preformatted version of the name of the person, not broken down into its component parts</a:documentation>
+        </ref>
+      </optional>
+    </group>
     <zeroOrMore>
-      <ref name="biblionote"/>
+      <ref name="biblionote">
+        <a:documentation>An additional note about the name of the person</a:documentation>
+      </ref>
     </zeroOrMore>
     <zeroOrMore>
-      <ref name="variantname"/>
+      <ref name="variantname">
+        <a:documentation>A variant name of the person</a:documentation>
+      </ref>
     </zeroOrMore>
   </define>
   <define name="name_abbreviation">
@@ -295,11 +365,19 @@
     </element>
   </define>
   <define name="forename">
+    <a:documentation>A forename of a person</a:documentation>
     <element name="forename">
       <optional>
-        <attribute name="initial"/>
+        <attribute name="initial">
+          <a:documentation>An individual initial of the person, corresponding to the given forename.
+Does not include final punctuation, but can include hyphens.
+Can be used instead of forenames, if formatted-initials are not provided 
+(in which case each initial will be punctuated following local practice).</a:documentation>
+        </attribute>
       </optional>
-      <ref name="LocalizedString"/>
+      <ref name="LocalizedString">
+        <a:documentation>A forename or given name of the person. Includes middle names</a:documentation>
+      </ref>
     </element>
   </define>
   <define name="completeName">
@@ -308,21 +386,34 @@
     </element>
   </define>
   <define name="variantname">
+    <a:documentation>A variant name of a person</a:documentation>
     <element name="variant">
-      <attribute name="type"/>
-      <ref name="FullNameType"/>
+      <attribute name="type">
+        <a:documentation>The type of variant name for the person. Examples include pseudonyms; user names (online);
+real names (if the person is named with a pseudonym or user name); previous legal names</a:documentation>
+      </attribute>
+      <ref name="FullNameType">
+        <a:documentation>The variant name itself</a:documentation>
+      </ref>
     </element>
   </define>
   <define name="affiliation">
+    <a:documentation>The affiliation of a person with an organization</a:documentation>
     <element name="affiliation">
       <optional>
-        <ref name="affiliationname"/>
+        <ref name="affiliationname">
+          <a:documentation>The name of the affiliation of the person with the organization; typically a position title</a:documentation>
+        </ref>
       </optional>
       <zeroOrMore>
-        <ref name="affiliationdescription"/>
+        <ref name="affiliationdescription">
+          <a:documentation>A more detailed description of the affiliation of the person</a:documentation>
+        </ref>
       </zeroOrMore>
       <optional>
-        <ref name="organization"/>
+        <ref name="organization">
+          <a:documentation>The organization with which the person is affiliated</a:documentation>
+        </ref>
       </optional>
     </element>
   </define>
@@ -333,140 +424,188 @@
   </define>
   <define name="affiliationdescription">
     <element name="description">
-      <ref name="FormattedString"/>
+      <ref name="LocalizedMarkedUpString"/>
     </element>
   </define>
   <define name="organization">
+    <a:documentation>Organization associated with a bibliographic item</a:documentation>
     <element name="organization">
-      <oneOrMore>
-        <ref name="orgname"/>
-      </oneOrMore>
-      <zeroOrMore>
-        <ref name="subdivision"/>
-      </zeroOrMore>
-      <optional>
-        <ref name="abbreviation"/>
-      </optional>
-      <zeroOrMore>
-        <ref name="uri"/>
-      </zeroOrMore>
-      <zeroOrMore>
-        <ref name="org-identifier"/>
-      </zeroOrMore>
-      <zeroOrMore>
-        <ref name="contact"/>
-      </zeroOrMore>
-      <optional>
-        <ref name="logo"/>
-      </optional>
+      <ref name="OrganizationType"/>
     </element>
   </define>
+  <define name="OrganizationType">
+    <oneOrMore>
+      <ref name="orgname">
+        <a:documentation>The name of the organization</a:documentation>
+      </ref>
+    </oneOrMore>
+    <zeroOrMore>
+      <ref name="subdivision">
+        <a:documentation>The subdivision of the organization directly involved with the production of the bibliographic item</a:documentation>
+      </ref>
+    </zeroOrMore>
+    <optional>
+      <ref name="abbreviation">
+        <a:documentation>Abbreviation under which the organization is known</a:documentation>
+      </ref>
+    </optional>
+    <zeroOrMore>
+      <ref name="org-identifier">
+        <a:documentation>An identifier of the organization according to an international identifier scheme</a:documentation>
+      </ref>
+    </zeroOrMore>
+    <optional>
+      <ref name="contact">
+        <a:documentation>Contact information for the organization, including address, phone number, and email</a:documentation>
+      </ref>
+    </optional>
+    <optional>
+      <ref name="logo">
+        <a:documentation>A logo for the organization</a:documentation>
+      </ref>
+    </optional>
+  </define>
   <define name="orgname">
     <element name="name">
-      <choice>
-        <ref name="LocalizedString"/>
-        <ref name="NameWithVariants"/>
-      </choice>
+      <optional>
+        <attribute name="type">
+          <a:documentation>Type of organisation name, to differentiate variant names</a:documentation>
+        </attribute>
+      </optional>
+      <ref name="LocalizedString"/>
     </element>
   </define>
   <define name="subdivision">
+    <a:documentation>Subdivision of organization associated with a bibliographic item</a:documentation>
     <element name="subdivision">
-      <choice>
-        <ref name="LocalizedString"/>
-        <ref name="NameWithVariants"/>
-      </choice>
+      <optional>
+        <attribute name="type">
+          <a:documentation>The type of subdivision</a:documentation>
+        </attribute>
+      </optional>
+      <ref name="OrganizationType">
+        <a:documentation>The subdivision, modelled recursively as an organization</a:documentation>
+      </ref>
     </element>
   </define>
   <define name="logo">
     <element name="logo">
-      <ref name="image"/>
+      <ref name="image-no-id"/>
     </element>
   </define>
   <define name="depiction">
+    <a:documentation>Depiction of the bibliographic item</a:documentation>
     <element name="depiction">
       <optional>
-        <attribute name="scope"/>
+        <attribute name="scope">
+          <a:documentation>Description of what is being depicted</a:documentation>
+        </attribute>
       </optional>
       <zeroOrMore>
-        <ref name="image"/>
+        <ref name="image-no-id">
+          <a:documentation>A visual depiction of the bibliographic item</a:documentation>
+        </ref>
       </zeroOrMore>
     </element>
   </define>
-  <define name="NameWithVariants">
-    <element name="primary">
-      <ref name="LocalizedString"/>
-    </element>
-    <zeroOrMore>
-      <element name="variant">
-        <ref name="NameWithVariants1"/>
-      </element>
-    </zeroOrMore>
-  </define>
-  <define name="NameWithVariants1">
-    <attribute name="type"/>
-    <element name="primary">
-      <ref name="LocalizedString"/>
-    </element>
-    <zeroOrMore>
-      <element name="variant">
-        <ref name="NameWithVariants1"/>
-      </element>
-    </zeroOrMore>
-  </define>
+  <!--
+    NameWithVariants =
+    element primary { LocalizedString },
+    element variant { NameWithVariants1 }*
+    
+    NameWithVariants1 =
+    attribute type { text },
+    element primary { LocalizedString },
+    element variant { NameWithVariants1 }*
+  -->
   <define name="abbreviation">
     <element name="abbreviation">
       <ref name="LocalizedString"/>
     </element>
   </define>
   <define name="uri">
+    <a:documentation>URI associated with a type</a:documentation>
     <element name="uri">
       <optional>
-        <attribute name="type"/>
+        <attribute name="type">
+          <a:documentation>The types of URI are open-ended, but include the IANA link relations specified in RFC 8288</a:documentation>
+        </attribute>
       </optional>
-      <data type="anyURI"/>
+      <ref name="LocalizedStringAttributes"/>
+      <data type="anyURI">
+        <a:documentation>URI content</a:documentation>
+      </data>
     </element>
   </define>
   <!-- TODO may change -->
   <define name="contact">
-    <choice>
+    <a:documentation>Contact information for a person or organization</a:documentation>
+    <zeroOrMore>
       <ref name="address"/>
+    </zeroOrMore>
+    <zeroOrMore>
       <ref name="phone"/>
+    </zeroOrMore>
+    <zeroOrMore>
       <ref name="email"/>
+    </zeroOrMore>
+    <zeroOrMore>
       <ref name="uri"/>
-    </choice>
+    </zeroOrMore>
   </define>
   <define name="phone">
+    <a:documentation>The phone number associated with a person or organization</a:documentation>
     <element name="phone">
       <optional>
-        <attribute name="type"/>
+        <attribute name="type">
+          <a:documentation>The type of phone number; can include "Fax" and "Mobile"</a:documentation>
+        </attribute>
       </optional>
-      <text/>
+      <text>
+        <a:documentation>The phone number itself</a:documentation>
+      </text>
     </element>
   </define>
   <define name="email">
+    <a:documentation>Email address</a:documentation>
     <element name="email">
       <text/>
     </element>
   </define>
   <define name="address">
+    <a:documentation>An address for a person or organization</a:documentation>
     <element name="address">
-      <choice>
+      <zeroOrMore>
         <!-- iso191606 TODO -->
-        <group>
-          <zeroOrMore>
-            <ref name="street"/>
-          </zeroOrMore>
-          <ref name="city"/>
-          <optional>
-            <ref name="state"/>
-          </optional>
-          <ref name="country"/>
-          <optional>
-            <ref name="postcode"/>
-          </optional>
-        </group>
-        <ref name="formattedAddress"/>
-      </choice>
+        <ref name="street">
+          <a:documentation>The street and street number or equivalent in the address, as one or more lines of text</a:documentation>
+        </ref>
+      </zeroOrMore>
+      <optional>
+        <ref name="city">
+          <a:documentation>The settlement or municipality in the address</a:documentation>
+        </ref>
+      </optional>
+      <optional>
+        <ref name="state">
+          <a:documentation>The region of the country in the address</a:documentation>
+        </ref>
+      </optional>
+      <optional>
+        <ref name="country">
+          <a:documentation>The country in the address</a:documentation>
+        </ref>
+      </optional>
+      <optional>
+        <ref name="postcode">
+          <a:documentation>The postal code or equivalent in the address</a:documentation>
+        </ref>
+      </optional>
+      <optional>
+        <ref name="formattedAddress">
+          <a:documentation>Preformatted version of the address, not decomposed into its component parts</a:documentation>
+        </ref>
+      </optional>
     </element>
   </define>
   <define name="street">
@@ -496,48 +635,77 @@
   </define>
   <define name="formattedAddress">
     <element name="formattedAddress">
-      <text/>
+      <oneOrMore>
+        <choice>
+          <text/>
+          <ref name="br"/>
+        </choice>
+      </oneOrMore>
     </element>
   </define>
   <define name="person-identifier">
+    <a:documentation>An identifier of a person according to an international identifier scheme</a:documentation>
     <element name="identifier">
       <attribute name="type">
-        <choice>
-          <value>isni</value>
-          <value>orcid</value>
-          <value>uri</value>
-        </choice>
+        <a:documentation>The international identifier scheme for the identifier of the person.
+Examples include "isni", "orcid", "uri"</a:documentation>
       </attribute>
-      <text/>
+      <text>
+        <a:documentation>The identifier value</a:documentation>
+      </text>
     </element>
   </define>
   <define name="org-identifier">
+    <a:documentation>An identifier of an organization according to an international identifier scheme</a:documentation>
     <element name="identifier">
-      <attribute name="type">
-        <data type="string" datatypeLibrary=""/>
-      </attribute>
-      <text/>
+      <optional>
+        <attribute name="type">
+          <a:documentation>The international identifier scheme for the identifier of the organization.
+Examples include GRID, LEI, CrossRef, and Ringgold</a:documentation>
+        </attribute>
+      </optional>
+      <text>
+        <a:documentation>The identifier value</a:documentation>
+      </text>
     </element>
   </define>
   <define name="citation">
+    <a:documentation>Representation of a citation of a bibliographic item, typically within a document</a:documentation>
     <element name="citation">
       <ref name="CitationType"/>
     </element>
   </define>
   <define name="CitationType">
     <attribute name="bibitemid">
+      <a:documentation>Bibliographic item that the citation applies to, referenced as the anchor of a bibliographic description</a:documentation>
       <data type="IDREF"/>
     </attribute>
     <choice>
       <zeroOrMore>
-        <ref name="locality"/>
+        <ref name="locality">
+          <a:documentation>Describes the location of the cited information resource within the subject of the bibliographic item.
+Multiple ``bibLocality``s are interpreted as discontinuous references.</a:documentation>
+        </ref>
       </zeroOrMore>
       <zeroOrMore>
-        <ref name="localityStack"/>
+        <ref name="localityStack">
+          <a:documentation>Describes the location of the cited information resource within the subject of the bibliographic item in a multi-level manner.
+For example, the hierarchical specification "Part IV, Chapter 3, Paragraphs 22-24" 
+is represented as a single `bibLocalityStack`, composed of those three localities
+(as opposed to three `bibLocality` references, which would be treated as three discontinuous references).
+Multiple ``bibLocalityStack``s are themselves interpreted as discontinuous references</a:documentation>
+        </ref>
       </zeroOrMore>
     </choice>
     <optional>
-      <ref name="date"/>
+      <ref name="date">
+        <a:documentation>Date of the citation, typically date of publication. 
+A combination of the date time elements year, month and day should be specified.
+Specification of month and day are optional. 
+This date is not intended for disambiguation, since `bibitemid`
+already identifies the source unambiguously; it is added for ease of processing, in case author-date
+citations cannot straightforwardly extract the date from the bibliographic source</a:documentation>
+      </ref>
     </optional>
   </define>
   <define name="date">
@@ -546,14 +714,20 @@
     </element>
   </define>
   <define name="locality">
+    <a:documentation>The extent or location of a bibliographic item being referred to.
+A sequence of locality elements is meant to indicate hierarchical ordering, from greater to smaller.
+e.g. Chapter, then page, then paragraph.
+A discontinuous range can be represented by using two adjacent localities with the same type</a:documentation>
     <element name="locality">
       <ref name="BibItemLocality"/>
     </element>
   </define>
   <define name="localityStack">
+    <a:documentation>Hierarchical arrangement of bibliographic localities, to refer to a single span of text in a bibliographic item</a:documentation>
     <element name="localityStack">
       <optional>
         <attribute name="connective">
+          <a:documentation>Logical connective linking localities. If not supplied, "and" is understood</a:documentation>
           <choice>
             <value>and</value>
             <value>or</value>
@@ -564,16 +738,23 @@
         </attribute>
       </optional>
       <zeroOrMore>
-        <ref name="locality"/>
+        <ref name="locality">
+          <a:documentation>Component bibliographic localities which group together to designate a single span of text.
+Earlier localities are assumed to include later localities, and be of different types;
+e.g. "Chapter 7, paragraph 9–11"</a:documentation>
+        </ref>
       </zeroOrMore>
     </element>
   </define>
   <define name="sourceLocality">
+    <a:documentation>The extent or location of a source bibliographic item being related to a target bibliographic item</a:documentation>
     <element name="sourceLocality">
       <ref name="BibItemLocality"/>
     </element>
   </define>
   <define name="sourceLocalityStack">
+    <a:documentation>Hierarchical arrangement of bibliographic localities, to refer to a single span of text in a source bibliographic item,
+being related to a target bibliographic item</a:documentation>
     <element name="sourceLocalityStack">
       <optional>
         <attribute name="connective">
@@ -593,16 +774,30 @@
   </define>
   <define name="BibItemLocality">
     <attribute name="type">
+      <a:documentation>The type of extent of a locality (e.g. section, clause, page)</a:documentation>
       <ref name="LocalityType"/>
     </attribute>
     <optional>
-      <ref name="referenceFrom"/>
+      <ref name="referenceFrom">
+        <a:documentation>The starting value of the extent, or point location</a:documentation>
+      </ref>
     </optional>
     <optional>
-      <ref name="referenceTo"/>
+      <ref name="referenceTo">
+        <a:documentation>The end value of the extent as a range, if applicable</a:documentation>
+      </ref>
     </optional>
   </define>
   <define name="LocalityType">
+    <a:documentation>Type of indicator of a location or extent within a bibliographic item.
+When the value `whole` or `title` is used, the corresponding `BibItemLocality`
+attribute `identifier` should be empty
+`whole` refers to the entire document.
+`list` is used for ordered lists in standards documents
+`time` is used for timestamps in audio and visual media
+`anchor` is used for locations within web pages
+`line` is a line number, dependent on printed form of document
+`locality:...` is an extension point: it allows a free-form text string that is human-readable</a:documentation>
     <data type="string">
       <param name="pattern">section|clause|part|paragraph|chapter|page|title|line|whole|table|annex|figure|note|list|example|volume|issue|time|anchor|locality:[a-zA-Z0-9_]+</param>
     </data>
@@ -619,6 +814,7 @@
   </define>
   <!-- unlike UML, has id attribute; that results from including bibitem in a docmodel -->
   <define name="bibitem">
+    <a:documentation>Description of a bibliographic item</a:documentation>
     <element name="bibitem">
       <attribute name="id">
         <data type="ID"/>
@@ -627,162 +823,312 @@
     </element>
   </define>
   <define name="bibitem_no_id">
+    <a:documentation>Description of a bibliographic item: no ID attribute (for use in Relaton, metadata)</a:documentation>
     <element name="bibitem">
       <ref name="BibliographicItem"/>
     </element>
   </define>
   <define name="relaton_collection">
+    <a:documentation>Used to present a group of bibliographic items as a single group;
+e.g. when summarising the collection of standards created by a standards body.
+A collection may be used for bibliographic exchange but is typically not necesary for citation purposes</a:documentation>
     <element name="relaton-collection">
       <optional>
-        <attribute name="type"/>
+        <attribute name="type">
+          <a:documentation>The type of grouping of bibliographic items</a:documentation>
+        </attribute>
       </optional>
-      <ref name="btitle"/>
+      <ref name="btitle">
+        <a:documentation>The title given to the grouping of bibliographic items</a:documentation>
+      </ref>
       <zeroOrMore>
-        <ref name="contributor"/>
+        <ref name="contributor">
+          <a:documentation>Contributors to the production of the bibliographic items as a grouping,
+with corporate responsibility for all the items in the group 
+(e.g. as compilers of a collection or corporate authors)</a:documentation>
+        </ref>
       </zeroOrMore>
       <zeroOrMore>
-        <ref name="docrelation"/>
+        <ref name="docrelation">
+          <a:documentation>The individual items which constitute the group, expressed as relations to the
+document group. The `type` attribute of each relation is expected to be either `includes` or `hasPart`, 
+depending on whether the items exist as independent documents, or are parts of a multi-part document</a:documentation>
+        </ref>
       </zeroOrMore>
     </element>
   </define>
   <define name="BibItemType" combine="choice">
+    <a:documentation>Type of bibliographic item.
+The value list complies with the types provided in ISO 690:2021.
+NOTE: These values represent a strict superset to BibTeX
+publication types, and therefore any BibTeX type value can be
+mapped to these values. Some values here do not have a corresponding
+entry in BibTeX, for instance, "standard" and "website".</a:documentation>
     <choice>
       <value>article</value>
+      <a:documentation>An article from a journal or magazine</a:documentation>
       <value>book</value>
+      <a:documentation>A monograph</a:documentation>
       <value>booklet</value>
+      <a:documentation>A booklet or pamphlet. The distinction between book and booklet is not made frequently</a:documentation>
       <value>manual</value>
+      <a:documentation>A manual</a:documentation>
       <value>proceedings</value>
+      <a:documentation>A conference proceedings</a:documentation>
       <value>presentation</value>
+      <a:documentation>A presentation given in a formal meeting</a:documentation>
       <value>thesis</value>
+      <a:documentation>A dissertation given in an academic institution, as a summation of research</a:documentation>
       <value>techreport</value>
+      <a:documentation>A technical report</a:documentation>
       <value>standard</value>
+      <a:documentation>A standard, a document issued by a Standards Defining Organization</a:documentation>
       <value>unpublished</value>
+      <a:documentation>An intellectual creation which has not been published, e.g. a manuscript.
+NOTE: Properly this does not represent a distinct bibliographic type, and it
+should be avoided in favour of using the `status` element of `BibliographicItem`</a:documentation>
       <value>map</value>
+      <a:documentation>A map or other cartographic resource</a:documentation>
       <value>electronic resource</value>
+      <a:documentation>A resource avaiulable in digital form
+NOTE: The overloaded type `electronicResource` should be avoided where possible, particularly if the
+resource corresponds closely to a paper bibliographic type, such as `book` or `article`.
+The distinction between offline and online resources should be made through `medium` (electronic vs physical).
+Specialisations of `electronicResource` include `dataset`, `webResource`, `website`,
+`socialMedia`, and `software`.</a:documentation>
       <value>audiovisual</value>
+      <a:documentation>An audiovisual resource. Is a superclass of other types such as `video` and `music`</a:documentation>
       <value>film</value>
+      <a:documentation>A film</a:documentation>
       <value>video</value>
+      <a:documentation>A video</a:documentation>
       <value>broadcast</value>
+      <a:documentation>A broadcast made through mass media, including radio and television</a:documentation>
       <value>software</value>
+      <a:documentation>Computer executable code, not itself human-readable text (though it may generate such text)</a:documentation>
       <value>graphic_work</value>
+      <a:documentation>A graphic work, a work with two-dimensional or three-dimensional content</a:documentation>
       <value>music</value>
+      <a:documentation>A musical work. Includes both notated music and music performances:
+The two are differentiated through `BibliographicItem/medium/content` as "notated music" vs "performed music"</a:documentation>
       <value>patent</value>
+      <a:documentation>A patent</a:documentation>
       <value>inbook</value>
+      <a:documentation>A (typically untitled) part of a book. May be a chapter (or section, etc.) and/or a range of pages</a:documentation>
       <value>incollection</value>
+      <a:documentation>A part of a book having its own title, and typically having distinct authorship</a:documentation>
       <value>inproceedings</value>
+      <a:documentation>An article in a conference proceedings</a:documentation>
       <value>journal</value>
+      <a:documentation>A journal or periodical publication</a:documentation>
       <value>website</value>
+      <a:documentation>A collection of web resources, presented under the same URL domain and under the same (individual or corporate) authorship</a:documentation>
       <value>webresource</value>
+      <a:documentation>A human-readable or consumable web resource, a single item accessible online via a web browser,
+which is not composed of components all of which can be accessed in the same way.
+Includes media files, as well as individual web pages</a:documentation>
       <value>dataset</value>
+      <a:documentation>An electronic dataset, a collection of data that is not meant to be human-readable, and which is typically only machine readable</a:documentation>
       <value>archival</value>
+      <a:documentation>A instance of a resource curated and preserved in an archive, which mediates any access to it. 
+Typically it is physical, unique, and unpublished.
+ NOTE: The content of the resource may be published separately,
+ but that makes it a distinct bibliographic item, as access to it is no longer mediated through the archive</a:documentation>
       <value>social_media</value>
+      <a:documentation>One or more resources within a collection that is typically collectively authored by member users.
+Includes blog posts, forum posts, social media posts, tweets. Is usually a `webResource`,
+but not always (e.g. blogs on WeChat are only accessible within the WeChat app.)</a:documentation>
       <value>alert</value>
+      <a:documentation>A single communication intended for multiple persons, and publicly accessible. 
+May be electronic (e.g. Facebook status update) or voice (e.g. evacuation alert), but is typically not print</a:documentation>
       <value>message</value>
+      <a:documentation>A single communication intended for a restricted number of authorised persons (typically one).
+May be electronic (e.g. Twitter direct message, email) or voice (e.g. a remark made to someone,
+typically cited as "personal communication")</a:documentation>
       <value>conversation</value>
+      <a:documentation>An exchange of messages between two or more persons. May be electronic (e.g. web chat) or voice (e.g. phone call)</a:documentation>
+      <value>collection</value>
+      <a:documentation>A compound resource consisting of other resources, which are themselves presupposed to have their type specified..</a:documentation>
       <value>misc</value>
+      <a:documentation>Bibliographic type not adequately described in the foregoing</a:documentation>
     </choice>
   </define>
   <define name="BibliographicItem">
+    <a:documentation>Description of a bibliographic resource</a:documentation>
     <optional>
       <attribute name="type">
+        <a:documentation>The type of the bibliographic item</a:documentation>
         <ref name="BibItemType"/>
       </attribute>
     </optional>
     <optional>
-      <attribute name="schema-version"/>
+      <attribute name="schema-version">
+        <a:documentation>The version of the Relaton schema that this description conforms to</a:documentation>
+      </attribute>
     </optional>
     <optional>
-      <ref name="fetched"/>
+      <ref name="fetched">
+        <a:documentation>The date at which the bibliographic item was last updated</a:documentation>
+      </ref>
     </optional>
     <optional>
-      <ref name="formattedref"/>
+      <ref name="formattedref">
+        <a:documentation>A pre-formatted version of the full bibliographic item reference,
+rendered for human reading, and used to sidestep the rendering of the reference out of its component parts</a:documentation>
+      </ref>
     </optional>
     <oneOrMore>
-      <ref name="btitle"/>
+      <ref name="btitle">
+        <a:documentation>The title(s) of the bibliographic item</a:documentation>
+      </ref>
     </oneOrMore>
     <zeroOrMore>
-      <ref name="bsource"/>
+      <ref name="bsource">
+        <a:documentation>The URI(s) associated with the bibliographic item</a:documentation>
+      </ref>
     </zeroOrMore>
     <oneOrMore>
-      <ref name="docidentifier"/>
+      <ref name="docidentifier">
+        <a:documentation>The identifier(s) of the bibliographic item in an international standard scheme</a:documentation>
+      </ref>
     </oneOrMore>
     <optional>
-      <ref name="docnumber"/>
+      <ref name="docnumber">
+        <a:documentation>Unprefixed, preferably numeric version of an identifier of the bibliographic item, intended for sorting of bibliography</a:documentation>
+      </ref>
     </optional>
     <zeroOrMore>
-      <ref name="bdate"/>
+      <ref name="bdate">
+        <a:documentation>One or more date-times associated with the production of or access to the bibliographic item</a:documentation>
+      </ref>
     </zeroOrMore>
     <zeroOrMore>
-      <ref name="contributor"/>
+      <ref name="contributor">
+        <a:documentation>Contributors to the production of the bibliographic item</a:documentation>
+      </ref>
     </zeroOrMore>
     <optional>
-      <ref name="edition"/>
+      <ref name="edition">
+        <a:documentation>The edition of the bibliographic item</a:documentation>
+      </ref>
     </optional>
     <zeroOrMore>
-      <ref name="version"/>
+      <ref name="version">
+        <a:documentation>The version of the bibliographic item (within an edition). Can be used for drafts. 
+Can be more than one, in case of multiple versioning schemes</a:documentation>
+      </ref>
     </zeroOrMore>
     <zeroOrMore>
-      <ref name="biblionote"/>
+      <ref name="biblionote">
+        <a:documentation>Note(s) associated with the bibliographic item</a:documentation>
+      </ref>
     </zeroOrMore>
     <zeroOrMore>
-      <ref name="language"/>
+      <ref name="language">
+        <a:documentation>The language(s) in which the bibliographic item is expressed</a:documentation>
+      </ref>
     </zeroOrMore>
     <zeroOrMore>
-      <ref name="locale"/>
+      <ref name="locale">
+        <a:documentation>The locale(s) in which the bibliographic item is expressed</a:documentation>
+      </ref>
     </zeroOrMore>
     <zeroOrMore>
-      <ref name="script"/>
+      <ref name="script">
+        <a:documentation>The script(s) in which the bibliographic item is written</a:documentation>
+      </ref>
     </zeroOrMore>
     <zeroOrMore>
-      <ref name="bibabstract"/>
+      <ref name="bibabstract">
+        <a:documentation>The abstract of the bibliographic item</a:documentation>
+      </ref>
     </zeroOrMore>
     <optional>
-      <ref name="status"/>
+      <ref name="status">
+        <a:documentation>The publication or preparation status of the bibliographic item</a:documentation>
+      </ref>
     </optional>
     <zeroOrMore>
-      <ref name="copyright"/>
+      <ref name="copyright">
+        <a:documentation>The copyright status of the bibliographic item</a:documentation>
+      </ref>
     </zeroOrMore>
     <zeroOrMore>
-      <ref name="docrelation"/>
+      <ref name="docrelation">
+        <a:documentation>The relation(s) of the bibliographic item to other bibliographic items</a:documentation>
+      </ref>
     </zeroOrMore>
     <zeroOrMore>
-      <ref name="series"/>
+      <ref name="series">
+        <a:documentation>The series of the bibliographic item</a:documentation>
+      </ref>
     </zeroOrMore>
     <optional>
-      <ref name="medium"/>
+      <ref name="medium">
+        <a:documentation>The medium the subject is realized on.
+Medium can be used to differentiate between "electronic" and "physical" manifestations of an information resource.</a:documentation>
+      </ref>
     </optional>
     <zeroOrMore>
-      <ref name="bplace"/>
+      <ref name="bplace">
+        <a:documentation>The geographic location associated with the production of the bibliographic item</a:documentation>
+      </ref>
     </zeroOrMore>
     <zeroOrMore>
-      <ref name="bprice"/>
+      <ref name="bprice">
+        <a:documentation>The price set on accessing the bibliographic item.
+The price should be treated as nominal, rather than capturing all possible pricings at a given time</a:documentation>
+      </ref>
     </zeroOrMore>
     <zeroOrMore>
-      <ref name="extent"/>
+      <ref name="extent">
+        <a:documentation>The extent of the bibliographic item, if reference is not being made to the entirety of the item described.
+Repeats for different levels of granularity (e.g. volume number, page number), or for discontinuous ranges
+(e.g. multiple page ranges, pages plus plates)</a:documentation>
+      </ref>
     </zeroOrMore>
     <optional>
-      <ref name="bibliographic_size"/>
+      <ref name="bibliographic_size">
+        <a:documentation>The bibliographic size of the bibliographic item, measured in the same units as extent (i.e. pages, volumes,
+megabytes, hours, rather than cm^2.) Distinct from the physical size of the bibliographic item, captured in medium/size</a:documentation>
+      </ref>
     </optional>
     <zeroOrMore>
-      <ref name="accesslocation"/>
+      <ref name="accesslocation">
+        <a:documentation>The location where the bibliographic item may be accessed.
+Used for archival resources. Also used for pathways to access digital resources, where a URI is not practical</a:documentation>
+      </ref>
     </zeroOrMore>
     <zeroOrMore>
-      <ref name="license"/>
+      <ref name="license">
+        <a:documentation>A license under which the bibliographic item has been issued.
+NOTE: This should preferably be encoded as  a URI or short identifier, rather than descriptive text</a:documentation>
+      </ref>
     </zeroOrMore>
     <zeroOrMore>
-      <ref name="bclassification"/>
+      <ref name="bclassification">
+        <a:documentation>The classification of the bibliographic item according to a standard classification scheme</a:documentation>
+      </ref>
     </zeroOrMore>
     <zeroOrMore>
-      <ref name="bkeyword"/>
+      <ref name="bkeyword">
+        <a:documentation>Keyword(s) for the bibliographic item</a:documentation>
+      </ref>
     </zeroOrMore>
     <optional>
-      <ref name="validity"/>
+      <ref name="validity">
+        <a:documentation>Information about how long the current description of the bibliographic item is valid for</a:documentation>
+      </ref>
     </optional>
     <optional>
-      <ref name="depiction"/>
+      <ref name="depiction">
+        <a:documentation>Depiction of the bibliographic item, typically an image</a:documentation>
+      </ref>
     </optional>
   </define>
   <define name="ReducedBibliographicItem">
+    <a:documentation>Reduced description of a bibliographic resource, without mandatory title and docidentifier, used for document relations
+Refer to `BibliographicItem` for definitions</a:documentation>
     <optional>
       <attribute name="type">
         <ref name="BibItemType"/>
@@ -883,6 +1229,7 @@
     </optional>
   </define>
   <define name="btitle">
+    <a:documentation>A title of a bibliographic item, associated with a type of title</a:documentation>
     <element name="title">
       <ref name="TypedTitleString"/>
     </element>
@@ -894,7 +1241,9 @@
   </define>
   <define name="formattedref">
     <element name="formattedref">
-      <ref name="FormattedString"/>
+      <oneOrMore>
+        <ref name="TextElement"/>
+      </oneOrMore>
     </element>
   </define>
   <define name="license">
@@ -908,140 +1257,205 @@
     </element>
   </define>
   <define name="validity">
+    <a:documentation>The time interval for which a bibliographic item is determined valid, and the associated revision date</a:documentation>
     <element name="validity">
       <optional>
-        <ref name="validityBegins"/>
+        <ref name="validityBegins">
+          <a:documentation>The date and time when this bibliographic item becomes valid</a:documentation>
+        </ref>
       </optional>
       <optional>
-        <ref name="validityEnds"/>
+        <ref name="validityEnds">
+          <a:documentation>The date and time when this bibliographic item becomes invalid</a:documentation>
+        </ref>
       </optional>
       <optional>
-        <ref name="validityRevision"/>
+        <ref name="validityRevision">
+          <a:documentation>The date and time of issuance of the version of the document
+for which this claim of validity is made, if applicable</a:documentation>
+        </ref>
       </optional>
     </element>
   </define>
   <define name="validityBegins">
     <element name="validityBegins">
-      <ref name="ISO8601DateTime"/>
+      <ref name="ISO8601Date"/>
     </element>
   </define>
   <define name="validityEnds">
     <element name="validityEnds">
-      <ref name="ISO8601DateTime"/>
+      <ref name="ISO8601Date"/>
     </element>
   </define>
   <define name="validityRevision">
     <element name="revision">
-      <ref name="ISO8601DateTime"/>
+      <ref name="ISO8601Date"/>
     </element>
   </define>
   <define name="TypedTitleString">
     <optional>
-      <attribute name="type"/>
+      <attribute name="type">
+        <a:documentation>Type of title given to a bibliographic item. Indicative values include:
+"alternative": alternate title for the item
+"original": The original title of the item. Includes the source language title of a translated item
+"unofficial": A title that has become prevalent but has never been the official or intended title of the item
+"subtitle": Subsidiary title of the item
+"main": The default title of the item, privileged in citation</a:documentation>
+      </attribute>
     </optional>
-    <ref name="FormattedString"/>
+    <optional>
+      <attribute name="format">
+        <a:documentation>(legacy attribute) format; can have value text/plain</a:documentation>
+      </attribute>
+    </optional>
+    <ref name="LocalizedMarkedUpString">
+      <a:documentation>Content of title</a:documentation>
+    </ref>
   </define>
   <!-- TitleType = ( "alternative" | "original" | "unofficial" | "subtitle" | "main" ) -->
   <define name="TypedUri">
+    <a:documentation>URI with type</a:documentation>
     <optional>
-      <attribute name="type"/>
-    </optional>
-    <optional>
-      <attribute name="language"/>
-    </optional>
-    <optional>
-      <attribute name="locale"/>
-    </optional>
-    <optional>
-      <attribute name="script"/>
+      <attribute name="type">
+        <a:documentation>Type of URI</a:documentation>
+      </attribute>
     </optional>
+    <ref name="LocalizedStringAttributes"/>
     <data type="anyURI"/>
   </define>
   <define name="DateType">
+    <a:documentation>Type which allows date and time to be specified as either a Gregorian
+date and time, as specified in ISO 8601, as text, or as both</a:documentation>
     <optional>
-      <attribute name="text"/>
+      <attribute name="text">
+        <a:documentation>Date and time, as specified in text</a:documentation>
+      </attribute>
     </optional>
     <optional>
-      <ref name="ISO8601Date"/>
+      <group>
+        <a:documentation>Gregorian date and time, as specified in ISO 8601. Can be used
+as a canonical interpretation of the date and time given in `text`</a:documentation>
+        <ref name="ISO8601Date"/>
+      </group>
     </optional>
   </define>
   <define name="BibliographicDateType">
+    <a:documentation>Indicates type of date within a bibliographic lifecycle.
+NOTE: Typically only the `published` date is of interest</a:documentation>
     <choice>
       <value>published</value>
+      <a:documentation>The date on which the document was published (distributed by the publisher)</a:documentation>
       <value>accessed</value>
+      <a:documentation>Date a document was last accessed by the compiler of the bibliographic record; routinely used for online publications.
+NOTE: Unlike in ISO 690:2021, no distinction is made between
+"viewed" and "accessed" based on whether the resource is human-readable or machine-readable.)</a:documentation>
       <value>created</value>
+      <a:documentation>The date on which the first version of the document was created</a:documentation>
       <value>implemented</value>
+      <a:documentation>The date on which the document takes effect. Applies to normative documents</a:documentation>
       <value>obsoleted</value>
+      <a:documentation>The date on which the document was obsoleted/</a:documentation>
       <value>confirmed</value>
+      <a:documentation>The date on which the document was reviewed and approved by the issuing authority</a:documentation>
       <value>updated</value>
+      <a:documentation>The date on which the current version of the document was updated</a:documentation>
       <value>corrected</value>
+      <a:documentation>The date on which the current version of the document was corrected, without that correction considered to amount to a full document update</a:documentation>
       <value>issued</value>
+      <a:documentation>The date on which the document was issued (authorised for publication by the issuing authority).
+Is typically differentiated from `published` for normative documents, such as standards and legislation</a:documentation>
       <value>transmitted</value>
+      <a:documentation>The date on which the document was broadcast</a:documentation>
       <value>copied</value>
+      <a:documentation>The date on which the document physically copied, or recreated without any substantial change in content (allowing for change in medium)</a:documentation>
       <value>unchanged</value>
+      <a:documentation>The date on which the document was last renewed or reprinted without any changes in content</a:documentation>
       <value>circulated</value>
+      <a:documentation>The date on which the unpublished document was last circulated officially as a preprint.
+For standards, this is associated with the latest transition to a formally defined preparation stage,
+such as Working Draft or Committee Draft</a:documentation>
       <value>adapted</value>
+      <a:documentation>The date on which a document adapted for a new purpose or audience, with some change in content (includes translation)</a:documentation>
       <value>vote-started</value>
+      <a:documentation>The date on which a formal process for approval of a document was initiated. Typically applies to standards documents in draft</a:documentation>
       <value>vote-ended</value>
+      <a:documentation>The date on which a formal process for approval of a document was closed. Typically applies to standards documents in draft</a:documentation>
       <value>announced</value>
+      <a:documentation>The date on which the existence of a document is made public.
+Applies whether the resource has already been created or not, and whether it is to be published or not</a:documentation>
       <value>stable-until</value>
+      <a:documentation>The document is guaranteed not to be changed or updated until this date</a:documentation>
     </choice>
   </define>
   <define name="bdate">
+    <a:documentation>Significant date in the lifecycle of the bibliographic item, including its production and its access</a:documentation>
     <element name="date">
-      <attribute name="type">
-        <choice>
-          <ref name="BibliographicDateType"/>
-          <text/>
-        </choice>
-      </attribute>
-      <optional>
-        <attribute name="text"/>
-      </optional>
+      <ref name="bDateAttributes"/>
       <optional>
         <choice>
           <group>
             <element name="from">
+              <a:documentation>The start of the date range described</a:documentation>
               <ref name="ISO8601Date"/>
             </element>
             <optional>
               <element name="to">
+                <a:documentation>The end of the date range described</a:documentation>
                 <ref name="ISO8601Date"/>
               </element>
             </optional>
           </group>
           <element name="on">
+            <a:documentation>The point date described</a:documentation>
             <ref name="ISO8601Date"/>
           </element>
         </choice>
       </optional>
     </element>
   </define>
+  <define name="bDateAttributes">
+    <attribute name="type">
+      <a:documentation>The phase of the production of or access to a bibliographic item</a:documentation>
+      <choice>
+        <ref name="BibliographicDateType"/>
+        <text/>
+      </choice>
+    </attribute>
+    <optional>
+      <attribute name="text">
+        <a:documentation>An optional textual description of the date, especially when a Gregorian date is not applicable</a:documentation>
+      </attribute>
+    </optional>
+  </define>
   <define name="docidentifier">
+    <a:documentation>An identifier of a bibliographic item in an international standard scheme</a:documentation>
     <element name="docidentifier">
-      <optional>
-        <attribute name="type"/>
-      </optional>
-      <optional>
-        <attribute name="scope"/>
-      </optional>
-      <optional>
-        <attribute name="primary">
-          <data type="boolean"/>
-        </attribute>
-      </optional>
-      <optional>
-        <attribute name="language"/>
-      </optional>
-      <optional>
-        <attribute name="locale"/>
-      </optional>
-      <optional>
-        <attribute name="script"/>
-      </optional>
-      <text/>
+      <ref name="DocIdentifierType"/>
     </element>
   </define>
+  <define name="DocIdentifierType">
+    <optional>
+      <attribute name="type">
+        <a:documentation>The scheme or namespace of the identifier</a:documentation>
+      </attribute>
+    </optional>
+    <optional>
+      <attribute name="scope">
+        <a:documentation>The scope of the identifier, in case the identifier does not apply to the document 
+but to a superset or subset of entities; or in case the identifier 
+is for a particular instance of the document, e.g. for a particular format or edition of the document</a:documentation>
+      </attribute>
+    </optional>
+    <optional>
+      <attribute name="primary">
+        <a:documentation>This is a primary identifier for the item, to be used in citation</a:documentation>
+        <data type="boolean"/>
+      </attribute>
+    </optional>
+    <ref name="LocalizedMarkedUpString">
+      <a:documentation>The identifier string</a:documentation>
+    </ref>
+  </define>
   <define name="docnumber">
     <element name="docnumber">
       <text/>
@@ -1049,26 +1463,37 @@
   </define>
   <define name="bclassification">
     <element name="classification">
-      <optional>
-        <attribute name="type"/>
-      </optional>
-      <text/>
+      <ref name="DocIdentifierType"/>
     </element>
   </define>
   <define name="bplace">
+    <a:documentation>Place associated with the production of a bibliographic item</a:documentation>
     <element name="place">
-      <choice>
-        <text/>
-        <group>
-          <ref name="bibliocity"/>
-          <zeroOrMore>
-            <ref name="biblioregion"/>
-          </zeroOrMore>
-          <zeroOrMore>
-            <ref name="bibliocountry"/>
-          </zeroOrMore>
-        </group>
-      </choice>
+      <optional>
+        <ref name="bibliocity">
+          <a:documentation>City</a:documentation>
+        </ref>
+      </optional>
+      <zeroOrMore>
+        <ref name="biblioregion">
+          <a:documentation>Region that city is located in, given for disambiguation purposes.</a:documentation>
+        </ref>
+      </zeroOrMore>
+      <zeroOrMore>
+        <ref name="bibliocountry">
+          <a:documentation>Country that city is located in, given for disambiguation purposes.</a:documentation>
+        </ref>
+      </zeroOrMore>
+      <optional>
+        <ref name="formattedPlace">
+          <a:documentation>Name of the place, not broken down semantically</a:documentation>
+        </ref>
+      </optional>
+      <optional>
+        <ref name="uri">
+          <a:documentation>URI in a geographical registry identifying the place</a:documentation>
+        </ref>
+      </optional>
     </element>
   </define>
   <define name="bibliocity">
@@ -1076,6 +1501,11 @@
       <text/>
     </element>
   </define>
+  <define name="formattedPlace">
+    <element name="formattedPlace">
+      <text/>
+    </element>
+  </define>
   <define name="biblioregion">
     <element name="region">
       <ref name="RegionType"/>
@@ -1087,41 +1517,90 @@
     </element>
   </define>
   <define name="RegionType">
+    <a:documentation>Encoding of region in bibliographic `place`. ISO 3166 encoding is recommended</a:documentation>
     <optional>
-      <attribute name="iso"/>
+      <attribute name="iso">
+        <a:documentation>ISO 3166 encoding</a:documentation>
+      </attribute>
     </optional>
     <optional>
       <attribute name="recommended">
+        <a:documentation>Whether the region should be included in rendering of the place, for disambiguation</a:documentation>
         <data type="boolean"/>
       </attribute>
     </optional>
+    <optional>
+      <text>
+        <a:documentation>Name of the region</a:documentation>
+      </text>
+    </optional>
+  </define>
+  <define name="CurrencyType">
+    <a:documentation>Code for currencies, taken from ISO 4217</a:documentation>
     <text/>
   </define>
   <define name="bprice">
+    <a:documentation>The price set on accessing the bibliographic item</a:documentation>
     <element name="price">
-      <attribute name="currency"/>
-      <text/>
+      <attribute name="currency">
+        <a:documentation>The currency denomination for the price</a:documentation>
+        <ref name="CurrencyType"/>
+      </attribute>
+      <text>
+        <a:documentation>The currency amount for the price</a:documentation>
+      </text>
     </element>
   </define>
   <define name="medium">
+    <a:documentation>Information about the medium and transmission of a bibliographic item</a:documentation>
     <element name="medium">
       <optional>
-        <ref name="bcontent"/>
+        <ref name="bcontent">
+          <a:documentation>The content type of the bibliographic item, reflecting the form of
+communication with which it is expressed and perceived. For example,
+`text`, `video`, `audio`.</a:documentation>
+          <a:documentation>NOTE: This field is intended to convey the
+Content attribute of the MARC and Resource Description and Access
+standards, although its values are not restricted to that
+vocabulary; see http://www.loc.gov/standards/valuelist/rdacontent.html</a:documentation>
+        </ref>
       </optional>
       <optional>
-        <ref name="genre"/>
+        <ref name="genre">
+          <a:documentation>The genre of the bibliographic item, as a classification of the
+type of communication it represents that is more specific than `content` or `BibliographicItem/type`.
+For example, "statistical dataset"</a:documentation>
+        </ref>
       </optional>
       <optional>
-        <ref name="form"/>
+        <ref name="form">
+          <a:documentation>The media type of the bibliographic item, used to access the content
+of the item, including file format for electronic media.</a:documentation>
+          <a:documentation>NOTE: This field is intended to convey the
+Media attribute of the MARC and Resource Description and Access
+standards, although its values are not restricted to that
+vocabulary; see http://www.loc.gov/standards/valuelist/rdamedia.html
+IANA Media Types are recommended for electronic resources</a:documentation>
+        </ref>
       </optional>
       <optional>
-        <ref name="carrier"/>
+        <ref name="carrier">
+          <a:documentation>The storage medium of the physical representation of the bibliographic item.</a:documentation>
+          <a:documentation>NOTE: This field is intended to convey the
+Carrier attribute of the MARC and Resource Description and Access
+standards, although its values are not restricted to that
+vocabulary; see https://www.loc.gov/standards/valuelist/rdacarrier.html</a:documentation>
+        </ref>
       </optional>
       <optional>
-        <ref name="size"/>
+        <ref name="size">
+          <a:documentation>The size of the physical representation of the bibliographic item</a:documentation>
+        </ref>
       </optional>
       <optional>
-        <ref name="scale"/>
+        <ref name="scale">
+          <a:documentation>The scale of the cartographic material in the bibliographic item</a:documentation>
+        </ref>
       </optional>
     </element>
   </define>
@@ -1161,9 +1640,19 @@
     </element>
   </define>
   <define name="sizevalue">
+    <a:documentation>The size of a bibliographic item being referred to.
+A sequence of sizes can be used to indicate different numberings, e.g. xii + 40 pp.,
+or different kinds of measures, e.g. pages + plates</a:documentation>
     <element name="value">
-      <attribute name="type"/>
-      <text/>
+      <attribute name="type">
+        <a:documentation>The type of size. Recommended values: page, volume, time (in ISO 8601 duration values), 
+data (including unit), value (free-form string)</a:documentation>
+      </attribute>
+      <optional>
+        <text>
+          <a:documentation>The quantity of the size</a:documentation>
+        </text>
+      </optional>
     </element>
   </define>
   <define name="bibliographic_size">
@@ -1186,46 +1675,80 @@
     </element>
   </define>
   <define name="series">
+    <a:documentation>Series to which a bibliographic item belongs. Series is to be understood broadly,
+and it includes monograph series, journals, newspapers, and report series within
+which the bibliographic item has appeared</a:documentation>
     <element name="series">
       <optional>
         <attribute name="type">
+          <a:documentation>The type of series description expressed in this container</a:documentation>
           <ref name="SeriesType"/>
         </attribute>
       </optional>
       <optional>
-        <ref name="formattedref"/>
+        <ref name="formattedref">
+          <a:documentation>A pre-formatted version of the series description, incorporating
+all needed disambiguating information in human-readable format</a:documentation>
+        </ref>
       </optional>
-      <ref name="btitle"/>
+      <oneOrMore>
+        <ref name="btitle">
+          <a:documentation>The title of the series</a:documentation>
+        </ref>
+      </oneOrMore>
       <optional>
-        <ref name="bplace"/>
+        <ref name="bplace">
+          <a:documentation>The place where the series is issued; used for disambiguation</a:documentation>
+        </ref>
       </optional>
       <optional>
-        <ref name="seriesorganization"/>
+        <ref name="seriesorganization">
+          <a:documentation>The organization issuing the series; used for disambiguation</a:documentation>
+        </ref>
       </optional>
       <optional>
-        <ref name="abbreviation"/>
+        <ref name="abbreviation">
+          <a:documentation>The abbreviation under which the series is known</a:documentation>
+        </ref>
       </optional>
       <optional>
-        <ref name="seriesfrom"/>
+        <ref name="seriesfrom">
+          <a:documentation>The start of the date range when the series has been known under the given title</a:documentation>
+        </ref>
       </optional>
       <optional>
-        <ref name="seriesto"/>
+        <ref name="seriesto">
+          <a:documentation>The end of the date range when the series has been known under the given title</a:documentation>
+        </ref>
       </optional>
       <optional>
-        <ref name="seriesnumber"/>
+        <ref name="seriesnumber">
+          <a:documentation>The number of the bibliographic item within the series</a:documentation>
+        </ref>
       </optional>
       <optional>
-        <ref name="seriespartnumber"/>
+        <ref name="seriespartnumber">
+          <a:documentation>The part-number of the bibliographic item within the series. For example,
+if the series is a journal, the number is the volume number, and the partnumber is the issue number</a:documentation>
+        </ref>
       </optional>
       <optional>
-        <ref name="seriesrun"/>
+        <ref name="seriesrun">
+          <a:documentation>An iteration of numbering of the series, if the series has restarted numbering
+(as occurs in some journals); referred to as "series" in the context of journals.
+For example, "n.s." (new series) or "2" indicates
+that the `number` given for the series applies to the second iteration of numbering</a:documentation>
+        </ref>
       </optional>
     </element>
   </define>
   <define name="SeriesType">
+    <a:documentation>The type of series description given</a:documentation>
     <choice>
       <value>main</value>
+      <a:documentation>Default type: The current, authoritative series description</a:documentation>
       <value>alt</value>
+      <a:documentation>An alternative, potentially historical series description</a:documentation>
       <text/>
     </choice>
   </define>
@@ -1260,32 +1783,75 @@
     </element>
   </define>
   <define name="biblionote">
+    <a:documentation>A note associated with the bibliographic item</a:documentation>
     <element name="note">
       <optional>
-        <attribute name="type"/>
+        <attribute name="type">
+          <a:documentation>The class of the note associated with the bibliographic item.
+May be used to differentiate rendering of notes in bibliographies</a:documentation>
+        </attribute>
       </optional>
-      <ref name="FormattedString"/>
+      <ref name="LocalizedStringAttributes">
+        <a:documentation>The content of the note</a:documentation>
+      </ref>
+      <choice>
+        <oneOrMore>
+          <ref name="BasicBlockNoId">
+            <a:documentation>Multiple blocks of content</a:documentation>
+          </ref>
+        </oneOrMore>
+        <oneOrMore>
+          <ref name="TextElement">
+            <a:documentation>Single block of content</a:documentation>
+          </ref>
+        </oneOrMore>
+      </choice>
     </element>
   </define>
   <define name="bibabstract">
+    <a:documentation>Abstract of bibliographic item</a:documentation>
     <element name="abstract">
-      <ref name="FormattedString"/>
+      <ref name="LocalizedStringAttributes"/>
+      <choice>
+        <oneOrMore>
+          <ref name="BasicBlockNoId">
+            <a:documentation>Multiple blocks of content</a:documentation>
+          </ref>
+        </oneOrMore>
+        <oneOrMore>
+          <ref name="TextElement">
+            <a:documentation>Single block of content</a:documentation>
+          </ref>
+        </oneOrMore>
+      </choice>
     </element>
   </define>
   <define name="copyright">
+    <a:documentation>The copyright status of a bibliographic item.</a:documentation>
     <element name="copyright">
-      <ref name="from"/>
+      <ref name="from">
+        <a:documentation>The copyright date of the bibliographic item</a:documentation>
+      </ref>
       <optional>
-        <ref name="to"/>
+        <ref name="to">
+          <a:documentation>The date when the copyright of the bibliographic item expires</a:documentation>
+        </ref>
       </optional>
       <oneOrMore>
-        <ref name="owner"/>
+        <ref name="owner">
+          <a:documentation>The copyright owner for the bibliographic item.</a:documentation>
+        </ref>
       </oneOrMore>
       <optional>
-        <ref name="copyright_scope"/>
+        <ref name="copyright_scope">
+          <a:documentation>The extent of the bibliographic item, or contexts of use, for which this
+assertion of copyright applies. For example, this description may only apply
+to the preface of a book</a:documentation>
+        </ref>
       </optional>
     </element>
   </define>
+  <!-- TODO potentially should be locality | localityStack -->
   <define name="copyright_scope">
     <element name="scope">
       <text/>
@@ -1302,11 +1868,14 @@
     </element>
   </define>
   <define name="owner">
+    <a:documentation>Copyright owner</a:documentation>
     <element name="owner">
       <ref name="ContributorInfo"/>
     </element>
   </define>
   <define name="DocRelationType">
+    <a:documentation>Type of the relationship between a main document (described in `BibliographicItem`) and a target document
+Detailed in https://www.relaton.org/model/relations/</a:documentation>
     <choice>
       <value>includes</value>
       <value>includedIn</value>
@@ -1338,6 +1907,10 @@
       <value>hasAnnotation</value>
       <value>draftOf</value>
       <value>hasDraft</value>
+      <value>preliminaryDraftOf</value>
+      <value>hasPreliminaryDraft</value>
+      <value>revisionDraftOf</value>
+      <value>hasRevisionDraft</value>
       <value>editionOf</value>
       <value>hasEdition</value>
       <value>updates</value>
@@ -1368,19 +1941,25 @@
     </choice>
   </define>
   <define name="docrelation">
+    <a:documentation>Relation between a bibliographic item and another bibliographic item</a:documentation>
     <element name="relation">
       <attribute name="type">
+        <a:documentation>The type of document relation described, using a controlled vocabulary</a:documentation>
         <ref name="DocRelationType"/>
       </attribute>
       <optional>
         <element name="description">
-          <ref name="FormattedString"/>
+          <a:documentation>A more complete description of the type of document relation described</a:documentation>
+          <ref name="LocalizedMarkedUpString"/>
         </element>
       </optional>
       <element name="bibitem">
+        <a:documentation>The target bibliographic item to which this bibliographic item is described as related to</a:documentation>
         <ref name="ReducedBibliographicItem"/>
       </element>
       <choice>
+        <a:documentation>The extent of the target bibliographic item which is related to this bibliographic item,
+provided that it is not the entire bibliographic item that is so related</a:documentation>
         <zeroOrMore>
           <ref name="locality"/>
         </zeroOrMore>
@@ -1389,6 +1968,8 @@
         </zeroOrMore>
       </choice>
       <choice>
+        <a:documentation>The extent of this bibliographic item which is related to the target bibliographic item,
+provided that it is not the entire bibliographic item that is so related</a:documentation>
         <zeroOrMore>
           <ref name="sourceLocality"/>
         </zeroOrMore>
@@ -1399,12 +1980,17 @@
     </element>
   </define>
   <define name="version">
+    <a:documentation>A version of the bibliographic item (within an edition). Can be used for drafts</a:documentation>
     <element name="version">
       <optional>
-        <ref name="revision-date"/>
+        <ref name="revision-date">
+          <a:documentation>The date at which the current version of the bibliographic item was produced</a:documentation>
+        </ref>
       </optional>
       <optional>
-        <ref name="draft"/>
+        <ref name="draft">
+          <a:documentation>The identifier for the current draft of the bibliographic item</a:documentation>
+        </ref>
       </optional>
     </element>
   </define>
@@ -1423,46 +2009,63 @@
       <text/>
     </element>
   </define>
+  <!--
+    bkeyword = element keyword {
+    LocalizedString |
+    (
+    element vocab { LocalizedString },
+    vocabid+
+    ) |
+    (
+    element taxon { LocalizedString }+,
+    vocabid+
+    )
+    }
+  -->
   <define name="bkeyword">
+    <a:documentation>Keyword for a bibliographic item</a:documentation>
     <element name="keyword">
-      <choice>
-        <ref name="LocalizedString"/>
-        <group>
-          <element name="vocab">
-            <ref name="LocalizedString"/>
-          </element>
-          <oneOrMore>
-            <ref name="vocabid"/>
-          </oneOrMore>
-        </group>
-        <group>
-          <oneOrMore>
-            <element name="taxon">
-              <ref name="LocalizedString"/>
-            </element>
-          </oneOrMore>
-          <oneOrMore>
-            <ref name="vocabid"/>
-          </oneOrMore>
-        </group>
-      </choice>
+      <optional>
+        <element name="vocab">
+          <a:documentation>The keyword as a single, controlled or uncontrolled vocabulary item</a:documentation>
+          <ref name="LocalizedString"/>
+        </element>
+      </optional>
+      <oneOrMore>
+        <element name="taxon">
+          <a:documentation>The keywords as a hierarchical taxonomy. For example, the sequence of `taxon` elements
+`pump`, `centrifugal pump`, `line shaft pump` represents a taxonomic classification</a:documentation>
+          <ref name="LocalizedString"/>
+        </element>
+      </oneOrMore>
+      <zeroOrMore>
+        <ref name="vocabid">
+          <a:documentation>Identifiers for the keyword as a controlled vocabulary</a:documentation>
+        </ref>
+      </zeroOrMore>
     </element>
   </define>
   <define name="vocabid">
+    <a:documentation>Item in a controlled vocabulary</a:documentation>
     <element name="vocabid">
-      <attribute name="type"/>
+      <attribute name="type">
+        <a:documentation>A label for the controlled vocabulary</a:documentation>
+      </attribute>
       <optional>
         <attribute name="uri">
+          <a:documentation>A URI for the controlled vocabulary item</a:documentation>
           <data type="anyURI"/>
         </attribute>
       </optional>
       <optional>
         <element name="code">
+          <a:documentation>The code or identifier for the controlled vocabulary item</a:documentation>
           <text/>
         </element>
       </optional>
       <optional>
         <element name="term">
+          <a:documentation>The term itself for the controlled vocabulary item</a:documentation>
           <text/>
         </element>
       </optional>
diff --git a/grammars/versions.json b/grammars/versions.json
index 442360e..6b5279f 100644
--- a/grammars/versions.json
+++ b/grammars/versions.json
@@ -1,21 +1,21 @@
 {
-"relaton-models": "v1.2.9",
-"basicdoc-models": "v1.1.3",
-"metanorma-requirements-models": "v1.0.1",
+"relaton-models": "v1.4.1",
+"basicdoc-models": "v1.2.2",
+"metanorma-requirements-models": "v1.0.2",
 "relaton-model-ieee": "v1.0.1",
-"relaton-model-iso": "v1.0.3",
+"relaton-model-iso": "v1.0.5",
 "relaton-model-iec": "v1.0.0",
-"relaton-model-bsi": "v1.0.2",
+"relaton-model-bsi": "v1.0.3",
 "relaton-model-gb": "v1.0.0",
 "relaton-model-mpfa": "v1.0.0",
-"relaton-model-bipm": "v1.0.0",
+"relaton-model-bipm": "v1.0.1",
 "relaton-model-w3c": "v1.0.0",
 "relaton-model-3gpp": "v1.0.1",
 "relaton-model-csa": "v1.0.0",
 "relaton-model-cc": "v1.0.0",
 "relaton-model-ietf": "v1.0.1",
 "relaton-model-iho": "v1.0.0",
-"relaton-model-itu": "v1.0.0",
+"relaton-model-itu": "v1.0.2",
 "relaton-model-m3aawg": "v1.0.0",
 "relaton-model-nist": "v1.0.0",
 "relaton-model-ribose": "v1.0.0",
@@ -29,7 +29,7 @@
 "relaton-model-oasis": "v1.0.1",
 "relaton-model-jis": "v0.0.1",
 "relaton-model-etsi": "v0.0.3",
-"relaton-model-plateau": "v0.0.1",
-"metanorma-model": "v1.3.0",
-"date": "2024-02-21T18:15:14Z"
+"relaton-model-plateau": "v0.0.2",
+"metanorma-model": "v1.4.1",
+"date": "2024-12-03T03:33:24Z"
 }
diff --git a/lib/relaton_bib.rb b/lib/relaton/bib.rb
similarity index 62%
rename from lib/relaton_bib.rb
rename to lib/relaton/bib.rb
index 2602b32..aeaeb58 100644
--- a/lib/relaton_bib.rb
+++ b/lib/relaton/bib.rb
@@ -2,24 +2,28 @@
 require "forwardable"
 require "yaml"
 require "htmlentities"
-require "relaton_bib/version"
-require "relaton_bib/deep_dup"
-require "relaton_bib/util"
-require "relaton_bib/localized_string"
-require "relaton_bib/forename"
-require "relaton_bib/full_name"
-require "relaton_bib/contributor"
-require "relaton_bib/document_type"
-require "relaton_bib/image"
-require "relaton_bib/bibliographic_item"
-require "relaton_bib/hit_collection"
-require "relaton_bib/hit"
-require "relaton_bib/bibxml_parser"
-require "relaton_bib/renderer/bibtex_builder"
-require "relaton_bib/renderer/bibxml"
+require "bibtex"
+require "iso639"
+# require_relative "deep_dup"
+# require_relative "bib/config"
+require_relative "bib/util"
+# require_relative "workers_pool"
+require_relative "bib/item"
+# require_relative "xml_parser"
+require_relative "bib/item_data"
+require_relative "bib/item_base"
+require_relative "bib/bibitem"
+require_relative "bib/bibdata"
+# require_relative "hit_collection"
+# require_relative "hit"
+require_relative "bibxml_parser"
+require_relative "renderer/bibtex_builder"
+require_relative "renderer/bibxml"
+require_relative "bib/relation"
+# require_relative "hash_converter"
 
-module RelatonBib
-  class Error < StandardError; end
+module Relaton
+  # class Error < StandardError; end
 
   class RequestError < StandardError; end
 
@@ -27,7 +31,7 @@ class << self
     # @param date [String, Integer, Date] date
     # @param str [Boolean] return string or Date
     # @return [Date, String, nil] date
-    def parse_date(date, str = true) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity,Metrics/AbcSize
+    def parse_date(date, str: true) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength
       return date if date.is_a?(Date)
 
       case date.to_s
@@ -58,7 +62,7 @@ def format_date(date, format, str, outformat = nil)
       date = Date.strptime(date, format)
       str ? date.strftime(outformat || format) : date
     rescue Date::Error => e
-      Util.warn "#{date} #{e.message}"
+      Bib::Util.warn "#{date} #{e.message}"
       date
     end
 
@@ -90,22 +94,24 @@ def parse_yaml(yaml, classes = [], symbolize_names: false)
     end
   end
 
-  def self.grammar_hash
-    # gem_path = File.expand_path "..", __dir__
-    # grammars_path = File.join gem_path, "grammars", "*"
-    # grammars = Dir[grammars_path].sort.map { |gp| File.read gp }.join
-    Digest::MD5.hexdigest RelatonBib::VERSION # grammars
+  module Bib
+    def self.grammar_hash
+      # gem_path = File.expand_path "..", __dir__
+      # grammars_path = File.join gem_path, "grammars", "*"
+      # grammars = Dir[grammars_path].sort.map { |gp| File.read gp }.join
+      Digest::MD5.hexdigest Relaton::Bib::VERSION # grammars
+    end
   end
 
-  private
+  # private
 
-  # @param array [Array]
-  # @return [Array<String>, String]
-  def single_element_array(array)
-    # if array.size > 1
-    array.map { |e| e.is_a?(String) ? e : e.to_hash }
-    # else
-    #   array.first.is_a?(String) ? array[0] : array.first&.to_hash
-    # end
-  end
+  # # @param array [Array]
+  # # @return [Array<String>, String]
+  # def single_element_array(array)
+  #   # if array.size > 1
+  #   array.map { |e| e.is_a?(String) ? e : e.to_hash }
+  #   # else
+  #   #   array.first.is_a?(String) ? array[0] : array.first&.to_hash
+  #   # end
+  # end
 end
diff --git a/lib/relaton/bib/address.rb b/lib/relaton/bib/address.rb
new file mode 100644
index 0000000..df7e581
--- /dev/null
+++ b/lib/relaton/bib/address.rb
@@ -0,0 +1,22 @@
+module Relaton
+  module Bib
+    class Address < Lutaml::Model::Serializable
+      attribute :street, :string, collection: true
+      attribute :city, :string
+      attribute :state, :string
+      attribute :country, :string
+      attribute :postcode, :string
+      attribute :formatted_address, :string, raw: true
+
+      xml do
+        root "address"
+        map_element "street", to: :street
+        map_element "city", to: :city
+        map_element "state", to: :state
+        map_element "country", to: :country
+        map_element "postcode", to: :postcode
+        map_element "formattedAddress", to: :formatted_address
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/affiliation.rb b/lib/relaton/bib/affiliation.rb
new file mode 100644
index 0000000..4e8ca09
--- /dev/null
+++ b/lib/relaton/bib/affiliation.rb
@@ -0,0 +1,16 @@
+module Relaton
+  module Bib
+    class Affiliation < Lutaml::Model::Serializable
+      attribute :name, LocalizedString
+      attribute :description, LocalizedMarkedUpString, collection: true
+      attribute :organization, Organization
+
+      xml do
+        root "affiliation"
+        map_element "name", to: :name
+        map_element "description", to: :description
+        map_element "organization", to: :organization
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/bibdata.rb b/lib/relaton/bib/bibdata.rb
new file mode 100644
index 0000000..82ee685
--- /dev/null
+++ b/lib/relaton/bib/bibdata.rb
@@ -0,0 +1,14 @@
+module Relaton
+  module Bib
+    # This class represents a bibliographic item as a bibdata.
+    class Bibdata < Item
+      model ItemData
+
+      mappings[:xml].instance_variable_get(:@attributes).delete("id")
+
+      xml do
+        root "bibdata"
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/bibitem.rb b/lib/relaton/bib/bibitem.rb
new file mode 100644
index 0000000..f7856cd
--- /dev/null
+++ b/lib/relaton/bib/bibitem.rb
@@ -0,0 +1,14 @@
+module Relaton
+  module Bib
+    # This class represents a bibliographic item as a bibitem.
+    class Bibitem < Item
+      model ItemData
+
+      mappings[:xml].instance_variable_get(:@elements).delete("ext")
+
+      xml do
+        root "bibitem"
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/contact.rb b/lib/relaton/bib/contact.rb
new file mode 100644
index 0000000..cc653b0
--- /dev/null
+++ b/lib/relaton/bib/contact.rb
@@ -0,0 +1,18 @@
+require_relative "address"
+require_relative "phone"
+require_relative "uri"
+
+module Relaton
+  module Bib
+    module Contact
+      def self.included(base)
+        base.instance_eval do
+          attribute :address, Address, collection: true
+          attribute :phone, Phone, collection: true
+          attribute :email, :string, collection: true
+          attribute :uri, Uri, collection: true
+        end
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/contribution_info.rb b/lib/relaton/bib/contribution_info.rb
new file mode 100644
index 0000000..2d23e2c
--- /dev/null
+++ b/lib/relaton/bib/contribution_info.rb
@@ -0,0 +1,16 @@
+module Relaton
+  module Bib
+    class ContributionInfo < Lutaml::Model::Serializable
+      choice(min: 1, max: 1) do
+        attribute :person, Person
+        attribute :organization, Organization
+      end
+
+      xml do
+        no_root
+        map_element "person", to: :person
+        map_element "organization", to: :organization
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/contributor.rb b/lib/relaton/bib/contributor.rb
new file mode 100644
index 0000000..025d7e4
--- /dev/null
+++ b/lib/relaton/bib/contributor.rb
@@ -0,0 +1,57 @@
+module Relaton
+  module Bib
+    class Contributor < Lutaml::Model::Serializable
+      attribute :role, Role, collection: true
+      # attribute :entity, ContributionInfo
+      # @TODO: use `import_model ContributionInfo` for person and organization when Lutaml supports it
+      choice(min: 1, max: 1) do
+        attribute :person, Person
+        attribute :organization, Organization
+      end
+      # import_model_attributes ContributionInfo
+
+      xml do
+        root "contributor"
+
+        map_element "role", to: :role
+        # map_content to: :entity, with: { from: :entity_from_xml, to: :entity_to_xml }
+        map_element "person", to: :person
+        map_element "organization", to: :organization # , with: { from: :organization_from_xml, to: :organization_to_xml }
+      end
+
+      # def entity
+      #   person || organization
+      # end
+
+      # def entity=(value)
+      #   if value.is_a? Person
+      #     self.person = value
+      #     self.organization = nil
+      #   elsif value.is_a? Organization
+      #     self.organization = value
+      #     self.person = nil
+      #   else
+      #     raise ArgumentError, "value must be a Person or Organization"
+      #   end
+      # end
+
+      # def organization_from_xml(model, node)
+      #   model.entity = Organization.of_xml node
+      # end
+
+      # def organization_to_xml(model, parent, _doc)
+      #   parent << model.entity.to_xml
+      # end
+
+      # def entity_from_xml(model, node)
+      #   n = node.instance_variable_get(:@node) || node
+      #   model.content = ContributionInfo.of_xml n
+      # rescue StandardError
+      # end
+
+      # def entity_to_xml(model, parent, _doc)
+      #   parent << model.content.to_xml
+      # end
+    end
+  end
+end
diff --git a/lib/relaton/bib/copyright.rb b/lib/relaton/bib/copyright.rb
new file mode 100644
index 0000000..429bf49
--- /dev/null
+++ b/lib/relaton/bib/copyright.rb
@@ -0,0 +1,27 @@
+module Relaton
+  module Bib
+    class Copyright < Lutaml::Model::Serializable
+      attribute :from, :string
+      attribute :to, :string
+      attribute :owner, ContributionInfo, collection: true
+      attribute :scope, :string
+
+      xml do
+        root "copyright"
+
+        map_element "from", to: :from
+        map_element "to", to: :to
+        map_element "owner", to: :owner # , with: { from: :owner_from_xml, to: :owner_to_xml }
+        map_element "scope", to: :scope
+      end
+
+      # def owner_from_xml(model, node)
+      #   model.owner = ContributionInfo.from_xml node
+      # end
+
+      # def owner_to_xml(model, parent, _doc)
+      #   model.owner.to_xml parent
+      # end
+    end
+  end
+end
diff --git a/lib/relaton/bib/date.rb b/lib/relaton/bib/date.rb
new file mode 100644
index 0000000..b18557d
--- /dev/null
+++ b/lib/relaton/bib/date.rb
@@ -0,0 +1,25 @@
+module Relaton
+  module Bib
+    class Date < Lutaml::Model::Serializable
+      attribute :type, :string
+      attribute :text, :string
+      choice(min: 1, max: 2) do
+        choice(min: 1, max: 2) do
+          attribute :from, :string
+          attribute :to, :string
+        end
+        # `on` is reserved word in YAML, so use `at` instead to avoid remapping key-value formats
+        attribute :at, :string
+      end
+
+      xml do
+        root "date"
+        map_attribute "type", to: :type
+        map_attribute "text", to: :text
+        map_element "from", to: :from
+        map_element "to", to: :to
+        map_element "on", to: :at
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/depiction.rb b/lib/relaton/bib/depiction.rb
new file mode 100644
index 0000000..ed62f4c
--- /dev/null
+++ b/lib/relaton/bib/depiction.rb
@@ -0,0 +1,14 @@
+module Relaton
+  module Bib
+    class Depiction < Lutaml::Model::Serializable
+      attribute :scope, :string
+      attribute :image, Image, collection: true
+
+      xml do
+        root "depiction"
+        map_attribute "scope", to: :scope
+        map_element "image", to: :image
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/docidentifier.rb b/lib/relaton/bib/docidentifier.rb
new file mode 100644
index 0000000..3ec4752
--- /dev/null
+++ b/lib/relaton/bib/docidentifier.rb
@@ -0,0 +1,15 @@
+module Relaton
+  module Bib
+    class Docidentifier < LocalizedMarkedUpString
+      attribute :type, :string
+      attribute :scope, :string
+      attribute :primary, :boolean
+
+      xml do
+        map_attribute "type", to: :type
+        map_attribute "scope", to: :scope
+        map_attribute "primary", to: :primary
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/doctype.rb b/lib/relaton/bib/doctype.rb
new file mode 100644
index 0000000..74e2a42
--- /dev/null
+++ b/lib/relaton/bib/doctype.rb
@@ -0,0 +1,14 @@
+module Relaton
+  module Bib
+    class Doctype < Lutaml::Model::Serializable
+      attribute :abbreviation, :string
+      attribute :content, :string
+
+      xml do
+        root "doctype"
+        map_attribute "abbreviation", to: :abbreviation
+        map_content to: :content
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/edition.rb b/lib/relaton/bib/edition.rb
new file mode 100644
index 0000000..c070a2c
--- /dev/null
+++ b/lib/relaton/bib/edition.rb
@@ -0,0 +1,14 @@
+module Relaton
+  module Bib
+    class Edition < Lutaml::Model::Serializable
+      attribute :number, :string
+      attribute :content, :string
+
+      xml do
+        root "edition"
+        map_attribute "number", to: :number
+        map_content to: :content
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/editorial_group.rb b/lib/relaton/bib/editorial_group.rb
new file mode 100644
index 0000000..b150839
--- /dev/null
+++ b/lib/relaton/bib/editorial_group.rb
@@ -0,0 +1,14 @@
+require_relative "workgroup"
+
+module Relaton
+  module Bib
+    class EditorialGroup < Lutaml::Model::Serializable
+      attribute :technical_committee, WorkGroup, collection: true
+
+      xml do
+        root "editorialgroup"
+        map_element "technical-committee", to: :technical_committee
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/ext.rb b/lib/relaton/bib/ext.rb
new file mode 100644
index 0000000..8e3429c
--- /dev/null
+++ b/lib/relaton/bib/ext.rb
@@ -0,0 +1,29 @@
+require_relative "doctype"
+require_relative "editorial_group"
+require_relative "ics"
+require_relative "structured_identifier"
+
+module Relaton
+  module Bib
+    class Ext < Lutaml::Model::Serializable
+      attribute :schema_version, :string
+      attribute :doctype, Doctype
+      attribute :subdoctype, :string
+      attribute :flavor, :string
+      attribute :editorialgroup, EditorialGroup
+      attribute :ics, ICS, collection: true
+      attribute :structuredidentifier, StructuredIdentifier, collection: true
+
+      xml do
+        root "ext"
+        map_attribute "schema-version", to: :schema_version
+        map_element "doctype", to: :doctype
+        map_element "subdoctype", to: :subdoctype
+        map_element "flavor", to: :flavor
+        map_element "editorialgroup", to: :editorialgroup
+        map_element "ics", to: :ics
+        map_element "structuredidentifier", to: :structuredidentifier
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/extent.rb b/lib/relaton/bib/extent.rb
new file mode 100644
index 0000000..01fa4a5
--- /dev/null
+++ b/lib/relaton/bib/extent.rb
@@ -0,0 +1,16 @@
+module Relaton
+  module Bib
+    class Extent < Lutaml::Model::Serializable
+      choice(min: 1, max: 1) do
+        attribute :locality, Locality, collection: true
+        attribute :locality_stack, LocalityStack, collection: true
+      end
+
+      xml do
+        root "extent"
+        map_element "locality", to: :locality
+        map_element "localityStack", to: :locality_stack
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/full_name_type.rb b/lib/relaton/bib/full_name_type.rb
new file mode 100644
index 0000000..6918d84
--- /dev/null
+++ b/lib/relaton/bib/full_name_type.rb
@@ -0,0 +1,60 @@
+module Relaton
+  module Bib
+    module FullNameType
+      class Forename < LocalizedString
+        attribute :initial, :string
+
+        xml do
+          map_attribute "initial", to: :initial
+        end
+      end
+
+      def self.included(base) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
+        base.instance_eval do
+          attribute :abbreviation, LocalizedString
+          attribute :prefix, LocalizedString, collection: true
+          attribute :forename, Forename, collection: true
+          attribute :formatted_initials, LocalizedString
+          attribute :surname, LocalizedString
+          attribute :addition, LocalizedString, collection: true
+          attribute :completename, LocalizedString
+          attribute :note, Note, collection: true
+          attribute :variant, Variant, collection: true
+
+          xml do
+            map_element "abbreviation", to: :abbreviation
+            map_element "prefix", to: :prefix
+            map_element "forename", to: :forename
+            map_element "formatted-initials", to: :formatted_initials
+            map_element "surname", to: :surname
+            map_element "addition", to: :addition
+            map_element "completename", to: :completename
+            map_element "note", to: :note
+            map_element "variant", to: :variant
+          end
+        end
+      end
+
+      # def content_from_xml(model, node)
+      #   model.content = Content.of_xml node.instance_variable_get(:@node) || node
+      # end
+
+      # def content_to_xml(model, parent, _doc)
+      #   model.content.add_to_xml parent
+      # end
+    end
+
+    module FullNameType
+      class Variant < Lutaml::Model::Serializable
+        include FullNameType
+
+        attribute :type, :string
+
+        xml do
+          root "variant"
+          map_attribute "type", to: :type
+        end
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/fullname.rb b/lib/relaton/bib/fullname.rb
new file mode 100644
index 0000000..1294545
--- /dev/null
+++ b/lib/relaton/bib/fullname.rb
@@ -0,0 +1,11 @@
+module Relaton
+  module Bib
+    class FullName < Lutaml::Model::Serializable
+      include FullNameType
+
+      xml do
+        root "name"
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/gem_version.rb b/lib/relaton/bib/gem_version.rb
new file mode 100644
index 0000000..f9e6ad5
--- /dev/null
+++ b/lib/relaton/bib/gem_version.rb
@@ -0,0 +1,5 @@
+module Relaton
+  module Bib
+    VERSION = "2.0.0-alpha.1".freeze
+  end
+end
diff --git a/lib/relaton/bib/ics.rb b/lib/relaton/bib/ics.rb
new file mode 100644
index 0000000..5826dd4
--- /dev/null
+++ b/lib/relaton/bib/ics.rb
@@ -0,0 +1,14 @@
+module Relaton
+  module Bib
+    class ICS < Lutaml::Model::Serializable
+      attribute :code, :string
+      attribute :text, :string
+
+      xml do
+        root "ics"
+        map_element "code", to: :code
+        map_element "text", to: :text
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/image.rb b/lib/relaton/bib/image.rb
new file mode 100644
index 0000000..605571d
--- /dev/null
+++ b/lib/relaton/bib/image.rb
@@ -0,0 +1,28 @@
+module Relaton
+  module Bib
+    class Image < Lutaml::Model::Serializable
+      attribute :id, :string
+      attribute :src, :string # anyURI
+      attribute :mimetype, :string
+      attribute :filename, :string
+      attribute :width, :string
+      attribute :height, :string
+      attribute :alt, :string
+      attribute :title, :string
+      attribute :longdesc, :string # anyURI
+
+      xml do
+        root "image"
+        map_attribute "id", to: :id
+        map_attribute "src", to: :src
+        map_attribute "mimetype", to: :mimetype
+        map_attribute "filename", to: :filename
+        map_attribute "width", to: :width
+        map_attribute "height", to: :height
+        map_attribute "alt", to: :alt
+        map_attribute "title", to: :title
+        map_attribute "longdesc", to: :longdesc
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/item.rb b/lib/relaton/bib/item.rb
new file mode 100644
index 0000000..9c68df9
--- /dev/null
+++ b/lib/relaton/bib/item.rb
@@ -0,0 +1,128 @@
+require "lutaml/model"
+require "lutaml/model/xml_adapter/nokogiri_adapter"
+require_relative "localized_string_attrs"
+require_relative "localized_string"
+require_relative "date"
+require_relative "locality"
+require_relative "locality_stack"
+require_relative "image"
+require_relative "title"
+require_relative "docidentifier"
+require_relative "note"
+require_relative "full_name_type"
+require_relative "fullname"
+require_relative "contact"
+require_relative "logo"
+require_relative "organization"
+require_relative "affiliation"
+require_relative "person"
+require_relative "contribution_info"
+require_relative "role"
+require_relative "contributor"
+require_relative "edition"
+require_relative "version"
+require_relative "status"
+require_relative "copyright"
+require_relative "place"
+require_relative "series"
+require_relative "medium"
+require_relative "uri"
+require_relative "price"
+require_relative "extent"
+require_relative "size"
+require_relative "keyword"
+require_relative "validity"
+require_relative "depiction"
+require_relative "source_locality_stack"
+require_relative "ext"
+
+Lutaml::Model::Config.configure do |config|
+  config.xml_adapter = Lutaml::Model::XmlAdapter::NokogiriAdapter
+end
+
+module Relaton
+  module Bib
+    class Relation < Lutaml::Model::Serializable
+    end
+
+    # Item class repesents bibliographic item metadata.
+    class Item < Lutaml::Model::Serializable
+      attribute :id, :string
+      attribute :type, :string, values: %W[
+        article book booklet manual proceedings presentation thesis techreport standard
+        unpublished map electronic\sresource audiovisual film video boradcast software
+        graphic_work music patent inbook incollection inproceedings journal website
+        webresource dataset archival social_media alert message convesation misc
+      ]
+      attribute :schema_version, :string
+      attribute :fetched, :date
+      attribute :formattedref, :string, raw: true
+      attribute :title, Title, collection: true
+      attribute :source, Uri, collection: true
+      attribute :docidentifier, Docidentifier, collection: true
+      attribute :docnumber, :string
+      attribute :date, Date, collection: true
+      attribute :contributor, Contributor, collection: true
+      attribute :edition, Edition
+      attribute :version, Version, collection: true
+      attribute :note, Note, collection: true
+      attribute :language, :string, collection: true
+      attribute :locale, :string, collection: true
+      attribute :script, :string, collection: true
+      attribute :abstract, LocalizedMarkedUpString, collection: true
+      attribute :status, Status
+      attribute :copyright, Copyright, collection: true
+      attribute :relation, Relation, collection: true
+      attribute :series, Series, collection: true
+      attribute :medium, Medium
+      attribute :place, Place, collection: true
+      attribute :price, Price, collection: true
+      attribute :extent, Extent, collection: true
+      attribute :size, Size
+      attribute :accesslocation, :string, collection: true
+      attribute :license, :string, collection: true
+      attribute :classification, Docidentifier, collection: true
+      attribute :keyword, Keyword, collection: true
+      attribute :validity, Validity
+      attribute :depiction, Depiction
+      attribute :ext, Ext
+
+      xml do # rubocop:disable Metrics/BlockLength
+        map_attribute "id", to: :id
+        map_attribute "type", to: :type
+        map_attribute "schema-version", to: :schema_version
+        map_element "fetched", to: :fetched
+        map_element "formattedref", to: :formattedref
+        map_element "title", to: :title # , with: { from: :title_from_xml, to: :title_to_xml }
+        map_element "uri", to: :source
+        map_element "docidentifier", to: :docidentifier
+        map_element "docnumber", to: :docnumber
+        map_element "date", to: :date
+        map_element "contributor", to: :contributor
+        map_element "edition", to: :edition
+        map_element "version", to: :version
+        map_element "note", to: :note
+        map_element "language", to: :language
+        map_element "locale", to: :locale
+        map_element "script", to: :script
+        map_element "abstract", to: :abstract
+        map_element "status", to: :status
+        map_element "copyright", to: :copyright
+        map_element "relation", to: :relation # , with: { from: :relation_from_xml, to: :relation_to_xml }
+        map_element "series", to: :series
+        map_element "medium", to: :medium
+        map_element "place", to: :place
+        map_element "price", to: :price
+        map_element "extent", to: :extent
+        map_element "size", to: :size
+        map_element "accesslocation", to: :accesslocation
+        map_element "license", to: :license
+        map_element "classification", to: :classification
+        map_element "keyword", to: :keyword
+        map_element "validity", to: :validity
+        map_element "depiction", to: :depiction
+        map_element "ext", to: :ext
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/item_base.rb b/lib/relaton/bib/item_base.rb
new file mode 100644
index 0000000..322396b
--- /dev/null
+++ b/lib/relaton/bib/item_base.rb
@@ -0,0 +1,13 @@
+module Relaton
+  autoload :Item, "relaton/bib/item"
+
+  module Bib
+    # The class is for relaton bibitem instances.
+    # The in relaton bibitem instances dosn't have schema-version & fetched attributes.
+    class ItemBase < Item
+      # we don't need schema-version & fetched attributes in reation/bibitem
+      mappings[:xml].instance_variable_get(:@attributes).delete("schema-version")
+      mappings[:xml].instance_variable_get(:@elements).delete("fetched")
+    end
+  end
+end
diff --git a/lib/relaton/bib/item_data.rb b/lib/relaton/bib/item_data.rb
new file mode 100644
index 0000000..c4f21b3
--- /dev/null
+++ b/lib/relaton/bib/item_data.rb
@@ -0,0 +1,15 @@
+module Relaton
+  module Bib
+    # This class represents the data of a bibliographic item.
+    # It needed to keep data fot different types of representations (bibitem, bibdata ...).
+    # @TODO: remove this class when Lutaml Model will support transformation between different types of models.
+    class ItemData
+      attr_accessor :id, :type, :schema_version, :fetched, :formattedref, :title,
+                    :source, :docidentifier, :docnumber, :date, :contributor,
+                    :edition, :version, :note, :language, :locale, :script,
+                    :abstract, :status, :copyright, :relation, :series, :medium,
+                    :place, :price, :extent, :size, :accesslocation, :license,
+                    :classification, :keyword, :validity, :depiction, :ext
+    end
+  end
+end
diff --git a/lib/relaton/bib/keyword.rb b/lib/relaton/bib/keyword.rb
new file mode 100644
index 0000000..5a12311
--- /dev/null
+++ b/lib/relaton/bib/keyword.rb
@@ -0,0 +1,30 @@
+module Relaton
+  module Bib
+    class Keyword < Lutaml::Model::Serializable
+      class Vocabid < Lutaml::Model::Serializable
+        attribute :type, :string
+        attribute :uri, :string
+        attribute :code, :string
+        attribute :term, :string
+
+        xml do
+          map_attribute "type", to: :type
+          map_attribute "uri", to: :uri
+          map_element "code", to: :code
+          map_element "term", to: :term
+        end
+      end
+
+      attribute :vocab, LocalizedString, collection: true
+      attribute :taxon, LocalizedString, collection: (1..)
+      attribute :vocabid, Vocabid
+
+      xml do
+        root "keyword"
+        map_element "vocab", to: :vocab
+        map_element "taxon", to: :taxon
+        map_element "vocabid", to: :vocabid
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/locality.rb b/lib/relaton/bib/locality.rb
new file mode 100644
index 0000000..97aabb9
--- /dev/null
+++ b/lib/relaton/bib/locality.rb
@@ -0,0 +1,18 @@
+module Relaton
+  module Bib
+    class Locality < Lutaml::Model::Serializable
+      attribute :type, :string, pattern: %r{
+        section|clause|part|paragraph|chapter|page|title|line|whole|table|annex|
+        figure|note|list|example|volume|issue|time|anchor|locality:[a-zA-Z0-9_]+
+      }x
+      attribute :reference_from, :string
+      attribute :reference_to, :string
+
+      xml do
+        map_attribute "type", to: :type
+        map_element "referenceFrom", to: :reference_from
+        map_element "referenceTo", to: :reference_to
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/locality_stack.rb b/lib/relaton/bib/locality_stack.rb
new file mode 100644
index 0000000..e4fd05c
--- /dev/null
+++ b/lib/relaton/bib/locality_stack.rb
@@ -0,0 +1,14 @@
+module Relaton
+  module Bib
+    class LocalityStack < Lutaml::Model::Serializable
+      attribute :connective, :string, values: %w[and or from to]
+      attribute :locality, Locality, collection: true
+
+      xml do
+        root "localityStack"
+        map_attribute "connective", to: :connective
+        map_element "locality", to: :locality
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/localized_string.rb b/lib/relaton/bib/localized_string.rb
new file mode 100644
index 0000000..a4be2f4
--- /dev/null
+++ b/lib/relaton/bib/localized_string.rb
@@ -0,0 +1,27 @@
+module Relaton
+  module Bib
+    class LocalizedString < LocalizedStringAttrs
+      attribute :content, :string
+
+      xml do
+        map_content to: :content
+      end
+    end
+
+    class TypedLocalizedString < LocalizedString
+      attribute :type, :string
+
+      xml do
+        map_attribute "type", to: :type
+      end
+    end
+
+    class LocalizedMarkedUpString < LocalizedStringAttrs
+      attribute :content, :string
+
+      xml do
+        map_all to: :content
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/localized_string_attrs.rb b/lib/relaton/bib/localized_string_attrs.rb
new file mode 100644
index 0000000..87a3557
--- /dev/null
+++ b/lib/relaton/bib/localized_string_attrs.rb
@@ -0,0 +1,20 @@
+module Relaton
+  module Bib
+    class LocalizedStringAttrs < Lutaml::Model::Serializable
+      attribute :language, :string
+      attribute :locale, :string
+      attribute :script, :string
+
+      # def self.inherited(base)
+      #   super
+      #   base.class_eval do
+      xml do
+        map_attribute "language", to: :language
+        map_attribute "locale", to: :locale
+        map_attribute "script", to: :script
+      end
+      #   end
+      # end
+    end
+  end
+end
diff --git a/lib/relaton/bib/logo.rb b/lib/relaton/bib/logo.rb
new file mode 100644
index 0000000..7120bb4
--- /dev/null
+++ b/lib/relaton/bib/logo.rb
@@ -0,0 +1,12 @@
+module Relaton
+  module Bib
+    class Logo < Lutaml::Model::Serializable
+      attribute :image, Image
+
+      xml do
+        root "logo"
+        map_element "image", to: :image
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/medium.rb b/lib/relaton/bib/medium.rb
new file mode 100644
index 0000000..82b8aa6
--- /dev/null
+++ b/lib/relaton/bib/medium.rb
@@ -0,0 +1,22 @@
+module Relaton
+  module Bib
+    class Medium < Lutaml::Model::Serializable
+      attribute :content, :string
+      attribute :genre, :string
+      attribute :form, :string
+      attribute :carrier, :string
+      attribute :size, :string
+      attribute :scale, :string
+
+      xml do
+        root "medium"
+        map_element "content", to: :content
+        map_element "genre", to: :genre
+        map_element "form", to: :form
+        map_element "carrier", to: :carrier
+        map_element "size", to: :size
+        map_element "scale", to: :scale
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/note.rb b/lib/relaton/bib/note.rb
new file mode 100644
index 0000000..515956d
--- /dev/null
+++ b/lib/relaton/bib/note.rb
@@ -0,0 +1,14 @@
+module Relaton
+  module Bib
+    class Note < LocalizedStringAttrs
+      attribute :type, :string
+      attribute :content, :string
+
+      xml do
+        root "note"
+        map_attribute "type", to: :type
+        map_all to: :content
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/organization.rb b/lib/relaton/bib/organization.rb
new file mode 100644
index 0000000..6b06f69
--- /dev/null
+++ b/lib/relaton/bib/organization.rb
@@ -0,0 +1,13 @@
+require_relative "organization_type"
+
+module Relaton
+  module Bib
+    class Organization < Lutaml::Model::Serializable
+      include OrganizationType
+
+      xml do
+        root "organization"
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/organization_type.rb b/lib/relaton/bib/organization_type.rb
new file mode 100644
index 0000000..72860c8
--- /dev/null
+++ b/lib/relaton/bib/organization_type.rb
@@ -0,0 +1,42 @@
+module Relaton
+  module Bib
+    module OrganizationType
+      class Identifier < Lutaml::Model::Serializable
+        attribute :type, :string
+        attribute :content, :string
+
+        xml do
+          root "identifier"
+          map_attribute "type", to: :type
+          map_content to: :content
+        end
+      end
+
+      def self.included(base) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
+        require_relative "subdivision"
+
+        base.instance_eval do
+          include Contact
+
+          attribute :name, TypedLocalizedString, collection: true
+          attribute :subdivision, Subdivision, collection: true
+          attribute :abbreviation, LocalizedString
+          attribute :identifier, Identifier, collection: true
+          attribute :logo, Logo
+
+          xml do
+            map_element "name", to: :name
+            map_element "subdivision", to: :subdivision
+            map_element "abbreviation", to: :abbreviation
+            map_element "identifier", to: :identifier
+            map_element "address", to: :address
+            map_element "phone", to: :phone
+            map_element "email", to: :email
+            map_element "uri", to: :uri
+            map_element "logo", to: :logo
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/person.rb b/lib/relaton/bib/person.rb
new file mode 100644
index 0000000..75a7194
--- /dev/null
+++ b/lib/relaton/bib/person.rb
@@ -0,0 +1,36 @@
+module Relaton
+  module Bib
+    class Person < Lutaml::Model::Serializable
+      class Identifier < Lutaml::Model::Serializable
+        attribute :type, :string
+        attribute :content, :string
+
+        xml do
+          root "identifier"
+          map_attribute "type", to: :type
+          map_content to: :content
+        end
+      end
+
+      include Contact
+
+      attribute :name, FullName
+      attribute :credential, :string, collection: true
+      attribute :affiliation, Affiliation, collection: true
+      attribute :identifier, Identifier, collection: true
+
+      xml do
+        root "person"
+
+        map_element "name", to: :name
+        map_element "credential", to: :credential
+        map_element "affiliation", to: :affiliation
+        map_element "identifier", to: :identifier
+        map_element "address", to: :address
+        map_element "phone", to: :phone
+        map_element "email", to: :email
+        map_element "uri", to: :uri
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/phone.rb b/lib/relaton/bib/phone.rb
new file mode 100644
index 0000000..8f932c6
--- /dev/null
+++ b/lib/relaton/bib/phone.rb
@@ -0,0 +1,14 @@
+module Relaton
+  module Bib
+    class Phone < Lutaml::Model::Serializable
+      attribute :type, :string
+      attribute :content, :string
+
+      xml do
+        root "phone"
+        map_attribute "type", to: :type
+        map_content to: :content
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/place.rb b/lib/relaton/bib/place.rb
new file mode 100644
index 0000000..fcdb3a8
--- /dev/null
+++ b/lib/relaton/bib/place.rb
@@ -0,0 +1,33 @@
+module Relaton
+  module Bib
+    class Place < Lutaml::Model::Serializable
+      class RegionType < Lutaml::Model::Serializable
+        attribute :iso, :string
+        attribute :recommended, :boolean
+        attribute :content, :string
+
+        xml do
+          root "region"
+          map_attribute "iso", to: :iso
+          map_attribute "recommended", to: :recommended
+          map_content to: :content
+        end
+      end
+
+      attribute :city, :string
+      attribute :region, RegionType, collection: true
+      attribute :country, RegionType, collection: true
+      attribute :formatted_place, :string
+      attribute :uri, Uri
+
+      xml do
+        root "place"
+        map_element "city", to: :city
+        map_element "region", to: :region
+        map_element "country", to: :country
+        map_element "formattedPlace", to: :formatted_place
+        map_element "uri", to: :uri
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/price.rb b/lib/relaton/bib/price.rb
new file mode 100644
index 0000000..8f6a8d8
--- /dev/null
+++ b/lib/relaton/bib/price.rb
@@ -0,0 +1,14 @@
+module Relaton
+  module Bib
+    class Price < Lutaml::Model::Serializable
+      attribute :currency, :string
+      attribute :content, :string
+
+      xml do
+        root "price"
+        map_attribute "currency", to: :currency
+        map_content to: :content
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/relation.rb b/lib/relaton/bib/relation.rb
new file mode 100644
index 0000000..3683025
--- /dev/null
+++ b/lib/relaton/bib/relation.rb
@@ -0,0 +1,31 @@
+require_relative "item_base"
+
+module Relaton
+  module Bib
+    class Relation
+      attribute :type, :string
+      attribute :description, LocalizedMarkedUpString
+      attribute :bibitem, ItemBase
+      choice(min: 1, max: 1) do
+        attribute :locality, Locality, collection: true
+        attribute :locality_stack, LocalityStack, collection: true
+      end
+      choice(min: 1, max: 1) do
+        attribute :source_locality, Locality, collection: true
+        attribute :source_locality_stack, SourceLocalityStack, collection: true
+      end
+
+      xml do
+        root "relation"
+
+        map_attribute "type", to: :type
+        map_element "description", to: :description
+        map_element "bibitem", to: :bibitem
+        map_element "locality", to: :locality
+        map_element "localityStack", to: :locality_stack
+        map_element "sourceLocality", to: :source_locality
+        map_element "sourceLocalityStack", to: :source_locality_stack
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/role.rb b/lib/relaton/bib/role.rb
new file mode 100644
index 0000000..c051245
--- /dev/null
+++ b/lib/relaton/bib/role.rb
@@ -0,0 +1,17 @@
+module Relaton
+  module Bib
+    class Role < Lutaml::Model::Serializable
+      attribute :type, :string, values: %w[
+        author performer publisher editor adapter translator distributor reazer
+        owner authorizer enabler subject
+      ]
+      attribute :description, LocalizedMarkedUpString, collection: true
+
+      xml do
+        root "role"
+        map_attribute "type", to: :type
+        map_element "description", to: :description
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/series.rb b/lib/relaton/bib/series.rb
new file mode 100644
index 0000000..11b3dac
--- /dev/null
+++ b/lib/relaton/bib/series.rb
@@ -0,0 +1,32 @@
+module Relaton
+  module Bib
+    class Series < Lutaml::Model::Serializable
+      attribute :type, :string, values: %w[main alt]
+      attribute :formattedref, :string, raw: true
+      attribute :title, Title, collection: (1..)
+      attribute :place, Place
+      attribute :organization, :string
+      attribute :abbreviation, LocalizedString
+      attribute :from, :date
+      attribute :to, :date
+      attribute :number, :string
+      attribute :partnumber, :string
+      attribute :run, :string
+
+      xml do
+        root "series"
+        map_attribute "type", to: :type
+        map_element "formattedref", to: :formattedref
+        map_element "title", to: :title
+        map_element "place", to: :place
+        map_element "organization", to: :organization
+        map_element "abbreviation", to: :abbreviation
+        map_element "from", to: :from
+        map_element "to", to: :to
+        map_element "number", to: :number
+        map_element "partnumber", to: :partnumber
+        map_element "run", to: :run
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/size.rb b/lib/relaton/bib/size.rb
new file mode 100644
index 0000000..71caaab
--- /dev/null
+++ b/lib/relaton/bib/size.rb
@@ -0,0 +1,23 @@
+module Relaton
+  module Bib
+    class Size < Lutaml::Model::Serializable
+      class Value < Lutaml::Model::Serializable
+        attribute :type, :string
+        attribute :content, :string
+
+        xml do
+          root "value"
+          map_attribute "type", to: :type
+          map_content to: :content
+        end
+      end
+
+      attribute :value, Value, collection: (1..)
+
+      xml do
+        root "size"
+        map_element "value", to: :value
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/source_locality_stack.rb b/lib/relaton/bib/source_locality_stack.rb
new file mode 100644
index 0000000..6205e10
--- /dev/null
+++ b/lib/relaton/bib/source_locality_stack.rb
@@ -0,0 +1,14 @@
+module Relaton
+  module Bib
+    class SourceLocalityStack < Lutaml::Model::Serializable
+      attribute :connective, :string, values: %w[and or from to]
+      attribute :source_locality, Locality, collection: true
+
+      xml do
+        root "sourceLocalityStack"
+        map_attribute "connective", to: :connective
+        map_element "sourceLocality", to: :source_locality
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/status.rb b/lib/relaton/bib/status.rb
new file mode 100644
index 0000000..91f6c46
--- /dev/null
+++ b/lib/relaton/bib/status.rb
@@ -0,0 +1,27 @@
+module Relaton
+  module Bib
+    class Status < Lutaml::Model::Serializable
+      class Stage < Lutaml::Model::Serializable
+        attribute :abbreviation, :string
+        attribute :content, :string
+
+        xml do
+          root "stage"
+          map_attribute "abbreviation", to: :abbreviation
+          map_content to: :content
+        end
+      end
+
+      attribute :stage, Stage
+      attribute :substage, Stage
+      attribute :iteration, :string
+
+      xml do
+        root "status"
+        map_element "stage", to: :stage
+        map_element "substage", to: :substage
+        map_element "iteration", to: :iteration
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/structured_identifier.rb b/lib/relaton/bib/structured_identifier.rb
new file mode 100644
index 0000000..ed1f546
--- /dev/null
+++ b/lib/relaton/bib/structured_identifier.rb
@@ -0,0 +1,36 @@
+module Relaton
+  module Bib
+    class StructuredIdentifier < Lutaml::Model::Serializable
+      attribute :type, :string
+      attribute :agency, :string, collection: (1..)
+      attribute :klass, :string
+      attribute :docnumber, :string
+      attribute :partnumber, :string
+      attribute :edition, :string
+      attribute :version, :string
+      attribute :supplementtype, :string
+      attribute :supplementnumber, :string
+      attribute :amendment, :string
+      attribute :corrigendum, :string
+      attribute :language, :string
+      attribute :year, :string
+
+      xml do
+        root "structuredidentifier"
+        map_attribute "type", to: :type
+        map_element "agency", to: :agency
+        map_element "class", to: :klass
+        map_element "docnumber", to: :docnumber
+        map_element "partnumber", to: :partnumber
+        map_element "edition", to: :edition
+        map_element "version", to: :version
+        map_element "supplementtype", to: :supplementtype
+        map_element "supplementnumber", to: :supplementnumber
+        map_element "amendment", to: :amendment
+        map_element "corrigendum", to: :corrigendum
+        map_element "language", to: :language
+        map_element "year", to: :year
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/subdivision.rb b/lib/relaton/bib/subdivision.rb
new file mode 100644
index 0000000..7535d25
--- /dev/null
+++ b/lib/relaton/bib/subdivision.rb
@@ -0,0 +1,14 @@
+module Relaton
+  module Bib
+    class Subdivision < Lutaml::Model::Serializable
+      include OrganizationType
+
+      attribute :type, :string
+
+      xml do
+        root "subdivision"
+        map_attribute "type", to: :type
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/technical_committee.rb b/lib/relaton/bib/technical_committee.rb
new file mode 100644
index 0000000..4488117
--- /dev/null
+++ b/lib/relaton/bib/technical_committee.rb
@@ -0,0 +1,14 @@
+require_relative "workgroup"
+
+module Relaton
+  module Bib
+    class TechnicalCommittee < Lutaml::Model::Serializable
+      attribute :workgroup, WorkGroup
+
+      xml do
+        root "technical-committee"
+        map_content to: :workgroup
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/title.rb b/lib/relaton/bib/title.rb
new file mode 100644
index 0000000..f86f9fe
--- /dev/null
+++ b/lib/relaton/bib/title.rb
@@ -0,0 +1,13 @@
+module Relaton
+  module Bib
+    class Title < LocalizedMarkedUpString
+      attribute :type, :string
+      attribute :format, :string # @DEPRECATED
+
+      xml do
+        map_attribute "type", to: :type
+        map_attribute "format", to: :format
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/uri.rb b/lib/relaton/bib/uri.rb
new file mode 100644
index 0000000..ea48e56
--- /dev/null
+++ b/lib/relaton/bib/uri.rb
@@ -0,0 +1,13 @@
+module Relaton
+  module Bib
+    class Uri < LocalizedStringAttrs
+      attribute :type, :string
+      attribute :content, :string
+
+      xml do
+        map_attribute "type", to: :type
+        map_content to: :content
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/util.rb b/lib/relaton/bib/util.rb
new file mode 100644
index 0000000..abd7048
--- /dev/null
+++ b/lib/relaton/bib/util.rb
@@ -0,0 +1,18 @@
+module Relaton
+  module Bib
+    module Util
+      extend self
+
+      PROGNAME = "relaton-bib".freeze
+
+      def method_missing(method_name, msg = nil, prog = nil, **opts, &block)
+        prog ||= self::PROGNAME
+        Relaton.logger_pool.send method_name, msg, prog, **opts, &block
+      end
+
+      def respond_to_missing?(method_name, include_private = false)
+        Relaton.logger_pool.respond_to?(method_name) || super
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/validity.rb b/lib/relaton/bib/validity.rb
new file mode 100644
index 0000000..324da81
--- /dev/null
+++ b/lib/relaton/bib/validity.rb
@@ -0,0 +1,16 @@
+module Relaton
+  module Bib
+    class Validity < Lutaml::Model::Serializable
+      attribute :begins, :date
+      attribute :ends, :date
+      attribute :revision, :date
+
+      xml do
+        root "validity"
+        map_element "validityBegins", to: :begins
+        map_element "validityEnds", to: :ends
+        map_element "revision", to: :revision
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/version.rb b/lib/relaton/bib/version.rb
new file mode 100644
index 0000000..549cdc2
--- /dev/null
+++ b/lib/relaton/bib/version.rb
@@ -0,0 +1,14 @@
+module Relaton
+  module Bib
+    class Version < Lutaml::Model::Serializable
+      attribute :revision_date, :date
+      attribute :draft, :string
+
+      xml do
+        root "version"
+        map_element "revision-date", to: :revision_date
+        map_element "draft", to: :draft
+      end
+    end
+  end
+end
diff --git a/lib/relaton/bib/workgroup.rb b/lib/relaton/bib/workgroup.rb
new file mode 100644
index 0000000..f31f538
--- /dev/null
+++ b/lib/relaton/bib/workgroup.rb
@@ -0,0 +1,20 @@
+module Relaton
+  module Bib
+    class WorkGroup < Lutaml::Model::Serializable
+      attribute :number, :string
+      attribute :type, :string
+      attribute :identifier, :string
+      attribute :prefix, :string
+      attribute :content, :string
+
+      xml do
+        root "workgroup"
+        map_attribute "number", to: :number
+        map_attribute "type", to: :type
+        map_attribute "identifier", to: :identifier
+        map_attribute "prefix", to: :prefix
+        map_content to: :content
+      end
+    end
+  end
+end
diff --git a/lib/relaton_bib/bibtex_parser.rb b/lib/relaton/bibtex_parser.rb
similarity index 82%
rename from lib/relaton_bib/bibtex_parser.rb
rename to lib/relaton/bibtex_parser.rb
index 6159265..6d9ee63 100644
--- a/lib/relaton_bib/bibtex_parser.rb
+++ b/lib/relaton/bibtex_parser.rb
@@ -1,15 +1,12 @@
-require "bibtex"
-require "iso639"
-
-module RelatonBib
-  # @todo: move this class to the RelatonBib::Bibtex module
+module Relaton
+  # @todo: move this class to the Relaton::Bib::Bibtex module
   class BibtexParser
     class << self
       # @param bibtex [String]
-      # @return [Hash{String=>RelatonBib::BibliographicItem}]
+      # @return [Hash{String=>Relaton::Bib::Item}]
       def from_bibtex(bibtex) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
         BibTeX.parse(bibtex).reduce({}) do |h, bt|
-          h[bt.key] = BibliographicItem.new(
+          h[bt.key] = Item.new(
             id: bt.key,
             docid: fetch_docid(bt),
             fetched: fetch_fetched(bt),
@@ -35,12 +32,12 @@ def from_bibtex(bibtex) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
       private
 
       # @param bibtex [BibTeX::Entry]
-      # @return [Array<RelatonBib::DocumentIdentifier>]
+      # @return [Array<Relaton::Bib::Docidentifier>]
       def fetch_docid(bibtex) # rubocop:disable Metrics/AbcSize
         docid = []
-        docid << DocumentIdentifier.new(id: bibtex.isbn.to_s, type: "isbn") if bibtex["isbn"]
-        docid << DocumentIdentifier.new(id: bibtex.lccn.to_s, type: "lccn") if bibtex["lccn"]
-        docid << DocumentIdentifier.new(id: bibtex.issn.to_s, type: "issn") if bibtex["issn"]
+        docid << Docidentifier.new(id: bibtex.isbn.to_s, type: "isbn") if bibtex["isbn"]
+        docid << Docidentifier.new(id: bibtex.lccn.to_s, type: "lccn") if bibtex["lccn"]
+        docid << Docidentifier.new(id: bibtex.issn.to_s, type: "issn") if bibtex["issn"]
         docid
       end
 
@@ -68,12 +65,12 @@ def fetch_place(bibtex)
       end
 
       # @param bibtex [BibTeX::Entry]
-      # @return [RelatonBib::TypedTitleStringCollection]
+      # @return [Relaton::Bib::TitleCollection]
       def fetch_title(bibtex)
         title = []
         title << { type: "main", content: bibtex.convert(:latex).title.to_s } if bibtex["title"]
         title << { type: "main", content: bibtex.convert(:latex).subtitle.to_s } if bibtex["subtitle"]
-        TypedTitleStringCollection.new title
+        TitleCollection.new title
       end
 
       # @param bibtex [BibTeX::Entry]
@@ -113,7 +110,7 @@ def fetch_org(org, type, desc = nil, &_)
       end
 
       # @param bibtex [BibTeX::Entry]
-      # @return [Array<RelatonBib::Person>]
+      # @return [Array<Relaton::Bib::Person>]
       def fetch_person(bibtex, role, &_) # rubocop:disable Metrics/AbcSize
         bibtex[role]&.each do |name|
           parts = name.split ", "
@@ -142,7 +139,7 @@ def fetch_date(bibtex)
       end
 
       # @param bibtex [BibTeX::Entry]
-      # @return [RelatonBib::BiblioNoteCollection]
+      # @return [Relaton::Bib::BiblioNoteCollection]
       def fetch_note(bibtex) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
         bibtex.select do |k, _v|
           %i[annote howpublished comment note content].include? k
@@ -163,9 +160,9 @@ def fetch_note(bibtex) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticCompl
       def fetch_relation(bibtex)
         return [] unless bibtex["booktitle"]
 
-        ttl = TypedTitleString.new(type: "main", content: bibtex.booktitle.to_s)
-        title = TypedTitleStringCollection.new [ttl]
-        [{ type: "partOf", bibitem: BibliographicItem.new(title: title) }]
+        ttl = Title.new(type: "main", content: bibtex.booktitle.to_s)
+        title = TitleCollection.new [ttl]
+        [{ type: "partOf", bibitem: Item.new(title: title) }]
       end
 
       # @param bibtex [BibTeX::Entry]
@@ -188,31 +185,31 @@ def fetch_extent(bibtex) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
       end
 
       # @param bibtex [BibTeX::Entry]
-      # @return [Array<RelatonBib::Series>]
+      # @return [Array<Relaton::Bib::Series>]
       def fetch_series(bibtex) # rubocop:disable Metrics/MethodLength
         series = []
         if bibtex["journal"]
           series << Series.new(
             type: "journal",
-            title: TypedTitleString.new(content: bibtex.journal.to_s),
-            number: bibtex["number"]&.to_s
+            title: Title.new(content: bibtex.journal.to_s),
+            number: bibtex["number"]&.to_s,
           )
         end
 
         if bibtex["series"]
-          title = TypedTitleString.new content: bibtex.series.to_s
+          title = Title.new content: bibtex.series.to_s
           series << Series.new(title: title)
         end
         series
       end
 
       # @param bibtex [BibTeX::Entry]
-      # @return [Array<RelatonBib::TypedUri>]
+      # @return [Array<Relaton::Bib::Bsource>]
       def fetch_link(bibtex) # rubocop:disable Metrics/AbcSize
         link = []
-        link << TypedUri.new(type: "src", content: bibtex.url.to_s) if bibtex["url"]
-        link << TypedUri.new(type: "doi", content: bibtex.doi.to_s) if bibtex["doi"]
-        link << TypedUri.new(type: "file", content: bibtex.file2.to_s) if bibtex["file2"]
+        link << Bsource.new(type: "src", content: bibtex.url.to_s) if bibtex["url"]
+        link << Bsource.new(type: "doi", content: bibtex.doi.to_s) if bibtex["doi"]
+        link << Bsource.new(type: "file", content: bibtex.file2.to_s) if bibtex["file2"]
         link
       end
 
@@ -225,7 +222,7 @@ def fetch_language(bibtex)
       end
 
       # @param bibtex [BibTeX::Entry]
-      # @return [RelatonBib::Classification, nil]
+      # @return [Relaton::Bib::Classification, nil]
       def fetch_classification(bibtex)
         cls = []
         cls << Classification.new(type: "type", value: bibtex["type"].to_s) if bibtex["type"]
diff --git a/lib/relaton_bib/bibxml_parser.rb b/lib/relaton/bibxml_parser.rb
similarity index 83%
rename from lib/relaton_bib/bibxml_parser.rb
rename to lib/relaton/bibxml_parser.rb
index 4713593..848c008 100644
--- a/lib/relaton_bib/bibxml_parser.rb
+++ b/lib/relaton/bibxml_parser.rb
@@ -1,4 +1,4 @@
-module RelatonBib
+module Relaton
   module BibXMLParser
     # SeriesInfo what should be saved as docidentifiers in the Relaton model.
     SERIESINFONAMES = ["DOI"].freeze
@@ -31,7 +31,7 @@ def parse(bibxml, url: nil, is_relation: false, ver: nil)
     # @param is_relation [Boolean] don't add fetched date for relation if true
     # @param url [String, nil]
     # @param ver [String, nil] Internet Draft version
-    # @return [RelatonBib::BibliographicItem]
+    # @return [Relaton::Bib::Item]
     def fetch_rfc(reference, is_relation: false, url: nil, ver: nil) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
       return unless reference
 
@@ -64,10 +64,10 @@ def docnumber(reference)
     end
 
     # @param attrs [Hash]
-    # @return [RelatonBib::BibliographicItem]
+    # @return [Relaton::Bib::Item]
     def bib_item(**attrs)
       # attrs[:place] = ["Fremont, CA"]
-      BibliographicItem.new(**attrs)
+      Item.new(**attrs)
     end
 
     # @param reference [Nokogiri::XML::Element]
@@ -82,7 +82,7 @@ def language(reference)
     # @param reference [Nokogiri::XML::Element]
     # @param ver [String, nil] Internet Draft version
     #
-    # @return [Array<RelatonBib::DocumentIdentifier>]
+    # @return [Array<Relaton::Bib::Docidentifier>]
     #
     def docids(reference, ver) # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/AbcSize
       ret = []
@@ -91,7 +91,7 @@ def docids(reference, ver) # rubocop:disable Metrics/MethodLength,Metrics/Cyclom
       if si
         id = si[:value]
         id.sub!(/(?<=-)\d{2}$/, ver) if ver
-        ret << DocumentIdentifier.new(type: "Internet-Draft", id: id, primary: true)
+        ret << Bib::Docidentifier.new(type: "Internet-Draft", id: id, primary: true)
       else
         id = reference[:anchor] || reference[:docName] || reference[:number]
         ret << create_docid(id, ver) if id
@@ -106,7 +106,7 @@ def docids(reference, ver) # rubocop:disable Metrics/MethodLength,Metrics/Cyclom
                     reference[atr]
                   end
           type = pubid_type id
-          ret << DocumentIdentifier.new(id: atrid, type: type, scope: atr)
+          ret << Bib::Docidentifier.new(id: atrid, type: type, scope: atr)
         end
       end
 
@@ -115,7 +115,7 @@ def docids(reference, ver) # rubocop:disable Metrics/MethodLength,Metrics/Cyclom
 
         id = si[:value]
         # id.sub!(/(?<=-)\d{2}$/, ver) if ver && si[:name] == "Internet-Draft"
-        DocumentIdentifier.new(id: id, type: si[:name])
+        Bib::Docidentifier.new(id: id, type: si[:name])
       end.compact
     end
 
@@ -132,7 +132,7 @@ def create_docid(id, ver) # rubocop:disable Metrics/MethodLength
         pid = pref ? "#{pref} #{num}" : id
         type = pubid_type id
       end
-      DocumentIdentifier.new(type: type, id: pid, primary: true)
+      Docidentifier.new(type: type, id: pid, primary: true)
     end
 
     def id_to_pref_num(id)
@@ -155,7 +155,7 @@ def pubid_type(id)
     # extract status
     # @param reference [Nokogiri::XML::Element]
     #
-    # @return [RelatonBib::DocumentStatus]
+    # @return [Relaton::Bib::DocumentStatus]
     #
     def status(reference)
       st = reference.at("./seriesinfo[@status]")
@@ -188,26 +188,24 @@ def titles(reference)
     end
 
     # @param reference [Nokogiri::XML::Element]
-    # @return [RelatonBib::FormattedRef, nil]
+    # @return [Relaton::Bib::Formattedref, nil]
     def formattedref(reference)
       return if reference.at "./front/title"
 
-      cont = (reference[:anchor] || reference[:docName] || reference[:number])
+      cont = reference[:anchor] || reference[:docName] || reference[:number]
       if cont
-        FormattedRef.new(
+        Formattedref.new(
           content: cont, language: language(reference), script: "Latn",
         )
       end
     end
 
     # @param reference [Nokogiri::XML::Element]
-    # @return [Array<RelatonBib::FormattedString>]
+    # @return [Array<Relaton::Bib::FormattedString>]
     def abstracts(ref)
       ref.xpath("./front/abstract").map do |a|
-        c = a.inner_html.gsub(/\s*(<\/?)t(>)\s*/, '\1p\2')
-          .gsub(/[\t\n]/, " ").squeeze " "
-        FormattedString.new(content: c, language: language(ref), script: "Latn",
-                            format: "text/html")
+        c = a.inner_html.gsub(/\s*(<\/?)t(>)\s*/, '\1p\2').gsub(/[\t\n]/, " ").squeeze " "
+        Bib::FormattedString.new(content: c, language: language(ref), script: "Latn", format: "text/html")
       end
     end
 
@@ -225,17 +223,16 @@ def contributors(reference)
 
     # @param author [Nokogiri::XML::Element]
     # @param lang [String]
-    # @return [RelatonBib::Person, nil]
+    # @return [Relaton::Bib::Person, nil]
     def person(author, lang)
       return unless author[:fullname] || author[:surname]
 
       name = full_name(author[:fullname], author[:surname], author[:initials], lang)
-      Person.new(name: name, affiliation: affiliation(author),
-                 contact: contacts(author.at("./address")))
+      Bib::Person.new(name: name, affiliation: affiliation(author), contact: contacts(author.at("./address")))
     end
 
     # @param contrib [Nokogiri::XML::Element]
-    # @return [RelatonBib::Organization, nil]
+    # @return [Relaton::Bib::Organization, nil]
     def organization(contrib)
       org = contrib.at("./organization")
       return unless org
@@ -251,10 +248,10 @@ def organization(contrib)
     # @param sname [String] surname
     # @param inits [String] initials
     # @param lang [String] language
-    # @return [RelatonBib::FullName]
+    # @return [Relaton::Bib::FullName]
     def full_name(fname, sname, inits, lang)
       initials = localized_string(inits, lang) if inits
-      FullName.new(
+      Bib::FullName.new(
         completename: localized_string(fname, lang), initials: initials,
         forename: forename(inits, lang), surname: localized_string(sname, lang)
       )
@@ -266,43 +263,43 @@ def full_name(fname, sname, inits, lang)
     # @param [String] initials initials
     # @param [String] lang language
     #
-    # @return [Array<RelatonBib::Forename>] forenames
+    # @return [Array<Relaton::Bib::Forename>] forenames
     #
     def forename(initials, lang = nil, script = nil)
       return [] unless initials
 
       initials.split(/\.-?\s?|\s/).map do |i|
-        Forename.new(initial: i, language: lang, script: script)
+        Bib::Forename.new(initial: i, language: lang, script: script)
       end
     end
 
     # @param author [Nokogiri::XML::Element]
-    # @return [Array<RelatonBib::Affiliation>]
+    # @return [Array<Relaton::Bib::Affiliation>]
     def affiliation(author)
       o = author.at("./organization")
       return [] if o.nil? || o.text.empty?
 
       org = new_org o.text, o[:abbrev]
-      [Affiliation.new(organization: org)]
+      [Bib::Affiliation.new(organization: org)]
     end
 
     # @param name [String]
     # @param abbr [String, nil]
-    # @return [RelatonBib::Organization]
+    # @return [Relaton::Bib::Organization]
     def new_org(name, abbr = nil)
-      Organization.new name: name, abbreviation: abbr
+      Bib::Organization.new name: name, abbreviation: abbr
     end
 
     # @param content [String, nil]
     # @param lang [String, nil]
     # @param script [String, nil]
-    # @return [RelatonBib::LocalizedString, nil]
+    # @return [Relaton::Bib::LocalizedString, nil]
     def localized_string(content, lang, script = nil)
-      LocalizedString.new(content, lang, script) if content
+      Bib::LocalizedString.new(content: content, laguage: lang, script: script) if content
     end
 
     # @param postal [Nokogiri::XML::Element]
-    # @return [Array<RelatonBib::Address, RelatonBib::Phone>]
+    # @return [Array<Relaton::Bib::Address, Relaton::Bib::Phone>]
     def contacts(addr)
       conts = []
       return conts unless addr
@@ -316,10 +313,10 @@ def contacts(addr)
     end
 
     # @param postal [Nokogiri::XML::Element]
-    # @rerurn [RelatonBib::Address]
+    # @return [Relaton::Bib::Address]
     def address(postal) # rubocop:disable Metrics/CyclomaticComplexity
       street = [postal.at("./postalLine | ./street")&.text].compact
-      Address.new(
+      Bib::Address.new(
         street: street,
         city: postal.at("./city")&.text,
         postcode: postal.at("./code")&.text,
@@ -328,11 +325,11 @@ def address(postal) # rubocop:disable Metrics/CyclomaticComplexity
       )
     end
 
-    # @param conts [Array<RelatonBib::Address, RelatonBib::Contact>]
+    # @param conts [Array<Relaton::Bib::Address, Relaton::Bib::Contact>]
     # @param type [String] allowed "phone", "email" or "uri"
     # @param value [String]
     def add_contact(conts, type, value)
-      conts << Contact.new(type: type, value: value.text) if value
+      conts << Bib::Contact.new(type: type, value: value.text) if value
     end
 
     # @param author [Nokogiri::XML::Document]
@@ -353,7 +350,7 @@ def relations(reference)
     # Extract date from reference.
     #
     # @param reference [Nokogiri::XML::Element]
-    # @return [Array<RelatonBib::BibliographicDate>] published data.
+    # @return [Array<Relaton::Bib::Bdate>] published data.
     #
     def dates(reference) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
       date = reference.at "./front/date"
@@ -363,23 +360,23 @@ def dates(reference) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/Abc
       d += "-#{month(date[:month])}" if date[:month] && !date[:month].empty?
       d += "-#{date[:day]}" if date[:day]
       # date = Time.parse(d).strftime "%Y-%m-%d"
-      [BibliographicDate.new(type: "published", on: d)]
+      [Bib::Date.new(type: "published", on: d)]
     end
 
     # @param reference [Nokogiri::XML::Element]
-    # @return [RelatonBib::EditorialGroup, nil]
+    # @return [Relaton::Bib::EditorialGroup, nil]
     def editorialgroup(reference)
       tc = reference.xpath("./front/workgroup").map do |ed|
-        wg = WorkGroup.new name: ed.text
+        wg = Bib::WorkGroup.new name: ed.text
         committee wg
       end
       EditorialGroup.new tc if tc.any?
     end
 
-    # @param [RelatonBib::WorkGroup]
-    # @return [RelatonBib::TechnicalCommittee]
+    # @param [Relaton::Bib::WorkGroup]
+    # @return [Relaton::Bib::TechnicalCommittee]
     def committee(wgr)
-      TechnicalCommittee.new wgr
+      Bib::TechnicalCommittee.new wgr
     end
 
     def month(mon)
@@ -393,13 +390,13 @@ def month(mon)
     # Extract series form reference
     # @param reference [Nokogiri::XML::Element]
     #
-    # @return [Array<RelatonBib::Series>]
+    # @return [Array<Relaton::Bib::Series>]
     #
     def series(reference)
       reference.xpath("./seriesInfo", "./front/seriesInfo").map do |si|
         next if SERIESINFONAMES.include?(si[:name]) || si[:stream] || si[:status]
 
-        t = TypedTitleString.new(
+        t = Title.new(
           content: si[:name], language: language(reference), script: "Latn",
         )
         Series.new(title: t, number: si[:value], type: "main")
diff --git a/lib/relaton_bib/deep_dup.rb b/lib/relaton/deep_dup.rb
similarity index 100%
rename from lib/relaton_bib/deep_dup.rb
rename to lib/relaton/deep_dup.rb
diff --git a/lib/relaton_bib/renderer/bibtex_builder.rb b/lib/relaton/renderer/bibtex_builder.rb
similarity index 86%
rename from lib/relaton_bib/renderer/bibtex_builder.rb
rename to lib/relaton/renderer/bibtex_builder.rb
index 4581395..309fa35 100644
--- a/lib/relaton_bib/renderer/bibtex_builder.rb
+++ b/lib/relaton/renderer/bibtex_builder.rb
@@ -15,7 +15,7 @@ def to_s(options = {}) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComp
   end
 end
 
-module RelatonBib
+module Relaton
   # BibTeX builder.
   module Renderer
     class BibtexBuilder
@@ -28,7 +28,7 @@ class BibtexBuilder
       #
       # Build BibTeX bibliography.
       #
-      # @param bib [RelatonBib::BibliographicItem]
+      # @param bib [Relaton::Bib::Item]
       # @param bibtex [BibTeX::Bibliography, nil] BibTeX bibliography
       #
       # @return [BibTeX::Bibliography] BibTeX bibliography
@@ -40,7 +40,7 @@ def self.build(bib, bibtex = nil)
       #
       # Initialize BibTeX builder.
       #
-      # @param bib [RelatonBib::BibliographicItem]
+      # @param bib [Relaton::Bib::Item]
       def initialize(bib)
         @bib = bib
       end
@@ -122,7 +122,7 @@ def add_editor
       #
       def add_author_editor(type)
         contribs = @bib.contributor.select do |c|
-          c.entity.is_a?(Person) && c.role.any? { |e| e.type == type }
+          c.entity.is_a?(Bib::Person) && c.role.any? { |e| e.type == type }
         end.map &:entity
 
         return unless contribs.any?
@@ -133,7 +133,7 @@ def add_author_editor(type)
       #
       # Concatenate names of contributors
       #
-      # @param [Array<RelatonBib::Person>] contribs contributors
+      # @param [Array<Relaton::Bib::Person>] contribs contributors
       #
       # @return [String] concatenated names
       #
@@ -150,13 +150,13 @@ def concat_names(contribs)
       #
       # Add series to BibTeX item
       #
-      def add_series
+      def add_series # rubocop:disable Metrics/AbcSize
         @bib.series.each do |s|
           case s.type
           when "journal"
-            @item.journal = s.title.title
+            @item.journal = s.title.first.content
             @item.number = s.number if s.number
-          when nil then @item.series = s.title.title
+          when nil then @item.series = s.title.first.content
           end
         end
       end
@@ -169,7 +169,7 @@ def add_number
 
         did = @bib.docidentifier.detect { |i| i.primary == true }
         did ||= @bib.docidentifier.first
-        @item.number = did.id if did
+        @item.number = did.content if did
       end
 
       #
@@ -219,7 +219,7 @@ def add_address # rubocop:disable Metrics/AbcSize
         return unless @bib.place.any?
 
         reg = @bib.place[0].region[0].name if @bib.place[0].region.any?
-        addr = [@bib.place[0].name, @bib.place[0].city, reg]
+        addr = [@bib.place[0].formatted_place, @bib.place[0].city, reg]
         @item.address = addr.compact.join(", ")
       end
 
@@ -227,7 +227,7 @@ def add_address # rubocop:disable Metrics/AbcSize
       # Add note to BibTeX item
       #
       def add_note # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
-        @bib.biblionote.each do |n|
+        @bib.note.each do |n|
           case n.type
           when "annote" then @item.annote = n.content
           when "howpublished" then @item.howpublished = n.content
@@ -245,7 +245,7 @@ def add_relation
         rel = @bib.relation.detect { |r| r.type == "partOf" }
         if rel
           title_main = rel.bibitem.title.detect { |t| t.type == "main" }
-          @item.booktitle = title_main.title.content
+          @item.booktitle = title_main.content
         end
       end
 
@@ -262,8 +262,8 @@ def add_extent
       def add_classification
         @bib.classification.each do |c|
           case c.type
-          when "type" then @item["type"] = c.value
-          when "mendeley" then @item["mendeley-tags"] = c.value
+          when "type" then @item["type"] = c.content
+          when "mendeley" then @item["mendeley-tags"] = c.content
           end
         end
       end
@@ -272,7 +272,9 @@ def add_classification
       # Add keywords to BibTeX item
       #
       def add_keyword
-        @item.keywords = @bib.keyword.map(&:content).join(", ") if @bib.keyword.any?
+        if @bib.keyword.any?
+          @item.keywords = @bib.keyword.reduce([]) { |m, kw| m + kw.taxon.map(&:content) }.join(", ")
+        end
       end
 
       #
@@ -281,9 +283,9 @@ def add_keyword
       def add_docidentifier
         @bib.docidentifier.each do |i|
           case i.type
-          when "isbn" then @item.isbn = i.id
-          when "lccn" then @item.lccn = i.id
-          when "issn" then @item.issn = i.id
+          when "isbn" then @item.isbn = i.content
+          when "lccn" then @item.lccn = i.content
+          when "issn" then @item.issn = i.content
           end
         end
       end
@@ -299,12 +301,12 @@ def add_timestamp
       # Add link to BibTeX item
       #
       def add_link
-        @bib.link.each do |l|
+        @bib.source.each do |l|
           case l.type&.downcase
           when "doi" then @item.doi = l.content
           when "file" then @item.file2 = l.content
           when "src" then @item.url = l.content
-          end
+          end.to_s
         end
       end
     end
diff --git a/lib/relaton_bib/renderer/bibxml.rb b/lib/relaton/renderer/bibxml.rb
similarity index 66%
rename from lib/relaton_bib/renderer/bibxml.rb
rename to lib/relaton/renderer/bibxml.rb
index 10ae959..a142fe8 100644
--- a/lib/relaton_bib/renderer/bibxml.rb
+++ b/lib/relaton/renderer/bibxml.rb
@@ -1,4 +1,4 @@
-module RelatonBib
+module Relaton
   module Renderer
     class BibXML
       def initialize(bib)
@@ -30,10 +30,10 @@ def render(builder: nil, include_keywords: true)
       # @param [Boolean] include_bibdata
       #
       def render_bibxml(builder, include_keywords) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
-        target = @bib.link.detect { |l| l.type.casecmp("src").zero? } ||
-          @bib.link.detect { |l| l.type.casecmp("doi").zero? }
-        bxml = if @bib.docnumber&.match(/^BCP/) || (@bib.docidentifier.detect(&:primary)&.id ||
-                    @bib.docidentifier[0].id).include?("BCP")
+        target = @bib.source.detect { |l| l.type.casecmp("src").zero? } ||
+          @bib.source.detect { |l| l.type.casecmp("doi").zero? }
+        bxml = if @bib.docnumber&.match(/^BCP/) ||
+            (@bib.docidentifier.detect(&:primary) || @bib.docidentifier[0])&.content&.include?("BCP")
                  render_bibxml_refgroup(builder, include_keywords)
                else
                  render_bibxml_ref(builder, include_keywords)
@@ -64,10 +64,10 @@ def render_bibxml_refgroup(builder, include_keywords)
       def render_bibxml_ref(builder, include_keywords) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
         builder.reference(**ref_attrs) do |xml|
           if @bib.title.any? || @bib.contributor.any? || @bib.date.any? || @bib.abstract.any? ||
-              @bib.editorialgroup&.technical_committee&.any? ||
+              @bib.ext&.editorialgroup&.technical_committee&.any? ||
               (include_keywords && @bib.keyword.any?)
             xml.front do
-              xml.title @bib.title[0].title.content if @bib.title.any?
+              xml.title @bib.title[0].content if @bib.title.any?
               render_authors xml
               render_date xml
               render_workgroup xml
@@ -90,13 +90,13 @@ def ref_attrs # rubocop:disable Metrics/AbcSize
         attrs = @bib.docidentifier.each_with_object({}) do |di, h|
           next unless discopes.include?(di.scope)
 
-          h[di.scope.to_sym] = di.id
+          h[di.scope.to_sym] = di.content
         end
         return attrs if attrs.any?
 
         @bib.docidentifier.first&.tap do |di|
-          anchor = di.type == "IANA" ? di.id.split[1..].join(" ").upcase : di.id
-          return { anchor: anchor.gsub(" ", ".") }
+          anchor = di.type == "IANA" ? di.content.split[1..].join(" ").upcase : di.content
+          return { anchor: anchor.tr(" ", ".") }
         end
       end
 
@@ -109,10 +109,10 @@ def render_authors(builder) # rubocop:disable Metrics/AbcSize
         @bib.contributor.each do |c|
           builder.author do |xml|
             xml.parent[:role] = "editor" if c.role.detect { |r| r.type == "editor" }
-            if c.entity.is_a?(Person) then render_person xml, c.entity
+            if c.entity.is_a?(Bib::Person) then render_person xml, c.entity
             else render_organization xml, c.entity, c.role
             end
-            render_address xml, c
+            render_address xml, c.entity
           end
         end
       end
@@ -121,53 +121,82 @@ def render_authors(builder) # rubocop:disable Metrics/AbcSize
       # Render address
       #
       # @param [Nokogiri::XML::Builder] builder xml builder
-      # @param [RelatonBib::ContributionInfo] contrib contributor
-      #
-      def render_address(builder, contrib) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
-        address, contact = address_contact contrib.entity.contact
-        if address || contact.any?
-          builder.address do |xml|
-            # address = contrib.entity.contact.detect { |cn| cn.is_a? Address }
-            if address
-              xml.postal do
-                xml.city address.city if address.city
-                xml.code address.postcode if address.postcode
-                xml.country address.country if address.country
-                xml.region address.state if address.state
-                xml.street address.street[0] if address.street.any?
-              end
-            end
-            render_contact xml, contact
-          end
+      # @param [Relaton::Bib::ContributionInfo] contrib contributor
+      #
+      def render_contacts(builder, contrib)
+        # address, contact = address_contact contrib.entity.contact
+        # if address || contact.any?
+        # contrib.entity.address.each { |address| render_address builder, address }
+        # render_contact builder, contrib.entity
+        render_address builder, contrib.entity
+      end
+
+      def render_address(builder, entity) # rubocop:disable Metrics/AbcSize
+        return unless entity.address.any? || entity.phone.any? || entity.email.any? || entity.uri.any?
+
+        builder.address do |xml|
+          render_postal xml, entity.address
+          render_contact xml, entity.phone.first, "phone"
+          xml.email entity.email.first if entity.email.any?
+          render_contact xml, entity.uri.first, "uri"
         end
       end
 
-      def address_contact(contact) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
-        addr = contact.detect do |c|
-          c.is_a?(Address) && (c.city || c.postcode || c.country || c.state || c.street.any?)
+      def render_postal(builder, address) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
+        addr = address.find do |a|
+          a.city || a.postcode || a.country || a.state || a.street.any?
+        end
+
+        if addr
+          builder.postal do |xml|
+            xml.city addr.city if addr.city
+            xml.code addr.postcode if addr.postcode
+            xml.country addr.country if addr.country
+            xml.region addr.state if addr.state
+            xml.street addr.street[0] if addr.street.any?
+          end
+          return
+        end
+
+        address.select(&:formatted_address).each do |a|
+          builder.postalLine a.formatted_address
         end
-        cont = contact.select { |c| c.is_a?(Contact) }
-        [addr, cont]
       end
 
+      def render_contact(builder, contact, type)
+        return unless contact
+
+        builder.send type, contact.content
+      end
+
+      # def address_contact(contact) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
+      #   addr = contact.detect do |c|
+      #     c.is_a?(Address) && (c.city || c.postcode || c.country || c.state || c.street.any?)
+      #   end
+      #   cont = contact.select { |c| c.is_a?(Contact) }
+      #   [addr, cont]
+      # end
+
       #
       # Render contact
       #
       # @param [Nokogiri::XML::Builder] builder xml builder
-      # @param [Array<RelatonBib::Address, RelatonBib::Contact>] addr contact
-      #
-      def render_contact(builder, addr)
-        %w[phone email uri].each do |type|
-          cont = addr.detect { |cn| cn.is_a?(Contact) && cn.type == type }
-          builder.send type, cont.value if cont
-        end
-      end
+      # @param [Array<Relaton::Bib::Address, Relaton::Bib::Contact>] addr contact
+      #
+      # def render_contact(builder, entity)
+      #   %w[phone email uri].each do |type|
+      #     entity.send(type).each do |cont|
+      #       # cont = addr.detect { |cn| cn.is_a?(Contact) && cn.type == type }
+      #       builder.send type, cont.value # if cont
+      #     end
+      #   end
+      # end
 
       #
       # Render person
       #
       # @param [Nokogiri::XML::Builder] builder xml builder
-      # @param [RelatonBib::Person] person person
+      # @param [Relaton::Bib::Person] person person
       #
       def render_person(builder, person) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
         render_organization builder, person.affiliation.first&.organization
@@ -197,7 +226,7 @@ def render_person(builder, person) # rubocop:disable Metrics/AbcSize, Metrics/Me
       # Render organization
       #
       # @param [Nokogiri::XML::Builder] builder xml builder
-      # @param [RelatonBib::Organization] org organization
+      # @param [Relaton::Bib::Organization] org organization
       #
       def render_organization(builder, org, _role = []) # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/AbcSize
         abbrev = org&.abbreviation&.content
@@ -240,8 +269,8 @@ def render_date(builder) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
       # @param [Nokogiri::XML::Builder] builder xml builder
       #
       def render_workgroup(builder)
-        @bib.editorialgroup&.technical_committee&.each do |tc|
-          builder.workgroup tc.workgroup.name
+        @bib.ext&.editorialgroup&.technical_committee&.each do |tc|
+          builder.workgroup tc.content
         end
       end
 
@@ -273,21 +302,23 @@ def render_abstract(builder)
       def render_seriesinfo(builder) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
         @bib.docidentifier.each do |di|
           if BibXMLParser::SERIESINFONAMES.include?(di.type) && di.scope != "trademark"
-            builder.seriesInfo(name: di.type, value: di.id)
+            builder.seriesInfo(name: di.type, value: di.content)
           end
         end
-        # di_types = docidentifier.map(&:type)
+
         @bib.series.select do |s|
-          s.title && # !di_types.include?(s.title.title.to_s) &&
-            !BibXMLParser::SERIESINFONAMES.include?(s.title.title.to_s)
-        end.uniq { |s| s.title.title.to_s }.each do |s|
-          si = builder.seriesInfo(name: s.title.title.to_s)
+          s.title.reject { |t| BibXMLParser::SERIESINFONAMES.include?(t.content) }.any?
+        end.uniq do |s|
+          s.title.find { |t| !BibXMLParser::SERIESINFONAMES.include?(t.content)}.content
+        end.each do |s|
+          title = s.title.find { |t| !BibXMLParser::SERIESINFONAMES.include?(t.content) }
+          si = builder.seriesInfo(name: title.content)
           si[:value] = s.number if s.number
         end
       end
 
       def render_format(builder)
-        @bib.link.select { |l| l.type == "TXT" }.each do |l|
+        @bib.source.select { |l| l.type == "TXT" }.each do |l|
           builder.format type: l.type, target: l.content
         end
       end
diff --git a/lib/relaton_bib/bib_item_locality.rb b/lib/relaton_bib/bib_item_locality.rb
deleted file mode 100644
index 4ec9db0..0000000
--- a/lib/relaton_bib/bib_item_locality.rb
+++ /dev/null
@@ -1,175 +0,0 @@
-module RelatonBib
-  # Bibliographic item locality.
-  class BibItemLocality
-    # @return [String]
-    attr_reader :type
-
-    # @return [String]
-    attr_reader :reference_from
-
-    # @return [String, nil]
-    attr_reader :reference_to
-
-    # @param type [String]
-    # @param referenceFrom [String]
-    # @param referenceTo [String, nil]
-    def initialize(type, reference_from, reference_to = nil)
-      type_ptrn = %r{section|clause|part|paragraph|chapter|page|title|line|
-        whole|table|annex|figure|note|list|example|volume|issue|time|anchor|
-        locality:[a-zA-Z0-9_]+}x
-      unless type&.match? type_ptrn
-        Util.warn "Invalid locality type: `#{type}`"
-      end
-
-      @type           = type
-      @reference_from = reference_from
-      @reference_to   = reference_to
-    end
-
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      builder.parent[:type] = type
-      builder.referenceFrom reference_from # { reference_from.to_xml(builder) }
-      builder.referenceTo reference_to if reference_to
-    end
-
-    # @return [Hash]
-    def to_hash
-      hash = { "type" => type, "reference_from" => reference_from }
-      hash["reference_to"] = reference_to if reference_to
-      hash
-    end
-
-    # @param prefix [String]
-    # @param count [Integeg] number of localities
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1)
-      pref = prefix.empty? ? prefix : "#{prefix}."
-      out = count > 1 ? "#{prefix}::\n" : ""
-      out += "#{pref}type:: #{type}\n"
-      out += "#{pref}reference_from:: #{reference_from}\n"
-      out += "#{pref}reference_to:: #{reference_to}\n" if reference_to
-      out
-    end
-
-    #
-    # Render locality as BibTeX.
-    #
-    # @param [BibTeX::Entry] item BibTeX entry.
-    #
-    def to_bibtex(item)
-      case type
-      when "chapter" then item.chapter = reference_from
-      when "page"
-        value = reference_from
-        value += "--#{reference_to}" if reference_to
-        item.pages = value
-      when "volume" then item.volume = reference_from
-      when "issue" then item.number = reference_from
-      end
-    end
-  end
-
-  class Locality < BibItemLocality
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      builder.locality { |b| super(b) }
-    end
-
-    #
-    # Render locality as hash.
-    #
-    # @return [Hash] locality as hash.
-    #
-    def to_hash
-      { "locality" => super }
-    end
-
-    #
-    # Render locality as AsciiBib.
-    #
-    # @param [String] prefix prefix of locality
-    # @param [Integer] count number of localities
-    #
-    # @return [String] AsciiBib.
-    #
-    def to_asciibib(prefix = "", count = 1)
-      pref = prefix.empty? ? "locality" : "#{prefix}.locality"
-      super(pref, count)
-    end
-  end
-
-  class LocalityStack
-    include RelatonBib
-
-    # @return [Array<RelatonBib::Locality>]
-    attr_reader :locality
-
-    # @param locality [Array<RelatonBib::Locality>]
-    def initialize(locality)
-      @locality = locality
-    end
-
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      builder.localityStack do |b|
-        locality.each { |l| l.to_xml(b) }
-      end
-    end
-
-    # @returnt [Hash]
-    def to_hash
-      hash = Hash.new { |h, k| h[k] = [] }
-      locality.each_with_object(hash) do |l, obj|
-        k, v = l.to_hash.first
-        obj[k] << v
-      end
-      { "locality_stack" => hash }
-    end
-
-    #
-    # Render locality stack as AsciiBib.
-    #
-    # @param [String] prefix <description>
-    # @param [Integer] size size of locality stack
-    #
-    # @return [String] AsciiBib.
-    #
-    def to_asciibib(prefix = "", size = 1)
-      pref = prefix.empty? ? "locality_stack" : "#{prefix}.locality_stack"
-      out = ""
-      out << "#{pref}::\n" if size > 1
-      out << locality.map { |l| l.to_asciibib(pref, locality.size) }.join
-    end
-
-    #
-    # Render locality stack as BibTeX.
-    #
-    # @param [BibTeX::Entry] item BibTeX entry.
-    #
-    def to_bibtex(item)
-      locality.each { |l| l.to_bibtex(item) }
-    end
-  end
-
-  class SourceLocality < BibItemLocality
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      builder.sourceLocality { |b| super(b) }
-    end
-  end
-
-  class SourceLocalityStack < LocalityStack
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      builder.sourceLocalityStack do |b|
-        locality.each { |l| l.to_xml(b) }
-      end
-    end
-
-    # @returnt [Hash]
-    def to_hash
-      { "source_locality_stack" => single_element_array(locality) }
-    end
-  end
-end
diff --git a/lib/relaton_bib/biblio_note.rb b/lib/relaton_bib/biblio_note.rb
deleted file mode 100644
index 4eb642d..0000000
--- a/lib/relaton_bib/biblio_note.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-module RelatonBib
-  class BiblioNoteCollection
-    extend Forwardable
-
-    def_delegators :@array, :[], :first, :last, :empty?, :any?, :size,
-                   :each, :map, :reduce, :detect, :length
-
-    def initialize(notes)
-      @array = notes
-    end
-
-    # @param bibnote [RelatonBib::BiblioNote]
-    # @return [self]
-    def <<(bibnote)
-      @array << bibnote
-      self
-    end
-
-    # @param opts [Hash]
-    # @option opts [Nokogiri::XML::Builder] XML builder
-    # @option opts [String] :lang language
-    def to_xml(**opts)
-      bnc = @array.select { |bn| bn.language&.include? opts[:lang] }
-      bnc = @array unless bnc.any?
-      bnc.each { |bn| bn.to_xml opts[:builder] }
-    end
-  end
-
-  class BiblioNote < FormattedString
-    # @return [String, nil]
-    attr_reader :type
-
-    # @param content [String]
-    # @param type [String, nil]
-    # @param language [String, nil] language code Iso639
-    # @param script [String, nil] script code Iso15924
-    # @param format [String, nil] the content format
-    def initialize(content:, type: nil, language: nil, script: nil, format: nil)
-      @type = type
-      super content: content, language: language, script: script, format: format
-    end
-
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      xml = builder.note { super }
-      xml[:type] = type if type
-      xml
-    end
-
-    # @return [Hash]
-    def to_hash
-      hash = super
-      return hash unless type
-
-      hash = { "content" => hash } if hash.is_a? String
-      hash["type"] = type
-      hash
-    end
-
-    # @param prefix [String]
-    # @param count [Integer] number of notes
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1)
-      pref = prefix.empty? ? prefix : prefix + "."
-      has_attrs = !(type.nil? || type.empty?)
-      out = count > 1 && has_attrs ? "#{pref}biblionote::\n" : ""
-      out += "#{pref}biblionote.type:: #{type}\n" if type
-      out += super "#{pref}biblionote", 1, has_attrs
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/biblio_version.rb b/lib/relaton_bib/biblio_version.rb
deleted file mode 100644
index dfc23b8..0000000
--- a/lib/relaton_bib/biblio_version.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-module RelatonBib
-  # Version
-  class BibliographicItem
-    class Version
-      include RelatonBib
-
-      # @return [String, nil]
-      attr_reader :revision_date, :draft
-
-      # @param revision_date [String, nil]
-      # @param draft [String, nil]
-      def initialize(revision_date = nil, draft = nil)
-        @revision_date = revision_date
-        @draft         = draft
-      end
-
-      # @param builder [Nokogiri::XML::Builder]
-      def to_xml(builder)
-        builder.version do
-          builder.send(:"revision-date", revision_date) if revision_date
-          builder.draft draft if draft
-        end
-      end
-
-      # @return [Hash]
-      def to_hash
-        hash = {}
-        hash["revision_date"] = revision_date if revision_date
-        hash["draft"] = draft if draft
-        hash
-      end
-
-      # @param prefix [String]
-      # @return [String]
-      def to_asciibib(prefix = "", count = 1)
-        pref = prefix.empty? ? prefix : "#{prefix}."
-        out = count > 1 ? "#{prefix}version::\n" : ""
-        if revision_date
-          out += "#{pref}version.revision_date:: #{revision_date}\n"
-        end
-        out += "#{pref}version.draft:: #{draft}\n" if draft
-        out
-      end
-    end
-  end
-end
diff --git a/lib/relaton_bib/bibliographic_date.rb b/lib/relaton_bib/bibliographic_date.rb
deleted file mode 100644
index 3ea3608..0000000
--- a/lib/relaton_bib/bibliographic_date.rb
+++ /dev/null
@@ -1,119 +0,0 @@
-# frozen_string_literal: true
-
-require "time"
-
-module RelatonBib
-  # Bibliographic date.
-  class BibliographicDate
-    TYPES = %w[published accessed created implemented obsoleted confirmed
-               updated corrected issued transmitted copied unchanged circulated adapted
-               vote-started vote-ended announced stable-until].freeze
-
-    # @return [String]
-    attr_reader :type
-
-    # @param type [String] "published", "accessed", "created", "activated"
-    # @param on [String]
-    # @param from [String]
-    # @param to [String]
-    def initialize(type:, on: nil, from: nil, to: nil)
-      raise ArgumentError, "expected :on or :from argument" unless on || from
-
-      # raise ArgumentError, "invalid type: #{type}" unless TYPES.include? type
-
-      @type = type
-      @on   = RelatonBib.parse_date on
-      @from = RelatonBib.parse_date from
-      @to   = RelatonBib.parse_date to
-    end
-
-    # @param part [Symbol] :year, :month, :day, :date
-    # @return [String, Date, nil]
-    def from(part = nil) # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
-      d = instance_variable_get "@#{__callee__}".to_sym
-      return d unless part && d
-
-      # date = parse_date(d)
-      # return date if part == :date
-
-      parts = d.split "-"
-      case part
-      when :year then parts[0]&.to_i
-      when :month then parts[1]&.to_i
-      when :day then parts[2]&.to_i
-      when :date then parse_date(d)
-      else d
-      end
-
-      # date.is_a?(Date) ? date.send(part) : date
-    end
-
-    alias_method :to, :from
-    alias_method :on, :from
-
-    # rubocop:disable Metrics/AbcSize
-
-    # @param builder [Nokogiri::XML::Builder]
-    # @return [Nokogiri::XML::Builder]
-    def to_xml(builder, **opts)
-      builder.date(type: type) do
-        if on
-          builder.on(opts[:no_year] ? "--" : date_format(on, opts[:date_format]))
-        elsif from
-          builder.from(opts[:no_year] ? "--" : date_format(from, opts[:date_format]))
-          builder.to date_format(to, opts[:date_format]) if to
-        end
-      end
-    end
-    # rubocop:enable Metrics/AbcSize
-
-    # @return [Hash]
-    def to_hash
-      hash = { "type" => type }
-      hash["value"] = on.to_s if on
-      hash["from"] = from.to_s if from
-      hash["to"] = to.to_s if to
-      hash
-    end
-
-    # @param prefix [String]
-    # @param count [Integer] number of dates
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1)
-      pref = prefix.empty? ? prefix : "#{prefix}."
-      out = count > 1 ? "#{pref}date::\n" : ""
-      out += "#{pref}date.type:: #{type}\n"
-      out += "#{pref}date.on:: #{on}\n" if on
-      out += "#{pref}date.from:: #{from}\n" if from
-      out += "#{pref}date.to:: #{to}\n" if to
-      out
-    end
-
-    private
-
-    # Formats date
-    # @param date [String]
-    # @param format [Symbol, nil] :full (yyyy-mm-dd), :short (yyyy-mm) or nil
-    # @return [String]
-    def date_format(date, format = nil)
-      tmplt = case format
-              when :short then "%Y-%m"
-              when :full then "%Y-%m-%d"
-              else return date
-              end
-      d = parse_date(date)
-      d.is_a?(Date) ? d.strftime(tmplt) : d
-    end
-
-    # @param date [String]
-    # @return [Date]
-    def parse_date(date)
-      case date
-      when /^\d{4}-\d{1,2}-\d{1,2}/ then Date.parse(date) # 2012-02-11
-      when /^\d{4}-\d{1,2}/ then Date.strptime(date, "%Y-%m") # 2012-02
-      when /^\d{4}/ then Date.strptime(date, "%Y") # 2012
-      else date
-      end
-    end
-  end
-end
diff --git a/lib/relaton_bib/bibliographic_item.rb b/lib/relaton_bib/bibliographic_item.rb
deleted file mode 100644
index 1cbb837..0000000
--- a/lib/relaton_bib/bibliographic_item.rb
+++ /dev/null
@@ -1,668 +0,0 @@
-# frozen_string_literal: true
-
-require "relaton_bib/typed_uri"
-require "relaton_bib/document_identifier"
-require "relaton_bib/copyright_association"
-require "relaton_bib/formatted_string"
-require "relaton_bib/contribution_info"
-require "relaton_bib/bibliographic_date"
-require "relaton_bib/series"
-require "relaton_bib/document_status"
-require "relaton_bib/organization"
-require "relaton_bib/document_relation_collection"
-require "relaton_bib/typed_title_string"
-require "relaton_bib/formatted_ref"
-require "relaton_bib/medium"
-require "relaton_bib/classification"
-require "relaton_bib/validity"
-require "relaton_bib/document_relation"
-require "relaton_bib/bib_item_locality"
-require_relative "extent"
-require "relaton_bib/xml_parser"
-require "relaton_bib/bibtex_parser"
-require "relaton_bib/biblio_note"
-require "relaton_bib/biblio_version"
-require "relaton_bib/workers_pool"
-require "relaton_bib/hash_converter"
-require "relaton_bib/place"
-require "relaton_bib/structured_identifier"
-require "relaton_bib/editorial_group"
-require "relaton_bib/ics"
-require "relaton_bib/bibliographic_size"
-require "relaton_bib/edition"
-
-module RelatonBib
-  # Bibliographic item
-  class BibliographicItem
-    include RelatonBib
-
-    TYPES = %W[article book booklet manual proceedings presentation
-               thesis techreport standard unpublished map electronic\sresource
-               audiovisual film video broadcast software graphic_work music
-               patent inbook incollection inproceedings journal website
-               webresource dataset archival social_media alert message
-               conversation collection misc internal].freeze # internal is defined in isodoc grammar
-
-    # @return [Boolean, nil]
-    attr_accessor :all_parts
-
-    # @return [String, nil]
-    attr_reader :id, :type, :docnumber, :subdoctype
-
-    # @return [RelatonBib::DocumentType] document type
-    attr_reader :doctype
-
-    # @return [RelatonBib::Edition, nil] edition
-    attr_reader :edition
-
-    # @!attribute [r] title
-    # @return [RelatonBib::TypedTitleStringCollection]
-
-    # @return [Array<RelatonBib::TypedUri>]
-    attr_reader :link
-
-    # @return [Array<RelatonBib::DocumentIdentifier>]
-    attr_reader :docidentifier
-
-    # @return [Array<RelatonBib::BibliographicDate>]
-    attr_writer :date
-
-    # @return [Array<RelatonBib::ContributionInfo>]
-    attr_reader :contributor
-
-    # @return [Array<RelatonBib::BibliographicItem::Version>]
-    attr_reader :version
-
-    # @return [RelatonBib::BiblioNoteCollection]
-    attr_reader :biblionote
-
-    # @return [Array<String>] language Iso639 code
-    attr_reader :language
-
-    # @return [Array<String>] script Iso15924 code
-    attr_reader :script
-
-    # @return [RelatonBib::FormattedRef, nil]
-    attr_reader :formattedref
-
-    # @!attribute [r] abstract
-    #   @return [Array<RelatonBib::FormattedString>]
-
-    # @return [RelatonBib::DocumentStatus, nil]
-    attr_reader :status
-
-    # @return [Array<RelatonBib::CopyrightAssociation>]
-    attr_reader :copyright
-
-    # @return [RelatonBib::DocRelationCollection]
-    attr_reader :relation
-
-    # @return [Array<RelatonBib::Series>]
-    attr_reader :series
-
-    # @return [RelatonBib::Medium, nil]
-    attr_reader :medium
-
-    # @return [Array<RelatonBib::Place>]
-    attr_reader :place
-
-    # @return [Array<RelatonBib::Extent>]
-    attr_reader :extent
-
-    # @return [Array<Strig>]
-    attr_reader :accesslocation, :license
-
-    # @return [Array<Relaton::Classification>]
-    attr_reader :classification
-
-    # @return [RelatonBib:Validity, nil]
-    attr_reader :validity
-
-    # @return [Date]
-    attr_accessor :fetched
-
-    # @return [Array<RelatonBib::LocalizedString>]
-    attr_reader :keyword
-
-    # @return [RelatonBib::EditorialGroup, nil]
-    attr_reader :editorialgroup
-
-    # @return [Array<RelatonBib:ICS>]
-    attr_reader :ics
-
-    # @return [RelatonBib::StructuredIdentifierCollection]
-    attr_reader :structuredidentifier
-
-    # @return [RelatonBib::BibliographicSize, nil]
-    attr_reader :size
-
-    # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
-    # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
-
-    # @param id [String, nil]
-    # @param title [RelatonBib::TypedTitleStringCollection,
-    #   Array<Hash, RelatonBib::TypedTitleString>]
-    # @param formattedref [RelatonBib::FormattedRef, nil]
-    # @param type [String, nil]
-    # @param docid [Array<RelatonBib::DocumentIdentifier>]
-    # @param docnumber [String, nil]
-    # @param language [Arra<String>]
-    # @param script [Array<String>]
-    # @param docstatus [RelatonBib::DocumentStatus, nil]
-    # @param edition [RelatonBib::Edition, String, Integer, Float, nil]
-    # @param version [Array<RelatonBib::BibliographicItem::Version>]
-    # @param biblionote [RelatonBib::BiblioNoteCollection]
-    # @param series [Array<RelatonBib::Series>]
-    # @param medium [RelatonBib::Medium, nil]
-    # @param place [Array<String, RelatonBib::Place>]
-    # @param extent [Array<RelatonBib::Extent>]
-    # @param accesslocation [Array<String>]
-    # @param classification [Array<RelatonBib::Classification>]
-    # @param validity [RelatonBib:Validity, nil]
-    # @param fetched [Date, nil] default nil
-    # @param keyword [Array<String>]
-    # @param doctype [RelatonBib::DocumentType]
-    # @param subdoctype [String]
-    # @param editorialgroup [RelatonBib::EditorialGroup, nil]
-    # @param ics [Array<RelatonBib::ICS>]
-    # @param structuredidentifier [RelatonBib::StructuredIdentifierCollection]
-    # @param size [RelatonBib::BibliographicSize, nil]
-    #
-    # @param copyright [Array<Hash, RelatonBib::CopyrightAssociation>]
-    # @option copyright [Array<Hash, RelatonBib::ContributionInfo>] :owner
-    # @option copyright [String] :from
-    # @option copyright [String, nil] :to
-    # @option copyright [String, nil] :scope
-    #
-    # @param date [Array<Hash, RelatonBib::BibliographicDate>]
-    # @option date [String] :type
-    # @option date [String, nil] :from required if :on is nil
-    # @option date [String, nil] :to
-    # @option date [String, nil] :on required if :from is nil
-    #
-    # @param contributor [Array<Hash, RelatonBib::ContributionInfo>]
-    # @option contributor [RealtonBib::Organization, RelatonBib::Person] :entity
-    # @option contributor [String] :type
-    # @option contributor [String] :from
-    # @option contributor [String] :to
-    # @option contributor [String] :abbreviation
-    # @option contributor [Array<Array<String,Array<String>>>] :role
-    #
-    # @param abstract [Array<Hash, RelatonBib::FormattedString>]
-    # @option abstract [String] :content
-    # @option abstract [String] :language
-    # @option abstract [String] :script
-    # @option abstract [String] :format
-    #
-    # @param relation [Array<Hash>]
-    # @option relation [String] :type
-    # @option relation [RelatonBib::BibliographicItem,
-    #                   RelatonIso::IsoBibliographicItem] :bibitem
-    # @option relation [Array<RelatonBib::Locality,
-    #                   RelatonBib::LocalityStack>] :locality
-    # @option relation [Array<RelatonBib::SourceLocality,
-    #                   RelatonBib::SourceLocalityStack>] :source_locality
-    #
-    # @param link [Array<Hash, RelatonBib::TypedUri>]
-    # @option link [String] :type
-    # @option link [String] :content
-    def initialize(**args)
-      if args[:type] && !TYPES.include?(args[:type])
-        Util.warn %{Type `#{args[:type]}` is invalid.}
-      end
-
-      @title = if args[:title].is_a?(TypedTitleStringCollection)
-                 args[:title]
-               else
-                 TypedTitleStringCollection.new(args[:title])
-               end
-
-      @date = (args[:date] || []).map do |d|
-        d.is_a?(Hash) ? BibliographicDate.new(**d) : d
-      end
-
-      @contributor = (args[:contributor] || []).map do |c|
-        if c.is_a? Hash
-          e = c[:entity].is_a?(Hash) ? Organization.new(**c[:entity]) : c[:entity]
-          ContributionInfo.new(entity: e, role: c[:role])
-        else c
-        end
-      end
-
-      @abstract = (args[:abstract] || []).map do |a|
-        a.is_a?(Hash) ? FormattedString.new(**a) : a
-      end
-
-      @copyright = args.fetch(:copyright, []).map do |c|
-        c.is_a?(Hash) ? CopyrightAssociation.new(**c) : c
-      end
-
-      @docidentifier  = args[:docid] || []
-      @formattedref   = args[:formattedref] if title.empty?
-      @id             = args[:id] || makeid(nil, false)
-      @type           = args[:type]
-      @docnumber      = args[:docnumber]
-      @edition        = case args[:edition]
-                        when Hash then Edition.new(**args[:edition])
-                        when String, Integer, Float
-                          Edition.new(content: args[:edition].to_s)
-                        when Edition then args[:edition]
-                        end
-      @version        = args.fetch :version, []
-      @biblionote     = args.fetch :biblionote, BiblioNoteCollection.new([])
-      @language       = args.fetch :language, []
-      @script         = args.fetch :script, []
-      @status         = args[:docstatus]
-      @relation       = DocRelationCollection.new(args[:relation] || [])
-      @link           = args.fetch(:link, []).map do |s|
-        case s
-        when Hash then TypedUri.new(**s)
-        when String then TypedUri.new(content: s)
-        else s
-        end
-      end
-      @series         = args.fetch :series, []
-      @medium         = args[:medium]
-      @place          = args.fetch(:place, []).map do |pl|
-        pl.is_a?(String) ? Place.new(name: pl) : pl
-      end
-      @extent         = args[:extent] || []
-      @size           = args[:size]
-      @accesslocation = args.fetch :accesslocation, []
-      @classification = args.fetch :classification, []
-      @validity       = args[:validity]
-      # we should pass the fetched arg from scrappers
-      @fetched        = args.fetch :fetched, nil
-      @keyword        = (args[:keyword] || []).map do |kw|
-        case kw
-        when Hash then LocalizedString.new(kw[:content], kw[:language], kw[:script])
-        when String then LocalizedString.new(kw)
-        else kw
-        end
-      end
-      @license        = args.fetch :license, []
-      @doctype        = args[:doctype]
-      @subdoctype     = args[:subdoctype]
-      @editorialgroup = args[:editorialgroup]
-      @ics            = args.fetch :ics, []
-      @structuredidentifier = args[:structuredidentifier]
-    end
-    # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
-    # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
-
-    #
-    # Fetch schema version
-    #
-    # @return [String] schema version
-    #
-    def schema
-      @schema ||= schema_versions["relaton-models"]
-    end
-
-    #
-    # Read schema versions from file
-    #
-    # @return [Hash{String=>String}] schema versions
-    #
-    def schema_versions
-      JSON.parse File.read(File.join(__dir__, "../../grammars/versions.json"))
-    end
-
-    # @param hash [Hash]
-    # @return [RelatonBipm::BipmBibliographicItem]
-    def self.from_hash(hash)
-      item_hash = Object.const_get(name.split("::")[0])::HashConverter.hash_to_bib(hash)
-      new(**item_hash)
-    end
-
-    #
-    # @param [String, nil] type if nil return all dates else return dates with type
-    #
-    # @return [Array<RelatonBib::BibliographicDate>]
-    #
-    def date(type: nil)
-      type ? @date.select { |d| d.type == type } : @date
-    end
-
-    # @param lang [String] language code Iso639
-    # @return [RelatonBib::FormattedString, Array<RelatonBib::FormattedString>]
-    def abstract(lang: nil)
-      if lang
-        @abstract.detect { |a| a.language&.include? lang }
-      else
-        @abstract
-      end
-    end
-
-    # @param identifier [RelatonBib::DocumentIdentifier, nil]
-    # @param attribute [Boolean, nil]
-    # @return [String]
-    def makeid(identifier, attribute)
-      return nil if attribute && !@id_attribute
-
-      identifier ||= @docidentifier.reject { |i| i.type == "DOI" }[0]
-      return unless identifier
-
-      idstr = identifier.id.gsub(/[:\/]/, "-").gsub(/[\s\(\)]/, "")
-      idstr.strip
-    end
-
-    # @param identifier [RelatonBib::DocumentIdentifier]
-    # @param options [Hash]
-    # @option options [boolean, nil] :no_year
-    # @option options [boolean, nil] :all_parts
-    # @return [String]
-    def shortref(identifier, **opts) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/AbcSize,Metrics/PerceivedComplexity
-      pubdate = date.select { |d| d.type == "published" || d.type == "issued" }
-      year = if opts[:no_year] || pubdate.empty? then ""
-             else ":#{pubdate&.first&.on(:year)}"
-             end
-      year += ": All Parts" if opts[:all_parts] || @all_parts
-
-      "#{makeid(identifier, false)}#{year}"
-    end
-
-    # @param opts [Hash]
-    # @option opts [Nokogiri::XML::Builder] :builder XML builder
-    # @option opts [Boolean] :bibdata
-    # @option opts [Symbol, nil] :date_format (:short), :full
-    # @option opts [String, Symbol] :lang language
-    # @return [String] XML
-    def to_xml(**opts, &block)
-      if opts[:builder]
-        render_xml(**opts, &block)
-      else
-        Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
-          render_xml builder: xml, **opts, &block
-        end.doc.root.to_xml
-      end
-    end
-
-    #
-    # Render BibXML (RFC)
-    #
-    # @param [Nokogiri::XML::Builder, nil] builder
-    # @param [Boolean] include_keywords (false)
-    #
-    # @return [String, Nokogiri::XML::Builder::NodeBuilder] XML
-    #
-    def to_bibxml(builder = nil, include_keywords: false)
-      Renderer::BibXML.new(self).render builder: builder, include_keywords: include_keywords
-    end
-
-    # @return [Hash]
-    def to_hash(embedded: false) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
-      hash = {}
-      hash["schema-version"] = schema unless embedded
-      hash["id"] = id if id
-      hash["title"] = title.to_hash if title&.any?
-      hash["link"] = single_element_array(link) if link&.any?
-      hash["type"] = type if type
-      hash["docid"] = single_element_array(docidentifier) if docidentifier&.any?
-      hash["docnumber"] = docnumber if docnumber
-      hash["date"] = single_element_array(date) if date&.any?
-      if contributor&.any?
-        hash["contributor"] = single_element_array(contributor)
-      end
-      hash["edition"] = edition.to_hash if edition
-      hash["version"] = version.map &:to_hash if version.any?
-      hash["revdate"] = revdate if revdate
-      hash["biblionote"] = single_element_array(biblionote) if biblionote&.any?
-      hash["language"] = single_element_array(language) if language&.any?
-      hash["script"] = single_element_array(script) if script&.any?
-      hash["formattedref"] = formattedref.to_hash if formattedref
-      hash["abstract"] = single_element_array(abstract) if abstract&.any?
-      hash["docstatus"] = status.to_hash if status
-      hash["copyright"] = single_element_array(copyright) if copyright&.any?
-      hash["relation"] = single_element_array(relation) if relation&.any?
-      hash["series"] = single_element_array(series) if series&.any?
-      hash["medium"] = medium.to_hash if medium
-      hash["place"] = single_element_array(place) if place&.any?
-      hash["extent"] = extent.map(&:to_hash) if extent&.any?
-      hash["size"] = size.to_hash if size&.any?
-      if accesslocation&.any?
-        hash["accesslocation"] = single_element_array(accesslocation)
-      end
-      if classification&.any?
-        hash["classification"] = single_element_array(classification)
-      end
-      hash["validity"] = validity.to_hash if validity
-      hash["fetched"] = fetched.to_s if fetched
-      hash["keyword"] = single_element_array(keyword) if keyword&.any?
-      hash["license"] = single_element_array(license) if license&.any?
-      if has_ext?
-        hash["ext"] = {}
-        hash["ext"]["schema-version"] = ext_schema if !embedded && respond_to?(:ext_schema) && ext_schema
-        hash["ext"]["doctype"] = doctype.to_hash if doctype
-        hash["ext"]["subdoctype"] = subdoctype if subdoctype
-        hash["ext"]["editorialgroup"] = editorialgroup.to_hash if editorialgroup&.presence?
-        hash["ext"]["ics"] = single_element_array ics if ics.any?
-        hash["ext"]["structuredidentifier"] = structuredidentifier.to_hash if structuredidentifier&.presence?
-      end
-      hash
-    end
-
-    #
-    # Reander BibTeX
-    #
-    # @param bibtex [BibTeX::Bibliography, nil]
-    #
-    # @return [String]
-    #
-    def to_bibtex(bibtex = nil)
-      Renderer::BibtexBuilder.build(self, bibtex).to_s
-    end
-
-    #
-    # Render citeproc
-    #
-    # @param bibtex [BibTeX::Bibliography, nil]
-    #
-    # @return [Hash] citeproc
-    #
-    def to_citeproc(bibtex = nil)
-      Renderer::BibtexBuilder.build(self, bibtex).to_citeproc.map do |cp|
-        cp.transform_keys(&:to_s)
-      end
-    end
-
-    # @param lang [String, nil] language code Iso639
-    # @return [RelatonIsoBib::TypedTitleStringCollection]
-    def title(lang: nil)
-      @title.lang lang
-    end
-
-    # @param type [Symbol] type of url, can be :src/:obp/:rss
-    # @return [String, nil]
-    def url(type = :src)
-      @link.detect { |s| s.type == type.to_s }&.content&.to_s
-    end
-
-    def abstract=(value)
-      @abstract = value
-    end
-
-    def deep_clone
-      dump = Marshal.dump self
-      Marshal.load dump # rubocop:disable Security/MarshalLoad
-    end
-
-    def disable_id_attribute
-      @id_attribute = false
-    end
-
-    # remove title part components and abstract
-    def to_all_parts # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength,Metrics/PerceivedComplexity
-      me = deep_clone
-      me.disable_id_attribute
-      me.relation << DocumentRelation.new(type: "instanceOf", bibitem: self)
-      me.language.each do |l|
-        me.title.delete_title_part!
-        ttl = me.title.select do |t|
-          t.type != "main" && t.title.language&.include?(l)
-        end
-        next if ttl.empty?
-
-        tm_en = ttl.map { |t| t.title.content }.join " – "
-        me.title.detect do |t|
-          t.type == "main" && t.title.language&.include?(l)
-        end&.title&.content = tm_en
-      end
-      me.abstract = []
-      me.docidentifier.each(&:remove_part)
-      me.docidentifier.each(&:all_parts)
-      me.structuredidentifier.remove_part
-      me.structuredidentifier.all_parts
-      me.docidentifier.each &:remove_date
-      me.structuredidentifier&.remove_date
-      me.all_parts = true
-      me
-    end
-
-    # convert ISO:yyyy reference to reference to most recent
-    # instance of reference, removing date-specific infomration:
-    # date of publication, abstracts. Make dated reference Instance relation
-    # of the redacated document
-    def to_most_recent_reference
-      me = deep_clone
-      disable_id_attribute
-      me.relation << DocumentRelation.new(type: "instanceOf", bibitem: self)
-      me.abstract = []
-      me.date = []
-      me.docidentifier.each &:remove_date
-      me.structuredidentifier&.remove_date
-      me.id&.sub!(/-[12]\d\d\d/, "")
-      me
-    end
-
-    # If revision_date exists then returns it else returns published date or nil
-    # @return [String, nil]
-    def revdate # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
-      @revdate ||= if (v = version.detect &:revision_date)
-                     v.revision_date
-                   else
-                     date.detect { |d| d.type == "published" }&.on&.to_s
-                   end
-    end
-
-    # @param prefix [String]
-    # @return [String]
-    def to_asciibib(prefix = "") # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
-      pref = prefix.empty? ? prefix : "#{prefix}."
-      out = prefix.empty? ? "[%bibitem]\n== {blank}\n" : ""
-      out += "#{pref}id:: #{id}\n" if id
-      out += "#{pref}fetched:: #{fetched}\n" if fetched
-      title.each { |t| out += t.to_asciibib(prefix, title.size) }
-      out += "#{pref}type:: #{type}\n" if type
-      docidentifier.each do |di|
-        out += di.to_asciibib prefix, docidentifier.size
-      end
-      out += "#{pref}docnumber:: #{docnumber}\n" if docnumber
-      out += edition.to_asciibib(prefix) if edition
-      language.each { |l| out += "#{pref}language:: #{l}\n" }
-      script.each { |s| out += "#{pref}script:: #{s}\n" }
-      version.each { |v| out += v.to_asciibib prefix, version.size }
-      biblionote&.each { |b| out += b.to_asciibib prefix, biblionote.size }
-      out += status.to_asciibib prefix if status
-      date.each { |d| out += d.to_asciibib prefix, date.size }
-      abstract.each do |a|
-        out += a.to_asciibib "#{pref}abstract", abstract.size
-      end
-      copyright.each { |c| out += c.to_asciibib prefix, copyright.size }
-      link.each { |l| out += l.to_asciibib prefix, link.size }
-      out += medium.to_asciibib prefix if medium
-      place.each { |pl| out += pl.to_asciibib prefix, place.size }
-      extent.each { |ex| out += ex.to_asciibib prefix, extent.size }
-      out += size.to_asciibib pref if size
-      accesslocation.each { |al| out += "#{pref}accesslocation:: #{al}\n" }
-      classification.each do |cl|
-        out += cl.to_asciibib prefix, classification.size
-      end
-      out += validity.to_asciibib prefix if validity
-      contributor.each do |c|
-        out += c.to_asciibib "contributor.*", contributor.size
-      end
-      out += relation.to_asciibib prefix if relation
-      series.each { |s| out += s.to_asciibib prefix, series.size }
-      out += doctype.to_asciibib prefix if doctype
-      out += "#{pref}subdoctype:: #{subdoctype}\n" if subdoctype
-      out += "#{pref}formattedref:: #{formattedref}\n" if formattedref
-      keyword.each { |kw| out += kw.to_asciibib "#{pref}keyword", keyword.size }
-      out += editorialgroup.to_asciibib prefix if editorialgroup
-      ics.each { |i| out += i.to_asciibib prefix, ics.size }
-      out += structuredidentifier.to_asciibib prefix if structuredidentifier
-      out
-    end
-
-    private
-
-    # @param opts [Hash]
-    # @option opts [Nokogiri::XML::Builder] :builder XML builder
-    # @option opts [Boolean] bibdata
-    # @option opts [Symbol, nil] :date_format (:short), :full
-    # @option opts [String] :lang language
-    def render_xml(**opts) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
-      root = opts[:bibdata] ? :bibdata : :bibitem
-      xml = opts[:builder].send(root) do |builder| # rubocop:disable Metrics/BlockLength
-        builder.fetched fetched if fetched
-        title.to_xml(**opts)
-        formattedref&.to_xml builder
-        link.each { |s| s.to_xml builder }
-        docidentifier.each { |di| di.to_xml(**opts) }
-        builder.docnumber docnumber if docnumber
-        date.each { |d| d.to_xml builder, **opts }
-        contributor.each do |c|
-          builder.contributor do
-            c.role.each { |r| r.to_xml(**opts) }
-            c.to_xml(**opts)
-          end
-        end
-        edition&.to_xml builder
-        version.each { |v| v.to_xml builder }
-        biblionote.to_xml(**opts)
-        opts[:note]&.each do |n|
-          builder.note(n[:text], format: "text/plain", type: n[:type])
-        end
-        language.each { |l| builder.language l }
-        script.each { |s| builder.script s }
-        abstr = abstract.select { |ab| ab.language&.include? opts[:lang] }
-        abstr = abstract unless abstr.any?
-        abstr.each { |a| builder.abstract { a.to_xml(builder) } }
-        status&.to_xml builder
-        copyright&.each { |c| c.to_xml(**opts) }
-        relation.each { |r| r.to_xml builder, **opts }
-        series.each { |s| s.to_xml builder }
-        medium&.to_xml builder
-        place.each { |pl| pl.to_xml builder }
-        extent.each { |e| e.to_xml builder }
-        size&.to_xml builder
-        accesslocation.each { |al| builder.accesslocation al }
-        license.each { |l| builder.license l }
-        classification.each { |cls| cls.to_xml builder }
-        kwrd = keyword.select { |kw| kw.language&.include? opts[:lang] }
-        kwrd = keyword unless kwrd.any?
-        kwrd.each { |kw| builder.keyword { kw.to_xml(builder) } }
-        validity&.to_xml builder
-        if block_given? then yield builder
-        elsif opts[:bibdata] && has_ext?
-          ext = builder.ext do |b|
-            doctype&.to_xml b
-            b.subdoctype subdoctype if subdoctype
-            editorialgroup&.to_xml b
-            ics.each { |i| i.to_xml b }
-            structuredidentifier&.to_xml b
-          end
-          ext["schema-version"] = ext_schema if !opts[:embedded] && respond_to?(:ext_schema) && ext_schema
-        end
-      end
-      xml[:id] = id if id && !opts[:bibdata] && !opts[:embedded]
-      xml[:type] = type if type
-      xml["schema-version"] = schema unless opts[:embedded]
-      xml
-    end
-
-    def has_ext? # rubocop:disable Metrics/CyclomaticComplexity
-      doctype || subdoctype || editorialgroup || ics&.any? || structuredidentifier&.presence?
-    end
-  end
-end
diff --git a/lib/relaton_bib/bibliographic_size.rb b/lib/relaton_bib/bibliographic_size.rb
deleted file mode 100644
index 98d08de..0000000
--- a/lib/relaton_bib/bibliographic_size.rb
+++ /dev/null
@@ -1,103 +0,0 @@
-module RelatonBib
-  class BibliographicSize
-    extend Forwardable
-
-    def_delegators :@size, :any?
-
-    # @return [Array<RelatonBib::BibliographicSize::Value>]
-    attr_reader :size
-
-    #
-    # Initialize a BibliographicSize object.
-    #
-    # @param [<Type>] size <description>
-    #
-    def initialize(size)
-      @size = size
-    end
-
-    #
-    # Render BibliographicSize object to XML.
-    #
-    # @param [Nokogiri::XML::Builder] builder the XML builder
-    #
-    def to_xml(builder)
-      return if size.empty?
-
-      builder.size do
-        size.each { |s| s.to_xml builder }
-      end
-    end
-
-    #
-    # Render BibliographicSize object to AsciiBib.
-    #
-    # @param [String] prefix prefix for the size
-    #
-    # @return [String] AsciiBib string
-    #
-    def to_asciibib(prefix = "")
-      pref = prefix.empty? ? "size" : "#{prefix}.size"
-      size.map { |s| s.to_asciibib pref, size.size }.join
-    end
-
-    #
-    # Render BibliographicSize object to hash.
-    #
-    # @return [<Type>] <description>
-    #
-    def to_hash
-      size.map &:to_hash
-    end
-
-    class Value
-      # @return [String]
-      attr_reader :type, :value
-
-      #
-      # Initialize a BibliographicSize::Value object.
-      #
-      # @param [String] type the type of the size
-      # @param [String] value size value
-      #
-      def initialize(type:, value:)
-        @type = type
-        @value = value
-      end
-
-      #
-      # Render BibliographicSize::Value object to XML.
-      #
-      # @param [Nokogiri::XML::Builder] builder the XML builder
-      #
-      def to_xml(builder)
-        builder.value value, type: type
-      end
-
-      #
-      # Render BibliographicSize::Value object to hash.
-      #
-      # @return [<Type>] <description>
-      #
-      def to_hash
-        { type: type, value: value }
-      end
-
-      #
-      # Render BibliographicSize::Value object to AsciiBib.
-      #
-      # @param [String] prefix prefix for the size
-      # @param [Integer] size size of the array
-      #
-      # @return [String] AsciiBib string
-      #
-      def to_asciibib(prefix, size)
-        pref = prefix.empty? ? "" : "#{prefix}."
-        out = ""
-        out << "#{prefix}::\n" if size.size > 1
-        out << "#{pref}type:: #{type}\n"
-        out << "#{pref}value:: #{value}\n"
-      end
-    end
-  end
-end
diff --git a/lib/relaton_bib/classification.rb b/lib/relaton_bib/classification.rb
deleted file mode 100644
index 8d51e17..0000000
--- a/lib/relaton_bib/classification.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-module RelatonBib
-  class Classification
-    # @return [String, nil]
-    attr_reader :type
-
-    # @return [String]
-    attr_reader :value
-
-    # @param type [String, nil]
-    # @param value [String]
-    def initialize(type: nil, value:)
-      @type  = type
-      @value = value
-    end
-
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      xml = builder.classification value
-      xml[:type] = type if type
-    end
-
-    # @return [Hash]
-    def to_hash
-      hash = { "value" => value }
-      hash["type"] = type if type
-      hash
-    end
-
-    # @param prefix [String]
-    # @param count [Integer] number of classifications
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1)
-      pref = prefix.empty? ? "classification" : prefix + ".classification"
-      out = count > 1 ? "#{pref}::\n" : ""
-      out += "#{pref}.type:: #{type}\n" if type
-      out += "#{pref}.value:: #{value}\n"
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/config.rb b/lib/relaton_bib/config.rb
deleted file mode 100644
index c74ceed..0000000
--- a/lib/relaton_bib/config.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-module RelatonBib
-  module Config
-    def configure
-      yield configuration if block_given?
-    end
-
-    def configuration
-      @configuration ||= self::Configuration.new
-    end
-  end
-
-  class Configuration
-  end
-
-  extend Config
-end
diff --git a/lib/relaton_bib/contribution_info.rb b/lib/relaton_bib/contribution_info.rb
deleted file mode 100644
index f55825d..0000000
--- a/lib/relaton_bib/contribution_info.rb
+++ /dev/null
@@ -1,117 +0,0 @@
-# frozen_string_literal: true
-
-require "relaton_bib/person"
-
-# RelatonBib module
-module RelatonBib
-  # Contributor's role.
-  class ContributorRole
-    include RelatonBib
-
-    TYPES = %w[author performer publisher editor adapter translator
-               distributor realizer owner authorizer enabler subject].freeze
-
-    # @return [Array<RelatonBib::FormattedString>]
-    attr_reader :description
-
-    # @return [Strig]
-    attr_reader :type
-
-    # @param type [String] allowed types "author", "editor",
-    #   "cartographer", "publisher"
-    # @param description [Array<String>]
-    def initialize(**args)
-      if args[:type] && !TYPES.include?(args[:type])
-        Util.warn %{Contributor's type `#{args[:type]}` is invalid.}
-      end
-
-      @type = args[:type]
-      @description = args.fetch(:description, []).map do |d|
-        FormattedString.new content: d, format: nil
-      end
-    end
-
-    # @param opts [Hash]
-    # @option opts [Nokogiri::XML::Builder] :builder XML builder
-    # @option opts [String] :lang language
-    def to_xml(**opts) # rubocop:disable Metrics/AbcSize
-      opts[:builder].role(type: type) do |builder|
-        desc = description.select { |d| d.language&.include? opts[:lang] }
-        desc = description unless desc.any?
-        desc.each do |d|
-          builder.description { |b| d.to_xml(b) }
-        end
-      end
-    end
-
-    # @return [Hash, String]
-    def to_hash
-      hash = {}
-      hash["description"] = description.map(&:to_hash) if description&.any?
-      hash["type"] = type if type
-      hash
-    end
-
-    # @param prefix [String]
-    # @param count [Integer] number of contributors
-    # 2return [String]
-    def to_asciibib(prefix = "", count = 1)
-      pref = prefix.empty? ? prefix : "#{prefix}."
-      out = count > 1 ? "#{prefix}.role::\n" : ""
-      description.each do |d|
-        out += d.to_asciibib "#{pref}role.description", description.size
-      end
-      out += "#{pref}role.type:: #{type}\n" if type
-      out
-    end
-  end
-
-  # Contribution info.
-  class ContributionInfo
-    include RelatonBib
-
-    # @return [Array<RelatonBib::ContributorRole>]
-    attr_reader :role
-
-    # @return
-    #   [RelatonBib::Person, RelatonBib::Organization]
-    attr_reader :entity
-
-    # @param entity [RelatonBib::Person, RelatonBib::Organization]
-    # @param role [Array<Hash>]
-    # @option role [String] :type
-    # @option role [Array<String>] :description
-    def initialize(entity:, role: [])
-      if role.empty?
-        role << { type: entity.is_a?(Person) ? "author" : "publisher" }
-      end
-      @entity = entity
-      @role   = role.map { |r| ContributorRole.new(**r) }
-    end
-
-    # @param opts [Hash]
-    # @option opts [Nokogiri::XML::Builder] :builder XML builder
-    # @option opts [String, Symbol] :lang language
-    def to_xml(**opts)
-      entity.to_xml(**opts)
-    end
-
-    # @return [Hash]
-    def to_hash
-      hash = entity.to_hash
-      hash["role"] = single_element_array(role) if role&.any?
-      hash
-    end
-
-    # @param prefix [String]
-    # @param count [Integer] number of contributors
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1)
-      pref = prefix.split(".").first
-      out = count > 1 ? "#{pref}::\n" : ""
-      out += entity.to_asciibib prefix
-      role.each { |r| out += r.to_asciibib pref, role.size }
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/contributor.rb b/lib/relaton_bib/contributor.rb
deleted file mode 100644
index 91bf3ac..0000000
--- a/lib/relaton_bib/contributor.rb
+++ /dev/null
@@ -1,277 +0,0 @@
-# frozen_string_literal: true
-
-require "uri"
-
-module RelatonBib
-  # Address class.
-  class Address
-    # @return [Array<String>]
-    attr_reader :street
-
-    # @return [String, nil]
-    attr_reader :city, :state, :country, :postcode, :formatted_address
-
-    # @param street [Array<String>] streets
-    # @param city [String, nil] city, should be present or formatted address provided
-    # @param state [String, nil] state
-    # @param country [String, nil] country, should be present or formatted address provided
-    # @param postcode [String, nil] postcode
-    # @param formatted_address [String, nil] formatted address, should be present or city and country provided
-    def initialize(**args) # rubocop:disable Metrics/CyclomaticComplexity
-      unless args[:formatted_address] || (args[:city] && args[:country])
-        raise ArgumentError, "Either formatted address or city and country must be provided"
-      end
-
-      @street   = args[:street] || []
-      @city     = args[:city]
-      @state    = args[:state]
-      @country  = args[:country]
-      @postcode = args[:postcode]
-      @formatted_address = args[:formatted_address] unless args[:city] && args[:country]
-    end
-
-    def ==(other)
-      street == other.street && city == other.city && state == other.state &&
-        country == other.country && postcode == other.postcode &&
-        formatted_address == other.formatted_address
-    end
-
-    # @param doc [Nokogiri::XML::Document]
-    def to_xml(doc) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
-      doc.address do
-        if formatted_address
-          doc.formattedAddress formatted_address
-        else
-          street.each { |str| doc.street str }
-          doc.city city
-          doc.state state if state
-          doc.country country
-          doc.postcode postcode if postcode
-        end
-      end
-    end
-
-    # @return [Hash]
-    def to_hash # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
-      hash = { "address" => {} }
-      if formatted_address
-        hash["address"]["formatted_address"] = formatted_address
-      else
-        hash["address"]["street"] = street if street.any?
-        hash["address"]["city"] = city
-        hash["address"]["state"] = state if state
-        hash["address"]["country"] = country
-        hash["address"]["postcode"] = postcode if postcode
-      end
-      hash
-    end
-
-    # @param prefix [String]
-    # @param count [Integer] number of addresses
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
-      pref = prefix.empty? ? "address" : "#{prefix}.address"
-      if formatted_address
-        "#{pref}.formatted_address:: #{formatted_address}\n"
-      else
-        out = count > 1 ? "#{pref}::\n" : ""
-        street.each { |st| out += "#{pref}.street:: #{st}\n" }
-        out += "#{pref}.city:: #{city}\n"
-        out += "#{pref}.state:: #{state}\n" if state
-        out += "#{pref}.country:: #{country}\n"
-        out += "#{pref}.postcode:: #{postcode}\n" if postcode
-        out
-      end
-    end
-  end
-
-  # Contact class.
-  class Contact
-    # @return [String] allowed "phone", "email" or "uri"
-    attr_reader :type
-
-    # @return [String, nil]
-    attr_reader :subtype
-
-    # @return [String]
-    attr_reader :value
-
-    # @param type [String] allowed "phone", "email" or "uri"
-    # @param subtype [String, nil] i.e. "fax", "mobile", "landline" for "phone"
-    #                              or "work", "personal" for "uri" type
-    # @param value [String]
-    def initialize(type:, value:, subtype: nil)
-      @type     = type
-      @subtype  = subtype
-      @value    = value
-    end
-
-    def ==(other)
-      type == other.type && subtype == other.subtype && value == other.value
-    end
-
-    # @param builder [Nokogiri::XML::Document]
-    def to_xml(builder)
-      node = builder.send type, value
-      node["type"] = subtype if subtype
-    end
-
-    # @return [Hash]
-    def to_hash
-      hash = { type => value }
-      hash["type"] = subtype if subtype
-      hash
-    end
-
-    # @param prefix [String]
-    # @param count [Integer] number of contacts
-    # @return [string]
-    def to_asciibib(prefix = "", count = 1)
-      pref = prefix.empty? ? prefix : "#{prefix}."
-      out = count > 1 ? "#{pref}contact::\n" : ""
-      out += "#{pref}contact.#{type}:: #{value}\n"
-      out += "#{pref}contact.type:: #{subtype}\n" if subtype
-      out
-    end
-  end
-
-  # Affiliation.
-  class Affiliation
-    include RelatonBib
-
-    # @return [RelatonBib::LocalizedString, nil]
-    attr_reader :name
-
-    # @return [RelatonBib::Organization]
-    attr_reader :organization
-
-    # @param organization [RelatonBib::Organization, nil]
-    # @param name [RelatonBib::LocalizedString, nil]
-    # @param description [Array<RelatonBib::FormattedString>]
-    def initialize(organization: nil, name: nil, description: [])
-      @name = name
-      @organization = organization
-      @description  = description
-    end
-
-    def ==(other)
-      name == other.name && organization == other.organization && description == other.description
-    end
-
-    # @param opts [Hash]
-    # @option opts [Nokogiri::XML::Builder] :builder XML builder
-    # @option opts [String] :lang language
-    def to_xml(**opts)
-      return unless organization || name || description&.any?
-
-      opts[:builder].affiliation do |builder|
-        name_xml builder
-        description_xml builder
-        organization&.to_xml(**opts)
-      end
-    end
-
-    def name_xml(builder)
-      builder.name { name.to_xml builder } if name
-    end
-
-    def description_xml(builder)
-      description.each { |d| builder.description { d.to_xml builder } }
-    end
-
-    #
-    # Get description.
-    #
-    # @param [String, nil] lang language if nil return all description
-    #
-    # @return return [Array<RelatonBib::FormattedString>] description
-    #
-    def description(lang = nil)
-      return @description unless lang
-
-      @description.select { |d| d.language&.include? lang }
-    end
-
-    #
-    # Render affiliation as hash.
-    #
-    # @return [Hash]
-    #
-    def to_hash
-      hash = organization&.to_hash || {}
-      hash["name"] = name.to_hash if name
-      if description&.any?
-        hash["description"] = single_element_array(description)
-      end
-      hash
-    end
-
-    # @param prefix [String]
-    # @param count [Integer]
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1) # rubocop:disable Metrics/AbcSize
-      pref = prefix.empty? ? prefix : "#{prefix}."
-      out = count > 1 ? "#{pref}affiliation::\n" : ""
-      out += name.to_asciibib "#{pref}affiliation.name" if name
-      description.each do |d|
-        out += d.to_asciibib "#{pref}affiliation.description", description.size
-      end
-      out += organization.to_asciibib "#{pref}affiliation.*" if organization
-      out
-    end
-  end
-
-  # Contributor.
-  class Contributor
-    include RelatonBib
-
-    # @return [URI]
-    attr_reader :uri
-
-    # @return [Array<RelatonBib::Address, RelatonBib::Contact>]
-    attr_reader :contact
-
-    # @param url [String, nil]
-    # @param contact [Array<RelatonBib::Address, RelatonBib::Contact>]
-    def initialize(url: nil, contact: [])
-      @uri = URI url if url
-      @contact = contact
-    end
-
-    def ==(other)
-      uri == other.uri && contact == other.contact
-    end
-
-    # Returns url.
-    # @return [String]
-    def url
-      @uri.to_s
-    end
-
-    # @params builder [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      contact.each { |contact| contact.to_xml builder }
-    end
-
-    # @return [Hash]
-    def to_hash
-      hash = {}
-      hash["url"] = uri.to_s if uri
-      hash["contact"] = single_element_array(contact) if contact&.any?
-      hash
-    end
-
-    # @param prefix [String]
-    # @return [String]
-    def to_asciibib(prefix = "") # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
-      pref = prefix.empty? ? prefix : "#{prefix}."
-      out = ""
-      out += "#{pref}url:: #{uri}\n" if uri
-      addr = contact.select { |c| c.is_a? RelatonBib::Address }
-      addr.each { |ct| out += ct.to_asciibib prefix, addr.size }
-      cont = contact.select { |c| c.is_a? RelatonBib::Contact }
-      cont.each { |ct| out += ct.to_asciibib prefix, cont.size }
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/copyright_association.rb b/lib/relaton_bib/copyright_association.rb
deleted file mode 100644
index 06ccbd1..0000000
--- a/lib/relaton_bib/copyright_association.rb
+++ /dev/null
@@ -1,79 +0,0 @@
-module RelatonBib
-  # Copyright association.
-  class CopyrightAssociation
-    include RelatonBib
-
-    # @return [Date]
-    attr_reader :from
-
-    # @return [Date, nil]
-    attr_reader :to
-
-    # @return [String, nil]
-    attr_reader :scope
-
-    # @return [Array<RelatonBib::ContributionInfo>]
-    attr_reader :owner
-
-    # rubocop:disable Metrics/AbcSize
-
-    # @param owner [Array<Hash, RelatonBib::ContributionInfo>] contributor
-    # @option owner [String] :name
-    # @option owner [String] :abbreviation
-    # @option owner [String] :url
-    # @param from [String] date
-    # @param to [String, nil] date
-    # @param scope [String, nil]
-    def initialize(owner:, from:, to: nil, scope: nil)
-      unless owner.any?
-        raise ArgumentError, "at least one owner should exist."
-      end
-
-      @owner = owner.map do |o|
-        o.is_a?(Hash) ? ContributionInfo.new(entity: Organization.new(**o)) : o
-      end
-
-      @from  = Date.strptime(from.to_s, "%Y") if from.to_s.match?(/\d{4}/)
-      @to    = Date.strptime(to.to_s, "%Y") unless to.to_s.empty?
-      @scope = scope
-    end
-
-    # @param opts [Hash]
-    # @option opts [Nokogiri::XML::Builder] :builder XML builder
-    # @option opts [String, Symbol] :lang language
-    def to_xml(**opts)
-      opts[:builder].copyright do |builder|
-        builder.from from ? from.year : "unknown"
-        builder.to to.year if to
-        owner.each { |o| builder.owner { o.to_xml(**opts) } }
-        builder.scope scope if scope
-      end
-    end
-    # rubocop:enable Metrics/AbcSize
-
-    # @return [Hash]
-    def to_hash # rubocop:disable Metrics/AbcSize
-      owners = single_element_array(owner.map { |o| o.to_hash["organization"] })
-      hash = {
-        "owner" => owners,
-        "from" => from.year.to_s,
-      }
-      hash["to"] = to.year.to_s if to
-      hash["scope"] = scope if scope
-      hash
-    end
-
-    # @param prefix [String]
-    # @param count [Iteger] number of copyright elements
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
-      pref = prefix.empty? ? "copyright" : "#{prefix}.copyright"
-      out = count > 1 ? "#{pref}::\n" : ""
-      owner.each { |ow| out += ow.to_asciibib "#{pref}.owner", owner.size }
-      out += "#{pref}.from:: #{from.year}\n" if from
-      out += "#{pref}.to:: #{to.year}\n" if to
-      out += "#{pref}.scope:: #{scope}\n" if scope
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/document_identifier.rb b/lib/relaton_bib/document_identifier.rb
deleted file mode 100644
index e8f67a4..0000000
--- a/lib/relaton_bib/document_identifier.rb
+++ /dev/null
@@ -1,118 +0,0 @@
-module RelatonBib
-  # Document identifier.
-  class DocumentIdentifier
-    # @return [String]
-    attr_reader :id
-
-    # @return [String, nil]
-    attr_reader :type, :scope, :language, :script
-
-    # @param type [Boolean, nil]
-    attr_reader :primary
-
-    # @param id [String]
-    # @param type [String, nil]
-    # @param scope [String, nil]
-    # @param primary [Bolean, nil]
-    # @param language [String, nil]
-    def initialize(**args)
-      @id       = args[:id]
-      @type     = args[:type]
-      @scope    = args[:scope]
-      @primary  = args[:primary]
-      @language = args[:language]
-      @script   = args[:script]
-    end
-
-    # in docid manipulations, assume ISO as the default: id-part:year
-    def remove_part
-      case @type
-      when "Chinese Standard" then @id.sub!(/\.\d+/, "")
-      when "URN" then remove_urn_part
-      else @id.sub!(/-[^:]+/, "")
-      end
-    end
-
-    def remove_date
-      case @type
-      when "Chinese Standard" then @id.sub!(/-[12]\d\d\d/, "")
-      when "URN"
-        @id.sub!(/^(urn:iec:std:[^:]+:[^:]+:)[^:]*/, '\1')
-      else @id.sub!(/:[12]\d\d\d/, "")
-      end
-    end
-
-    def all_parts
-      if type == "URN"
-        @id.sub!(%r{^(urn:iec:std(?::[^:]*){4}).*}, '\1:ser')
-      else
-        @id += " (all parts)"
-      end
-    end
-
-    #
-    # Add docidentifier xml element
-    #
-    # @param opts [Hash]
-    # @option opts [Nokogiri::XML::Builder] :builder XML builder
-    # @option opts [String] :lang language
-    def to_xml(**opts) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
-      lid = if type == "URN" && opts[:lang]
-              id.sub %r{(?<=:)(?:\w{2},)*?(#{opts[:lang]})(?:,\w{2})*}, '\1'
-            else id
-            end
-      element = opts[:builder].docidentifier { |b| b.parent.inner_html = lid }
-      element[:type] = type if type
-      element[:scope] = scope if scope
-      element[:primary] = primary if primary
-      element[:language] = language if language
-      element[:script] = script if script
-    end
-
-    # @return [Hash]
-    def to_hash # rubocop:disable Metrics/AbcSize
-      hash = { "id" => id }
-      hash["type"] = type if type
-      hash["scope"] = scope if scope
-      hash["primary"] = primary if primary
-      hash["language"] = language if language
-      hash["script"] = script if script
-      hash
-    end
-
-    # @param prefix [String]
-    # @param count [Integer] number of docids
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
-      pref = prefix.empty? ? prefix : "#{prefix}."
-      return "#{pref}docid:: #{id}\n" unless type || scope
-
-      out = count > 1 ? "#{pref}docid::\n" : ""
-      out += "#{pref}docid.type:: #{type}\n" if type
-      out += "#{pref}docid.scope:: #{scope}\n" if scope
-      out += "#{pref}docid.primary:: #{primary}\n" if primary
-      out += "#{pref}docid.language:: #{language}\n" if language
-      out += "#{pref}docid.script:: #{script}\n" if script
-      out + "#{pref}docid.id:: #{id}\n"
-    end
-
-    private
-
-    def remove_urn_part # rubocop:disable Metrics/MethodLength
-      @id.sub!(%r{^
-        (urn:iso:std:[^:]+ # ISO prefix and originator
-          (?::(?:data|guide|isp|iwa|pas|r|tr|ts|tta)) # type
-          ?:\d+) # docnumber
-        (?::-[^:]+)? # partnumber
-        (?::(draft|cancelled|stage-[^:]+))? # status
-        (?::ed-\d+)?(?::v[^:]+)? # edition and version
-        (?::\w{2}(?:,\w{2})*)? # langauge
-      }x, '\1') # remove partnumber, status, version, and language
-      @id.sub!(%r{^
-        (urn:iec:std:[^:]+ # IEC prefix and originator
-          :\d+) # docnumber
-        (?:-[^:]+)? # partnumber
-      }x, '\1') # remove partnumber
-    end
-  end
-end
diff --git a/lib/relaton_bib/document_relation.rb b/lib/relaton_bib/document_relation.rb
deleted file mode 100644
index b27c197..0000000
--- a/lib/relaton_bib/document_relation.rb
+++ /dev/null
@@ -1,95 +0,0 @@
-module RelatonBib
-  # Documett relation
-  class DocumentRelation
-    include RelatonBib
-
-    TYPES = %w[
-      includes includedIn hasPart partOf merges mergedInto splits splitInto
-      instanceOf hasInstance exemplarOf hasExemplar manifestationOf
-      hasManifestation reproductionOf hasReproduction reprintOf hasReprint
-      expressionOf hasExpression translatedFrom hasTranslation arrangementOf
-      hasArrangement abridgementOf hasAbridgement annotationOf hasAnnotation
-      draftOf hasDraft editionOf hasEdition updates updatedBy derivedFrom
-      derives describes describedBy catalogues cataloguedBy hasSuccessor
-      successorOf adaptedFrom hasAdaptation adoptedFrom adoptedAs reviewOf
-      hasReview commentaryOf hasCommentary related hasComplement complementOf
-      obsoletes obsoletedBy cites isCitedIn
-    ].freeze
-
-    # @return [String]
-    attr_accessor :type
-
-    # @return [RelatonBib::FormattedString, nil]
-    attr_reader :description
-
-    # @return [String]
-    # attr_reader :identifier, :url
-
-    # @return [RelatonBib::BibliographicItem]
-    attr_reader :bibitem
-
-    # @return [Array<RelatonBib::Locality, RelatonBib::LocalityStack>]
-    attr_reader :locality
-
-    # @return [Array<RelatonBib::SourceLocality,
-    #   RelatonBib::SourceLocalityStack>]
-    attr_reader :source_locality
-
-    # @param type [String]
-    # @param description [RelatonBib::FormattedString, nil]
-    # @param bibitem [RelatonBib::BibliographicItem,
-    #   RelatonIso::IsoBibliographicItem]
-    # @param locality [Array<RelatonBib::Locality>]
-    # @param locality_stack [Array<RelatonBib::LocalityStack>]
-    # @param source_locality [Array<RelatonBib::SourceLocality,
-    #   RelatonBib::SourceLocalityStack>]
-    def initialize(type:, bibitem:, **args)
-      type = "obsoletes" if type == "Now withdrawn"
-      unless self.class::TYPES.include? type
-        Util.warn "Invalid relation type: `#{type}`"
-      end
-      @type = type
-      @description = args[:description]
-      @locality = args[:locality] || args[:locality_stack] || []
-      @source_locality = args[:source_locality] || args[:source_locality_stack] || []
-      @bibitem = bibitem
-    end
-
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder, **opts)
-      opts.delete :bibdata
-      opts.delete :note
-      builder.relation(type: type) do
-        builder.description { description.to_xml builder } if description
-        bibitem.to_xml(**opts.merge(builder: builder, embedded: true))
-        locality.each { |l| l.to_xml builder }
-        source_locality.each { |l| l.to_xml builder }
-      end
-    end
-
-    # @return [Hash]
-    def to_hash # rubocop:disable Metrics/AbcSize
-      hash = { "type" => type, "bibitem" => bibitem.to_hash(embedded: true) }
-      hash["description"] = description.to_hash if description
-      locality.each_with_object(hash) do |l, obj|
-        k, v = l.to_hash.first
-        hash[k] ||= []
-        hash[k] << v
-      end
-      if source_locality&.any?
-        hash["source_locality"] = single_element_array(source_locality)
-      end
-      hash
-    end
-
-    # @param prefix [String]
-    # @return [String]
-    def to_asciibib(prefix = "")
-      pref = prefix.empty? ? prefix : prefix + "."
-      out = "#{prefix}.type:: #{type}\n"
-      out += description.to_asciibib "#{pref}desctiption" if description
-      out += bibitem.to_asciibib "#{pref}bibitem" if bibitem
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/document_relation_collection.rb b/lib/relaton_bib/document_relation_collection.rb
deleted file mode 100644
index aab6d07..0000000
--- a/lib/relaton_bib/document_relation_collection.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-# frozen_string_literal: true
-
-module RelatonBib
-  # Document relation collection
-  class DocRelationCollection
-    extend Forwardable
-
-    def_delegators :@array, :<<, :[], :first, :last, :empty?, :any?, :size,
-                   :each, :detect, :map, :reduce, :length, :unshift, :max_by
-
-    # @param relation [Array<RelatonBib::DocumentRelation, Hash>]
-    # @option relation [String] :type
-    # @option relation [String] :identifier
-    # @option relation [String, NIllClass] :url (nil)
-    # @option relation [Array<RelatonBib::Locality, RelatonBib::LocalityStack>] :locality
-    # @option relation [Array<RelatonBib::SourceLocality, RelatonBib::SourceLocalityStack>] :source_locality
-    # @option relation [RelatonBib::BibliographicItem, nil] :bibitem (nil)
-    def initialize(relation)
-      @array = relation.map { |r| r.is_a?(Hash) ? DocumentRelation.new(**r) : r }
-    end
-
-    #
-    # Returns new DocumentRelationCollection with selected relations.
-    #
-    # @example Select relations with type "obsoletes"
-    #   relations.select { |r| r.type == "obsoletes" }
-    #   #=> <RelatonBib::DocRelationCollection:0x00007f9a0191d5f0 @array=[...]>
-    #
-    # @return [RelatonBib::DocRelationCollection] new DocumentRelationCollection
-    #   with selected relations
-    #
-    def select(&block)
-      arr = @array.select(&block)
-      self.class.new arr
-    end
-
-    # @todo We don't have replace type anymore. Suppose we should update this
-    #   method or delete it.
-    #
-    # @return [RelatonBib::DocRelationCollection]
-    def replaces
-      DocRelationCollection.new(@array.select { |r| r.type == "replace" })
-    end
-
-    # @param prefix [String]
-    # @return [String]
-    def to_asciibib(prefix = "")
-      pref = prefix.empty? ? "relation" : "#{prefix}.relation"
-      out = ""
-      @array.each do |r|
-        out += size > 1 ? "#{pref}::\n" : ""
-        out += r.to_asciibib pref
-      end
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/document_status.rb b/lib/relaton_bib/document_status.rb
deleted file mode 100644
index c23e6b9..0000000
--- a/lib/relaton_bib/document_status.rb
+++ /dev/null
@@ -1,92 +0,0 @@
-# frozen_string_literal: true
-
-module RelatonBib
-  # Document status.
-  class DocumentStatus
-    # @return [RelatonBib::DocumentStatus::Stage]
-    attr_reader :stage
-
-    # @return [RelatonBib::DocumentStatus::Stage, nil]
-    attr_reader :substage
-
-    # @return [String, nil]
-    attr_reader :iteration
-
-    # @param stage [String, Hash, RelatonBib::DocumentStatus::Stage]
-    # @param substage [String, Hash, nil, RelatonBib::DocumentStatus::Stage]
-    # @param iteration [String, nil]
-    def initialize(stage:, substage: nil, iteration: nil)
-      @stage = stage_new stage
-      @substage = stage_new substage
-      @iteration = iteration
-    end
-
-    # @param [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      builder.status do
-        # FormattedString.instance_method(:to_xml).bind(status).call builder
-        builder.stage { |b| stage.to_xml b }
-        builder.substage { |b| substage.to_xml b } if substage
-        builder.iteration iteration unless iteration.to_s.empty?
-      end
-    end
-
-    # @return [Hash]
-    def to_hash
-      hash = { "stage" => stage.to_hash }
-      hash["substage"] = substage.to_hash if substage
-      hash["iteration"] = iteration if iteration
-      hash
-    end
-
-    # @param prefix [String]
-    # @return [String]
-    def to_asciibib(prefix = "")
-      pref = prefix.empty? ? prefix : "#{prefix}."
-      out = "#{pref}docstatus.stage:: #{stage.value}\n"
-      out += "#{pref}docstatus.substage:: #{substage.value}\n" if substage
-      out += "#{pref}docstatus.iteration:: #{iteration}\n" if iteration
-      out
-    end
-
-    private
-
-    # @param stg [RelatonBib::DocumentStatus::Stage, Hash, String, nil]
-    # @return [RelatonBib::DocumentStatus::Stage]
-    def stage_new(stg)
-      case stg
-      when Stage then stg
-      when Hash then self.class::Stage.new(**stg)
-      when String then self.class::Stage.new(value: stg)
-      end
-    end
-
-    class Stage
-      # @return [String]
-      attr_reader :value
-
-      # @return [String, nil]
-      attr_reader :abbreviation
-
-      # @param value [String]
-      # @param abbreviation [String, nil]
-      def initialize(value:, abbreviation: nil)
-        @value = value
-        @abbreviation = abbreviation
-      end
-
-      # @param [Nokogiri::XML::Builder]
-      def to_xml(builder)
-        builder.parent[:abbreviation] = abbreviation if abbreviation
-        builder.text value
-      end
-
-      # @return [Hash]
-      def to_hash
-        hash = { "value" => value }
-        hash["abbreviation"] = abbreviation if abbreviation
-        hash
-      end
-    end
-  end
-end
diff --git a/lib/relaton_bib/document_type.rb b/lib/relaton_bib/document_type.rb
deleted file mode 100644
index cd26aa9..0000000
--- a/lib/relaton_bib/document_type.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-module RelatonBib
-  class DocumentType
-    attr_reader :type, :abbreviation
-
-    #
-    # Initialize a DocumentType.
-    #
-    # @param [String] type document type
-    # @param [String, nil] abbreviation type abbreviation
-    #
-    def initialize(type:, abbreviation: nil)
-      @type = type
-      @abbreviation = abbreviation
-    end
-
-    #
-    # Build XML representation of the document type.
-    #
-    # @param [Nokogiri::XML::Builder] builder XML builder
-    #
-    def to_xml(builder)
-      xml = builder.doctype @type
-      xml[:abbreviation] = @abbreviation if @abbreviation
-    end
-
-    #
-    # Hash representation of the document type.
-    #
-    # @return [Hash]
-    #
-    def to_hash
-      hash = { "type" => @type }
-      hash["abbreviation"] = @abbreviation if @abbreviation
-      hash
-    end
-
-    #
-    # Asciibib representation of the document type.
-    #
-    # @param [String] prefix prefix
-    #
-    # @return [String] AsciiBib representation
-    #
-    def to_asciibib(prefix = "")
-      pref = prefix.empty? ? prefix : "#{prefix}."
-      pref += "doctype."
-      out = "#{pref}type:: #{@type}\n"
-      out += "#{pref}abbreviation:: #{@abbreviation}\n" if @abbreviation
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/edition.rb b/lib/relaton_bib/edition.rb
deleted file mode 100644
index 18c267f..0000000
--- a/lib/relaton_bib/edition.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-module RelatonBib
-  class Edition
-    # @return [String] edition
-    attr_reader :content
-
-    # @return [String, nil] number
-    attr_reader :number
-
-    #
-    # Initialize edition.
-    #
-    # @param [String, Integer, Float] content edition
-    # @param [String, Integer, Float, nil] number number
-    #
-    def initialize(content:, number: nil)
-      @content = content.to_s
-      @number = number&.to_s
-    end
-
-    #
-    # Render edition as XML.
-    #
-    # @param [Nokogiri::XML::Builder] builder XML builder
-    #
-    def to_xml(builder)
-      node = builder.edition(content)
-      node[:number] = number if number
-    end
-
-    #
-    # Return edition as hash.
-    #
-    # @return [Hash] edition as hash.
-    #
-    def to_hash
-      hash = { "content" => content }
-      hash["number"] = number if number
-      hash
-    end
-
-    #
-    # Render edition as AsciiBib.
-    #
-    # @param [String] prefix prefix
-    #
-    # @return [String] edition as AsciiBib.
-    #
-    def to_asciibib(prefix = "")
-      pref = prefix.empty? ? "edition" : "#{prefix}.edition"
-      out = "#{pref}.content:: #{content}\n"
-      out += "#{pref}.number:: #{number}\n" if number
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/editorial_group.rb b/lib/relaton_bib/editorial_group.rb
deleted file mode 100644
index 41908b7..0000000
--- a/lib/relaton_bib/editorial_group.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-require "relaton_bib/technical_committee"
-
-module RelatonBib
-  class EditorialGroup
-    include RelatonBib
-
-    # @return [Array<RelatonBib::TechnicalCommittee>]
-    attr_accessor :technical_committee
-
-    # @param technical_committee [Array<RelatonBib::TechnicalCommittee>]
-    def initialize(technical_committee)
-      @technical_committee = technical_committee
-    end
-
-    # @param builder [Nokogigi::XML::Builder]
-    def to_xml(builder)
-      builder.editorialgroup do |b|
-        technical_committee.each { |tc| tc.to_xml b }
-      end
-    end
-
-    # @return [Hash]
-    def to_hash
-      single_element_array technical_committee
-    end
-
-    # @param prefix [String]
-    # @return [String]
-    def to_asciibib(prefix = "")
-      pref = prefix.empty? ? "editorialgroup" : "#{prefix}.editorialgroup"
-      technical_committee.map do |tc|
-        tc.to_asciibib pref, technical_committee.size
-      end.join
-    end
-
-    # @return [true]
-    def presence?
-      technical_committee.any?
-    end
-  end
-end
diff --git a/lib/relaton_bib/extent.rb b/lib/relaton_bib/extent.rb
deleted file mode 100644
index 7061b8a..0000000
--- a/lib/relaton_bib/extent.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-module RelatonBib
-  class Extent
-    attr_accessor :locality
-
-    #
-    # @param [Array<RelatonBib::Locality, RelatonBib::LocalityStack>] locality
-    #
-    def initialize(locality)
-      @locality = locality
-    end
-
-    def to_xml(builder)
-      builder.extent do |b|
-        locality.each { |l| l.to_xml(b) }
-      end
-    end
-
-    def to_hash
-      hash = Hash.new { |h, k| h[k] = [] }
-      locality.each_with_object(hash) do |l, obj|
-        k, v = l.to_hash.first
-        obj[k] << v
-      end
-    end
-
-    def to_asciibib(prefix = "", count = 1)
-      pref = prefix.empty? ? "extent" : "#{prefix}.extent"
-      out = count > 1 ? "#{pref}::\n" : ""
-      locality.each do |l|
-        out += l.to_asciibib(pref, locality.size)
-      end
-      out
-    end
-
-    def to_bibtex(item)
-      locality.map { |l| l.to_bibtex(item) }.join
-    end
-  end
-end
diff --git a/lib/relaton_bib/forename.rb b/lib/relaton_bib/forename.rb
deleted file mode 100644
index a09edcd..0000000
--- a/lib/relaton_bib/forename.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-module RelatonBib
-  class Forename < LocalizedString
-    # @return [String, nil]
-    attr_accessor :initial
-
-    #
-    # Initialize Forename instance
-    #
-    # @param [String] content content of forename, can be empty
-    # @param [Array<String>] language languages, `en`, `fr`, `de` etc.
-    # @param [Array<String>] script scripts `Latn`, `Cyrl` etc.
-    # @param [String, nil] initial initial of forename
-    #
-    def initialize(content: nil, language: [], script: [], initial: nil)
-      @initial = initial
-      super content, language, script
-    end
-
-    def ==(other)
-      super && initial == other.initial
-    end
-
-    def to_s
-      content.nil? ? initial : super
-    end
-
-    #
-    # Render forename to XML
-    #
-    # @param [Nokogiri::XML::Builder] builder XML builder
-    #
-    def to_xml(builder)
-      node = builder.forename { super }
-      node[:initial] = initial if initial
-    end
-
-    #
-    # Render forename to hash
-    #
-    # @return [Hash, String] forename hash or string representation
-    #
-    def to_hash
-      ls = super
-      hash = ls.is_a?(Hash) ? ls : { "content" => ls }
-      hash["initial"] = initial if initial
-      hash
-    end
-
-    #
-    # Render forename to asciibib
-    #
-    # @param [String] pref prefix
-    # @param [Integer] count size of array
-    #
-    # @return [String] asciibib string
-    #
-    def to_asciibib(pref, count = 1)
-      prf = pref.empty? ? pref : "#{pref}."
-      prf += "forename"
-      out = super prf, count
-      out += "#{prf}.initial:: #{initial}\n" if initial
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/formatted_ref.rb b/lib/relaton_bib/formatted_ref.rb
deleted file mode 100644
index f89f7f1..0000000
--- a/lib/relaton_bib/formatted_ref.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-require "relaton_bib/formatted_string"
-
-module RelatonBib
-  class FormattedRef < FormattedString
-    # @param [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      builder.formattedref { super }
-    end
-
-    # @param prefix [String]
-    # @return [String]
-    def to_asciibib(prefix = "")
-      pref = prefix.empty? ? "formattedref" : "#{prefix}.formattedref"
-      super pref
-    end
-  end
-end
diff --git a/lib/relaton_bib/formatted_string.rb b/lib/relaton_bib/formatted_string.rb
deleted file mode 100644
index 7d78816..0000000
--- a/lib/relaton_bib/formatted_string.rb
+++ /dev/null
@@ -1,133 +0,0 @@
-# frozen_string_literal: true
-
-require "relaton_bib/localized_string"
-
-module RelatonBib
-  # Formatted string
-  class FormattedString < LocalizedString
-    FORMATS = %w[text/plain text/html application/docbook+xml
-                 application/tei+xml text/x-asciidoc text/markdown
-                 application/x-metanorma+xml].freeze
-
-    # @return [String]
-    attr_reader :format
-
-    # @param content [String, Array<RelatonBib::LocalizedString>]
-    # @param language [String, nil] language code Iso639
-    # @param script [String, nil] script code Iso15924
-    # @param format [String] the content type
-    def initialize(content: "", language: nil, script: nil, format: "text/plain")
-      # if format && !FORMATS.include?(format)
-      #   raise ArgumentError, %{Format "#{format}" is invalid.}
-      # end
-
-      @format = format
-      super(content, language, script)
-    end
-
-    def ==(other)
-      super && format == other.format
-    end
-
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      builder.parent["format"] = format if format
-      super
-    end
-
-    #
-    # Encode content.
-    #
-    # @param [String] cnt content
-    #
-    # @return [String] encoded content
-    #
-    def encode(cnt) # rubocop:disable Metrics/MethodLength
-      return escp(cnt) unless format == "text/html"
-
-      parts = cnt.scan(%r{
-        <(?<tago>\w+)(?<attrs>[^>]*)> | # tag open
-        </(?<tagc>\w+)> | # tag close
-        (?<cmt><!--.*?-->) | # comment
-        (?<cnt>.+?)(?=<|$) # content
-        }x)
-      scan_xml parts
-    end
-
-    #
-    # Scan XML and escape HTML entities.
-    #
-    # @param [Array<Array<String,nil>>] parts XML parts
-    #
-    # @return [String] output string
-    #
-    def scan_xml(parts) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/MethodLength
-      return "" unless parts.any?
-
-      out = ""
-      while parts.any? && (parts.first[3] || parts.first[4])
-        _, _, _, cmt, cnt = parts.shift
-        out += "#{cmt}#{escp(cnt)}"
-      end
-      unless out.empty?
-        out += scan_xml(parts) if parts.any? && parts.first[0]
-        return out
-      end
-
-      tago, attrs, tagc, = parts.shift
-      out = if tago && attrs && attrs[-1] == "/"
-              "<#{tago}#{attrs}>"
-            elsif tago
-              inr = scan_xml parts
-              _, _, tagc, = parts.shift
-              if tago == tagc
-                "<#{tago}#{attrs}>#{inr}</#{tagc}>"
-              else
-                "#{escp("<#{tago}#{attrs}>")}#{inr}#{escp("</#{tagc}>")}"
-              end
-            end
-      out += scan_xml(parts) if parts.any? && (parts.first[0] || parts.first[3] || parts.first[4])
-      out
-    end
-
-    # @return [Hash]
-    def to_hash
-      hash = super
-      return hash unless format
-
-      hash = { "content" => hash } unless hash.is_a? Hash
-      hash["format"] = format
-      hash
-    end
-
-    # @param prefix [String]
-    # @param count [Integer] number of elements
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1, has_attrs = false)
-      has_attrs ||= !(format.nil? || format.empty?)
-      pref = prefix.empty? ? prefix : "#{prefix}."
-      # out = count > 1 ? "#{prefix}::\n" : ""
-      out = super
-      out += "#{pref}format:: #{format}\n" if format
-      out
-    end
-
-    #
-    # Remove HTML tags except <em>, <strong>, <stem>, <sup>, <sub>, <tt>, <br>, <p>.
-    # Replace <i> with <em>, <b> with <strong>.
-    #
-    # @param [String] str content
-    #
-    # @return [String] cleaned content
-    #
-    def cleanup(str)
-      return str unless format == "text/html"
-
-      str.gsub(/(?<=<)\w+:(?=\w+>)/, "").gsub(/(?<=<\/)\w+:(?=\w+>)/, "")
-        .gsub(/<i>/, "<em>").gsub(/<\/i>/, "</em>")
-        .gsub(/<b>/, "<strong>").gsub(/<\/b>/, "</strong>")
-        .gsub(/<(?!\/?(em|strong|stem|sup|sub|tt|br\s?\/|p|ol|ul|li))[^\s!]\/?.*?>/i, "")
-        .gsub(/\s+([.,:;!?<])/, "\\1").strip.squeeze(" ")
-    end
-  end
-end
diff --git a/lib/relaton_bib/full_name.rb b/lib/relaton_bib/full_name.rb
deleted file mode 100644
index 8063054..0000000
--- a/lib/relaton_bib/full_name.rb
+++ /dev/null
@@ -1,106 +0,0 @@
-module RelatonBib
-  # Person's full name
-  class FullName
-    include RelatonBib
-
-    # @return [Array<RelatonBib::Forename>]
-    attr_accessor :forename
-
-    # @return [Array<RelatonBib::LocalizedString>]
-    attr_accessor :initials, :addition, :prefix
-
-    # @return [RelatonBib::LocalizedString, nil]
-    attr_accessor :surname, :abbreviation, :completename
-
-    #
-    # Initialize FullName instance
-    #
-    # @param surname [RelatonBib::LocalizedString, nil] surname or completename should be present
-    # @param abbreviation [RelatonBib::LocalizedString, nil] abbreviation
-    # @param forename [Array<RelatonBib::Forename>] forename
-    # @param initials [RelatonBib::LocalizedString, String, nil] string of initials
-    # @param addition [Array<RelatonBib::LocalizedString>] array of additions
-    # @param prefix [Array<RelatonBib::LocalizedString>] array of prefixes
-    # @param completename [RelatonBib::LocalizedString, nil] completename or surname should be present
-    #
-    def initialize(**args) # rubocop:disable Metrics/AbcSize
-      unless args[:surname] || args[:completename]
-        raise ArgumentError, "Should be given :surname or :completename"
-      end
-
-      @surname      = args[:surname]
-      @abbreviation = args[:abbreviation]
-      @forename     = args.fetch :forename, []
-      @initials     = args[:initials].is_a?(String) ? LocalizedString.new(args[:initials]) : args[:initials]
-      @addition     = args.fetch :addition, []
-      @prefix       = args.fetch :prefix, []
-      @completename = args[:completename]
-    end
-
-    def ==(other)
-      surname == other.surname && abbreviation == other.abbreviation && completename == other.completename &&
-        forename == other.forename && initials == other.initials && addition == other.addition && prefix == other.prefix
-    end
-
-    # @param opts [Hash]
-    # @option opts [Nokogiri::XML::Builder] :builder XML builder
-    # @option opts [String] :lang language
-    def to_xml(**opts) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
-      opts[:builder].name do |builder|
-        builder.abbreviation { abbreviation.to_xml builder } if abbreviation
-        if completename
-          builder.completename { completename.to_xml builder }
-        else
-          pref = prefix.select { |p| p.language&.include? opts[:lang] }
-          pref = prefix unless pref.any?
-          pref.each { |p| builder.prefix { p.to_xml builder } }
-          frnm = forename.select { |f| f.language&.include? opts[:lang] }
-          frnm = forename unless frnm.any?
-          frnm.each { |f| f.to_xml builder }
-          builder.send(:"formatted-initials") { initials.to_xml builder } if initials
-          builder.surname { surname.to_xml builder }
-          addn = addition.select { |a| a.language&.include? opts[:lang] }
-          addn = addition unless addn.any?
-          addn.each { |a| builder.addition { a.to_xml builder } }
-        end
-      end
-    end
-
-    # @return [Hash]
-    def to_hash # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/MethodLength
-      hash = {}
-      hash["abbreviation"] = abbreviation.to_hash if abbreviation
-      if forename.any? || initials
-        hash["given"] = {}
-        hash["given"]["forename"] = single_element_array(forename) if forename&.any?
-        hash["given"]["formatted_initials"] = initials.to_hash if initials
-      end
-      hash["surname"] = surname.to_hash if surname
-      hash["addition"] = single_element_array(addition) if addition&.any?
-      hash["prefix"] = single_element_array(prefix) if prefix&.any?
-      hash["completename"] = completename.to_hash if completename
-      hash
-    end
-
-    # @param pref [String]
-    # @return [String]
-    def to_asciibib(pref) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
-      prf = pref.empty? ? pref : "#{pref}."
-      prf += "name"
-      out = ""
-      out += abbreviation.to_asciibib "#{prf}.abbreviation" if abbreviation
-      given = "#{pref}.given"
-      out += forename.map do |fn|
-        fn.to_asciibib given, forename.size
-      end.join
-      out += initials.to_asciibib "#{given}.formatted-initials" if initials
-      out += surname.to_asciibib "#{prf}.surname" if surname
-      addition.each do |ad|
-        out += ad.to_asciibib "#{prf}.addition", addition.size
-      end
-      prefix.each { |pr| out += pr.to_asciibib "#{prf}.prefix", prefix.size }
-      out += completename.to_asciibib "#{prf}.completename" if completename
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/hash_converter.rb b/lib/relaton_bib/hash_converter.rb
deleted file mode 100644
index 81ce265..0000000
--- a/lib/relaton_bib/hash_converter.rb
+++ /dev/null
@@ -1,568 +0,0 @@
-module RelatonBib
-  module HashConverter
-    extend self
-    # @param args [Hash]
-    # @return [Hash]
-    def hash_to_bib(args) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
-      return nil unless args.is_a?(Hash)
-
-      ret = Marshal.load(Marshal.dump(symbolize(args))) # deep copy
-      title_hash_to_bib(ret)
-      link_hash_to_bib(ret)
-      language_hash_to_bib(ret)
-      script_hash_to_bib(ret)
-      dates_hash_to_bib(ret)
-      docid_hash_to_bib(ret)
-      version_hash_to_bib(ret)
-      biblionote_hash_to_bib(ret)
-      abstract_hash_to_bib(ret)
-      formattedref_hash_to_bib(ret)
-      docstatus_hash_to_bib(ret)
-      contributors_hash_to_bib(ret)
-      copyright_hash_to_bib(ret)
-      relations_hash_to_bib(ret)
-      series_hash_to_bib(ret)
-      medium_hash_to_bib(ret)
-      place_hash_to_bib(ret)
-      extent_hash_to_bib(ret)
-      size_hash_to_bib(ret)
-      accesslocation_hash_to_bib(ret)
-      classification_hash_to_bib(ret)
-      validity_hash_to_bib(ret)
-      keyword_hash_to_bib(ret)
-      # ret[:keyword] = RelatonBib.array(ret[:keyword])
-      ret[:license] = RelatonBib.array(ret[:license])
-      # editorialgroup_hash_to_bib ret
-      # ics_hash_to_bib ret
-      # structuredidentifier_hash_to_bib ret
-      # doctype_hash_to_bib ret
-      ext_has_to_bib ret
-      ret
-    end
-
-    def ext_has_to_bib(ret)
-      doctype_hash_to_bib ret
-      ret[:subdoctype] = ret[:ext][:subdoctype] if ret.dig(:ext, :subdoctype)
-      editorialgroup_hash_to_bib ret
-      ics_hash_to_bib ret
-      structuredidentifier_hash_to_bib ret
-    end
-
-    def keyword_hash_to_bib(ret)
-      ret[:keyword] = RelatonBib.array(ret[:keyword]).map do |keyword|
-        localizedstring keyword
-      end
-    end
-
-    def extent_hash_to_bib(ret)
-      return unless ret[:extent]
-
-      ret[:extent] = RelatonBib.array(ret[:extent]).map do |e|
-        RelatonBib::Extent.new locality(e)
-      end
-    end
-
-    def locality(loc)
-      if loc[:locality_stack]
-        RelatonBib.array(loc[:locality_stack]).map do |l|
-          LocalityStack.new locality(l)
-        end
-      else
-        RelatonBib.array(loc[:locality]).map do |l|
-          Locality.new(l[:type], l[:reference_from], l[:reference_to])
-        end
-      end
-    end
-
-    def size_hash_to_bib(ret)
-      return unless ret[:size]
-
-      ret[:size] = RelatonBib.array(ret[:size])
-      size = ret[:size]&.map do |val|
-        BibliographicSize::Value.new(**val)
-      end
-      ret[:size] = BibliographicSize.new(size)
-    end
-
-    def title_hash_to_bib(ret)
-      return unless ret[:title]
-
-      ret[:title] = RelatonBib.array(ret[:title])
-        .reduce(TypedTitleStringCollection.new) do |m, t|
-        if t.is_a?(Hash) then m << TypedTitleString.new(**t)
-        else
-          m + TypedTitleString.from_string(t)
-        end
-      end
-    end
-
-    def language_hash_to_bib(ret)
-      return unless ret[:language]
-
-      ret[:language] = RelatonBib.array(ret[:language])
-    end
-
-    def script_hash_to_bib(ret)
-      return unless ret[:script]
-
-      ret[:script] = RelatonBib.array(ret[:script])
-    end
-
-    def abstract_hash_to_bib(ret)
-      return unless ret[:abstract]
-
-      ret[:abstract] = RelatonBib.array(ret[:abstract]).map do |a|
-        a.is_a?(String) ? FormattedString.new(content: a) : a
-      end
-    end
-
-    def link_hash_to_bib(ret)
-      return unless ret[:link]
-
-      ret[:link] = RelatonBib.array(ret[:link])
-    end
-
-    def place_hash_to_bib(ret)
-      return unless ret[:place]
-
-      ret[:place] = RelatonBib.array(ret[:place]).map do |pl|
-        pl.is_a?(String) ? Place.new(name: pl) : Place.new(**pl)
-      end
-    end
-
-    def accesslocation_hash_to_bib(ret)
-      return unless ret[:accesslocation]
-
-      ret[:accesslocation] = RelatonBib.array(ret[:accesslocation])
-    end
-
-    def dates_hash_to_bib(ret) # rubocop:disable Metrics/AbcSize
-      return unless ret[:date]
-
-      ret[:date] = RelatonBib.array(ret[:date])
-      ret[:date].each_with_index do |d, i|
-        # value is synonym of on: it is reserved word in YAML
-        if d[:value]
-          ret[:date][i][:on] ||= d[:value]
-          ret[:date][i].delete(:value)
-        end
-      end
-    end
-
-    def docid_hash_to_bib(ret) # rubocop:disable Metrics/AbcSize
-      return unless ret[:docid]
-
-      ret[:docid] = RelatonBib.array(ret[:docid]).map do |id|
-        id[:type] ||= id[:id].match(/^\w+(?=\s)/)&.to_s
-        create_docid(**id)
-      end
-    end
-
-    def create_docid(**args)
-      DocumentIdentifier.new(**args)
-    end
-
-    def version_hash_to_bib(ret)
-      return unless ret[:version]
-
-      ret[:version] = RelatonBib.array(ret[:version]).map do |v|
-        BibliographicItem::Version.new(v[:revision_date], v[:draft])
-      end
-    end
-
-    def biblionote_hash_to_bib(ret) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
-      return unless ret[:biblionote]
-
-      ret[:biblionote] = RelatonBib.array(ret[:biblionote])
-        .reduce(BiblioNoteCollection.new([])) do |mem, n|
-        mem << if n.is_a?(String) then BiblioNote.new content: n
-                else BiblioNote.new(**n)
-                end
-      end
-    end
-
-    def formattedref_hash_to_bib(ret)
-      ret[:formattedref] &&
-        ret[:formattedref] = formattedref(ret[:formattedref])
-    end
-
-    def docstatus_hash_to_bib(ret)
-      ret[:docstatus] && ret[:docstatus] = DocumentStatus.new(
-        stage: stage(ret[:docstatus][:stage]),
-        substage: stage(ret[:docstatus][:substage]),
-        iteration: ret[:docstatus][:iteration],
-      )
-    end
-
-    # @param stg [Hash]
-    # @return [RelatonBib::DocumentStatus::Stage]
-    def stage(stg)
-      return unless stg
-
-      args = stg.is_a?(String) ? { value: stg } : stg
-      DocumentStatus::Stage.new(**args)
-    end
-
-    def contributors_hash_to_bib(ret) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength,Metrics/PerceivedComplexity
-      return unless ret[:contributor]
-
-      ret[:contributor] = RelatonBib.array(ret[:contributor])
-      ret[:contributor]&.each_with_index do |c, i|
-        roles = RelatonBib.array(ret[:contributor][i][:role]).map do |r|
-          if r.is_a? Hash
-            desc = RelatonBib.array(r[:description]).map { |d| d.is_a?(String) ? d : d[:content] }
-            { type: r[:type], description: desc }
-          # elsif r.is_a? Array
-          #   { type: r[0], description: r.fetch(1) }
-          else
-            { type: r }
-          end
-        end
-        ret[:contributor][i][:role] = roles
-        ret[:contributor][i][:entity] = if c[:person]
-                                          person_hash_to_bib(c[:person])
-                                        else
-                                          org_hash_to_bib(c[:organization])
-                                        end
-        ret[:contributor][i].delete(:person)
-        ret[:contributor][i].delete(:organization)
-      end
-    end
-
-    def org_hash_to_bib(org) # rubocop:disable Metrics/AbcSize
-      return nil if org.nil?
-
-      org[:identifier] = RelatonBib.array(org[:identifier])&.map do |a|
-        OrgIdentifier.new(a[:type], a[:id])
-      end
-      org[:subdivision] = RelatonBib.array(org[:subdivision]).map do |sd|
-        LocalizedString.new sd.is_a?(Hash) ? sd[:content] : sd
-      end
-      org[:contact] = contacts_hash_to_bib(org)
-      org[:logo] = Image.new(**org[:logo][:image]) if org[:logo]
-      org
-    end
-
-    def person_hash_to_bib(person)
-      Person.new(
-        name: fullname_hash_to_bib(person),
-        credential: RelatonBib.array(person[:credential]),
-        affiliation: affiliation_hash_to_bib(person),
-        contact: contacts_hash_to_bib(person),
-        identifier: person_identifiers_hash_to_bib(person),
-      )
-    end
-
-    def fullname_hash_to_bib(person) # rubocop:disable Metrics/AbcSize
-      n = person[:name]
-      fname, inits = given_hash_to_bib n[:given] || n # `n` is for backward compatibility
-      FullName.new(
-        abbreviation: localizedstring(n[:abbreviation]),
-        forename: fname, initials: inits,
-        addition: RelatonBib.array(n[:addition])&.map { |f| localizedstring(f) },
-        prefix: RelatonBib.array(n[:prefix])&.map { |f| localizedstring(f) },
-        surname: localizedstring(n[:surname]),
-        completename: localizedstring(n[:completename])
-      )
-    end
-
-    def given_hash_to_bib(given)
-      return [[], nil] unless given
-
-      fname = RelatonBib.array(given[:forename])&.map { |f| forename_hash_to_bib(f) }
-      inits = localizedstring(given[:formatted_initials])
-      [fname, inits]
-    end
-
-    def forename_hash_to_bib(fname)
-      case fname
-      when Hash then Forename.new(**fname)
-      when String then Forename.new(content: fname)
-      end
-    end
-
-    def person_identifiers_hash_to_bib(person)
-      RelatonBib.array(person[:identifier])&.map do |a|
-        PersonIdentifier.new(a[:type], a[:id])
-      end
-    end
-
-    def affiliation_hash_to_bib(person) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
-      return [] unless person[:affiliation]
-
-      RelatonBib.array(person[:affiliation]).map do |a|
-        a[:description] = RelatonBib.array(a[:description]).map do |d|
-          cnt = if d.is_a?(Hash)
-                  { content: d[:content], language: d[:language],
-                    script: d[:script], format: d[:format] }
-                else { content: d }
-                end
-          FormattedString.new(**cnt)
-        end
-        Affiliation.new(
-          organization: Organization.new(**org_hash_to_bib(a[:organization])),
-          description: a[:description], name: localizedstring(a[:name])
-        )
-      end
-    end
-
-    def contacts_hash_to_bib(entity) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity
-      return [] unless entity[:contact]
-
-      RelatonBib.array(entity[:contact]).map do |a|
-        type, value = a.reject { |k, _| k == :type }.flatten
-        case type
-        when :street, :city, :state, :country, :postcode # it's for old version compatibility, should be removed in the future
-          a[:street] = RelatonBib.array(a[:street])
-          Address.new(**a)
-        when :address then create_address(a[:address])
-        when :phone, :email, :uri
-          Contact.new(type: type.to_s, value: value, subtype: a[:type])
-        else # it's for old version compatibility, should be removed in the future
-          Contact.new(**a)
-        end
-      end
-    end
-
-    def create_address(adr)
-      if adr.is_a?(Hash)
-        adr[:street] = RelatonBib.array(adr[:street])
-        Address.new(**adr)
-      else
-        Address.new(formatted_address: adr)
-      end
-    end
-
-    # @param ret [Hash]
-    def copyright_hash_to_bib(ret)
-      return unless ret[:copyright]
-
-      ret[:copyright] = RelatonBib.array(ret[:copyright]).map do |c|
-        c[:owner] = RelatonBib.array(c[:owner]).map do |o|
-          org_hash_to_bib(o)
-        end
-        c
-      end
-    end
-
-    # @param ret [Hash]
-    def relations_hash_to_bib(ret) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
-      return unless ret[:relation]
-
-      ret[:relation] = RelatonBib.array(ret[:relation])
-      ret[:relation]&.each do |rel|
-        rel[:description] = FormattedString.new(**rel[:description]) if rel[:description]
-        relation_bibitem_hash_to_bib(rel)
-        relation_locality_hash_to_bib(rel)
-        relation_locality_stack_hash_to_bib(rel)
-        relation_source_locality_hash_to_bib(rel)
-        relaton_source_locality_stack_hash_to_bib(rel)
-      end
-    end
-
-    # @param rel [Hash] relation
-    def relation_bibitem_hash_to_bib(rel)
-      if rel[:bibitem]
-        rel[:bibitem] = bib_item hash_to_bib(rel[:bibitem])
-      else
-        Util.warn "Bibitem missing: `#{rel}`"
-        rel[:bibitem] = nil
-      end
-    end
-
-    # @param item_hash [Hash]
-    # @return [RelatonBib::BibliographicItem]
-    def bib_item(item_hash)
-      BibliographicItem.new(**item_hash)
-    end
-
-    # @param rel [Hash] relation
-    # @return [RelatonBib::LocalityStack]
-    def relation_locality_hash_to_bib(rel)
-      return unless rel[:locality]&.any?
-
-      rel[:locality] = RelatonBib.array(rel[:locality]).map do |bl|
-        Locality.new(bl[:type], bl[:reference_from], bl[:reference_to])
-      end
-    end
-
-    def relation_locality_stack_hash_to_bib(rel)
-      return unless rel[:locality_stack]&.any?
-
-      rel[:locality_stack] = RelatonBib.array(rel[:locality_stack]).map do |ls|
-        LocalityStack.new relation_locality_hash_to_bib(ls)
-      end
-    end
-
-    # def locality_locality_stack(lls)
-    #   if lls[:locality_stack]
-    #     RelatonBib.array(lls[:locality_stack]).map do |lc|
-    #       l = lc[:locality] || lc
-    #       Locality.new(l[:type], l[:reference_from], l[:reference_to])
-    #     end
-    #   else
-    #     [Locality.new(lls[:type], lls[:reference_from], lls[:reference_to])]
-    #   end
-    # end
-
-    # @param rel [Hash] relation
-    def relation_source_locality_hash_to_bib(rel) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
-      return unless rel[:source_locality]&.any?
-
-      rel[:source_locality] = RelatonBib.array(rel[:source_locality])&.map do |loc|
-        # sls = if sl[:source_locality_stack]
-        #         RelatonBib.array(sl[:source_locality_stack]).map do |l|
-        #           SourceLocality.new(l[:type], l[:reference_from], l[:reference_to])
-        #         end
-        #       else
-        #         l = SourceLocality.new(sl[:type], sl[:reference_from], sl[:reference_to])
-        #         [l]
-        #       end
-        SourceLocality.new loc[:type], loc[:reference_from], loc[:reference_to]
-      end
-    end
-
-    def relaton_source_locality_stack_hash_to_bib(rel)
-      return unless rel[:source_locality_stack]&.any?
-
-      rel[:source_locality_stack] = RelatonBib.array(rel[:source_locality_stack]).map do |loc|
-        SourceLocalityStack.new relation_source_locality_hash_to_bib(loc)
-      end
-    end
-
-    # @param ret [Hash]
-    def series_hash_to_bib(ret) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
-      ret[:series] = RelatonBib.array(ret[:series])&.map do |s|
-        s[:formattedref] && s[:formattedref] = formattedref(s[:formattedref])
-        if s[:title]
-          s[:title] = { content: s[:title] } unless s[:title].is_a?(Hash)
-          s[:title] = typed_title_strig(s[:title])
-        end
-        s[:abbreviation] &&
-          s[:abbreviation] = localizedstring(s[:abbreviation])
-        Series.new(**s)
-      end
-    end
-
-    # @param title [Hash]
-    # @return [RelatonBib::TypedTitleString]
-    def typed_title_strig(title)
-      TypedTitleString.new(**title)
-    end
-
-    # @param ret [Hash]
-    def medium_hash_to_bib(ret)
-      ret[:medium] = Medium.new(**ret[:medium]) if ret[:medium]
-    end
-
-    # @param ret [Hash]
-    def classification_hash_to_bib(ret)
-      if ret[:classification]
-        ret[:classification] = RelatonBib.array(ret[:classification]).map do |cls|
-          Classification.new(**cls)
-        end
-      end
-    end
-
-    # @param ret [Hash]
-    def validity_hash_to_bib(ret)
-      return unless ret[:validity]
-
-      b = parse_validity_time(ret[:validity], :begins)
-      e = parse_validity_time(ret[:validity], :ends)
-      r = parse_validity_time(ret[:validity], :revision)
-      ret[:validity] = Validity.new(begins: b, ends: e, revision: r)
-    end
-
-    def parse_validity_time(val, period)
-      t = val[period]&.to_s
-      return unless t
-
-      p = period == :ends ? -1 : 1
-      case t
-      when /^\d{4}$/
-        Date.new(t.to_i, p, p).to_time
-      when /^(?<year>\d{4})-(?<month>\d{1,2})$/
-        Date.new($~[:year].to_i, $~[:month].to_i, p).to_time
-      else Time.parse t
-      end
-    end
-
-    # @param ret [Hash]
-    def editorialgroup_hash_to_bib(ret)
-      eg = ret.dig(:ext, :editorialgroup) || ret[:editorialgroup] # @todo remove ret[:editorialgroup] in the future
-      return unless eg
-
-      technical_committee = RelatonBib.array(eg).map do |wg|
-        TechnicalCommittee.new WorkGroup.new(**wg)
-      end
-      ret[:editorialgroup] = EditorialGroup.new technical_committee
-    end
-
-    # @param ret [Hash]
-    def ics_hash_to_bib(ret)
-      ics = ret.dig(:ext, :ics) || ret[:ics] # @todo remove ret[:ics] in the future
-      return unless ics
-
-      ret[:ics] = RelatonBib.array(ics).map { |item| ICS.new(**item) }
-    end
-
-    # @param ret [Hash]
-    def structuredidentifier_hash_to_bib(ret)
-      struct_id = ret.dig(:ext, :structuredidentifier) || ret[:structuredidentifier] # @todo remove ret[:structuredidentifier] in the future
-      return unless struct_id
-
-      sids = RelatonBib.array(struct_id).map do |si|
-        si[:agency] = RelatonBib.array si[:agency]
-        StructuredIdentifier.new(**si)
-      end
-      ret[:structuredidentifier] = StructuredIdentifierCollection.new sids
-    end
-
-    # @param ogj [Hash, Array, String]
-    # @return [Hash, Array, String]
-    def symbolize(obj)
-      case obj
-      when Hash
-        obj.reduce({}) do |memo, (k, v)|
-          memo[k.to_sym] = symbolize(v)
-          memo
-        end
-      when Array then obj.reduce([]) { |memo, v| memo << symbolize(v) }
-      else obj
-      end
-    end
-
-    # @param lst [Hash, Array<RelatonBib::LocalizedString>, String]
-    # @return [RelatonBib::LocalizedString]
-    def localizedstring(lst)
-      return unless lst
-
-      if lst.is_a?(Hash)
-        LocalizedString.new(lst[:content], lst[:language], lst[:script])
-      else LocalizedString.new(lst)
-      end
-    end
-
-    # @param frf [Hash, String]
-    # @return [RelatonBib::FormattedRef]
-    def formattedref(frf)
-      if frf.is_a?(Hash)
-        RelatonBib::FormattedRef.new(**frf)
-      else
-        RelatonBib::FormattedRef.new(content: frf)
-      end
-    end
-
-    def doctype_hash_to_bib(ret)
-      doctype = ret.dig(:ext, :doctype) || ret[:doctype] # @todo remove ret[:doctype] in the future
-      return unless doctype
-
-      ret[:doctype] = doctype.is_a?(String) ? create_doctype(type: doctype) : create_doctype(**doctype)
-    end
-
-    def create_doctype(**args)
-      DocumentType.new(**args)
-    end
-  end
-end
diff --git a/lib/relaton_bib/hit.rb b/lib/relaton_bib/hit.rb
deleted file mode 100644
index b5b0b70..0000000
--- a/lib/relaton_bib/hit.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-require "weakref"
-
-module RelatonBib
-  class Hit
-    # @return [RelatonBib::HitCollection]
-    attr_accessor :hit_collection
-
-    # @return [Array<Hash>]
-    attr_reader :hit
-
-    # @param hit [Hash]
-    # @param hit_collection [RelatonBib::HitCollection]
-    def initialize(hit, hit_collection = nil)
-      @hit            = hit
-      @hit_collection = WeakRef.new hit_collection if hit_collection
-    end
-
-    # @return [String]
-    def to_s
-      inspect
-    end
-
-    # @return [String]
-    def inspect
-      "<#{self.class}:#{format('%<id>#.14x', id: object_id << 1)} " \
-        "@text=\"#{@hit_collection&.text}\" " \
-        "@fetched=\"#{!@fetch.nil?}\" " \
-        "@fullIdentifier=\"#{@fetch&.shortref(nil)}\" " \
-        "@title=\"#{@hit[:code]}\">"
-    end
-
-    def fetch
-      raise "Not implemented"
-    end
-
-    # @param opts [Hash]
-    # @option opts [Nokogiri::XML::Builder] :builder XML builder
-    # @option opts [Boolean] :bibdata
-    # @option opts [String, Symbol] :lang language
-    # @return [String] XML
-    def to_xml(**opts)
-      if opts[:builder]
-        fetch.to_xml(**opts)
-      else
-        builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
-          fetch.to_xml(**opts.merge(builder: xml))
-        end
-        builder.doc.root.to_xml
-      end
-    end
-  end
-end
diff --git a/lib/relaton_bib/hit_collection.rb b/lib/relaton_bib/hit_collection.rb
deleted file mode 100644
index 0c1b546..0000000
--- a/lib/relaton_bib/hit_collection.rb
+++ /dev/null
@@ -1,105 +0,0 @@
-require "forwardable"
-
-module RelatonBib
-  class HitCollection
-    extend Forwardable
-
-    def_delegators :@array, :<<, :[], :first, :empty?, :any?, :size, :each,
-                   :each_slice, :reduce, :map
-
-    # @return [TrueClass, FalseClass]
-    attr_reader :fetched
-
-    # @return [String]
-    attr_reader :text
-
-    # @return [String]
-    attr_reader :year
-
-    # @param text [String] reference to search
-    def initialize(text, year = nil)
-      @array = []
-      @text = text
-      @year = year
-      @fetched = false
-    end
-
-    #
-    # Fetches hits from the data source
-    #
-    # @return [self] self object
-    #
-    def fetch
-      workers = WorkersPool.new 4
-      workers.worker(&:fetch)
-      each do |hit|
-        workers << hit
-      end
-      workers.end
-      workers.result
-      @fetched = true
-      self
-    end
-
-    #
-    # Renders the collection as XML
-    #
-    # @param opts [Hash] options
-    # @option opts [Nokogiri::XML::Builder] :builder XML builder
-    # @option opts [Boolean] :bibdata render bibdata if true
-    # @option opts [String, Symbol] :lang language
-    #
-    # @return [String] XML representation of the collection
-    #
-    def to_xml(**opts)
-      builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
-        xml.documents do
-          @array.each do |hit|
-            hit.fetch
-            hit.to_xml(**opts.merge(builder: xml))
-          end
-        end
-      end
-      builder.to_xml
-    end
-
-    #
-    # Selects matching hits and returns a new collection
-    #
-    # @param [Proc] &block proc to select hits
-    #
-    # @return [RelatonBib::HitCollection] new hit collection
-    #
-    def select(&block)
-      me = deep_dup
-      array_dup = instance_variable_get(:@array).deep_dup
-      me.instance_variable_set(:@array, array_dup)
-      array_dup.select!(&block)
-      array_dup.each { |h| h.hit_collection = WeakRef.new me }
-      me
-    end
-
-    def reduce!(sum, &block)
-      @array = @array.reduce sum, &block
-      self
-    end
-
-    #
-    # Returns String representation of the collection
-    #
-    # @return [String] String representation of the collection
-    #
-    def to_s
-      inspect
-    end
-
-    #
-    # Returns String representation of the collection
-    #
-    # @return [String] String representation of the collection
-    #
-    def inspect
-      "<#{self.class}:#{format('%#.14x', object_id << 1)} @ref=#{@text} @fetched=#{@fetched}>"
-    end
-  end
-end
diff --git a/lib/relaton_bib/ics.rb b/lib/relaton_bib/ics.rb
deleted file mode 100644
index 55561b7..0000000
--- a/lib/relaton_bib/ics.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-module RelatonBib
-  class ICS
-    # @return [String]
-    attr_reader :code
-
-    # @return [String, nil]
-    attr_reader :text
-
-    # @param code [String]
-    # @param text [String, nil]
-    def initialize(code:, text: nil)
-      @code = code
-      @text = text
-    end
-
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      builder.ics do |b|
-        b.code code
-        b.text_ text if text
-      end
-    end
-
-    # @return [Hash]
-    def to_hash
-      hash = { "code" => code }
-      hash["text"] = text if text
-      hash
-    end
-
-    # @param prefix [String]
-    # @param count [Integer] number of ics
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1)
-      pref = prefix.empty? ? "ics" : "#{prefix}.ics"
-      out = count > 1 ? "#{pref}::\n" : ""
-      out += "#{pref}.code:: #{code}\n"
-      out += "#{pref}.text:: #{text}\n" if text
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/image.rb b/lib/relaton_bib/image.rb
deleted file mode 100644
index f0491a2..0000000
--- a/lib/relaton_bib/image.rb
+++ /dev/null
@@ -1,95 +0,0 @@
-module RelatonBib
-  class Image
-    # @return [String]
-    attr_accessor :src, :mimetype
-
-    # @return [String, nil]
-    attr_accessor :id, :filename, :width, :height, :alt, :title, :longdesc
-
-    #
-    # Initializes a new Image object.
-    #
-    # @param src [String] the source URL of the image
-    # @param mimetype [String] the MIME type of the image
-    # @param args [Hash] additional arguments
-    # @option id [String, nil] the ID of the image
-    # @option args [String, nil] :filename the filename of the image
-    # @option args [String, nil] :width the width of the image
-    # @option args [String, nil] :height the height of the image
-    # @option args [String, nil] :alt the alternative text for the image
-    # @option args [String, nil] :title the title of the image
-    # @option args [String, nil] :longdesc the long description of the image
-    #
-    def initialize(src:, mimetype:, **args)
-      @src = src
-      @mimetype = mimetype
-      args.each { |k, v| send "#{k}=", v }
-    end
-
-    def ==(other)
-      other.is_a?(Image) && id == other.id && src == other.src && mimetype == other.mimetype &&
-        filename == other.filename && width == other.width && height == other.height &&
-        alt == other.alt && title == other.title && longdesc == other.longdesc
-    end
-
-    #
-    # Converts the image object to XML format.
-    #
-    # @param [Nokogiri::XML::Builder] builder The XML builder object.
-    #
-    # @return [void]
-    #
-    def to_xml(builder) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
-      builder.image do
-        builder.parent[:id] = id if id
-        builder.parent[:src] = src
-        builder.parent[:mimetype] = mimetype
-        builder.parent[:filename] = filename if filename
-        builder.parent[:width] = width if width
-        builder.parent[:height] = height if height
-        builder.parent[:alt] = alt if alt
-        builder.parent[:title] = title if title
-        builder.parent[:longdesc] = longdesc if longdesc
-      end
-    end
-
-    #
-    # Converts the Image object to a hash representation.
-    #
-    # @return [Hash] The hash representation of the Image object.
-    #
-    def to_hash # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity
-      hash = { "image" => { "src" => src, "mimetype" => mimetype } }
-      hash["image"]["id"] = id if id
-      hash["image"]["filename"] = filename if filename
-      hash["image"]["width"] = width if width
-      hash["image"]["height"] = height if height
-      hash["image"]["alt"] = alt if alt
-      hash["image"]["title"] = title if title
-      hash["image"]["longdesc"] = longdesc if longdesc
-      hash
-    end
-
-    #
-    # Converts the image object to AsciiBib format.
-    #
-    # @param prefix [String] The prefix to be added to the AsciiBib output.
-    #
-    # @return [String] The image object converted to AsciiBib format.
-    #
-    def to_asciibib(prefix = "") # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/MethodLength
-      pref = prefix.empty? ? "image." : "#{prefix}.image."
-      out = ""
-      out += "#{pref}id:: #{id}\n" if id
-      out += "#{pref}src:: #{src}\n"
-      out += "#{pref}mimetype:: #{mimetype}\n"
-      out += "#{pref}filename:: #{filename}\n" if filename
-      out += "#{pref}width:: #{width}\n" if width
-      out += "#{pref}height:: #{height}\n" if height
-      out += "#{pref}alt:: #{alt}\n" if alt
-      out += "#{pref}title:: #{title}\n" if title
-      out += "#{pref}longdesc:: #{longdesc}\n" if longdesc
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/localized_string.rb b/lib/relaton_bib/localized_string.rb
deleted file mode 100644
index 342ed37..0000000
--- a/lib/relaton_bib/localized_string.rb
+++ /dev/null
@@ -1,149 +0,0 @@
-# frozen_string_literal: true
-
-module RelatonBib
-  # Localized string.
-  class LocalizedString
-    include RelatonBib
-
-    # @return [Array<String>] language Iso639 code
-    attr_reader :language
-
-    # @return [Array<String>] script Iso15924 code
-    attr_reader :script
-
-    # @return [String, Array<RelatonBib::LocalizedString>]
-    attr_accessor :content
-
-    # @param content [String, Array<RelatonBib::LocalizedString>]
-    # @param language [String] language code Iso639
-    # @param script [String] script code Iso15924
-    def initialize(content, language = nil, script = nil) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
-      if content.is_a?(Array) && content.none?
-        raise ArgumentError, "LocalizedString content is empty"
-      end
-
-      @language = language.is_a?(String) ? [language] : language
-      @script = script.is_a?(String) ? [script] : script
-      @content = if content.is_a?(Array)
-                   content.map do |c|
-                     case c
-                     when Hash
-                       LocalizedString.new c[:content], c[:language], c[:script]
-                     when String then LocalizedString.new c
-                     else c
-                     end
-                   end
-                 else cleanup content
-                 end
-    end
-
-    def ==(other)
-      return false unless other.is_a? LocalizedString
-
-      content == other.content && language == other.language && script == other.script
-    end
-
-    #
-    # String representation.
-    #
-    # @return [String]
-    #
-    def to_s
-      content.is_a?(Array) ? content.first.to_s : content.to_s
-    end
-
-    #
-    # Returns true if content is empty.
-    #
-    # @return [Boolean]
-    #
-    def empty?
-      content.empty?
-    end
-
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
-      return unless content
-
-      if content.is_a?(Array)
-        content.each { |c| builder.variant { c.to_xml builder } }
-      else
-        builder.parent["language"] = language.join(",") if language&.any?
-        builder.parent["script"]   = script.join(",") if script&.any?
-        builder.parent.inner_html = encode content
-      end
-    end
-
-    #
-    # Encode content.
-    #
-    # @param [String] cnt content
-    #
-    # @return [String] encoded content
-    #
-    def encode(cnt)
-      escp cnt
-    end
-
-    #
-    # Escope HTML entities.
-    #
-    # @param [String] str input string
-    #
-    # @return [String] output string
-    #
-    def escp(str)
-      return unless str
-
-      coder = HTMLEntities.new
-      coder.encode coder.decode(str.dup.force_encoding("UTF-8"))
-    end
-
-    # @return [Hash, Array<Hash>]
-    def to_hash # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
-      if content.nil? || content.is_a?(String)
-        # return content unless language || script
-
-        hash = {}
-        hash["content"] = content # unless content.nil? || content.empty?
-        hash["language"] = single_element_array(language) if language&.any?
-        hash["script"] = single_element_array(script) if script&.any?
-        hash
-      else content&.map &:to_hash
-      end
-    end
-
-    # @param prefix [String]
-    # @param count [Integer] number of elements
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1, has_attrs = false) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/MethodLength
-      pref = prefix.empty? ? prefix : "#{prefix}."
-      case content
-      when String
-        unless language&.any? || script&.any? || has_attrs
-          return "#{prefix}:: #{content}\n"
-        end
-
-        out = count > 1 ? "#{prefix}::\n" : ""
-        out += "#{pref}content:: #{content}\n"
-        language&.each { |l| out += "#{pref}language:: #{l}\n" }
-        script&.each { |s| out += "#{pref}script:: #{s}\n" }
-        out
-      when Array
-        content.map { |c| c.to_asciibib "#{pref}variant", content.size }.join
-      else count > 1 ? "#{prefix}::\n" : ""
-      end
-    end
-
-    #
-    # Should be implemented in subclass.
-    #
-    # @param [String] str content
-    #
-    # @return [String] cleaned content
-    #
-    def cleanup(str)
-      str
-    end
-  end
-end
diff --git a/lib/relaton_bib/medium.rb b/lib/relaton_bib/medium.rb
deleted file mode 100644
index 845f570..0000000
--- a/lib/relaton_bib/medium.rb
+++ /dev/null
@@ -1,76 +0,0 @@
-module RelatonBib
-  class Medium
-    # @return [String, nil]
-    attr_reader :content, :genre, :form, :carrier, :size, :scale
-
-    #
-    # Initialize a Medium object.
-    #
-    # @param content [String, nil] content of the medium
-    # @param genre [String, nil] genre of the medium
-    # @param form [String, nil] form of the medium
-    # @param carrier [String, nil] carrier of the medium
-    # @param size [String, nil] size of the medium
-    # @param scale [String, nil]
-    #
-    def initialize(**args)
-      @content = args[:content]
-      @genre   = args[:genre]
-      @form    = args[:form]
-      @carrier = args[:carrier]
-      @size    = args[:size]
-      @scale   = args[:scale]
-    end
-
-    #
-    # Render Medium object to XML.
-    #
-    # @param builder [Nokogiri::XML::Builder]
-    #
-    def to_xml(builder) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
-      builder.medium do
-        builder.content content if content
-        builder.genre genre if genre
-        builder.form form if form
-        builder.carrier carrier if carrier
-        builder.size size if size
-        builder.scale scale if scale
-      end
-    end
-
-    #
-    # Render Medium object to hash.
-    #
-    # @return [Hash]
-    #
-    def to_hash # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
-      hash = {}
-      hash["content"] = content if content
-      hash["genre"] = genre if genre
-      hash["form"] = form if form
-      hash["carrier"] = carrier if carrier
-      hash["size"] = size if size
-      hash["scale"] = scale if scale
-      hash
-    end
-
-    #
-    # Render Medium object to AsciiBib.
-    #
-    # @param prefix [String]
-    #
-    # @return [String]
-    #
-    def to_asciibib(prefix = "") # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
-      pref = prefix.empty? ? "medium." : "#{prefix}.medium."
-      out = ""
-      out += "#{pref}content:: #{content}\n" if content
-      out += "#{pref}genre:: #{genre}\n" if genre
-      out += "#{pref}form:: #{form}\n" if form
-      out += "#{pref}carrier:: #{carrier}\n" if carrier
-      out += "#{pref}size:: #{size}\n" if size
-      out += "#{pref}scale:: #{scale}\n" if scale
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/organization.rb b/lib/relaton_bib/organization.rb
deleted file mode 100644
index 636793e..0000000
--- a/lib/relaton_bib/organization.rb
+++ /dev/null
@@ -1,165 +0,0 @@
-# frozen_string_literal: true
-
-require "relaton_bib/contributor"
-
-module RelatonBib
-  # Organization identifier.
-  class OrgIdentifier
-    # ORCID = "orcid"
-    # URI   = "uri"
-
-    # @return [String]
-    attr_reader :type
-
-    # @return [String]
-    attr_reader :value
-
-    # @param type [String]
-    # @param value [String]
-    def initialize(type, value)
-      # unless [ORCID, URI].include? type
-      #   raise ArgumentError, 'Invalid type. It should be "orsid" or "uri".'
-      # end
-
-      @type  = type
-      @value = value
-    end
-
-    def ==(other)
-      type == other.type && value == other.value
-    end
-
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      builder.identifier(value, type: type)
-    end
-
-    # @return [Hash]
-    def to_hash
-      { "type" => type, "id" => value }
-    end
-
-    # @param prefix [String]
-    # @param count [Integer]
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1)
-      pref = prefix.empty? ? prefix : "#{prefix}."
-      out = count > 1 ? "#{pref}identifier::\n" : ""
-      out += "#{pref}identifier.type:: #{type}\n"
-      out += "#{pref}identifier.value:: #{value}\n"
-      out
-    end
-  end
-
-  # Organization.
-  class Organization < Contributor
-    # @return [Array<RelatonBib::LocalizedString>]
-    attr_reader :name
-
-    # @return [RelatonBib::LocalizedString, nil]
-    attr_reader :abbreviation
-
-    # @return [Array<RelatonBib::LocalizedString>]
-    attr_reader :subdivision
-
-    # @return [Array<RelatonBib::OrgIdentifier>]
-    attr_reader :identifier
-
-    # @return [RelatonBib::Image, nil]
-    attr_reader :logo
-
-    # @param name [String, Hash, Array<String, Hash>]
-    # @param abbreviation [RelatoBib::LocalizedString, String]
-    # @param subdivision [Array<RelatoBib::LocalizedString>]
-    # @param url [String]
-    # @param identifier [Array<RelatonBib::OrgIdentifier>]
-    # @param contact [Array<RelatonBib::Address, RelatonBib::Contact>]
-    # @param logo [RelatonBib::Image, nil]
-    def initialize(**args) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
-      raise ArgumentError, "missing keyword: name" unless args[:name]
-
-      super(url: args[:url], contact: args.fetch(:contact, []))
-
-      @name = if args[:name].is_a?(Array)
-                args[:name].map { |n| localized_string(n) }
-              else
-                [localized_string(args[:name])]
-              end
-
-      @abbreviation = localized_string args[:abbreviation]
-      @subdivision  = (args[:subdivision] || []).map do |sd|
-        localized_string sd
-      end
-      @identifier = args.fetch(:identifier, [])
-      @logo = args[:logo]
-    end
-
-    def ==(other)
-      name == other.name && abbreviation == other.abbreviation &&
-        subdivision == other.subdivision && identifier == other.identifier &&
-        logo == other.logo && super
-    end
-
-    # @param opts [Hash]
-    # @option opts [Nokogiri::XML::Builder] :builder XML builder
-    # @option opts [String] :lang language
-    def to_xml(**opts) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/MethodLength
-      opts[:builder].organization do |builder|
-        nm = name.select { |n| n.language&.include? opts[:lang] }
-        nm = name unless nm.any?
-        nm.each { |n| builder.name { |b| n.to_xml b } }
-        sbdv = subdivision.select { |sd| sd.language&.include? opts[:lang] }
-        sbdv = subdivision unless sbdv.any?
-        sbdv.each { |sd| builder.subdivision { sd.to_xml builder } }
-        builder.abbreviation { |a| abbreviation.to_xml a } if abbreviation
-        builder.uri url if uri
-        identifier.each { |identifier| identifier.to_xml builder }
-        super builder
-        builder.logo { |b| logo.to_xml b } if logo
-      end
-    end
-
-    # @return [Hash]
-    def to_hash # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity
-      hash = { "name" => single_element_array(name) }
-      hash["abbreviation"] = abbreviation.to_hash if abbreviation
-      hash["identifier"] = single_element_array(identifier) if identifier&.any?
-      if subdivision&.any?
-        hash["subdivision"] = single_element_array(subdivision)
-      end
-      hash["logo"] = logo.to_hash if logo
-      { "organization" => hash.merge(super) }
-    end
-
-    # @param prefix [String]
-    # @param count [Integer]
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
-      pref = prefix.sub(/\*$/, "organization")
-      out = count > 1 ? "#{pref}::\n" : ""
-      name.each { |n| out += n.to_asciibib "#{pref}.name", name.size }
-      out += abbreviation.to_asciibib "#{pref}.abbreviation" if abbreviation
-      subdivision.each do |sd|
-        out += "#{pref}.subdivision::" if subdivision.size > 1
-        out += sd.to_asciibib "#{pref}.subdivision"
-      end
-      identifier.each { |n| out += n.to_asciibib pref, identifier.size }
-      out += super pref
-      out += logo.to_asciibib "#{pref}.logo" if logo
-      out
-    end
-
-    private
-
-    # @param arg [String, Hash, RelatoBib::LocalizedString]
-    # @return [RelatoBib::LocalizedString]
-    def localized_string(arg)
-      case arg
-      when String then LocalizedString.new(arg)
-      when Hash
-        LocalizedString.new(arg[:content], arg[:language], arg[:script])
-      when LocalizedString then arg
-      end
-    end
-  end
-end
diff --git a/lib/relaton_bib/person.rb b/lib/relaton_bib/person.rb
deleted file mode 100644
index c0ad785..0000000
--- a/lib/relaton_bib/person.rb
+++ /dev/null
@@ -1,129 +0,0 @@
-# frozen_string_literal: true
-
-module RelatonBib
-  # Person identifier type.
-  module PersonIdentifierType
-    ISNI  = "isni"
-    ORCID = "orcid"
-    URI   = "uri"
-
-    # Checks type.
-    # @param type [String]
-    # @raise [ArgumentError] if type isn't "isni" or "uri"
-    def self.check(type)
-      unless [ISNI, ORCID, URI].include? type
-        raise ArgumentError, 'Invalid type. It should be "isni", "orcid", "\
-          "or "uri".'
-      end
-    end
-  end
-
-  # Person identifier.
-  class PersonIdentifier
-    # @return [RelatonBib::PersonIdentifierType::ISNI,
-    #   RelatonBib::PersonIdentifierType::ORCID,
-    #   RelatonBib::PersonIdentifierType::URI]
-    attr_accessor :type
-
-    # @return [String]
-    attr_accessor :value
-
-    # @param type [RelatonBib::PersonIdentifierType::ISNI,
-    #   RelatonBib::PersonIdentifierType::ORCID,
-    #   RelatonBib::PersonIdentifierType::URI]
-    # @param value [String]
-    def initialize(type, value)
-      PersonIdentifierType.check type
-
-      @type  = type
-      @value = value
-    end
-
-    # @param builser [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      builder.identifier value, type: type
-    end
-
-    # @return [Hash]
-    def to_hash
-      { "type" => type, "id" => value }
-    end
-
-    # @param prefix [String]
-    # @param count [Integer] number of ids
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1)
-      pref = prefix.empty? ? prefix : "#{prefix}."
-      out = count > 1 ? "#{prefix}::\n" : ""
-      out += "#{pref}type:: #{type}\n"
-      out += "#{pref}value:: #{value}\n"
-      out
-    end
-  end
-
-  # Person class.
-  class Person < Contributor
-    # @return [RelatonBib::FullName]
-    attr_accessor :name
-
-    # @return [Array<String>]
-    attr_reader :credential
-
-    # @return [Array<RelatonBib::Affiliation>]
-    attr_accessor :affiliation
-
-    # @return [Array<RelatonBib::PersonIdentifier>]
-    attr_accessor :identifier
-
-    # @param name [RelatonBib::FullName]
-    # @param credential [Array<String>]
-    # @param affiliation [Array<RelatonBib::Affiliation>]
-    # @param contact [Array<RelatonBib::Address, RelatonBib::Contact>]
-    # @param identifier [Array<RelatonBib::PersonIdentifier>]
-    # @param url [String, nil]
-    def initialize(name:, **args)
-      contact = args[:contact] || []
-      super(contact: contact, url: args[:url])
-      @name        = name
-      @credential  = args[:credential] || []
-      @affiliation = args[:affiliation] || []
-      @identifier = args[:identifier] || []
-    end
-
-    # @param opts [Hash]
-    # @option opts [Nokogiri::XML::Builder] :builder XML builder
-    # @option opts [String, Symbol] :lang language
-    def to_xml(**opts) # rubocop:disable Metrics/AbcSize
-      opts[:builder].person do |builder|
-        name.to_xml(**opts)
-        credential.each { |c| builder.credential c }
-        affiliation.each { |a| a.to_xml(**opts) }
-        identifier.each { |id| id.to_xml builder }
-        contact.each { |contact| contact.to_xml builder }
-      end
-    end
-
-    # @return [Hash]
-    def to_hash # rubocop:disable Metrics/AbcSize
-      hash = { "name" => name.to_hash }
-      hash["credential"] = credential if credential.any?
-      hash["affiliation"] = affiliation.map &:to_hash if affiliation.any?
-      hash["identifier"] = identifier.map &:to_hash if identifier.any?
-      { "person" => hash.merge(super) }
-    end
-
-    # @param prefix [String]
-    # @count [Integer] number of persons
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1) # rubocop:disable Metrics/AbcSize
-      pref = prefix.sub(/\*$/, "person")
-      out = count > 1 ? "#{pref}::\n" : ""
-      out += name.to_asciibib pref
-      credential.each { |c| out += "#{pref}.credential:: #{c}\n" }
-      affiliation.each { |af| out += af.to_asciibib pref, affiliation.size }
-      identifier.each { |id| out += id.to_asciibib pref, identifier.size }
-      out += super pref
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/place.rb b/lib/relaton_bib/place.rb
deleted file mode 100644
index b92d71b..0000000
--- a/lib/relaton_bib/place.rb
+++ /dev/null
@@ -1,203 +0,0 @@
-module RelatonBib
-  class Place
-
-    # @return [String, nil]
-    attr_reader :name, :city
-
-    # @return [Array<RelatonBib::Place::RegionType>]
-    attr_reader :region, :country
-
-    #
-    # Initialize place.
-    #
-    # @param name [String, nil] name of place, name or city should be provided
-    # @param city [String, nil] name of city, city or name should be provided
-    # @param region [Array<RelatonBib::Place::RegionType>] region of place
-    # @param country [Array<RelatonBib::Place::RegionType>] country of place
-    #
-    def initialize(name: nil, city: nil, region: [], country: []) # rubocop:disable Metrics/CyclomaticComplexity
-      if name.nil? && city.nil?
-        raise ArgumentError, "`name` or `city` should be provided"
-      end
-
-      @name    = name
-      @city    = city
-      @region  = region.map { |r| r.is_a?(Hash) ? RegionType.new(**r) : r }
-      @country = country.map { |c| c.is_a?(Hash) ? RegionType.new(**c) : c }
-    end
-
-    #
-    # Render place as XML.
-    #
-    # @param builder [Nologiri::XML::Builder]
-    #
-    def to_xml(builder)
-      if name
-        builder.place name
-      else
-        builder.place do |b|
-          b.city city
-          region.each { |r| b.region { r.to_xml b } }
-          country.each { |c| b.country { c.to_xml b } }
-        end
-      end
-    end
-
-    #
-    # Render place as Hash.
-    #
-    # @return [Hash]
-    #
-    def to_hash
-      if name then name
-      else
-        hash = { "city" => city }
-        hash["region"] = region.map(&:to_hash) if region.any?
-        hash["country"] = country.map(&:to_hash) if country.any?
-        hash
-      end
-    end
-
-    #
-    # Render place as AsciiBib.
-    #
-    # @param prefix [String]
-    # @param count [Integer] number of places
-    #
-    # @return [Stirng]
-    #
-    def to_asciibib(prefix = "", count = 1) # rubocop:disable Metrics/AbcSize
-      pref = prefix.empty? ? "place" : "#{prefix}.place"
-      out = count > 1 ? "#{pref}::\n" : ""
-      return "#{out}#{pref}.name:: #{name}\n" if name
-
-      out += "#{pref}.city:: #{city}\n"
-      out += region.map { |r| r.to_asciibib("#{pref}.region", region.size) }.join
-      out + country.map { |c| c.to_asciibib("#{pref}.country", country.size) }.join
-    end
-
-    class RegionType
-      STATES = {
-        "AK" =>	"Alaska",
-        "AL" =>	"Alabama",
-        "AR" =>	"Arkansas",
-        "AZ" =>	"Arizona",
-        "CA" =>	"California",
-        "CO" =>	"Colorado",
-        "CT" =>	"Connecticut",
-        "DC" =>	"District Of Columbia",
-        "DE" =>	"Delaware",
-        "FL" =>	"Florida",
-        "GA" =>	"Georgia",
-        "GU" =>	"Guam",
-        "HI" =>	"Hawaii",
-        "IA" =>	"Iowa",
-        "ID" =>	"Idaho",
-        "IL" =>	"Illinois",
-        "IN" =>	"Indiana",
-        "KS" =>	"Kansas",
-        "KY" =>	"Kentucky",
-        "LA" =>	"Louisiana",
-        "MA" =>	"Massachusetts",
-        "MD" =>	"Maryland",
-        "ME" =>	"Maine",
-        "MI" =>	"Michigan",
-        "MN" =>	"Minnesota",
-        "MO" =>	"Missouri",
-        "MS" =>	"Mississippi",
-        "MT" =>	"Montana",
-        "NC" =>	"North Carolina",
-        "ND" =>	"North Dakota",
-        "NE" =>	"Nebraska",
-        "NH" =>	"New Hampshire",
-        "NJ" =>	"New Jersey",
-        "NM" =>	"New Mexico",
-        "NV" =>	"Nevada",
-        "NY" =>	"New York",
-        "OH" =>	"Ohio",
-        "OK" =>	"Oklahoma",
-        "OR" =>	"Oregon",
-        "PA" =>	"Pennsylvania",
-        "PR" =>	"Puerto Rico",
-        "RI" =>	"Rhode Island",
-        "SC" =>	"South Carolina",
-        "SD" =>	"South Dakota",
-        "TN" =>	"Tennessee",
-        "TX" =>	"Texas",
-        "UT" =>	"Utah",
-        "VA" =>	"Virginia",
-        "VI" =>	"Virgin Islands",
-        "VT" =>	"Vermont",
-        "WA" =>	"Washington",
-        "WI" =>	"Wisconsin",
-        "WV" =>	"West Virginia",
-        "WY" =>	"Wyoming",
-      }.freeze
-
-      # @return [Strign] name of region
-      attr_reader :name
-
-      # @return [Strign, nil] ISO code of region
-      attr_reader :iso
-
-      # @return [Boolean, nil]
-      attr_reader :recommended
-
-      #
-      # Initialize region type. Name or valid US state ISO code should be provided.
-      #
-      # @param [String, nil] name name of region
-      # @param [String, nil] iso ISO code of region
-      # @param [Boolean, nil] recommended recommended region
-      #
-      def initialize(name: nil, iso: nil, recommended: nil)
-        unless name || STATES.key?(iso&.upcase)
-          raise ArgumentError, "`name` or valid US state ISO code should be provided"
-        end
-
-        @name = name || STATES[iso&.upcase]
-        @iso  = iso
-        @recommended = recommended
-      end
-
-      #
-      # Render region type as XML.
-      #
-      # @param [Nokogiri::XML::Builder] builder XML builder
-      #
-      def to_xml(builder)
-        builder.parent["iso"] = iso if iso
-        builder.parent["recommended"] = recommended.to_s unless recommended.nil?
-        builder.text name
-      end
-
-      #
-      # Render region type as Hash.
-      #
-      # @return [Hash] region type as Hash
-      #
-      def to_hash
-        hash = { "name" => name }
-        hash["iso"] = iso if iso
-        hash["recommended"] = recommended unless recommended.nil?
-        hash
-      end
-
-      #
-      # Render region type as AsciiBib.
-      #
-      # @param [String] pref prefix
-      # @param [Integer] count number of region types
-      #
-      # @return [String] region type as AsciiBib
-      #
-      def to_asciibib(pref, count = 1) # rubocop:disable Metrics/AbcSize
-        out = count > 1 ? "#{pref}::\n" : ""
-        out += "#{pref}.name:: #{name}\n"
-        out += "#{pref}.iso:: #{iso}\n" if iso
-        out += "#{pref}.recommended:: #{recommended}\n" if recommended
-        out
-      end
-    end
-  end
-end
diff --git a/lib/relaton_bib/series.rb b/lib/relaton_bib/series.rb
deleted file mode 100644
index a9babc4..0000000
--- a/lib/relaton_bib/series.rb
+++ /dev/null
@@ -1,119 +0,0 @@
-# frozen_string_literal: true
-
-module RelatonBib
-  #
-  # Series class.
-  #
-  class Series
-    # TYPES = %w[main alt].freeze
-
-    # @return [String, nil] allowed values: "main" or "alt"
-    attr_reader :type
-
-    # @return [RelatonBib::FormattedRef, nil]
-    attr_reader :formattedref
-
-    # @return [RelatonBib::TypedTitleString] title
-    attr_reader :title
-
-    # @return [String, nil]
-    attr_reader :place, :organization, :from, :to, :number, :partnumber, :run
-
-    # @return [RelatonBib::LocalizedString, nil]
-    attr_reader :abbreviation
-
-    # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
-
-    # @param type [String, nil]
-    # @param formattedref [RelatonBib::FormattedRef, nil]
-    # @param title [RelatonBib::TypedTitleString] title
-    # @param place [String, nil]
-    # @param orgaization [String, nil]
-    # @param abbreviation [RelatonBib::LocalizedString, nil]
-    # @param from [String, nil]
-    # @param to [String, nil]
-    # @param number [String, nil]
-    # @param partnumber [String, nil]
-    # @param run [String, nil]
-    def initialize(**args)
-      unless args[:title].is_a?(RelatonBib::TypedTitleString)
-        raise ArgumentError, "argument `title` should present in series"
-      end
-
-      # if args[:type] && !TYPES.include?(args[:type])
-      #   warn "[relaton-bib] Series type is invalid: #{args[:type]}"
-      # end
-
-      @type         = args[:type] # if %w[main alt].include? args[:type]
-      @title        = args[:title]
-      @formattedref = args[:formattedref]
-      @place        = args[:place]
-      @organization = args[:organization]
-      @abbreviation = args[:abbreviation]
-      @from         = args[:from]
-      @to           = args[:to]
-      @number       = args[:number]
-      @partnumber   = args[:partnumber]
-      @run          = args[:run]
-    end
-    # rubocop:enable Metrics/MethodLength
-
-    # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
-
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder) # rubocop:disable Metrics/MethodLength
-      xml = builder.series do
-        formattedref&.to_xml builder
-        builder.title { title.to_xml builder }
-        builder.place place if place
-        builder.organization organization if organization
-        builder.abbreviation { abbreviation.to_xml builder } if abbreviation
-        builder.from from if from
-        builder.to to if to
-        builder.number number if number
-        builder.partnumber partnumber if partnumber
-        builder.run run if run
-      end
-      xml[:type] = type if type
-    end
-    # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
-    # rubocop:enable Metrics/PerceivedComplexity
-
-    # @return [Hash]
-    def to_hash # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
-      hash = {}
-      hash["type"] = type if type
-      hash["formattedref"] = formattedref.to_hash if formattedref
-      hash["title"] = title.to_hash
-      hash["place"] = place if place
-      hash["organization"] = organization if organization
-      hash["abbreviation"] = abbreviation.to_hash if abbreviation
-      hash["from"] = from if from
-      hash["to"] = to if to
-      hash["number"] = number if number
-      hash["partnumber"] = partnumber if partnumber
-      hash["run"] = run if run
-      hash
-    end
-
-    # @param prefix [String]
-    # @param count [Integer]
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength,Metrics/PerceivedComplexity
-      pref = prefix.empty? ? "series" : prefix + ".series"
-      out = count > 1 ? "#{pref}::\n" : ""
-      out += "#{pref}.type:: #{type}\n" if type
-      out += formattedref.to_asciibib pref if formattedref
-      out += title.to_asciibib pref
-      out += "#{pref}.place:: #{place}\n" if place
-      out += "#{pref}.organization:: #{organization}\n" if organization
-      out += abbreviation.to_asciibib "#{pref}.abbreviation" if abbreviation
-      out += "#{pref}.from:: #{from}\n" if from
-      out += "#{pref}.to:: #{to}\n" if to
-      out += "#{pref}.number:: #{number}\n" if number
-      out += "#{pref}.partnumber:: #{partnumber}\n" if partnumber
-      out += "#{pref}.run:: #{run}\n" if run
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/structured_identifier.rb b/lib/relaton_bib/structured_identifier.rb
deleted file mode 100644
index 85c972d..0000000
--- a/lib/relaton_bib/structured_identifier.rb
+++ /dev/null
@@ -1,173 +0,0 @@
-module RelatonBib
-  class StructuredIdentifierCollection
-    include RelatonBib
-    extend Forwardable
-
-    def_delegators :@collection, :any?, :size, :[], :detect, :map, :each,
-                   :reduce
-
-    # @param collection [Array<RelatonBib::StructuredIdentifier>]
-    def initialize(collection)
-      @collection = collection
-    end
-
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      @collection.each { |si| si.to_xml builder }
-    end
-
-    # @return [Array<Hash>]
-    def to_hash
-      single_element_array @collection
-    end
-
-    # @param prefix [String]
-    # @return [String]
-    def to_asciibib(prefix = "")
-      pref = prefix.empty? ? prefix : prefix + "."
-      pref += "structured_identifier"
-      @collection.reduce("") do |out, si|
-        out += "#{pref}::\n" if @collection.size > 1
-        out + si.to_asciibib(pref)
-      end
-    end
-
-    # remoe year from docnumber
-    def remove_date
-      @collection.each &:remove_date
-    end
-
-    def remove_part
-      @collection.each &:remove_part
-    end
-
-    def all_parts
-      @collection.each &:all_parts
-    end
-
-    def presence?
-      any?
-    end
-
-    # @return [RelatonBib::StructuredIdentifierCollection]
-    # def map(&block)
-    #   StructuredIdentifierCollection.new @collection.map &block
-    # end
-  end
-
-  class StructuredIdentifier
-    include RelatonBib
-
-    # @return [String]
-    attr_reader :docnumber
-
-    # @return [Array<String>]
-    attr_reader :agency
-
-    # @return [String, nil]
-    attr_reader :type, :klass, :partnumber, :edition, :version, :supplementtype,
-                :supplementnumber, :language, :year
-
-    # rubocop:disable Metrics/MethodLength
-
-    # @param docnumber [String]
-    # @param args [Hash]
-    # @option args [String, nil] :type
-    # @option args [Array<String>] :agency
-    # @option args [Stirng, nil] :class
-    # @option args [String, nil] :partnumber
-    # @option args [String, nil] :edition
-    # @option args [String, nil] :version
-    # @option args [String, nil] :supplementtype
-    # @option args [String, nil] :supplementnumber
-    # @option args [String, nil] :language
-    # @option args [String, nil] :year
-    def initialize(docnumber:, **args)
-      @type = args[:type]
-      @agency = args[:agency]
-      @klass = args[:class]
-      @docnumber = docnumber
-      @partnumber = args[:partnumber]
-      @edition = args[:edition]
-      @version = args[:version]
-      @supplementtype = args[:supplementtype]
-      @supplementnumber = args[:supplementnumber]
-      @language = args[:language]
-      @year = args[:year]
-    end
-
-    # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
-
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      xml = builder.structuredidentifier do |b|
-        agency&.each { |a| b.agency a }
-        b.class_ klass if klass
-        b.docnumber docnumber
-        b.partnumber partnumber if partnumber
-        b.edition edition if edition
-        b.version version if version
-        b.supplementtype supplementtype if supplementtype
-        b.supplementnumber supplementnumber if supplementnumber
-        b.language language if language
-        b.year year if year
-      end
-      xml[:type] = type if type
-    end
-
-    # @return [Hash]
-    def to_hash
-      hash = { "docnumber" => docnumber }
-      hash["type"] = type if type
-      hash["agency"] = single_element_array agency if agency&.any?
-      hash["class"] = klass if klass
-      hash["partnumber"] = partnumber if partnumber
-      hash["edition"] = edition if edition
-      hash["version"] = version if version
-      hash["supplementtype"] = supplementtype if supplementtype
-      hash["supplementnumber"] = supplementnumber if supplementnumber
-      hash["language"] = language if language
-      hash["year"] = year if year
-      hash
-    end
-    # rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
-
-    # @param prefix [String]
-    # @return [String]
-    def to_asciibib(prefix) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength,Metrics/PerceivedComplexity
-      out = "#{prefix}.docnumber:: #{docnumber}\n"
-      agency.each { |a| out += "#{prefix}.agency:: #{a}\n" }
-      out += "#{prefix}.type:: #{type}\n" if type
-      out += "#{prefix}.class:: #{klass}\n" if klass
-      out += "#{prefix}.partnumber:: #{partnumber}\n" if partnumber
-      out += "#{prefix}.edition:: #{edition}\n" if edition
-      out += "#{prefix}.version:: #{version}\n" if version
-      out += "#{prefix}.supplementtype:: #{supplementtype}\n" if supplementtype
-      if supplementnumber
-        out += "#{prefix}.supplementnumber:: #{supplementnumber}\n"
-      end
-      out += "#{prefix}.language:: #{language}\n" if language
-      out += "#{prefix}.year:: #{year}\n" if year
-      out
-    end
-
-    def remove_date
-      if @type == "Chinese Standard"
-        @docnumber.sub!(/-[12]\d\d\d/, "")
-      else
-        @docnumber.sub!(/:[12]\d\d\d/, "")
-      end
-      @year = nil
-    end
-
-    # in docid manipulations, assume ISO as the default: id-part:year
-    def remove_part
-      @partnumber = nil
-      @docnumber = @docnumber.sub(/-\d+/, "")
-    end
-
-    def all_parts
-      @docnumber = @docnumber + " (all parts)"
-    end
-  end
-end
diff --git a/lib/relaton_bib/technical_committee.rb b/lib/relaton_bib/technical_committee.rb
deleted file mode 100644
index c7120bc..0000000
--- a/lib/relaton_bib/technical_committee.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-require "relaton_bib/workgroup"
-
-module RelatonBib
-  class TechnicalCommittee
-    # @return [RelatonBib::WorkGroup]
-    attr_reader :workgroup
-
-    # @param workgroup [RelatonBib::WorkGroup]
-    def initialize(workgroup)
-      @workgroup = workgroup
-    end
-
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      builder.send(:"technical-committee") { |b| workgroup.to_xml b }
-    end
-
-    # @return [Hash]
-    def to_hash
-      workgroup.to_hash
-    end
-
-    # @param prefix [String]
-    # @param count [Integer] number of technical committees
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1)
-      pref = prefix.empty? ? prefix : "#{prefix}."
-      pref += "technical_committee"
-      out = count > 1 ? "#{pref}::\n" : ""
-      out += workgroup.to_asciibib pref
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/typed_title_string.rb b/lib/relaton_bib/typed_title_string.rb
deleted file mode 100644
index c6efa46..0000000
--- a/lib/relaton_bib/typed_title_string.rb
+++ /dev/null
@@ -1,191 +0,0 @@
-module RelatonBib
-  class TypedTitleStringCollection
-    extend Forwardable
-
-    def_delegators :@array, :[], :first, :last, :empty?, :any?, :size,
-                   :each, :detect, :map, :reduce, :length
-
-    # @param title [Array<RelatonBib::TypedTitleString, Hash>]
-    def initialize(title = [])
-      @array = (title || []).map do |t|
-        t.is_a?(Hash) ? TypedTitleString.new(**t) : t
-      end
-    end
-
-    # @param lang [String, nil] language code Iso639
-    # @return [RelatonIsoBib::TypedTitleStringCollection]
-    def lang(lang = nil)
-      if lang
-        TypedTitleStringCollection.new select_lang(lang)
-      else self
-      end
-    end
-
-    def delete_title_part!
-      titles.delete_if { |t| t.type == "title-part" }
-    end
-
-    # @return [RelatonBib::TypedTitleStringCollection]
-    def select(&block)
-      TypedTitleStringCollection.new titles.select(&block)
-    end
-
-    # @param init [Array, Hash]
-    # @return [RelatonBib::TypedTitleStringCollection]
-    # def reduce(init)
-    #   self.class.new @array.reduce(init) { |m, t| yield m, t }
-    # end
-
-    # @param title [RelatonBib::TypedTitleString]
-    # @return [self]
-    def <<(title)
-      titles << title
-      self
-    end
-
-    # @param tcoll [RelatonBib::TypedTitleStringCollection]
-    # @return [RelatonBib::TypedTitleStringCollection]
-    def +(tcoll)
-      TypedTitleStringCollection.new titles + tcoll.titles
-    end
-
-    def titles
-      @array
-    end
-
-    # @param opts [Hash]
-    # @option opts [Nokogiri::XML::Builder] XML builder
-    # @option opts [String, Symbol] :lang language
-    def to_xml(**opts)
-      tl = select_lang(opts[:lang])
-      tl = titles unless tl.any?
-      tl.each { |t| opts[:builder].title { t.to_xml opts[:builder] } }
-    end
-
-    def to_hash
-      @array.map(&:to_hash)
-    end
-
-    #
-    # Add main title ot bibtex entry
-    #
-    # @param [BibTeX::Entry] item bibtex entry
-    #
-    def to_bibtex(item)
-      tl = titles.detect { |t| t.type == "main" } || titles.first
-      return unless tl
-
-      item.title = tl.title.content
-    end
-
-    private
-
-    # @param lang [String]
-    # @return [Array<RelatonBib::TypedTitleString]
-    def select_lang(lang)
-      titles.select { |t| t.title.language&.include? lang }
-    end
-  end
-
-  class TypedTitleString
-    ARGS = %i[content language script format].freeze
-
-    # @return [String]
-    attr_reader :type
-
-    # @return [RelatonBib::FormattedString]
-    attr_reader :title
-
-    # @param type [String]
-    # @param title [RelatonBib::FormattedString, Hash]
-    # @param content [String]
-    # @param language [String]
-    # @param script [String]
-    # @param format [String]
-    def initialize(**args) # rubocop:disable Metrics/MethodLength
-      unless args[:title] || args[:content]
-        raise ArgumentError, %{Keyword "title" or "content" should be passed.}
-      end
-
-      @type = args[:type]
-
-      case args[:title]
-      when FormattedString then @title = args[:title]
-      when Hash then @title = FormattedString.new(**args[:title])
-      else
-        fsargs = args.select { |k, _v| ARGS.include? k }
-        @title = FormattedString.new(**fsargs)
-      end
-    end
-
-    #
-    # Create TypedTitleStringCollection from string
-    #
-    # @param title [String] title string
-    # @param lang [String, nil] language code Iso639
-    # @param script [String, nil] script code Iso15924
-    # @param format [String] format text/html, text/plain
-    #
-    # @return [TypedTitleStringCollection] collection of TypedTitleString
-    #
-    def self.from_string(title, lang = nil, script = nil, format = "text/plain")
-      types = %w[title-intro title-main title-part]
-      ttls = split_title(title)
-      tts = ttls.map.with_index do |p, i|
-        next unless p
-
-        new type: types[i], content: p, language: lang, script: script, format: format
-      end.compact
-      tts << new(type: "main", content: ttls.compact.join(" - "),
-                 language: lang, script: script, format: format)
-      TypedTitleStringCollection.new tts
-    end
-
-    # @param title [String]
-    # @return [Array<String, nil>]
-    def self.split_title(title)
-      ttls = title.sub(/\w\.Imp\s?\d+\u00A0:\u00A0/, "").split " - "
-      case ttls.size
-      when 0, 1 then [nil, ttls.first.to_s, nil]
-      else intro_or_part ttls
-      end
-    end
-
-    # @param ttls [Array<String>]
-    # @return [Array<String, nil>]
-    def self.intro_or_part(ttls)
-      if /^(Part|Partie) \d+:/.match? ttls[1]
-        [nil, ttls[0], ttls[1..].join(" -- ")]
-      else
-        parts = ttls.slice(2..-1)
-        part = parts.join " -- " if parts.any?
-        [ttls[0], ttls[1], part]
-      end
-    end
-
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      builder.parent[:type] = type if type
-      title.to_xml builder
-    end
-
-    # @return [Hash]
-    def to_hash
-      th = title.to_hash
-      return th unless type
-
-      th.merge "type" => type
-    end
-
-    # @param prefix [String]
-    # @param count [Integer] number of titles
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1) # rubocop:disable Metrics/AbcSize
-      pref = prefix.empty? ? prefix : "#{prefix}."
-      out = count > 1 ? "#{pref}title::\n" : ""
-      out += "#{pref}title.type:: #{type}\n" if type
-      out += title.to_asciibib "#{pref}title", 1, !(type.nil? || type.empty?)
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/typed_uri.rb b/lib/relaton_bib/typed_uri.rb
deleted file mode 100644
index 4f8dfcd..0000000
--- a/lib/relaton_bib/typed_uri.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-require "addressable"
-
-module RelatonBib
-  # Typed URI
-  class TypedUri
-    # @return [String, nil]
-    attr_reader :type, :language, :script
-    # @retutn [Addressable::URI]
-    attr_reader :content
-
-    # @param content [String] URL
-    # @param type [String, nil] src/obp/rss
-    # @param language [String, nil] language code Iso639 (optional) (default: nil)
-    # @param script [String, nil] script code Iso15924 (optional) (default: nil)
-    def initialize(content:, type: nil, language: nil, script: nil)
-      @type     = type
-      @language = language
-      @script   = script
-      @content  = Addressable::URI.parse content if content
-    end
-
-    # @param url [String]
-    def content=(url)
-      @content = Addressable::URI.parse url
-    end
-
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      doc = builder.uri content.to_s
-      doc[:type] = type if type
-      doc[:language] = language if language
-      doc[:script] = script if script
-    end
-
-    # @return [Hash]
-    def to_hash
-      hash = { "content" => content.to_s }
-      hash["type"] = type.to_s if type
-      hash["language"] = language if language
-      hash["script"] = script if script
-      hash
-    end
-
-    # @param prefix [String]
-    # @param count [Integer] number of links
-    # @return [String]
-    def to_asciibib(prefix = "", count = 1)
-      pref = prefix.empty? ? "link" : "#{prefix}.link"
-      out = count > 1 ? "#{pref}::\n" : ""
-      out += "#{pref}.type:: #{type}\n" if type
-      out += "#{pref}.content:: #{content}\n"
-      out += "#{pref}.language:: #{language}\n" if language
-      out += "#{pref}.script:: #{script}\n" if script
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/util.rb b/lib/relaton_bib/util.rb
deleted file mode 100644
index 1922b68..0000000
--- a/lib/relaton_bib/util.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-module RelatonBib
-  module Util
-    extend self
-
-    PROGNAME = "relaton-bib".freeze
-
-    def method_missing(method_name, msg = nil, prog = nil, **opts, &block)
-      prog ||= self::PROGNAME
-      Relaton.logger_pool.send method_name, msg, prog, **opts, &block
-    end
-
-    def respond_to_missing?(method_name, include_private = false)
-      Relaton.logger_pool.respond_to?(method_name) || super
-    end
-  end
-end
diff --git a/lib/relaton_bib/validity.rb b/lib/relaton_bib/validity.rb
deleted file mode 100644
index 04141ec..0000000
--- a/lib/relaton_bib/validity.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-module RelatonBib
-  class Validity
-    FORMAT = "%Y-%m-%d %H:%M".freeze
-
-    # @return [Time, nil]
-    attr_reader :begins
-
-    # @return [Time, nil]
-    attr_reader :ends
-
-    # @return [Time, nil]
-    attr_reader :revision
-
-    # @param begins [Time, nil]
-    # @param ends [Time, nil]
-    # @param revision [Time, nil]
-    def initialize(begins: nil, ends: nil, revision: nil)
-      @begins   = begins
-      @ends     = ends
-      @revision = revision
-    end
-
-    # @param [Nokogiri::XML::Builder]
-    def to_xml(builder)
-      builder.validity do
-        builder.validityBegins begins.strftime(FORMAT) if begins
-        builder.validityEnds ends.strftime(FORMAT) if ends
-        builder.revision revision.strftime(FORMAT) if revision
-      end
-    end
-
-    # @return [Hash]
-    def to_hash
-      hash = {}
-      hash["begins"] = begins.strftime(FORMAT) if begins
-      hash["ends"] = ends.strftime(FORMAT) if ends
-      hash["revision"] = revision.strftime(FORMAT) if revision
-      hash
-    end
-
-    # @param prefix [String]
-    # @return [String]
-    def to_asciibib(prefix = "")
-      pref = prefix.empty? ? "validity." : "#{prefix}.validity."
-      out = ""
-      out += "#{pref}begins:: #{begins.strftime(FORMAT)}\n" if begins
-      out += "#{pref}ends:: #{ends.strftime(FORMAT)}\n" if ends
-      out += "#{pref}revision:: #{revision.strftime(FORMAT)}\n" if revision
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/version.rb b/lib/relaton_bib/version.rb
deleted file mode 100644
index 553e62f..0000000
--- a/lib/relaton_bib/version.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-module RelatonBib
-  VERSION = "1.20.4".freeze
-end
diff --git a/lib/relaton_bib/workers_pool.rb b/lib/relaton_bib/workers_pool.rb
deleted file mode 100644
index 86106c6..0000000
--- a/lib/relaton_bib/workers_pool.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-module RelatonBib
-  # Workers poll.
-  class WorkersPool
-    attr_accessor :nb_hits
-
-    def initialize(num_workers = 2)
-      @num_workers = num_workers < 2 ? 2 : num_workers
-      @queue = SizedQueue.new(num_workers * 2)
-      @result = []
-      @nb_hits = 0
-    end
-
-    def worker(&block)
-      @threads = Array.new @num_workers do
-        Thread.new do
-          until (item = @queue.pop) == :END
-            @result << yield(item) if block
-          end
-        end
-      end
-    end
-
-    def result
-      @threads.each(&:join)
-      @result
-    end
-
-    def <<(item)
-      @queue << item
-      self
-    end
-
-    def end
-      @num_workers.times { @queue << :END }
-    end
-
-    def size
-      @result.size
-    end
-  end
-end
diff --git a/lib/relaton_bib/workgroup.rb b/lib/relaton_bib/workgroup.rb
deleted file mode 100644
index 84934a5..0000000
--- a/lib/relaton_bib/workgroup.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-module RelatonBib
-  class WorkGroup
-    # @return [String]
-    attr_reader :name
-
-    # @return [Integer, nil]
-    attr_reader :number
-
-    # @return [String, nil]
-    attr_reader :identifier, :prefix, :type
-
-    # @param name [String]
-    # @param identifier [String, nil]
-    # @param prefix [String, nil]
-    # @param number [Integer, nil]
-    # @param type [String, nil]
-    def initialize(name:, identifier: nil, prefix: nil, number: nil, type: nil)
-      @identifier = identifier
-      @prefix = prefix
-      @name = name
-      @number = number
-      @type = type
-    end
-
-    # @param builder [Nokogiri::XML::Builder]
-    def to_xml(builder) # rubocop:disable Metrics/AbcSize
-      builder.text name
-      builder.parent[:number] = number if number
-      builder.parent[:type] = type if type
-      builder.parent[:identifier] = identifier if identifier
-      builder.parent[:prefix] = prefix if prefix
-    end
-
-    # @return [Hash]
-    def to_hash
-      hash = { "name" => name }
-      hash["number"] = number if number
-      hash["type"] = type if type
-      hash["identifier"] = identifier if identifier
-      hash["prefix"] = prefix if prefix
-      hash
-    end
-
-    # @param prfx [String]
-    # @param count [Integer]
-    # @return [String]
-    def to_asciibib(prfx = "", count = 1) # rubocop:disable Metrics/CyclomaticComplexity
-      pref = prfx.empty? ? prfx : "#{prfx}."
-      out = count > 1 ? "#{pref}::\n" : ""
-      out += "#{pref}name:: #{name}\n"
-      out += "#{pref}number:: #{number}\n" if number
-      out += "#{pref}type:: #{type}\n" if type
-      out += "#{pref}identifier:: #{identifier}\n" if identifier
-      out += "#{pref}prefix:: #{prefix}\n" if prefix
-      out
-    end
-  end
-end
diff --git a/lib/relaton_bib/xml_parser.rb b/lib/relaton_bib/xml_parser.rb
deleted file mode 100644
index 6d236ca..0000000
--- a/lib/relaton_bib/xml_parser.rb
+++ /dev/null
@@ -1,718 +0,0 @@
-require "nokogiri"
-
-module RelatonBib
-  class XMLParser
-    class << self
-      #
-      # Parse XML bibdata
-      #
-      # @param [String] xml XML string
-      #
-      # @return [RelatonBib::BibliographicItem, nil] bibliographic item
-      #
-      def from_xml(xml)
-        doc = Nokogiri::XML(xml)
-        doc.remove_namespaces!
-        bibitem = doc.at "/bibitem|/bibdata"
-        if bibitem
-          bib_item item_data(bibitem)
-        else
-          Util.warn "Can't find bibitem or bibdata element in the XML"
-          nil
-        end
-      end
-
-      private
-
-      #
-      # Parse bibitem data
-      #
-      # @param bibitem [Nokogiri::XML::Element] bibitem element
-      #
-      # @return [Hash] bibitem data
-      #
-      def item_data(bibitem) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize, Metrics/MethodLength
-        ext = bibitem.at "//ext"
-        {
-          id: bibitem[:id].nil? || bibitem[:id].empty? ? nil : bibitem[:id],
-          type: bibitem[:type].nil? || bibitem[:type].empty? ? nil : bibitem[:type],
-          fetched: bibitem.at("./fetched")&.text,
-          title: fetch_titles(bibitem),
-          formattedref: fref(bibitem),
-          link: fetch_link(bibitem),
-          docid: fetch_docid(bibitem),
-          docnumber: bibitem.at("./docnumber")&.text,
-          date: fetch_dates(bibitem),
-          contributor: fetch_contributors(bibitem),
-          edition: fetch_edition(bibitem),
-          version: fetch_version(bibitem),
-          biblionote: fetch_note(bibitem),
-          language: fetch_language(bibitem),
-          script: fetch_script(bibitem),
-          abstract: fetch_abstract(bibitem),
-          docstatus: fetch_status(bibitem),
-          copyright: fetch_copyright(bibitem),
-          relation: fetch_relations(bibitem),
-          series: fetch_series(bibitem),
-          medium: fetch_medium(bibitem),
-          place: fetch_place(bibitem),
-          extent: fetch_extent(bibitem),
-          size: fetch_size(bibitem),
-          accesslocation: bibitem.xpath("./accesslocation").map(&:text),
-          classification: fetch_classification(bibitem),
-          keyword: bibitem.xpath("keyword").map(&:text),
-          license: bibitem.xpath("license").map(&:text),
-          validity: fetch_validity(bibitem),
-          doctype: fetch_doctype(ext),
-          subdoctype: ext&.at("subdoctype")&.text,
-          editorialgroup: fetch_editorialgroup(ext),
-          ics: fetch_ics(ext),
-          structuredidentifier: fetch_structuredidentifier(ext),
-        }
-      end
-
-      #
-      # Fetch version.
-      #
-      # @param [Nokogiri::XML::Elemetn] item bibitem element
-      #
-      # @return [Array<RelatonBib::BibliographicItem::Version>] versions
-      #
-      def fetch_version(item)
-        item.xpath("./version").map do |v|
-          revision_date = v.at("revision-date")&.text
-          draft = v.at("draft")&.text
-          RelatonBib::BibliographicItem::Version.new revision_date, draft
-        end
-      end
-
-      #
-      # Fetch edition
-      #
-      # @param [Nokogiri::XML::Elemetn] item bibitem element
-      #
-      # @return [RelatonBib::Edition, nil] edition
-      #
-      def fetch_edition(item)
-        edt = item.at("./edition")
-        return unless edt
-
-        Edition.new content: edt.text, number: edt[:number]
-      end
-
-      #
-      # Fetch place.
-      #
-      # @param [Nokogiri::XML::Element] item bibitem element
-      #
-      # @return [Array<RelatonBib::Place>] array of places
-      #
-      def fetch_place(item)
-        item.xpath("./place").map do |pl|
-          if (city = pl.at("./city"))
-            Place.new(city: city.text, region: create_region_country(pl),
-                      country: create_region_country(pl, "country"))
-          else
-            Place.new(name: pl.text)
-          end
-        end
-      end
-
-      #
-      # Create region or country from place element
-      #
-      # @param [Nokogiri::XML::Element] place place element
-      # @param [String] node name of the node to parse
-      #
-      # @return [Array<RelatonBib::Place::RegionType>] <description>
-      #
-      def create_region_country(place, node = "region")
-        place.xpath("./#{node}").map do |r|
-          Place::RegionType.new(name: r.text, iso: r[:iso], recommended: r[:recommended])
-        end
-      end
-
-      def fetch_note(item)
-        bnotes = item.xpath("./note").map do |n|
-          BiblioNote.new(
-            content: n.text,
-            type: n[:type],
-            format: n[:format],
-            language: n[:language],
-            script: n[:script],
-          )
-        end
-        BiblioNoteCollection.new bnotes
-      end
-
-      #
-      # Fetch language
-      #
-      # @param [Nokogiri::XML::Element] item bibitem element
-      #
-      # @return [Array<String>] language en, fr, etc.
-      #
-      def fetch_language(item)
-        item.xpath("./language").reduce([]) do |a, l|
-          l.text.empty? ? a : a << l.text
-        end
-      end
-
-      #
-      # Fetch script
-      #
-      # @param [Nokogiri::XML::Element] item XML element
-      #
-      # @return [Array<String>] scripts Latn, Cyr, etc.
-      #
-      def fetch_script(item)
-        item.xpath("./script").reduce([]) do |a, s|
-          s.text.empty? ? a : a << s.text
-        end
-      end
-
-      #
-      # Fetch series
-      #
-      # @param [Nokogiri::XML::Element] item bibitem element
-      #
-      # @return [Array<RelatonBib::Series>] series
-      #
-      def fetch_series(item) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/AbcSize,Metrics/MethodLength,Metrics/PerceivedComplexity
-        item.xpath("./series").reduce([]) do |mem, sr|
-          formattedref = fref(sr)
-          title = ttitle(sr.at("title"))
-          next mem unless formattedref || title
-
-          abbreviation = localized_string sr.at("abbreviation")
-          mem << Series.new(
-            type: sr[:type], formattedref: formattedref,
-            title: title, place: sr.at("place")&.text,
-            organization: sr.at("organization")&.text,
-            abbreviation: abbreviation, from: sr.at("from")&.text,
-            to: sr.at("to")&.text, number: sr.at("number")&.text,
-            partnumber: sr.at("partnumber")&.text, run: sr.at("run")&.text
-          )
-        end
-      end
-
-      #
-      # Fetch medium
-      #
-      # @param [Nokogiri::XML::Element] item item element
-      #
-      # @return [RelatonBib::Medium, nil] medium
-      #
-      def fetch_medium(item) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/AbcSize,Metrics/PerceivedComplexity
-        medium = item.at("./medium")
-        return unless medium
-
-        Medium.new(
-          content: medium.at("content")&.text, genre: medium.at("genre")&.text,
-          form: medium.at("form")&.text, carrier: medium.at("carrier")&.text,
-          size: medium.at("size")&.text, scale: medium.at("scale")&.text
-        )
-      end
-
-      #
-      # Fetch extent
-      #
-      # @param [Nokogiri::XML::Element] item item element
-      #
-      # @return [Array<RelatonBib::Extent>] extent
-      #
-      def fetch_extent(item)
-        item.xpath("./extent").map do |ex|
-          RelatonBib::Extent.new localities(ex)
-        end
-      end
-
-      #
-      # Fetch size
-      #
-      # @param [Nokogiri::XML::Element] item item element
-      #
-      # @return [RelatonBib::BibliographicSize, nil] size
-      #
-      def fetch_size(item)
-        size = item.xpath("./size/value").map do |sz|
-          BibliographicSize::Value.new type: sz[:type], value: sz.text
-        end
-        BibliographicSize.new size if size.any?
-      end
-
-      #
-      # Fetch classification
-      #
-      # @param [Nokogiri::XML::Element] item bibitem element
-      #
-      # @return [Array<RelatonBib::Classification>] classifications
-      #
-      def fetch_classification(item)
-        item.xpath("classification").map do |cls|
-          Classification.new type: cls[:type], value: cls.text
-        end
-      end
-
-      #
-      # Parse validity
-      #
-      # @param [Nokogiri::XML::Element] item bibitem element
-      #
-      # @return [RelatonBib::Validity, nil] validity
-      #
-      def fetch_validity(item)
-        vl = item.at("./validity")
-        return unless vl
-
-        begins = (b = vl.at("validityBegins")) &&
-          Time.strptime(b.text, "%Y-%m-%d %H:%M")
-        ends = (e = vl.at("validityEnds")) &&
-          Time.strptime(e.text, "%Y-%m-%d %H:%M")
-        revision = (r = vl.at("revision")) &&
-          Time.strptime(r.text, "%Y-%m-%d %H:%M")
-        Validity.new begins: begins, ends: ends, revision: revision
-      end
-
-      def fetch_doctype(ext)
-        dt = ext&.at("doctype")
-        return unless dt
-
-        create_doctype dt
-      end
-
-      def create_doctype(type)
-        DocumentType.new type: type.text, abbreviation: type[:abbreviation]
-      end
-
-      # @param item [Nokogiri::XML::Element]
-      # @return [Array<RelatonBib::DocumentIdentifier>]
-      def fetch_docid(item)
-        item.xpath("./docidentifier").map do |id|
-          args = id.to_h.transform_keys(&:to_sym)
-          args[:id] = id.children.map { |n| n.text? ? n.content : n.to_xml }.join
-          args[:primary] = id[:primary] == "true" ? true : nil
-          create_docid(**args)
-        end
-      end
-
-      def create_docid(**args)
-        DocumentIdentifier.new(**args)
-      end
-
-      # @param item [Nokogiri::XML::Element]
-      # @return [RelatonBib::TypedTitleStringCollection]
-      def fetch_titles(item)
-        ttl = item.xpath("./title").map { |t| ttitle t }
-        TypedTitleStringCollection.new ttl
-      end
-
-      # @param title [Nokogiri::XML::Element]
-      # @return [RelatonBib::TypedTitleString]
-      def ttitle(title)
-        return unless title
-
-        content = variants(title)
-        content = title.children.map { |n| n.text? ? n.content : n.to_xml }.join unless content.any?
-        TypedTitleString.new(
-          type: title[:type], content: content, language: title[:language],
-          script: title[:script], format: title[:format]
-        )
-      end
-
-      # @param title [Nokogiri::XML::Element]
-      # @return [Array<RelatonBib::LocalizedString>]
-      def variants(elm)
-        elm.xpath("variant").map { |v| localized_string v }
-      end
-
-      #
-      # Parse status
-      #
-      # @param [Nokogiri::XML::Element] item XML element
-      #
-      # @return [RelatonBib::DocumentStatus, nil] status
-      #
-      def fetch_status(item)
-        status = item.at("./status")
-        return unless status
-
-        stg = status.at "stage"
-        DocumentStatus.new(
-          stage: stg ? stage(stg) : status.text,
-          substage: stage(status.at("substage")),
-          iteration: status.at("iteration")&.text,
-        )
-      end
-
-      # @param node [Nokogiri::XML::Elemen]
-      # @return [RelatonBib::DocumentStatus::Stage]
-      def stage(elm)
-        return unless elm
-
-        DocumentStatus::Stage.new(value: elm.text,
-                                  abbreviation: elm[:abbreviation])
-      end
-
-      # @param node [Nokogiri::XML::Elemen]
-      # @return [Array<RelatonBib::BibliographicDate>]
-      def fetch_dates(item) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
-        item.xpath("./date").each_with_object([]) do |d, a|
-          type = d[:type].to_s.empty? ? "published" : d[:type]
-          if (on = d.at("on"))
-            a << RelatonBib::BibliographicDate.new(type: type, on: on.text,
-                                                   to: d.at("to")&.text)
-          elsif (from = d.at("from"))
-            a << RelatonBib::BibliographicDate.new(type: type, from: from.text,
-                                                   to: d.at("to")&.text)
-          end
-        end
-      end
-
-      #
-      # Parse organization
-      #
-      # @param [Nokogiri::XML::Element] org XML element
-      #
-      # @return [RelatonBib::Organization, nil] organization
-      #
-      def get_org(org) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
-        return unless org
-
-        names = org.xpath("name").map do |n|
-          { content: n.text, language: n[:language], script: n[:script] }
-        end
-        identifier = org.xpath("./identifier").map do |i|
-          OrgIdentifier.new(i[:type], i.text)
-        end
-        subdiv = org.xpath("subdivision").map &:text
-        contact = parse_contact org
-        logo = fetch_image org.at("./logo/image")
-        Organization.new(
-          name: names, abbreviation: org.at("abbreviation")&.text,
-          subdivision: subdiv, # url: org.at("uri")&.text,
-          identifier: identifier, contact: contact, logo: logo
-        )
-      end
-
-      def fetch_image(elm)
-        return unless elm
-
-        Image.new(**elm.to_h.transform_keys(&:to_sym))
-      end
-
-      #
-      # Parse person from XML
-      #
-      # @param [Nokogiri::XML::Element] person XML element
-      #
-      # @return [RelatonBib::Person, nil] person
-      #
-      def get_person(person) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
-        return unless person
-
-        affiliations = person.xpath("./affiliation").map { |a| fetch_affiliation a }
-
-        contact = parse_contact person
-        identifier = person.xpath("./identifier").map do |pi|
-          PersonIdentifier.new pi[:type], pi.text
-        end
-
-        Person.new(
-          name: full_name(person.at("./name")),
-          credential: person.xpath("./credential").map(&:text),
-          affiliation: affiliations,
-          contact: contact,
-          identifier: identifier,
-        )
-      end
-
-      def full_name(name)
-        cname = localized_string name.at("./completename")
-        sname = localized_string name.at("./surname")
-        abbreviation = localized_string name.at("./abbreviation")
-
-        FullName.new(
-          completename: cname, surname: sname, abbreviation: abbreviation,
-          initials: parse_initials(name), forename: parse_forename(name),
-          addition: name_part(name, "addition"), prefix: name_part(name, "prefix")
-        )
-      end
-
-      def fetch_affiliation(elm)
-        org = get_org elm.at("./organization")
-        desc = elm.xpath("./description").map do |e|
-          FormattedString.new(content: e.text, language: e[:language],
-                              script: e[:script], format: e[:format])
-        end
-        name = localized_string elm.at("./name")
-        Affiliation.new organization: org, description: desc, name: name
-      end
-
-      def localized_string(elm)
-        return unless elm
-
-        LocalizedString.new(elm.text, elm[:language], elm[:script])
-      end
-
-      #
-      # Parse contact information
-      #
-      # @param [Nokogiri::XML::Element] contrib contributor element
-      #
-      # @return [Array<RelatonBib::Address, RelatonBib::Contact>] contacts
-      #
-      def parse_contact(contrib)
-        contrib.xpath("./address|./phone|./email|./uri").map do |c|
-          parse_address(c) || Contact.new(type: c.name, value: c.text, subtype: c[:type])
-        end
-      end
-
-      #
-      # Parse address
-      #
-      # @param [Nokogiri::XML::Element] contact contact element
-      #
-      # @return [RelatonBib::Address] address
-      #
-      def parse_address(contact) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
-        return unless contact.name == "address"
-
-        Address.new(
-          street: contact.xpath("./street").map(&:text),
-          city: contact.at("./city")&.text,
-          state: contact.at("./state")&.text,
-          country: contact.at("./country")&.text,
-          postcode: contact.at("./postcode")&.text,
-          formatted_address: contact.at("./formattedAddress")&.text,
-        )
-      end
-
-      #
-      # Parse initials
-      #
-      # @param [Nokogiri::XML::Element] name person name element
-      #
-      # @return [RelatonBib::LocalizedString, nil] initials
-      #
-      def parse_initials(name)
-        localized_string name.at("./formatted-initials")
-      end
-
-      #
-      # Parse forename
-      #
-      # @param [Nokogiri::XML::Element] name person name element
-      #
-      # @return [Array<RelatonBib::Forename>] forenames
-      #
-      def parse_forename(name)
-        name.xpath("./forename").map do |np|
-          args = np.attributes.each_with_object({}) { |(k, v), h| h[k.to_sym] = v.to_s }
-          args[:content] = np.text
-          Forename.new(**args)
-        end
-      end
-
-      #
-      # Parse name part
-      #
-      # @param [Nokogiri::XML::Element] name person name element
-      # @param [String] part name part
-      #
-      # @return [Array<RelatonBib::LocalizedString>] name parts
-      #
-      def name_part(name, part)
-        name.xpath("./#{part}").map { |np| localized_string np }
-      end
-
-      # @param item [Nokogiri::XML::Element]
-      # @return [Array<RelatonBib::ContributionInfo>]
-      def fetch_contributors(item)
-        item.xpath("./contributor").map { |c| fetch_contribution_info c }
-      end
-
-      def fetch_contribution_info(contrib)
-        entity = get_org(contrib.at("./organization")) || get_person(contrib.at("./person"))
-        role = contrib.xpath("./role").map do |r|
-          { type: r[:type], description: r.xpath("./description").map(&:text) }
-        end
-        ContributionInfo.new entity: entity, role: role
-      end
-
-      # @param item [Nokogiri::XML::Element]
-      # @return [Array<RelatonBib::FormattedString>]
-      def fetch_abstract(item)
-        item.xpath("./abstract").map do |a|
-          c = a.children.to_xml(encoding: "utf-8").strip
-          FormattedString.new(content: c, language: a[:language],
-                              script: a[:script], format: a[:format])
-        end
-      end
-
-      # @param item [Nokogiri::XML::Element]
-      # @return [Array<RelatonBib::CopyrightAssociation>]
-      def fetch_copyright(item)
-        item.xpath("./copyright").map do |cp|
-          owner = cp.xpath("owner").map { |o| fetch_contribution_info o }
-          from = cp.at("from")&.text
-          to   = cp.at("to")&.text
-          scope = cp.at("scope")&.text
-          CopyrightAssociation.new(owner: owner, from: from, to: to, scope: scope)
-        end
-      end
-
-      # @param item [Nokogiri::XML::Element]
-      # @return [Arra<RelatonBib::TypedUri>]
-      def fetch_link(item)
-        item.xpath("./uri").map do |l|
-          TypedUri.new(type: l[:type], content: l.text, language: l[:language],
-                       script: l[:script])
-        end
-      end
-
-      # @param item [Nokogiri::XML::Element]
-      # @param klass [RelatonBib::DocumentRelation.class,
-      #   RelatonNist::DocumentRelation.class]
-      # @return [Array<RelatonBib::DocumentRelation>]
-      def fetch_relations(item, klass = DocumentRelation)
-        item.xpath("./relation").map do |rel|
-          klass.new(
-            type: rel[:type].nil? || rel[:type].empty? ? nil : rel[:type],
-            description: relation_description(rel),
-            bibitem: bib_item(item_data(rel.at("./bibitem"))),
-            locality: localities(rel),
-            source_locality: source_localities(rel),
-          )
-        end
-      end
-
-      # @param rel [Nokogiri::XML::Element]
-      # @return [RelatonBib::FormattedString, nil]
-      def relation_description(rel)
-        d = rel.at "./description"
-        return unless d
-
-        FormattedString.new(content: d.text, language: d[:language],
-                            script: d[:script], format: d[:format])
-      end
-
-      #
-      # Create bibliographic item
-      #
-      # @param item_hash [Hash] bibliographic item hash
-      #
-      # @return [RelatonBib::BibliographicItem] bibliographic item
-      #
-      def bib_item(item_hash)
-        BibliographicItem.new(**item_hash)
-      end
-
-      #
-      # Parse locality
-      #
-      # @param rel [Nokogiri::XML::Element] relation element
-      #
-      # @return [Array<RelatonBib::Locality, RelatonBib::LocalityStack>] localities
-      #
-      def localities(rel)
-        rel.xpath("./locality|./localityStack").map do |lc|
-          if lc.name == "locality"
-            locality lc
-          else
-            LocalityStack.new(lc.xpath("./locality").map { |l| locality l })
-          end
-        end
-      end
-
-      #
-      # Create Locality object from Nokogiri::XML::Element
-      #
-      # @param loc [Nokogiri::XML::Element]
-      # @param klass [RelatonBib::Locality, RelatonBib::LocalityStack]
-      #
-      # @return [RelatonBib::Locality]
-      def locality(loc, klass = Locality)
-        klass.new(
-          loc[:type],
-          loc.at("./referenceFrom")&.text,
-          loc.at("./referenceTo")&.text,
-        )
-      end
-
-      # @param rel [Nokogiri::XML::Element]
-      # @return [Array<RelatonBib::SourceLocality,
-      #   RelatonBib::SourceLocalityStack>]
-      def source_localities(rel)
-        rel.xpath("./sourceLocality|./sourceLocalityStack").map do |loc|
-          if loc.name == "sourceLocality"
-            # src_locs = loc.xapth("./sourceLocality").map { |sl| locality(sl, SourceLocality) }
-            # SourceLocalityStack.new src_locs
-            locality loc, SourceLocality
-          else
-            sls = loc.xpath("./sourceLocality").map { |l| locality l, SourceLocality }
-            SourceLocalityStack.new sls
-          end
-        end
-      end
-
-      # @param item [Nokogiri::XML::Element]
-      # @return [RelatonBib::FormattedRef, nil]
-      def fref(item)
-        ident = item&.at("./formattedref")
-        return unless ident
-
-        FormattedRef.new(
-          content: ident.children.to_s, format: ident[:format],
-          language: ident[:language], script: ident[:script]
-        )
-      end
-
-      # @param ext [Nokogiri::XML::Element]
-      # @return [RelatonBib::EditorialGroup, nil]
-      def fetch_editorialgroup(ext)
-        return unless ext && (eg = ext.at "editorialgroup")
-
-        eg = eg.xpath("technical-committee").map do |tc|
-          wg = WorkGroup.new(
-            name: tc.text, number: tc[:number]&.to_i, type: tc[:type],
-            identifier: tc[:identifier], prefix: tc[:prefix]
-          )
-          TechnicalCommittee.new wg
-        end
-        EditorialGroup.new eg if eg.any?
-      end
-
-      def fetch_ics(ext)
-        return [] unless ext
-
-        ext.xpath("ics").map do |ics|
-          ICS.new code: ics.at("code")&.text, text: ics.at("text")&.text
-        end
-      end
-
-      # @param ext [Nokogiri::XML::Element]
-      # @return [RelatonBib::StructuredIdentifierCollection]
-      def fetch_structuredidentifier(ext) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
-        return unless ext
-
-        sids = ext.xpath("structuredidentifier").map do |si|
-          StructuredIdentifier.new(
-            type: si[:type],
-            agency: si.xpath("agency").map(&:text),
-            class: si.at("class")&.text,
-            docnumber: si.at("docnumber")&.text,
-            partnumber: si.at("partnumber")&.text,
-            edition: si.at("edition")&.text,
-            version: si.at("version")&.text,
-            supplementtype: si.at("supplementtype")&.text,
-            supplementnumber: si.at("supplementnumber")&.text,
-            language: si.at("language")&.text,
-            year: si.at("year")&.text,
-          )
-        end
-        StructuredIdentifierCollection.new sids
-      end
-    end
-  end
-end
diff --git a/relaton-bib.gemspec b/relaton-bib.gemspec
index 7f10a33..1149dc4 100644
--- a/relaton-bib.gemspec
+++ b/relaton-bib.gemspec
@@ -1,15 +1,15 @@
 lib = File.expand_path("lib", __dir__)
 $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
-require "relaton_bib/version"
+require "relaton/bib/gem_version"
 
 Gem::Specification.new do |spec|
   spec.name          = "relaton-bib"
-  spec.version       = RelatonBib::VERSION
+  spec.version       = Relaton::Bib::VERSION
   spec.authors       = ["Ribose Inc."]
   spec.email         = ["open.source@ribose.com"]
 
-  spec.summary       = "RelatonBib: Ruby XMLDOC impementation."
-  spec.description   = "RelatonBib: Ruby XMLDOC impementation."
+  spec.summary       = "Relaton::Bib: Ruby XMLDOC impementation."
+  spec.description   = "Relaton::Bib: Ruby XMLDOC impementation."
   spec.homepage      = "https://github.com/relaton/relaton-bib"
   spec.license       = "BSD-2-Clause"
 
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
   spec.add_dependency "bibtex-ruby"
   spec.add_dependency "htmlentities"
   spec.add_dependency "iso639"
+  spec.add_dependency "lutaml-model", "~> 0.6"
   spec.add_dependency "nokogiri", "~> 1.16.0"
   spec.add_dependency "relaton-logger", "~> 0.2.0"
 end
diff --git a/spec/examples/asciibib.adoc b/spec/fixtures/asciibib.adoc
similarity index 100%
rename from spec/examples/asciibib.adoc
rename to spec/fixtures/asciibib.adoc
diff --git a/spec/examples/bcp_item.xml b/spec/fixtures/bcp_item.xml
similarity index 100%
rename from spec/examples/bcp_item.xml
rename to spec/fixtures/bcp_item.xml
diff --git a/spec/examples/bcp_item.yml b/spec/fixtures/bcp_item.yml
similarity index 100%
rename from spec/examples/bcp_item.yml
rename to spec/fixtures/bcp_item.yml
diff --git a/spec/examples/bib_item.yml b/spec/fixtures/bib_item.yml
similarity index 93%
rename from spec/examples/bib_item.yml
rename to spec/fixtures/bib_item.yml
index 3489c89..a6d1638 100644
--- a/spec/examples/bib_item.yml
+++ b/spec/fixtures/bib_item.yml
@@ -181,6 +181,9 @@ contributor:
       identifier:
         type: uri
         id: www.person.com
+    role:
+      - type: author
+        description: Author description
 
   - person:
       name:
@@ -300,13 +303,12 @@ series:
       content: Journal
     number: "7"
   - title:
-      content:
-        - content: Series
-          language: en
-          script: Latn
-        - content: Séries
-          language: fr
-          script: Latn
+      - content: Series
+        language: en
+        script: Latn
+      - content: Séries
+        language: fr
+        script: Latn
   - title:
       content: RFC
     number: "4"
@@ -320,10 +322,10 @@ place:
   - bib place
   - city: Geneva
     region:
-      - name: Region
+      - name: Europe
     country:
       - iso: CH
-        name: Switzelznd
+        name: Switzeland
         recommended: true
 
 extent:
@@ -366,9 +368,21 @@ keyword:
 license: License
 
 validity:
-  begins: "2010-10-10 12:21"
-  ends: "2011-02-03 18:30"
-  revision: "2011-03-04 09:00"
+  begins: "2010-10-10"
+  ends: "2011-02-03"
+  revision: "2011-03-04"
+
+# depiction:
+#   scope: cover
+#   image:
+#     srl: cover1.png
+#     mimetype: image/png
+#     filename: cover1.png
+#     width: "200"
+#     height: 100%
+#     alt: Cover 1
+#     title: Cover #1
+#     longdesc: Cover number 1
 
 ext:
   doctype:
diff --git a/spec/fixtures/bibdata_from_old_yaml.xml b/spec/fixtures/bibdata_from_old_yaml.xml
new file mode 100644
index 0000000..c5b7ffe
--- /dev/null
+++ b/spec/fixtures/bibdata_from_old_yaml.xml
@@ -0,0 +1,331 @@
+<bibdata type="standard" schema-version="v1.4.1">
+  <fetched>2024-12-11</fetched>
+  <title>Geographic information</title>
+  <title language="fr" script="Latn">Information géographique</title>
+  <uri type="src" language="en" script="Latn">https://www.iso.org/standard/53798.html</uri>
+  <uri type="obp">https://www.iso.org/obp/ui/#!iso:std:53798:en</uri>
+  <uri type="rss">https://www.iso.org/contents/data/standard/05/37/53798.detail.rss</uri>
+  <uri type="doi">http://standrd.org/doi-123</uri>
+  <uri type="file">file://path/file</uri>
+  <docidentifier type="ISO" primary="true" language="en" script="Latn">ISO TC 211</docidentifier>
+  <docidentifier type="isbn">ISBN</docidentifier>
+  <docidentifier type="lccn">LCCN</docidentifier>
+  <docidentifier type="issn" scope="series">ISSN</docidentifier>
+  <docidentifier type="URN">urn:iso:std:iso:123:stage-90.93:ed-3:en,fr</docidentifier>
+  <docidentifier>XYZ</docidentifier>
+  <docidentifier type="DOI">10.17487/rfc1149</docidentifier>
+  <docidentifier type="Internet-Draft">draft-ietf-somewg-someprotocol-07</docidentifier>
+  <docnumber>TC211</docnumber>
+  <date type="issued">
+    <on>2014</on>
+  </date>
+  <date type="published">
+    <on>2014-04</on>
+  </date>
+  <date type="accessed">
+    <on>2015-05-20</on>
+  </date>
+  <contributor>
+    <role type="publisher">
+      <description>Publisher role</description>
+    </role>
+    <organization>
+      <name>International Organization for Standardization</name>
+      <subdivision>
+        <name>division</name>
+      </subdivision>
+      <abbreviation>ISO</abbreviation>
+      <uri>www.iso.org</uri>
+      <logo>
+        <image id="logo1" src="logo1.png" mimetype="image/png" filename="logo1.png" width="200" height="100%" alt="Logo 1" title="Logo #1" longdesc="Logo number 1"/>
+      </logo>
+    </organization>
+  </contributor>
+  <contributor>
+    <role type="author"/>
+    <person>
+      <name>
+        <abbreviation>AB</abbreviation>
+        <completename language="en" script="Latn">A. Bierman</completename>
+      </name>
+      <credential>Credential</credential>
+      <affiliation>
+        <organization>
+          <name>IETF</name>
+          <abbreviation>IETF</abbreviation>
+          <identifier type="uri">www.ietf.org</identifier>
+        </organization>
+      </affiliation>
+      <address>
+        <street>Street</street>
+        <city>City</city>
+        <state>State</state>
+        <country>Country</country>
+        <postcode>123456</postcode>
+      </address>
+      <phone type="work">223322</phone>
+      <email>person@email.org</email>
+      <uri>www.person.com</uri>
+    </person>
+  </contributor>
+  <contributor>
+    <role type="publisher">
+      <description>Publisher description</description>
+    </role>
+    <role type="editor">
+      <description>Editor description</description>
+    </role>
+    <organization>
+      <name>Institute of Electrical and Electronics Engineers</name>
+      <abbreviation>IEEE</abbreviation>
+      <identifier type="uri">www.ieee.org</identifier>
+      <address>
+        <formattedAddress>Formatted address</formattedAddress>
+      </address>
+    </organization>
+  </contributor>
+  <contributor>
+    <role type="author">
+      <description>Author description</description>
+    </role>
+    <person>
+      <name>
+        <prefix>Prefix</prefix>
+        <forename>Arnold</forename>
+        <formatted-initials>A.</formatted-initials>
+        <surname>Bierman</surname>
+        <addition>Addition</addition>
+      </name>
+      <affiliation>
+        <name language="en" script="Latn">Name</name>
+        <description language="en">Description</description>
+        <organization>
+          <name>IETF</name>
+          <abbreviation>IETF</abbreviation>
+        </organization>
+      </affiliation>
+      <identifier type="uri">www.person.com</identifier>
+      <address>
+        <street>Street</street>
+        <city>City</city>
+        <state>State</state>
+        <country>Country</country>
+        <postcode>123456</postcode>
+      </address>
+      <phone type="work">223322</phone>
+    </person>
+  </contributor>
+  <contributor>
+    <role type="editor"/>
+    <person>
+      <name>
+        <forename language="en" script="Latn" initial="A">Arnold</forename>
+        <forename initial="B"/>
+        <formatted-initials language="en" script="Latn">A. B.</formatted-initials>
+        <surname language="en" script="Latn">Bierman</surname>
+      </name>
+    </person>
+  </contributor>
+  <contributor>
+    <role type="distributor">
+      <description>sponsor</description>
+    </role>
+    <organization>
+      <name>World Wide Web Consortium</name>
+      <address>
+        <formattedAddress>Address string</formattedAddress>
+      </address>
+    </organization>
+  </contributor>
+  <edition number="1.2">Edition 1</edition>
+  <version>
+    <revision-date>2019-04-01</revision-date>
+    <draft>draft</draft>
+  </version>
+  <note>note</note>
+  <note type="annote">An note</note>
+  <note type="howpublished">How published</note>
+  <note type="comment">Comment</note>
+  <note type="tableOfContents">Table Of Contents</note>
+  <language>en</language>
+  <language>fr</language>
+  <script>Latn</script>
+  <abstract language="en" script="Latn">
+    <p>ISO 19115-1:2014 defines the schema required for...</p>
+  </abstract>
+  <abstract language="fr" script="Latn">L'ISO 19115-1:2014 définit le schéma requis pour...</abstract>
+  <status>
+    <stage abbreviation="CD">30</stage>
+    <substage>substage</substage>
+    <iteration>final</iteration>
+  </status>
+  <copyright>
+    <from>2014</from>
+    <to>2020</to>
+    <owner>
+      <organization>
+        <name>International Organization for Standardization</name>
+        <abbreviation>ISO</abbreviation>
+        <uri>www.iso.org</uri>
+      </organization>
+    </owner>
+    <scope>Scope</scope>
+  </copyright>
+  <relation type="updates">
+    <bibitem>
+      <formattedref>ISO 19115:2003</formattedref>
+    </bibitem>
+    <locality type="section">
+      <referenceFrom>Reference from</referenceFrom>
+    </locality>
+    <sourceLocalityStack>
+      <sourceLocality type="volume">
+        <referenceFrom>2</referenceFrom>
+      </sourceLocality>
+      <sourceLocality type="chapter">
+        <referenceFrom>3</referenceFrom>
+      </sourceLocality>
+    </sourceLocalityStack>
+  </relation>
+  <relation type="obsoletes">
+    <description>supersedes</description>
+    <bibitem type="standard">
+      <formattedref>ISO 19115:2003/Cor 1:2006</formattedref>
+    </bibitem>
+    <localityStack>
+      <locality type="chapter">
+        <referenceFrom>1</referenceFrom>
+      </locality>
+    </localityStack>
+    <localityStack>
+      <locality type="page">
+        <referenceFrom>2</referenceFrom>
+      </locality>
+    </localityStack>
+    <sourceLocality type="section">
+      <referenceFrom>Reference from</referenceFrom>
+      <referenceTo>Reference to</referenceTo>
+    </sourceLocality>
+  </relation>
+  <relation type="partOf">
+    <bibitem>
+      <title type="main">Book title</title>
+    </bibitem>
+  </relation>
+  <series type="Internet-Draft">
+    <title>Internet-Draft</title>
+    <number>draft-ietf-somewg-someprotocol-07</number>
+    <run>seriesrun</run>
+  </series>
+  <series type="main">
+    <title type="original" format="text/plain" language="en" script="Latn">ISO/IEC FDIS 10118-3</title>
+    <place>
+      <formattedPlace>Serie's place</formattedPlace>
+    </place>
+    <organization>Serie's organization</organization>
+    <abbreviation>ABVR</abbreviation>
+    <from>2009-02-01</from>
+    <to>2010-12-20</to>
+    <number>serie1234</number>
+    <partnumber>part5678</partnumber>
+  </series>
+  <series type="alt">
+    <formattedref>serieref</formattedref>
+    <title>Formattedref</title>
+  </series>
+  <series type="journal">
+    <title>Journal</title>
+    <number>7</number>
+  </series>
+  <series>
+    <title language="en" script="Latn">Series</title>
+    <title language="fr" script="Latn">Séries</title>
+  </series>
+  <series>
+    <title>RFC</title>
+    <number>4</number>
+  </series>
+  <medium>
+    <form>medium form</form>
+    <size>medium size</size>
+    <scale>medium scale</scale>
+  </medium>
+  <place>
+    <formattedPlace>bib place</formattedPlace>
+  </place>
+  <place>
+    <city>Geneva</city>
+    <region>Europe</region>
+    <country iso="CH" recommended="true">Switzeland</country>
+  </place>
+  <extent>
+    <locality type="section">
+      <referenceFrom>Reference from</referenceFrom>
+      <referenceTo>Reference to</referenceTo>
+    </locality>
+    <locality type="chapter">
+      <referenceFrom>4</referenceFrom>
+    </locality>
+  </extent>
+  <extent>
+    <localityStack>
+      <locality type="page">
+        <referenceFrom>10</referenceFrom>
+        <referenceTo>20</referenceTo>
+      </locality>
+      <locality type="volume">
+        <referenceFrom>1</referenceFrom>
+      </locality>
+    </localityStack>
+  </extent>
+  <size>
+    <value type="page">490</value>
+    <value type="plate">3</value>
+  </size>
+  <accesslocation>accesslocation1</accesslocation>
+  <accesslocation>accesslocation2</accesslocation>
+  <license>License</license>
+  <classification type="type">value</classification>
+  <classification type="keyword">Keywords</classification>
+  <classification type="mendeley">Mendeley Tags</classification>
+  <keyword>
+    <taxon>Keyword</taxon>
+  </keyword>
+  <keyword>
+    <taxon>Key Word</taxon>
+  </keyword>
+  <validity>
+    <validityBegins>2010-10-10</validityBegins>
+    <validityEnds>2011-02-03</validityEnds>
+    <revision>2011-03-04</revision>
+  </validity>
+  <ext>
+    <doctype abbreviation="DCT">Doctype</doctype>
+    <subdoctype>Subdoctype</subdoctype>
+    <flavor>iso</flavor>
+    <editorialgroup>
+      <technical-committee number="1" type="Type" identifier="Identifier" prefix="Prefix">Editorial group</technical-committee>
+    </editorialgroup>
+    <ics>
+      <code>01</code>
+      <text>First</text>
+    </ics>
+    <structuredidentifier type="type 1">
+      <agency>agency 1</agency>
+      <agency>agency 2</agency>
+      <class>class 1</class>
+      <docnumber>123</docnumber>
+      <partnumber>4</partnumber>
+      <edition>1</edition>
+      <version>2</version>
+      <supplementtype>type 2</supplementtype>
+      <supplementnumber>5</supplementnumber>
+      <language>en</language>
+      <year>2020</year>
+    </structuredidentifier>
+    <structuredidentifier>
+      <agency>agency 3</agency>
+      <docnumber>456</docnumber>
+    </structuredidentifier>
+  </ext>
+</bibdata>
diff --git a/spec/examples/bibdata_item.xml b/spec/fixtures/bibdata_item.xml
similarity index 90%
rename from spec/examples/bibdata_item.xml
rename to spec/fixtures/bibdata_item.xml
index 0dcb33b..f8faa18 100644
--- a/spec/examples/bibdata_item.xml
+++ b/spec/fixtures/bibdata_item.xml
@@ -32,7 +32,9 @@
     </role>
     <organization>
       <name>International Organization for Standardization</name>
-      <subdivision>division</subdivision>
+      <subdivision>
+        <name>Subdivision</name>
+      </subdivision>
       <abbreviation>ISO</abbreviation>
       <uri>www.iso.org</uri>
       <logo>
@@ -147,10 +149,10 @@
   <language>en</language>
   <language>fr</language>
   <script>Latn</script>
-  <abstract format="text/html" language="en" script="Latn">
+  <abstract language="en" script="Latn">
     <p>ISO 19115-1:2014 defines the schema required for...</p>
   </abstract>
-  <abstract format="text/plain" language="fr" script="Latn">L'ISO 19115-1:2014 définit le schéma requis pour...</abstract>
+  <abstract language="fr" script="Latn">L'ISO 19115-1:2014 définit le schéma requis pour...</abstract>
   <status>
     <stage abbreviation="CD">30</stage>
     <substage>substage</substage>
@@ -170,7 +172,7 @@
   </copyright>
   <relation type="updates">
     <bibitem>
-      <formattedref format="text/plain">ISO 19115:2003</formattedref>
+      <formattedref>ISO 19115:2003</formattedref>
     </bibitem>
     <locality type="section">
       <referenceFrom>Reference from</referenceFrom>
@@ -185,9 +187,9 @@
     </sourceLocalityStack>
   </relation>
   <relation type="obsoletes">
-    <description format="text/plain">supersedes</description>
+    <description>supersedes</description>
     <bibitem type="standard">
-      <formattedref format="text/plain">ISO 19115:2003/Cor 1:2006</formattedref>
+      <formattedref>ISO 19115:2003/Cor 1:2006</formattedref>
     </bibitem>
     <localityStack>
       <locality type="chapter">
@@ -216,7 +218,9 @@
   </series>
   <series type="main">
     <title type="original" format="text/plain" language="en" script="Latn">ISO/IEC FDIS 10118-3</title>
-    <place>Serie's place</place>
+    <place>
+      <formattedPlace>Serie's place</formattedPlace>
+    </place>
     <organization>Serie's organization</organization>
     <abbreviation>ABVR</abbreviation>
     <from>2009-02-01</from>
@@ -225,7 +229,7 @@
     <partnumber>part5678</partnumber>
   </series>
   <series type="alt">
-    <formattedref format="text/plain" language="en" script="Latn">serieref</formattedref>
+    <formattedref>serieref</formattedref>
     <title format="text/plain">Formattedref</title>
   </series>
   <series type="journal">
@@ -233,10 +237,8 @@
     <number>7</number>
   </series>
   <series>
-    <title format="text/plain">
-      <variant language="en" script="Latn">Series</variant>
-      <variant language="fr" script="Latn">Séries</variant>
-    </title>
+    <title format="text/plain" language="en" script="Latn">Series</title>
+    <title language="fr" script="Latn">Séries</title>
   </series>
   <series>
     <title format="text/plain">RFC</title>
@@ -247,7 +249,9 @@
     <size>medium size</size>
     <scale>medium scale</scale>
   </medium>
-  <place>bib place</place>
+  <place>
+    <formattedPlace>bib place</formattedPlace>
+  </place>
   <place>
     <city>Geneva</city>
     <region>Region</region>
@@ -283,16 +287,21 @@
   <classification type="type">value</classification>
   <classification type="keyword">Keywords</classification>
   <classification type="mendeley">Mendeley Tags</classification>
-  <keyword>Keyword</keyword>
-  <keyword>Key Word</keyword>
+  <keyword>
+    <taxon>Keyword</taxon>
+  </keyword>
+  <keyword>
+    <taxon>Key Word</taxon>
+  </keyword>
   <validity>
-    <validityBegins>2010-10-10 12:21</validityBegins>
-    <validityEnds>2011-02-03 18:30</validityEnds>
-    <revision>2011-03-04 09:00</revision>
+    <validityBegins>2010-10-10</validityBegins>
+    <validityEnds>2011-02-03</validityEnds>
+    <revision>2011-03-04</revision>
   </validity>
   <ext>
     <doctype abbreviation="DCT">Doctype</doctype>
     <subdoctype>Subdoctype</subdoctype>
+    <flavor>iso</flavor>
     <editorialgroup>
       <technical-committee number="1" type="Type" identifier="Identifier" prefix="Prefix">Editorial group</technical-committee>
     </editorialgroup>
@@ -318,4 +327,4 @@
       <docnumber>456</docnumber>
     </structuredidentifier>
   </ext>
-</bibdata>
\ No newline at end of file
+</bibdata>
diff --git a/spec/examples/bibdata_item_fr.xml b/spec/fixtures/bibdata_item_fr.xml
similarity index 100%
rename from spec/examples/bibdata_item_fr.xml
rename to spec/fixtures/bibdata_item_fr.xml
diff --git a/spec/fixtures/bibitem.xml b/spec/fixtures/bibitem.xml
new file mode 100644
index 0000000..123f60a
--- /dev/null
+++ b/spec/fixtures/bibitem.xml
@@ -0,0 +1,301 @@
+<bibitem id="ISOTC211" type="standard" schema-version="v1.4.1">
+  <fetched>2024-12-11</fetched>
+  <formattedref>ISO TC 211</formattedref>
+  <title type="title-main" format="text/plain">Geographic information</title>
+  <title type="main" format="text/plain">Geographic information</title>
+  <title format="text/plain" language="fr" script="Latn">Information géographique</title>
+  <uri type="src" language="en" script="Latn">https://www.iso.org/standard/53798.html</uri>
+  <uri type="obp">https://www.iso.org/obp/ui/#!iso:std:53798:en</uri>
+  <uri type="rss">https://www.iso.org/contents/data/standard/05/37/53798.detail.rss</uri>
+  <uri type="doi">http://standrd.org/doi-123</uri>
+  <uri type="file">file://path/file</uri>
+  <docidentifier type="ISO" primary="true" language="en" script="Latn">ISO TC 211</docidentifier>
+  <docidentifier type="isbn">ISBN</docidentifier>
+  <docidentifier type="lccn">LCCN</docidentifier>
+  <docidentifier type="issn" scope="series">ISSN</docidentifier>
+  <docidentifier type="URN">urn:iso:std:iso:123:stage-90.93:ed-3:en,fr</docidentifier>
+  <docidentifier>XYZ</docidentifier>
+  <docidentifier type="DOI">10.17487/rfc1149</docidentifier>
+  <docidentifier type="Internet-Draft">draft-ietf-somewg-someprotocol-07</docidentifier>
+  <docnumber>TC211</docnumber>
+  <date type="issued" text="">
+    <on>2014</on>
+  </date>
+  <date type="published" text="">
+    <on>2014-04</on>
+  </date>
+  <date type="accessed" text="">
+    <on>2015-05-20</on>
+  </date>
+  <contributor>
+    <role type="publisher">
+      <description>Publisher role</description>
+    </role>
+    <organization>
+      <name type="Org name type" language="en" script="Latn" locale="en-US">International Organization for Standardization</name>
+      <subdivision type="Sub Div type">
+        <name>Sub division name</name>
+      </subdivision>
+      <abbreviation>ISO</abbreviation>
+      <uri>www.iso.org</uri>
+      <logo>
+        <image id="logo1" src="logo1.png" mimetype="image/png" filename="logo1.png" width="200" height="100%" alt="Logo 1" title="Logo #1" longdesc="Logo number 1"/>
+      </logo>
+    </organization>
+  </contributor>
+  <contributor>
+    <role type="author"/>
+    <person>
+      <name>
+        <abbreviation>AB</abbreviation>
+        <completename language="en" script="Latn">A. Bierman</completename>
+      </name>
+      <credential>Credential</credential>
+      <affiliation>
+        <organization>
+          <name>IETF</name>
+          <abbreviation>IETF</abbreviation>
+          <identifier type="uri">www.ietf.org</identifier>
+        </organization>
+      </affiliation>
+      <address>
+        <street>Street</street>
+        <city>City</city>
+        <state>State</state>
+        <country>Country</country>
+        <postcode>123456</postcode>
+      </address>
+      <phone type="mobile">223322</phone>
+      <email>person@email.org</email>
+      <uri>www.person.com</uri>
+    </person>
+  </contributor>
+  <contributor>
+    <role type="publisher">
+      <description>Publisher description</description>
+    </role>
+    <role type="editor">
+      <description>Editor description</description>
+    </role>
+    <organization>
+      <name>Institute of Electrical and Electronics Engineers</name>
+      <abbreviation>IEEE</abbreviation>
+      <identifier type="uri">www.ieee.org</identifier>
+      <address>
+        <formattedAddress>Formatted address</formattedAddress>
+      </address>
+    </organization>
+  </contributor>
+  <contributor>
+    <role type="author"/>
+    <person>
+      <name>
+        <prefix>Prefix</prefix>
+        <forename>Arnold</forename>
+        <formatted-initials>A.</formatted-initials>
+        <surname>Bierman</surname>
+        <addition>Addition</addition>
+      </name>
+      <affiliation>
+        <name language="en" script="Latn">Name</name>
+        <description language="en">Description</description>
+        <organization>
+          <name>IETF</name>
+          <abbreviation>IETF</abbreviation>
+        </organization>
+      </affiliation>
+      <identifier type="uri">www.person.com</identifier>
+      <address>
+        <street>Street</street>
+        <city>City</city>
+        <state>State</state>
+        <country>Country</country>
+        <postcode>123456</postcode>
+      </address>
+      <phone type="work">223322</phone>
+    </person>
+  </contributor>
+  <contributor>
+    <role type="editor"/>
+    <person>
+      <name>
+        <forename language="en" script="Latn" initial="A">Arnold</forename>
+        <forename initial="B"/>
+        <formatted-initials language="en" script="Latn">A. B.</formatted-initials>
+        <surname language="en" script="Latn">Bierman</surname>
+      </name>
+    </person>
+  </contributor>
+  <contributor>
+    <role type="distributor">
+      <description>sponsor</description>
+    </role>
+    <organization>
+      <name>World Wide Web Consortium</name>
+      <address>
+        <formattedAddress>Address string</formattedAddress>
+      </address>
+    </organization>
+  </contributor>
+  <edition number="1.2">Edition 1</edition>
+  <version>
+    <revision-date>2019-04-01</revision-date>
+    <draft>draft</draft>
+  </version>
+  <note>note</note>
+  <note type="annote">An note</note>
+  <note type="howpublished">How published</note>
+  <note type="comment">Comment</note>
+  <note type="tableOfContents">Table Of Contents</note>
+  <language>en</language>
+  <language>fr</language>
+  <locale>en-US</locale>
+  <script>Latn</script>
+  <abstract language="en" script="Latn">
+    <p>ISO 19115-1:2014 defines the schema required for...</p>
+  </abstract>
+  <abstract language="fr" script="Latn">L'ISO 19115-1:2014 définit le schéma requis pour...</abstract>
+  <status>
+    <stage abbreviation="CD">30</stage>
+    <substage>substage</substage>
+    <iteration>final</iteration>
+  </status>
+  <copyright>
+    <from>2014</from>
+    <to>2020</to>
+    <owner>
+      <organization>
+        <name>International Organization for Standardization</name>
+        <abbreviation language="en">ISO</abbreviation>
+        <uri>www.iso.org</uri>
+      </organization>
+    </owner>
+    <scope>Scope</scope>
+  </copyright>
+  <relation type="updates">
+    <bibitem>
+      <formattedref>ISO 19115:2003</formattedref>
+    </bibitem>
+    <locality type="section">
+      <referenceFrom>Reference from</referenceFrom>
+    </locality>
+    <sourceLocalityStack>
+      <sourceLocality type="volume">
+        <referenceFrom>2</referenceFrom>
+      </sourceLocality>
+      <sourceLocality type="chapter">
+        <referenceFrom>3</referenceFrom>
+      </sourceLocality>
+    </sourceLocalityStack>
+  </relation>
+  <relation type="obsoletes">
+    <description>supersedes</description>
+    <bibitem type="standard">
+      <formattedref>ISO 19115:2003/Cor 1:2006</formattedref>
+    </bibitem>
+    <localityStack>
+      <locality type="chapter">
+        <referenceFrom>1</referenceFrom>
+      </locality>
+    </localityStack>
+    <localityStack>
+      <locality type="page">
+        <referenceFrom>2</referenceFrom>
+      </locality>
+    </localityStack>
+    <sourceLocality type="section">
+      <referenceFrom>Reference from</referenceFrom>
+      <referenceTo>Reference to</referenceTo>
+    </sourceLocality>
+  </relation>
+  <relation type="partOf">
+    <bibitem>
+      <title type="main" format="text/plain">Book title</title>
+    </bibitem>
+  </relation>
+  <series type="main">
+    <formattedref>Series formatted ref</formattedref>
+    <title type="main">Series Title</title>
+    <place>
+      <city>New York</city>
+      <region iso="NY" recommended="true">New York</region>
+      <country iso="US" recommended="true">USA</country>
+      <formattedPlace>New York, NY, US</formattedPlace>
+    </place>
+  </series>
+  <series type="alt">
+    <formattedref>ISO/IEC FDIS 10118-3</formattedref>
+    <title type="original" language="en" script="Latn" locale="en-US">ISO/IEC FDIS 10118-3</title>
+    <organization>Serie's organization</organization>
+    <abbreviation language="en" script="Latn" locale="en-US">ABVR</abbreviation>
+    <from>2009-02-01</from>
+    <to>2010-12-20</to>
+    <number>serie1234</number>
+    <partnumber>part5678</partnumber>
+    <run>2</run>
+  </series>
+  <medium>
+    <content>Medium content</content>
+    <genre>Medium Genre</genre>
+    <form>Medium form</form>
+    <carrier>Medium carrier</carrier>
+    <size>Medium size</size>
+    <scale>Medium scale</scale>
+  </medium>
+  <place>
+    <city>Geneva</city>
+    <region>Europe</region>
+    <country iso="CH" recommended="true">Switzeland</country>
+    <formattedPlace>Geneva, Switzeland</formattedPlace>
+  </place>
+  <price currency="USD">123</price>
+  <extent>
+    <localityStack>
+      <locality type="section">
+        <referenceFrom>Reference from</referenceFrom>
+        <referenceTo>Reference to</referenceTo>
+      </locality>
+      <locality type="chapter">
+        <referenceFrom>4</referenceFrom>
+      </locality>
+    </localityStack>
+  </extent>
+  <extent>
+    <localityStack>
+      <locality type="page">
+        <referenceFrom>10</referenceFrom>
+        <referenceTo>20</referenceTo>
+      </locality>
+      <locality type="volume">
+        <referenceFrom>1</referenceFrom>
+      </locality>
+    </localityStack>
+  </extent>
+  <size>
+    <value type="page">490</value>
+    <value type="plate">3</value>
+  </size>
+  <accesslocation>accesslocation1</accesslocation>
+  <accesslocation>accesslocation2</accesslocation>
+  <license>License</license>
+  <classification type="type">value</classification>
+  <classification type="keyword">Keywords</classification>
+  <classification type="mendeley">Mendeley Tags</classification>
+  <keyword>
+    <vocab language="en" script="Latn">Vocab 1</vocab>
+    <taxon language="en" script="Latn">Taxon 1</taxon>
+    <taxon language="fr" script="Latn">Taxon 2</taxon>
+    <vocabid type="vocab-id-type" uri="http://vovab">
+      <code>444</code>
+      <term>VocabId Term</term>
+    </vocabid>
+  </keyword>
+  <validity>
+    <validityBegins>2010-10-10</validityBegins>
+    <validityEnds>2011-02-03</validityEnds>
+    <revision>2011-03-04</revision>
+  </validity>
+  <depiction scope="cover">
+    <image src="cover1.png" mimetype="image/png" filename="cover1.png" width="200" height="100%" alt="Cover 1" title="Cover #1" longdesc="Cover number 1"/>
+  </depiction>
+</bibitem>
diff --git a/spec/examples/bibtex_article.xml b/spec/fixtures/bibtex_article.xml
similarity index 100%
rename from spec/examples/bibtex_article.xml
rename to spec/fixtures/bibtex_article.xml
diff --git a/spec/examples/bibtex_book.xml b/spec/fixtures/bibtex_book.xml
similarity index 100%
rename from spec/examples/bibtex_book.xml
rename to spec/fixtures/bibtex_book.xml
diff --git a/spec/examples/bibtex_inbook.xml b/spec/fixtures/bibtex_inbook.xml
similarity index 100%
rename from spec/examples/bibtex_inbook.xml
rename to spec/fixtures/bibtex_inbook.xml
diff --git a/spec/examples/bibtex_inproceedings.xml b/spec/fixtures/bibtex_inproceedings.xml
similarity index 100%
rename from spec/examples/bibtex_inproceedings.xml
rename to spec/fixtures/bibtex_inproceedings.xml
diff --git a/spec/examples/bibtex_phdthesis.xml b/spec/fixtures/bibtex_phdthesis.xml
similarity index 100%
rename from spec/examples/bibtex_phdthesis.xml
rename to spec/fixtures/bibtex_phdthesis.xml
diff --git a/spec/examples/bibtex_techreport.xml b/spec/fixtures/bibtex_techreport.xml
similarity index 100%
rename from spec/examples/bibtex_techreport.xml
rename to spec/fixtures/bibtex_techreport.xml
diff --git a/spec/examples/citeproc.json b/spec/fixtures/citeproc.json
similarity index 100%
rename from spec/examples/citeproc.json
rename to spec/fixtures/citeproc.json
diff --git a/spec/examples/from_bibtex.xml b/spec/fixtures/from_bibtex.xml
similarity index 100%
rename from spec/examples/from_bibtex.xml
rename to spec/fixtures/from_bibtex.xml
diff --git a/spec/examples/bib_item.xml b/spec/fixtures/from_old_yaml.xml
similarity index 79%
rename from spec/examples/bib_item.xml
rename to spec/fixtures/from_old_yaml.xml
index ac55493..d73d067 100644
--- a/spec/examples/bib_item.xml
+++ b/spec/fixtures/from_old_yaml.xml
@@ -1,14 +1,13 @@
-<bibitem id="ISOTC211" type="standard" schema-version="v1.2.9">
-  <fetched>2024-12-11</fetched>
-  <title type="title-main" format="text/plain">Geographic information</title>
-  <title type="main" format="text/plain">Geographic information</title>
-  <title format="text/plain" language="fr" script="Latn">Information géographique</title>
-  <uri type="src" language="en" script="Latn">https://www.iso.org/standard/53798.html</uri>
+<bibitem id="ISOTC211" type="standard" schema-version="v1.4.1">
+  <fetched>2025-01-23</fetched>
+  <title>Geographic information</title>
+  <title language="fr" script="Latn">Information géographique</title>
+  <uri language="en" script="Latn" type="src">https://www.iso.org/standard/53798.html</uri>
   <uri type="obp">https://www.iso.org/obp/ui/#!iso:std:53798:en</uri>
   <uri type="rss">https://www.iso.org/contents/data/standard/05/37/53798.detail.rss</uri>
   <uri type="doi">http://standrd.org/doi-123</uri>
   <uri type="file">file://path/file</uri>
-  <docidentifier type="ISO" primary="true" language="en" script="Latn">ISO TC 211</docidentifier>
+  <docidentifier language="en" script="Latn" type="ISO" primary="true">ISO TC 211</docidentifier>
   <docidentifier type="isbn">ISBN</docidentifier>
   <docidentifier type="lccn">LCCN</docidentifier>
   <docidentifier type="issn" scope="series">ISSN</docidentifier>
@@ -32,7 +31,9 @@
     </role>
     <organization>
       <name>International Organization for Standardization</name>
-      <subdivision>division</subdivision>
+      <subdivision>
+        <name>division</name>
+      </subdivision>
       <abbreviation>ISO</abbreviation>
       <uri>www.iso.org</uri>
       <logo>
@@ -62,7 +63,7 @@
         <country>Country</country>
         <postcode>123456</postcode>
       </address>
-      <phone type="mobile">223322</phone>
+      <phone type="work">223322</phone>
       <email>person@email.org</email>
       <uri>www.person.com</uri>
     </person>
@@ -84,7 +85,9 @@
     </organization>
   </contributor>
   <contributor>
-    <role type="author"/>
+    <role type="author">
+      <description>Author description</description>
+    </role>
     <person>
       <name>
         <prefix>Prefix</prefix>
@@ -147,10 +150,10 @@
   <language>en</language>
   <language>fr</language>
   <script>Latn</script>
-  <abstract format="text/html" language="en" script="Latn">
+  <abstract language="en" script="Latn">
     <p>ISO 19115-1:2014 defines the schema required for...</p>
   </abstract>
-  <abstract format="text/plain" language="fr" script="Latn">L'ISO 19115-1:2014 définit le schéma requis pour...</abstract>
+  <abstract language="fr" script="Latn">L'ISO 19115-1:2014 définit le schéma requis pour...</abstract>
   <status>
     <stage abbreviation="CD">30</stage>
     <substage>substage</substage>
@@ -170,7 +173,7 @@
   </copyright>
   <relation type="updates">
     <bibitem>
-      <formattedref format="text/plain">ISO 19115:2003</formattedref>
+      <formattedref>ISO 19115:2003</formattedref>
     </bibitem>
     <locality type="section">
       <referenceFrom>Reference from</referenceFrom>
@@ -185,9 +188,9 @@
     </sourceLocalityStack>
   </relation>
   <relation type="obsoletes">
-    <description format="text/plain">supersedes</description>
+    <description>supersedes</description>
     <bibitem type="standard">
-      <formattedref format="text/plain">ISO 19115:2003/Cor 1:2006</formattedref>
+      <formattedref>ISO 19115:2003/Cor 1:2006</formattedref>
     </bibitem>
     <localityStack>
       <locality type="chapter">
@@ -206,17 +209,19 @@
   </relation>
   <relation type="partOf">
     <bibitem>
-      <title type="main" format="text/plain">Book title</title>
+      <title type="main">Book title</title>
     </bibitem>
   </relation>
   <series type="Internet-Draft">
-    <title format="text/plain">Internet-Draft</title>
+    <title>Internet-Draft</title>
     <number>draft-ietf-somewg-someprotocol-07</number>
     <run>seriesrun</run>
   </series>
   <series type="main">
-    <title type="original" format="text/plain" language="en" script="Latn">ISO/IEC FDIS 10118-3</title>
-    <place>Serie's place</place>
+    <title language="en" script="Latn" type="original" format="text/plain">ISO/IEC FDIS 10118-3</title>
+    <place>
+      <formattedPlace>Serie's place</formattedPlace>
+    </place>
     <organization>Serie's organization</organization>
     <abbreviation>ABVR</abbreviation>
     <from>2009-02-01</from>
@@ -225,21 +230,19 @@
     <partnumber>part5678</partnumber>
   </series>
   <series type="alt">
-    <formattedref format="text/plain" language="en" script="Latn">serieref</formattedref>
-    <title format="text/plain">Formattedref</title>
+    <formattedref>serieref</formattedref>
+    <title>Formattedref</title>
   </series>
   <series type="journal">
-    <title format="text/plain">Journal</title>
+    <title>Journal</title>
     <number>7</number>
   </series>
   <series>
-    <title format="text/plain">
-      <variant language="en" script="Latn">Series</variant>
-      <variant language="fr" script="Latn">Séries</variant>
-    </title>
+    <title language="en" script="Latn">Series</title>
+    <title language="fr" script="Latn">Séries</title>
   </series>
   <series>
-    <title format="text/plain">RFC</title>
+    <title>RFC</title>
     <number>4</number>
   </series>
   <medium>
@@ -247,11 +250,13 @@
     <size>medium size</size>
     <scale>medium scale</scale>
   </medium>
-  <place>bib place</place>
+  <place>
+    <formattedPlace>bib place</formattedPlace>
+  </place>
   <place>
     <city>Geneva</city>
-    <region>Region</region>
-    <country iso="CH" recommended="true">Switzelznd</country>
+    <region>Europe</region>
+    <country iso="CH" recommended="true">Switzeland</country>
   </place>
   <extent>
     <locality type="section">
@@ -283,11 +288,15 @@
   <classification type="type">value</classification>
   <classification type="keyword">Keywords</classification>
   <classification type="mendeley">Mendeley Tags</classification>
-  <keyword>Keyword</keyword>
-  <keyword>Key Word</keyword>
+  <keyword>
+    <taxon>Keyword</taxon>
+  </keyword>
+  <keyword>
+    <taxon>Key Word</taxon>
+  </keyword>
   <validity>
-    <validityBegins>2010-10-10 12:21</validityBegins>
-    <validityEnds>2011-02-03 18:30</validityEnds>
-    <revision>2011-03-04 09:00</revision>
+    <validityBegins>2010-10-10</validityBegins>
+    <validityEnds>2011-02-03</validityEnds>
+    <revision>2011-03-04</revision>
   </validity>
-</bibitem>
\ No newline at end of file
+</bibitem>
diff --git a/spec/examples/hash.yml b/spec/fixtures/hash.yml
similarity index 100%
rename from spec/examples/hash.yml
rename to spec/fixtures/hash.yml
diff --git a/spec/examples/id_item.xml b/spec/fixtures/id_item.xml
similarity index 100%
rename from spec/examples/id_item.xml
rename to spec/fixtures/id_item.xml
diff --git a/spec/examples/id_item.yml b/spec/fixtures/id_item.yml
similarity index 100%
rename from spec/examples/id_item.yml
rename to spec/fixtures/id_item.yml
diff --git a/spec/examples/ieee_bibxml.xml b/spec/fixtures/ieee_bibxml.xml
similarity index 100%
rename from spec/examples/ieee_bibxml.xml
rename to spec/fixtures/ieee_bibxml.xml
diff --git a/spec/fixtures/item.yaml b/spec/fixtures/item.yaml
new file mode 100644
index 0000000..475290b
--- /dev/null
+++ b/spec/fixtures/item.yaml
@@ -0,0 +1,410 @@
+id: ISO1231994
+type: standard
+schema_version: 1.0.0
+fetched: "2022-05-02"
+formattedref: ISO 123:1994
+title:
+  - content: Geographic information -- Metadata
+    language: en
+    script: Latn
+    locale: en-US
+  - content: Information géographique -- Métadonnées
+    language: fr
+    script: Latn
+    locale: fr-FR
+source:
+  - type: src
+    content: https://www.iso.org/standard/22722.html
+  - type: doi
+    content: 10.1007/978-3-319-99155-2_1
+docidentifier:
+  - type: ISO
+    content: ISO 123:1994
+    language: en
+    script: Latn
+    locale: en-US
+    scope: global
+    primary: true
+  - type: DOI
+    content: 10.1007/978-3-319-99155-2_1
+docnumber: "123"
+date:
+  - type: published
+    at: "1994-01-01"
+  - type: confirmed
+    from: "1994-02-01"
+    to: "1994-12-31"
+contributor:
+  - role:
+      type: author
+      description:
+        - content: Role of the author
+          language: en
+          script: Latn
+          locale: en-US
+    person:
+      name:
+        abbreviation:
+          content: Prof. J.
+          language: en
+          script: Latn
+          locale: en-US
+        prefix:
+          - content: Prof.
+            language: en
+            script: Latn
+            locale: en-US
+        forename:
+          - initial: J
+            content: John
+            language: en
+            script: Latn
+            locale: en-US
+        formatted_initials:
+          content: J.D.
+          language: en
+          script: Latn
+          locale: en-US
+        surname:
+          content: Doe
+          language: en
+          script: Latn
+          locale: en-US
+        addition:
+          - content: PhD
+            language: en
+            script: Latn
+            locale: en-US
+        completename:
+          content: Prof. John Doe PhD
+          language: en
+          script: Latn
+          locale: en-US
+        note:
+          - type: legal
+            content: J.D.
+            language: en
+            script: Latn
+            locale: en-US
+        variant:
+          - type: pseudonym
+            completename:
+              content: John Q. Public
+              language: en
+              script: Latn
+              locale: en-US
+      credential:
+        - PhD
+      affiliation:
+        - name:
+            content: ISO
+            language: en
+            script: Latn
+            locale: en-US
+          description:
+            - content: Affiliation of the author
+              language: en
+              script: Latn
+              locale: en-US
+          organization:
+            name:
+              - type: primary
+                content: International Organization for Standardization
+      identifier:
+        - type: orcid
+          content: 0000-0002-1825-0097
+      address:
+        - street:
+            - 1, rue de Varembé
+          city: Geneva
+          country: Switzerland
+          postcode: "1211"
+          formatted_address: 1, rue de Varembé,<br>Geneva, Switzerland, 1211
+      phone:
+        - type: mobile
+          content: "+41 22 749 01 11"
+      email:
+        - jdoe@email.org
+      uri:
+        - type: primary
+          content: https://orcid.org/0000-0002-1825-0097
+  - role:
+      type: publisher
+      description:
+        - content: Role of the publisher
+    organization:
+        name:
+          - type: primary
+            content: International Organization for Standardization
+            language: en
+            script: Latn
+            locale: en-US
+        subdivision:
+          - type: primary
+            name:
+                content: ISO/TC 211
+        abbreviation:
+          content: ISO
+        identifier:
+          - type: ISNI
+            content: 0000 0001 2345 6789
+        address:
+          - street:
+              - 1, rue de Varembé
+            city: Geneva
+            country: Switzerland
+            postcode: "1211"
+            formatted_address: 1, rue de Varembé,<br>Geneva, Switzerland, 1211
+        phone:
+          - type: main
+            content: "+41 22 749 01 11"
+        email:
+          - office@iso.org
+        uri:
+          - type: primary
+            content: https://www.iso.org
+            language: en
+            script: Latn
+            locale: en-US
+        logo:
+          image:
+            id: 12345678-abcd-1234-abcd-1234567890ab
+            src: https://www.iso.org/files/live/sites/isoorg/files/store/en/PUB100080.jpg
+            mimetype: image/jpeg
+            filename: PUB100080.jpg
+            alt: ISO logo
+            title: ISO Logo
+            longdesc: https://www.iso.org/files/live/sites/isoorg/files/store/en/PUB100080.jpg
+            width: 100%
+            height: auto
+edition:
+  number: "1"
+  content: First edition
+version:
+  - revision_date: "1994-01-01"
+    draft: PD
+note:
+  - type: errata
+    content: This is an errata
+    language: en
+    script: Latn
+    locale: en-US
+language:
+  - en
+  - fr
+locale:
+  - en-US
+  - fr-FR
+script:
+  - Latn
+abstract:
+  - content: This is an abstract. <em>This is emphasized</em>
+    language: en
+    script: Latn
+    locale: en-US
+status:
+  stage:
+    abbreviation: IS
+    content: Published
+  substage:
+    abbreviation: FDIS
+    content: Final Draft International Standard
+  iteration: "3"
+copyright:
+  - from: "1994"
+    to: "2000"
+    owner:
+      - organization:
+          name:
+            - content: ISO
+      - person:
+          name:
+            completename:
+              content: John Doe
+    scope: Book preface
+relation:
+  - type: isPartOf
+    description:
+      content: Part of the ISO 123 serieso
+      language: en
+      script: Latn
+      locale: en-US
+    bibitem:
+      formattedref: ISO 123-1:1994
+      docidentifier:
+        - type: ISO
+          content: ISO 123-1:1994
+    locality:
+      - type: section
+        reference_from: "1"
+        reference_to: "10"
+    locality_stack:
+      - connective: and
+        locality:
+          - type: article
+            reference_from: "1"
+          - type: page
+            reference_from: "2"
+            reference_to: "5"
+    source_locality:
+      - type: chapter
+        reference_from: "4"
+        reference_to: "11"
+    source_locality_stack:
+      - connective: or
+        source_locality:
+          - type: article
+            reference_from: "2"
+            reference_to: "5"
+        source_locality:
+          - type: article
+            reference_from: "7"
+            reference_to: "9"
+series:
+  - type: main
+    formattedref: ISO 123
+    title:
+      - content: ISO 123
+    place:
+      city: New York
+      region:
+        - iso: US-NY
+          recommended: true
+          content: New York
+      country:
+        - iso: US
+          recommended: true
+          content: United States
+      formatted_place: New York, United States
+      uri:
+        type: primary
+        content: https://www.iso.org/series/123
+    organization: International Organization for Standardization
+    abbreviation:
+      content: ISO
+    from: "2000-01-01"
+    to: "2000-12-31"
+    number: "1"
+    partnumber: "1"
+    run: Run 1
+medium:
+  content: cri
+  genre: statical dataset
+  form: c
+  carrier: cr
+  size: 500 kB
+  scale: 1:10,000
+place:
+  - city: Geneva
+    region:
+      - iso: CH-GE
+        recommended: true
+        content: Geneva
+    country:
+      - iso: CH
+        recommended: true
+        content: Switzerland
+    formatted_place: Geneva, Switzerland
+    uri:
+      type: primary
+      content: https://www.iso.org/series/123
+price:
+  - currency: CHF
+    content: "123.45"
+  - currency: USD
+    content: "123.45"
+extent:
+  - locality:
+    - type: page
+      reference_from: "1"
+      reference_to: "10"
+  - locality_stack:
+      - connective: and
+        locality:
+          - type: article
+            reference_from: "1"
+          - type: page
+            reference_from: "2"
+            reference_to: "5"
+size:
+  value:
+    - type: page
+      content: "10"
+    - type: article
+      content: "5"
+accesslocation:
+  - file/path
+license:
+  - MIT
+classification:
+  - type: ISO
+    content: "123"
+    language: en
+    script: Latn
+    locale: en-US
+    scope: local
+    primary: true
+keyword:
+  - vocab:
+      - content: geographic
+        language: en
+        script: Latn
+        locale: en-US
+    taxon:
+      - content: information
+        language: en
+        script: Latn
+        locale: en-US
+    vocabid:
+      type: AGROVOC
+      uri: http://aims.fao.org/aos/agrovoc/
+      code: "1234"
+      term: Test term
+validity:
+  begins: "1994-01-01"
+  ends: "1994-12-31"
+  revision: "1994-12-31"
+depiction:
+  scope: local
+  image:
+    - id: 12345678-abcd-1234-abcd-1234567890ab
+      src: https://www.iso.org/files/live/sites/isoorg/files/store/en/PUB100080.jpg
+      mimetype: image/jpeg
+      filename: PUB100080.jpg
+      alt: ISO logo
+      title: ISO Logo
+      longdesc: https://www.iso.org/files/live/sites/isoorg/files/store/en/PUB100080.jpg
+      width: 100%
+      height: auto
+ext:
+  schema_version: 1.0.0
+  doctype:
+    abbreviation: std
+    content: Standard
+  subdoctype: Technical Report
+  flavor: iso
+  editorialgroup:
+    technical_committee:
+      number: "211"
+      type: main
+      identifier: ISO/TC 211
+      prefix: ISO
+      content: Geographic information
+  ics:
+    - code: "01.040.11"
+      text: ISO 123-1
+  structuredidentifier:
+    - type: standard
+      agency:
+        - ISO
+      klass: technical report
+      docnumber: "123-1"
+      partnumber: "1"
+      edition: "2"
+      version: "3"
+      supplementtype: "A"
+      supplementnumber: "1"
+      amendment: "1"
+      corrigendum: "1"
+      language: "en"
+      year: "1994"
diff --git a/spec/examples/manual.bib b/spec/fixtures/manual.bib
similarity index 100%
rename from spec/examples/manual.bib
rename to spec/fixtures/manual.bib
diff --git a/spec/examples/misc.bib b/spec/fixtures/misc.bib
similarity index 100%
rename from spec/examples/misc.bib
rename to spec/fixtures/misc.bib
diff --git a/spec/examples/phdthesis.bib b/spec/fixtures/phdthesis.bib
similarity index 100%
rename from spec/examples/phdthesis.bib
rename to spec/fixtures/phdthesis.bib
diff --git a/spec/examples/rfc.xml b/spec/fixtures/rfc.xml
similarity index 88%
rename from spec/examples/rfc.xml
rename to spec/fixtures/rfc.xml
index b893601..d471db8 100644
--- a/spec/examples/rfc.xml
+++ b/spec/fixtures/rfc.xml
@@ -3,6 +3,9 @@
     <title>Geographic information</title>
     <author>
       <organization abbrev="ISO">International Organization for Standardization</organization>
+      <address>
+        <uri>www.iso.org</uri>
+      </address>
     </author>
     <author fullname="A. Bierman">
       <organization abbrev="IETF">IETF</organization>
@@ -21,6 +24,9 @@
     </author>
     <author role="editor">
       <organization abbrev="IEEE">IEEE</organization>
+      <address>
+        <postalLine>Formatted address</postalLine>
+      </address>
     </author>
     <author fullname="Arnold Bierman" initials="A." surname="Bierman">
       <organization abbrev="IETF">IETF</organization>
@@ -40,6 +46,9 @@
     </author>
     <author>
       <organization>W3C</organization>
+      <address>
+        <postalLine>Address string</postalLine>
+      </address>
     </author>
     <date year="2014" month="April"/>
     <workgroup>Editorial group</workgroup>
@@ -54,4 +63,4 @@
   <seriesInfo name="Journal" value="7"/>
   <seriesInfo name="Series"/>
   <seriesInfo name="RFC" value="4"/>
-</reference>
\ No newline at end of file
+</reference>
diff --git a/spec/examples/techreport.bib b/spec/fixtures/techreport.bib
similarity index 100%
rename from spec/examples/techreport.bib
rename to spec/fixtures/techreport.bib
diff --git a/spec/relaton/bib/bibdata_spec.rb b/spec/relaton/bib/bibdata_spec.rb
new file mode 100644
index 0000000..c092cbc
--- /dev/null
+++ b/spec/relaton/bib/bibdata_spec.rb
@@ -0,0 +1,14 @@
+describe Relaton::Bib::Bibdata do
+  context "XML" do
+    let(:file) { "spec/fixtures/bibdata_item.xml" }
+    let(:input_xml) { File.read file, encoding: "UTF-8" }
+    let(:item) { described_class.from_xml input_xml }
+
+    it "round trip" do
+      expect(described_class.to_xml(item)).to be_equivalent_to input_xml
+      schema = Jing.new "grammars/biblio-compile.rng"
+      errors = schema.validate file
+      expect(errors).to eq []
+    end
+  end
+end
diff --git a/spec/relaton/bib/bibitem_spec.rb b/spec/relaton/bib/bibitem_spec.rb
new file mode 100644
index 0000000..bcb2810
--- /dev/null
+++ b/spec/relaton/bib/bibitem_spec.rb
@@ -0,0 +1,14 @@
+describe Relaton::Bib::Bibitem do
+  context "XML" do
+    let(:file) { "spec/fixtures/bibitem.xml" }
+    let(:input_xml) { File.read(file, encoding: "UTF-8") }
+    let(:item) { described_class.from_xml input_xml }
+
+    it "round trip" do
+      expect(described_class.to_xml(item)).to be_equivalent_to input_xml
+      schema = Jing.new "grammars/biblio-compile.rng"
+      errors = schema.validate file
+      expect(errors).to eq []
+    end
+  end
+end
diff --git a/spec/relaton/bib/item_spec.rb b/spec/relaton/bib/item_spec.rb
new file mode 100644
index 0000000..7803822
--- /dev/null
+++ b/spec/relaton/bib/item_spec.rb
@@ -0,0 +1,10 @@
+describe Relaton::Bib::Item do
+  let(:input_yaml) { File.read("spec/fixtures/item.yaml", encoding: "UTF-8") }
+  let(:item) { described_class.from_yaml input_yaml }
+
+  it "round trip" do
+    input_hash = YAML.safe_load input_yaml
+    output_hash = YAML.safe_load described_class.to_yaml(item)
+    expect(output_hash).to eq input_hash
+  end
+end
diff --git a/spec/relaton_bib/util_spec.rb b/spec/relaton/bib/util_spec.rb
similarity index 71%
rename from spec/relaton_bib/util_spec.rb
rename to spec/relaton/bib/util_spec.rb
index a51f514..38df284 100644
--- a/spec/relaton_bib/util_spec.rb
+++ b/spec/relaton/bib/util_spec.rb
@@ -1,11 +1,11 @@
-describe RelatonBib::Util do
+describe Relaton::Bib::Util do
   it "#respond_to_missing?" do
     expect(described_class.respond_to?(:warn)).to be true
   end
 
   it "#method_missing" do
     expect do
-      expect(described_class.warn("msg")).to be nil
+      expect(described_class.warn("msg")).to be_nil # true
     end.to output(/\[relaton-bib\] WARN: msg\n/).to_stderr_from_any_process
   end
 end
diff --git a/spec/relaton/bib_spec.rb b/spec/relaton/bib_spec.rb
new file mode 100644
index 0000000..e08c967
--- /dev/null
+++ b/spec/relaton/bib_spec.rb
@@ -0,0 +1,67 @@
+describe Relaton::Bib do
+  it "has a version number" do
+    expect(Relaton::Bib::VERSION).not_to be nil
+  end
+
+  it "returns grammar hash" do
+    hash = Relaton::Bib.grammar_hash
+    expect(hash).to be_instance_of String
+    expect(hash.size).to eq 32
+  end
+
+  # context "parse date" do
+  #   it "February 2012" do
+  #     expect(Relaton.parse_date("February 2012")).to eq "2012-02"
+  #     expect(Relaton.parse_date("February 2012", str: false)).to eq Date.new(2012, 2, 1)
+  #   end
+
+  #   it "February 11, 2012" do
+  #     expect(Relaton.parse_date("February 11, 2012")).to eq "2012-02-11"
+  #     expect(Relaton.parse_date("February 11, 2012", str: false)).to eq Date.new(2012, 2, 11)
+  #   end
+
+  #   it "2012-02-11" do
+  #     expect(Relaton.parse_date("2012-02-11")).to eq "2012-02-11"
+  #     expect(Relaton.parse_date("2012-02-11", str: false)).to eq Date.new(2012, 2, 11)
+  #   end
+
+  #   it "2012-2-3" do
+  #     expect(Relaton.parse_date("2012-2-3")).to eq "2012-02-03"
+  #     expect(Relaton.parse_date("2012-2-3", str: false)).to eq Date.new(2012, 2, 3)
+  #   end
+
+  #   it "2012-02" do
+  #     expect(Relaton.parse_date("2012-02")).to eq "2012-02"
+  #     expect(Relaton.parse_date("2012-02", str: false)).to eq Date.new(2012, 2, 1)
+  #   end
+
+  #   it "2012-2" do
+  #     expect(Relaton.parse_date("2012-2")).to eq "2012-02"
+  #     expect(Relaton.parse_date("2012-2", str: false)).to eq Date.new(2012, 2, 1)
+  #   end
+
+  #   it "invalid date" do
+  #     expect do
+  #       expect(Relaton.parse_date("2012-02-31")).to eq "2012-02-31"
+  #     end.to output(/invalid date/).to_stderr_from_any_process
+  #   end
+  # end
+
+  # it "parse YAML with an old version of Psych" do
+  #   method = double "params"
+  #   expect(method).to receive(:parameters).and_return [%i[req yaml]]
+  #   expect(YAML).to receive(:method).with(:safe_load).and_return method
+  #   expect(YAML).to receive(:safe_load).with(kind_of(String), [], symbolize_names: false).and_return({})
+  #   Relaton.parse_yaml "key: value"
+  # end
+
+  # it "parse YAML with a new version of Psych" do
+  #   method = double "params"
+  #   expect(method).to receive(:parameters).and_return [%i[req yaml permitted_classes]]
+  #   expect(YAML).to receive(:method).with(:safe_load).and_return method
+  #   expect(YAML).to receive(:safe_load)
+  #     .with(kind_of(String), permitted_classes: [], symbolize_names: false)
+  #     .and_return({})
+  #   Relaton.parse_yaml "key: value"
+  # end
+end
diff --git a/spec/relaton_bib/bibtex_parser_spec.rb b/spec/relaton/bibtex_parser_spec.rb
similarity index 86%
rename from spec/relaton_bib/bibtex_parser_spec.rb
rename to spec/relaton/bibtex_parser_spec.rb
index e8b8fdd..59c2e55 100644
--- a/spec/relaton_bib/bibtex_parser_spec.rb
+++ b/spec/relaton/bibtex_parser_spec.rb
@@ -1,6 +1,6 @@
-RSpec.describe RelatonBib::BibtexParser do
-  it "parse BibTex" do
-    items = RelatonBib::BibtexParser.from_bibtex <<~BIBTEX
+describe "Relaton::BibtexParser" do
+  xit "parse BibTex" do
+    items = described_class.from_bibtex <<~BIBTEX
       @article{mrx05,
         type = "standard",
         auTHor = "Mr. X and Y, Mr.",
@@ -66,7 +66,7 @@
       }
     BIBTEX
     expect(items).to be_instance_of Hash
-    expect(items["mrx05"]).to be_instance_of RelatonBib::BibliographicItem
+    expect(items["mrx05"]).to be_instance_of Relaton::Bib::Item
 
     file = "spec/examples/from_bibtex.xml"
     xml = items["mrx05"].to_xml
@@ -75,7 +75,7 @@
   end
 
   context "parse title" do
-    it "with subtitle" do
+    xit "with subtitle" do
       bibtex = BibTeX.parse <<~BIBTEX
         @article{mrx05,
           title = {Something Great},
@@ -87,7 +87,7 @@
       expect(title[1].title.content).to eq "Sub title"
     end
 
-    it "with double curly braces" do
+    xit "with double curly braces" do
       bibtex = BibTeX.parse <<~BIBTEX
         @article{mrx05,
           title = {{Something Great}},
@@ -99,34 +99,34 @@
   end
 
   context "parse contributor" do
-    it "howpublished" do
+    xit "howpublished" do
       bibtex = BibTeX.parse <<~BIBTEX
         @article{mrx05,
         howpublished = "\\publisher{Taylor {\\&} Francis},\\url{http://www.tandfonline.com/doi/abs/10.1080/17538940802439549}"
         }
       BIBTEX
       contribs = described_class.send :fetch_contributor, bibtex["mrx05"]
-      expect(contribs[0][:entity]).to be_instance_of RelatonBib::Organization
+      expect(contribs[0][:entity]).to be_instance_of Relaton::Bib::Organization
       expect(contribs[0][:entity].name[0].content).to eq "Taylor & Francis"
       expect(contribs[0][:role][0][:type]).to eq "publisher"
     end
   end
 
   context "parse note" do
-    it "with howpublished as note" do
+    xit "with howpublished as note" do
       bibtex = BibTeX.parse <<~BIBTEX
         @article{mrx05,
           howpublished = {How Published Note},
         }
       BIBTEX
       note = described_class.send :fetch_note, bibtex["mrx05"]
-      expect(note).to be_instance_of RelatonBib::BiblioNoteCollection
-      expect(note[0]).to be_instance_of RelatonBib::BiblioNote
+      expect(note).to be_instance_of Relaton::Bib::BiblioNoteCollection
+      expect(note[0]).to be_instance_of Relaton::Bib::BiblioNote
       expect(note[0].type).to eq "howpublished"
       expect(note[0].content).to eq "How Published Note"
     end
 
-    it "don't parse howpublished as note" do
+    xit "don't parse howpublished as note" do
       bibtex = <<~BIBTEX
         @article{mrx05,
           howpublished = "\\publisher{Taylor {\&} Francis},\\url{http://www.tandfonline.com/doi/abs/10.1080/17538940802439549}"
@@ -134,13 +134,13 @@
       BIBTEX
       docs = BibTeX.parse bibtex
       note = described_class.send :fetch_note, docs["mrx05"]
-      expect(note).to be_instance_of RelatonBib::BiblioNoteCollection
+      expect(note).to be_instance_of Relaton::Bib::BiblioNoteCollection
       expect(note).to be_empty
     end
   end
 
   context "parse keywords" do
-    it "with comma separator" do
+    xit "with comma separator" do
       bibtex = BibTeX.parse <<~BIBTEX
         @article{mrx05,
           keywords = {Sensor Web,data acquisition},
@@ -150,7 +150,7 @@
       expect(keywords).to eq %w[Sensor\ Web data\ acquisition]
     end
 
-    it "with comma and space separator" do
+    xit "with comma and space separator" do
       bibtex = BibTeX.parse <<~BIBTEX
         @article{mrx05,
           keywords = {Sensor Web, data acquisition},
@@ -160,7 +160,7 @@
       expect(keywords).to eq %w[Sensor\ Web data\ acquisition]
     end
 
-    it "empty" do
+    xit "empty" do
       bibtex = BibTeX.parse <<~BIBTEX
         @article{mrx05,
         }
diff --git a/spec/relaton_bib/bibxml_parser_spec.rb b/spec/relaton/bibxml_parser_spec.rb
similarity index 75%
rename from spec/relaton_bib/bibxml_parser_spec.rb
rename to spec/relaton/bibxml_parser_spec.rb
index aa27783..bcdcc2b 100644
--- a/spec/relaton_bib/bibxml_parser_spec.rb
+++ b/spec/relaton/bibxml_parser_spec.rb
@@ -1,23 +1,23 @@
-RSpec.describe "BibXML parser" do
-  it "parse RFC" do
+describe Relaton::BibXMLParser do
+  xit "parse RFC" do
     bibxml = File.read "spec/examples/rfc.xml", encoding: "UTF-8"
-    bib = RelatonBib::BibXMLParser.parse bibxml
+    bib = described_class.parse bibxml
     expect(bib.to_bibxml).to be_equivalent_to bibxml
   end
 
-  it "parse BCP" do
+  xit "parse BCP" do
     bibxml = File.read "spec/examples/bcp_item.xml", encoding: "UTF-8"
-    bib = RelatonBib::BibXMLParser.parse bibxml
+    bib = described_class.parse bibxml
     expect(bib.to_bibxml).to be_equivalent_to bibxml
   end
 
-  it "IEEE" do
+  xit "IEEE" do
     bibxml = File.read "spec/examples/ieee_bibxml.xml", encoding: "UTF-8"
-    bib = RelatonBib::BibXMLParser.parse bibxml
+    bib = described_class.parse bibxml
     expect(bib.to_bibxml).to be_equivalent_to bibxml
   end
 
-  it "returns contacts" do
+  xit "returns contacts" do
     doc = Nokogiri::XML <<~END_XML
       <reference anchor="RFC8341" target="https://www.rfc-editor.org/info/rfc8341">
         <front>
@@ -39,106 +39,106 @@
       </reference>
     END_XML
     addr = doc.at "//reference/front/author[1]/address"
-    cont = RelatonBib::BibXMLParser.send(:contacts, addr)
-    expect(cont[0]).to be_instance_of RelatonBib::Address
+    cont = described_class.send(:contacts, addr)
+    expect(cont[0]).to be_instance_of Relaton::Bib::Address
     expect(cont[1].type).to eq "phone"
     expect(cont[2].type).to eq "email"
     expect(cont[3].type).to eq "uri"
   end
 
-  it "parse I-D doctype" do
-    doctype = RelatonBib::BibXMLParser.doctype("I-D")
-    expect(doctype).to be_instance_of RelatonBib::DocumentType
+  xit "parse I-D doctype" do
+    doctype = described_class.doctype("I-D")
+    expect(doctype).to be_instance_of Relaton::Bib::DocumentType
     expect(doctype.type).to eq "internet-draft"
   end
 
   context "parse PubID" do
-    it "Internet-Draft" do
+    xit "Internet-Draft" do
       doc = Nokogiri::XML <<~END_XML
         <reference anchor="I-D.3k1n-6tisch-alice0">
         </reference>
       END_XML
       ref = doc.at "/reference"
-      id = RelatonBib::BibXMLParser.docids ref, nil
+      id = described_class.docids ref, nil
       expect(id).to be_a Array
-      expect(id.first).to be_a RelatonBib::DocumentIdentifier
+      expect(id.first).to be_a Relaton::Bib::Docidentifier
       expect(id.first.type).to eq "Internet-Draft"
       expect(id.first.id).to eq "draft-3k1n-6tisch-alice0"
-      expect(id[1]).to be_a RelatonBib::DocumentIdentifier
+      expect(id[1]).to be_a Relaton::Bib::Docidentifier
       expect(id[1].type).to eq "I-D"
       expect(id[1].id).to eq "I-D.3k1n-6tisch-alice0"
       expect(id[1].scope).to eq "anchor"
     end
 
-    it "Internet-Draft from seriesInfo" do
+    xit "Internet-Draft from seriesInfo" do
       doc = Nokogiri::XML <<~END_XML
         <reference>
           <seriesInfo name="Internet-Draft" value="draft-3k1n-6tisch-alice0-01"/>
         </reference>
       END_XML
       ref = doc.at "/reference"
-      id = RelatonBib::BibXMLParser.docids ref, nil
+      id = described_class.docids ref, nil
       expect(id).to be_a Array
-      expect(id.first).to be_a RelatonBib::DocumentIdentifier
+      expect(id.first).to be_a Relaton::Bib::Docidentifier
       expect(id.first.type).to eq "Internet-Draft"
       expect(id.first.id).to eq "draft-3k1n-6tisch-alice0-01"
     end
 
-    it "Internet-Draft from docName" do
+    xit "Internet-Draft from docName" do
       doc = Nokogiri::XML <<~END_XML
         <reference docName="draft-ietf-acvp-subsha-1.0">
         </reference>
       END_XML
       ref = doc.at "/reference"
-      id = RelatonBib::BibXMLParser.docids ref, nil
-      expect(id[0]).to be_a RelatonBib::DocumentIdentifier
+      id = described_class.docids ref, nil
+      expect(id[0]).to be_a Relaton::Bib::Docidentifier
       expect(id[0].type).to eq "Internet-Draft"
       expect(id[0].id).to eq "draft-ietf-acvp-subsha-1.0"
       expect(id[1].scope).to eq "docName"
     end
 
-    it "add version" do
+    xit "add version" do
       doc = Nokogiri::XML <<~END_XML
         <reference anchor="I-D.3k1n-6tisch-alice0-01">
         </reference>
       END_XML
       ref = doc.at "/reference"
-      id = RelatonBib::BibXMLParser.docids ref, "02"
+      id = described_class.docids ref, "02"
       expect(id).to be_a Array
-      expect(id.first).to be_a RelatonBib::DocumentIdentifier
+      expect(id.first).to be_a Relaton::Bib::Docidentifier
       expect(id.first.type).to eq "Internet-Draft"
       expect(id.first.id).to eq "draft-3k1n-6tisch-alice0-02"
     end
   end
 
   context "parse I-D format links" do
-    it "DOI" do
+    xit "DOI" do
       doc = Nokogiri::XML <<~END_XML
         <reference anchor="I-D-12.3">
           <format type="DOC" target="https://www.rfc-editor.org/info/I-D-12.3.doc"/>
         </reference>
       END_XML
       ref = doc.at "/reference"
-      link = RelatonBib::BibXMLParser.link ref, nil, "1"
+      link = described_class.link ref, nil, "1"
       expect(link.size).to eq 1
       expect(link[0][:type]).to eq "DOC"
     end
 
-    it "TXT" do
+    xit "TXT" do
       bibxml = <<~END_XML
         <reference anchor="I-D-12.3">
           <format type="TXT" target="https://www.rfc-editor.org/info/rfc1.txt"/>
         </reference>
       END_XML
-      id = RelatonBib::BibXMLParser.parse bibxml
+      id = described_class.parse bibxml
       expect(id.link).to be_instance_of Array
-      expect(id.link[0]).to be_instance_of RelatonBib::TypedUri
+      expect(id.link[0]).to be_instance_of Relaton::Bib::Bsource
       expect(id.link[0].type).to eq "TXT"
       expect(id.link[0].content.to_s).to eq "https://www.rfc-editor.org/info/rfc1.txt"
     end
   end
 
-  it "parse RFC seriesinfo" do
+  xit "parse RFC seriesinfo" do
     bibxml = <<~END_XML
       <reference anchor="RFC0001" target="https://www.rfc-editor.org/info/rfc1">
         <front>
@@ -152,16 +152,16 @@
         <seriesInfo name="DOI" value="10.17487/RFC0001"/>
       </reference>
     END_XML
-    rfc = RelatonBib::BibXMLParser.parse bibxml
+    rfc = described_class.parse bibxml
     expect(rfc.docidentifier[2].type).to eq "DOI"
     expect(rfc.docidentifier[2].id).to eq "10.17487/RFC0001"
   end
 
-  it "parse incomplete month name" do
-    expect(RelatonBib::BibXMLParser.month("Sept")).to eq "09"
+  xit "parse incomplete month name" do
+    expect(described_class.month("Sept")).to eq "09"
   end
 
-  it "skip empty organization" do
+  xit "skip empty organization" do
     bibxml = <<~END_XML
       <reference anchor="RFC0001" target="https://www.rfc-editor.org/info/rfc1">
         <front>
@@ -174,7 +174,7 @@
         </front>
       </reference>
     END_XML
-    rfc = RelatonBib::BibXMLParser.parse bibxml
+    rfc = described_class.parse bibxml
     expect(rfc.contributor).to be_empty
   end
 
@@ -187,8 +187,8 @@
   #       </front>
   #     </reference>
   #   END_XML
-  #   rfc = RelatonBib::BibXMLParser.parse bibxml
-  #   expect(rfc.contributor[0].entity).to be_instance_of RelatonBib::Organization
+  #   rfc = described_class.parse bibxml
+  #   expect(rfc.contributor[0].entity).to be_instance_of Relaton::Bib::Organization
   #   expect(rfc.contributor[0].entity.name[0].content).to eq "IAB"
   #   expect(rfc.contributor[0].role[0].type).to eq "author"
   #   # expect(rfc.contributor[0].role[0].description[0].content).to eq "BibXML author"
diff --git a/spec/relaton_bib/renderer/bibtex_builder_spec.rb b/spec/relaton/renderer/bibtex_builder_spec.rb
similarity index 71%
rename from spec/relaton_bib/renderer/bibtex_builder_spec.rb
rename to spec/relaton/renderer/bibtex_builder_spec.rb
index 69b93db..6c2db26 100644
--- a/spec/relaton_bib/renderer/bibtex_builder_spec.rb
+++ b/spec/relaton/renderer/bibtex_builder_spec.rb
@@ -1,9 +1,9 @@
-describe RelatonBib::Renderer::BibtexBuilder do
+describe Relaton::Renderer::BibtexBuilder do
   context "instance methods" do
-    subject { RelatonBib::Renderer::BibtexBuilder.new bibitem }
+    subject { Relaton::Renderer::BibtexBuilder.new bibitem }
     context "add_link" do
-      let(:bibitem) { RelatonBib::BibliographicItem.new link: ["http://example.com"] }
-      it "ignore links without type" do
+      let(:bibitem) { Relaton::Bib::Item.new link: ["http://example.com"] }
+      xit "ignore links without type" do
         item = double "item"
         expect(item).not_to receive :doi=
         expect(item).not_to receive :url=
@@ -14,8 +14,8 @@
     end
   end
 
-  it "render article" do
-    bibitem = RelatonBib::XMLParser.from_xml File.read("spec/examples/bibtex_article.xml")
+  xit "render article" do
+    bibitem = Relaton::XMLParser.from_xml File.read("spec/examples/bibtex_article.xml")
     expect(bibitem.to_bibtex).to eq <<~"OUTPUT"
       @article{DOC123,
         title = {Miscellaneous},
@@ -29,8 +29,8 @@
     OUTPUT
   end
 
-  it "render book, rpoceedings" do
-    bibitem = RelatonBib::XMLParser.from_xml File.read("spec/examples/bibtex_book.xml")
+  xit "render book, rpoceedings" do
+    bibitem = Relaton::XMLParser.from_xml File.read("spec/examples/bibtex_book.xml")
     expect(bibitem.to_bibtex).to eq <<~"OUTPUT"
       @book{DOC123,
         title = {Title},
@@ -46,8 +46,8 @@
     OUTPUT
   end
 
-  it "render inbook, incollection" do
-    bibitem = RelatonBib::XMLParser.from_xml File.read("spec/examples/bibtex_inbook.xml")
+  xit "render inbook, incollection" do
+    bibitem = Relaton::XMLParser.from_xml File.read("spec/examples/bibtex_inbook.xml")
     expect(bibitem.to_bibtex).to eq <<~"OUTPUT"
       @inbook{DOC123,
         title = {Title},
@@ -66,8 +66,8 @@
     OUTPUT
   end
 
-  it "render inproceedings" do
-    bibitem = RelatonBib::XMLParser.from_xml File.read("spec/examples/bibtex_inproceedings.xml")
+  xit "render inproceedings" do
+    bibitem = Relaton::XMLParser.from_xml File.read("spec/examples/bibtex_inproceedings.xml")
     expect(bibitem.to_bibtex).to eq <<~"OUTPUT"
       @inproceedings{DOC123,
         title = {Title},
@@ -84,8 +84,8 @@
     OUTPUT
   end
 
-  it "render phdthesis" do
-    bibitem = RelatonBib::XMLParser.from_xml File.read("spec/examples/bibtex_phdthesis.xml")
+  xit "render phdthesis" do
+    bibitem = Relaton::XMLParser.from_xml File.read("spec/examples/bibtex_phdthesis.xml")
     expect(bibitem.to_bibtex).to eq <<~"OUTPUT"
       @phdthesis{DOC123,
         title = {Title},
@@ -97,8 +97,8 @@
     OUTPUT
   end
 
-  it "render techreport" do
-    bibitem = RelatonBib::XMLParser.from_xml File.read("spec/examples/bibtex_techreport.xml")
+  xit "render techreport" do
+    bibitem = Relaton::XMLParser.from_xml File.read("spec/examples/bibtex_techreport.xml")
     expect(bibitem.to_bibtex).to eq <<~"OUTPUT"
       @techreport{DOC123,
         title = {Title},
diff --git a/spec/relaton/renderer/bibxml_spec.rb b/spec/relaton/renderer/bibxml_spec.rb
new file mode 100644
index 0000000..283c67d
--- /dev/null
+++ b/spec/relaton/renderer/bibxml_spec.rb
@@ -0,0 +1,28 @@
+describe Relaton::Renderer::BibXML do
+  context "instance methods" do
+    context "ref_attrs" do
+      xit "upcase anchor for IANA" do
+        docid = Relaton::Bib::Docidentifier.new id: "IANA dns-parameters", type: "IANA"
+        bib = Relaton::Bib::Item.new(docid: [docid])
+        renderer = Relaton::Renderer::BibXML.new bib
+        ref_attrs = renderer.ref_attrs
+        expect(ref_attrs).to be_instance_of Hash
+        expect(ref_attrs[:anchor]).to eq "DNS-PARAMETERS"
+      end
+    end
+
+    context "render_seriesinfo" do
+      xit "do not render trademark" do
+        docid = [
+          Relaton::Bib::Docidentifier.new(id: "IEEE 123", type: "IEEE"),
+          Relaton::Bib::Docidentifier.new(id: "IEEE 123", type: "IEEE", scope: "trademark"),
+        ]
+        bib = Relaton::Bib::Item.new docid: docid
+        renderer = Relaton::Bib::Renderer::BibXML.new bib
+        builder = double "builder"
+        # expect(builder).to receive(:seriesInfo).with(name: "IEEE", value: "IEEE 123").once
+        renderer.render_seriesinfo builder
+      end
+    end
+  end
+end
diff --git a/spec/relaton_bib/bib_item_locality_spec.rb b/spec/relaton_bib/bib_item_locality_spec.rb
deleted file mode 100644
index 94f3533..0000000
--- a/spec/relaton_bib/bib_item_locality_spec.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-RSpec.describe RelatonBib::BibItemLocality do
-  it "warn if locality type is invalid" do
-    expect do
-      RelatonBib::BibItemLocality.new "type", "from"
-    end.to output(/Invalid locality type/).to_stderr_from_any_process
-  end
-end
diff --git a/spec/relaton_bib/bibliographic_date_spec.rb b/spec/relaton_bib/bibliographic_date_spec.rb
deleted file mode 100644
index fa668c2..0000000
--- a/spec/relaton_bib/bibliographic_date_spec.rb
+++ /dev/null
@@ -1,125 +0,0 @@
-# forzen_string_literal: true
-
-require "relaton_bib/bibliographic_item"
-
-RSpec.describe RelatonBib::BibliographicDate do
-  context "date on given" do
-    subject do
-      RelatonBib::BibliographicDate.new(type: "published", on: "November 2014")
-    end
-
-    it "parse 'November 2014' format date" do
-      expect(subject.on).to eq "2014-11"
-    end
-
-    it "return full date if part isn't :year, :month, or :day" do
-      expect(subject.on(:hour)).to eq "2014-11"
-    end
-
-    it "return Date" do
-      expect(subject.on(:date)).to be_instance_of Date
-    end
-
-    it "returns xml string" do
-      xml = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |builder|
-        subject.to_xml builder
-      end.doc.root.to_xml
-      expect(xml).to be_equivalent_to <<~XML
-        <date type="published"><on>2014-11</on></date>
-      XML
-    end
-
-    it "returns xml string with full date" do
-      xml = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |builder|
-        subject.to_xml builder, date_format: :full
-      end.doc.root.to_xml
-      expect(xml).to be_equivalent_to <<~XML
-        <date type="published"><on>2014-11-01</on></date>
-      XML
-    end
-  end
-
-  context "parse date" do
-    subject { RelatonBib::BibliographicDate.new(type: "published", on: "2014") }
-
-    it "yyyy-mm-dd" do
-      date = subject.send :parse_date, "2014-11-02"
-      expect(date).to be_instance_of Date
-      expect(date).to eq Date.new(2014, 11, 2)
-    end
-
-    it "yyyy-m-d" do
-      expect(subject.send(:parse_date, "2014-2-3")).to eq Date.new(2014, 2, 3)
-    end
-
-    it "yyyy-mm" do
-      expect(subject.send(:parse_date, "2014-11")).to eq Date.new(2014, 11, 1)
-    end
-
-    it "yyyy-m" do
-      expect(subject.send(:parse_date, "2014-2")).to eq Date.new(2014, 2, 1)
-    end
-
-    it "yyyy" do
-      expect(subject.send(:parse_date, "2014")).to eq Date.new(2014, 1, 1)
-    end
-
-    it "not match any pattern" do
-      expect(subject.send(:parse_date, "November 2014")).to eq "November 2014"
-    end
-  end
-
-  context "dates from and to given" do
-    subject do
-      RelatonBib::BibliographicDate.new(
-        type: "published", from: "2014-11", to: "2015-12",
-      )
-    end
-
-    it "returns xml string" do
-      xml = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |builder|
-        subject.to_xml builder
-      end.doc.root.to_xml
-      expect(xml).to be_equivalent_to <<~XML
-        <date type="published"><from>2014-11</from><to>2015-12</to></date>
-      XML
-    end
-
-    it "returns xml string with short date" do
-      xml = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |builder|
-        subject.to_xml builder, date_format: :short
-      end.doc.root.to_xml
-      expect(xml).to be_equivalent_to <<~XML
-        <date type="published"><from>2014-11</from><to>2015-12</to></date>
-      XML
-    end
-  end
-
-  it "handle full date" do
-    item = RelatonBib::BibliographicDate.new type: "published", on: "2014-11-22"
-    xml = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |builder|
-      item.to_xml builder, date_format: :full
-    end.doc.root.to_xml
-
-    expect(xml).to be_equivalent_to <<~XML
-      <date type="published"><on>2014-11-22</on></date>
-    XML
-  end
-
-  it "handle year only" do
-    item = RelatonBib::BibliographicDate.new(type: "published", on: "2014")
-    xml = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |builder|
-      item.to_xml builder, date_format: :full
-    end.doc.root.to_xml
-
-    expect(xml).to be_equivalent_to <<~XML
-      <date type="published"><on>2014-01-01</on></date>
-    XML
-  end
-
-  it "handle date not matched any patterns" do
-    item = RelatonBib::BibliographicDate.new type: "published", on: "Nov 2020"
-    expect(item.on(:year)).to eq 2020
-    expect(item.on(:month)).to eq 11
-  end
-end
diff --git a/spec/relaton_bib/bibliographic_item_spec.rb b/spec/relaton_bib/bibliographic_item_spec.rb
deleted file mode 100644
index 6449bc0..0000000
--- a/spec/relaton_bib/bibliographic_item_spec.rb
+++ /dev/null
@@ -1,358 +0,0 @@
-# frozen_string_literal: true
-
-require "yaml"
-require "jing"
-
-RSpec.describe "RelatonBib" => :BibliographicItem do
-  context "initialize" do
-    it "with keyword Hash" do
-      keyword = [{ content: "keyword", language: "en", script: "Latn" }]
-      bib = RelatonBib::BibliographicItem.new(formattedref: "ref", keyword: keyword)
-      expect(bib.keyword).to be_instance_of Array
-      expect(bib.keyword.first).to be_instance_of RelatonBib::LocalizedString
-      expect(bib.keyword.first.content).to eq "keyword"
-      expect(bib.keyword.first.language).to eq ["en"]
-      expect(bib.keyword.first.script).to eq ["Latn"]
-    end
-  end
-
-  context "instance" do
-    subject do
-      hash = YAML.load_file "spec/examples/bib_item.yml"
-      RelatonBib::BibliographicItem.from_hash(hash)
-    end
-
-    context "makeid" do
-      it "with docid" do
-        expect(subject.makeid(nil, false)).to eq "ISOTC211"
-      end
-
-      it "with argument" do
-        docid = RelatonBib::DocumentIdentifier.new type: "ISO", id: "ISO 123 (E)"
-        expect(subject.makeid(docid, false)).to eq "ISO123E"
-      end
-    end
-
-    it "has schema-version" do
-      expect(subject.schema).to match(/^v\d+\.\d+\.\d+$/)
-    end
-
-    it "is instance of BibliographicItem" do
-      expect(subject).to be_instance_of RelatonBib::BibliographicItem
-    end
-
-    it "get set fetched" do
-      expect(subject.fetched).to eq "2022-05-02"
-      subject.fetched = "2022-05-03"
-      expect(subject.fetched).to eq "2022-05-03"
-    end
-
-    it "has array of titiles" do
-      expect(subject.title).to be_instance_of(
-        RelatonBib::TypedTitleStringCollection,
-      )
-      expect(subject.title(lang: "fr")[0].title.content).to eq(
-        "Information g\u00E9ographique",
-      )
-    end
-
-    it "has urls" do
-      expect(subject.url).to eq "https://www.iso.org/standard/53798.html"
-      expect(subject.url(:rss)).to eq "https://www.iso.org/contents/data/"\
-                                      "standard/05/37/53798.detail.rss"
-    end
-    it "returns shortref" do
-      expect(subject.shortref(subject.docidentifier.first)).to eq "ISOTC211:2014"
-    end
-
-    it "returns abstract with en language" do
-      expect(subject.abstract(lang: "en")).to be_instance_of(
-        RelatonBib::FormattedString,
-      )
-    end
-
-    it "to most recent reference" do
-      item = subject.to_most_recent_reference
-      expect(item.relation[3].bibitem.structuredidentifier[0].year).to eq "2020"
-      expect(item.structuredidentifier[0].year).to be_nil
-    end
-
-    it "to all parts" do
-      item = subject.to_all_parts
-      expect(item).to_not be subject
-      expect(item.all_parts).to be true
-      expect(item.relation.last.type).to eq "instanceOf"
-      expect(item.title.detect { |t| t.type == "title-part" }).to be_nil
-      expect(item.title.detect { |t| t.type == "main" }.title.content).to eq(
-        "Geographic information",
-      )
-      expect(item.abstract).to be_empty
-      id_with_part = item.docidentifier.detect do |d|
-        d.type != "Internet-Draft" && d.id =~ /-\d/
-      end
-      expect(id_with_part).to be_nil
-      expect(item.docidentifier.reject { |d| d.id =~ %r{(all parts)} }.size)
-        .to eq 1
-      expect(item.docidentifier.detect { |d| d.id =~ /:[12]\d\d\d/ }).to be_nil
-      expect(item.structuredidentifier.detect { |d| !d.partnumber.nil? })
-        .to be_nil
-      expect(item.structuredidentifier.detect { |d| d.docnumber =~ /-\d/ })
-        .to be_nil
-      expect(
-        item.structuredidentifier.detect { |d| d.docnumber !~ %r{(all parts)} },
-      ).to be_nil
-      expect(
-        item.structuredidentifier.detect { |d| d.docnumber =~ /:[12]\d\d\d/ },
-      ).to be_nil
-    end
-
-    context "render XML" do
-      it "returns bibitem xml string" do
-        file = "spec/examples/bib_item.xml"
-        subject_xml = subject.to_xml
-          .gsub(/(?<=<fetched>)\d{4}-\d{2}-\d{2}/, Date.today.to_s)
-        File.write file, subject_xml, encoding: "utf-8" unless File.exist? file
-        xml = File.read(file, encoding: "utf-8")
-          .gsub(/(?<=<fetched>)\d{4}-\d{2}-\d{2}/, Date.today.to_s)
-        expect(subject_xml).to be_equivalent_to xml
-        schema = Jing.new "grammars/biblio-compile.rng"
-        errors = schema.validate file
-        expect(errors).to eq []
-      end
-
-      it "returns bibdata xml string" do
-        file = "spec/examples/bibdata_item.xml"
-        subject_xml = subject.to_xml(bibdata: true)
-          .gsub(/(?<=<fetched>)\d{4}-\d{2}-\d{2}/, Date.today.to_s)
-        File.write file, subject_xml, encoding: "utf-8" unless File.exist? file
-        xml = File.read(file, encoding: "utf-8")
-          .gsub(/(?<=<fetched>)\d{4}-\d{2}-\d{2}/, Date.today.to_s)
-        expect(subject_xml).to be_equivalent_to xml
-        schema = Jing.new "grammars/biblio-compile.rng"
-        errors = schema.validate file
-        expect(errors).to eq []
-      end
-
-      it "render only French laguage tagged string" do
-        file = "spec/examples/bibdata_item_fr.xml"
-        xml = subject.to_xml(bibdata: true, lang: "fr")
-          .sub(/(?<=<fetched>)\d{4}-\d{2}-\d{2}/, Date.today.to_s)
-        File.write file, xml, encoding: "UTF-8" unless File.exist? file
-        expect(xml).to be_equivalent_to File.read(file, encoding: "UTF-8")
-          .sub(/(?<=<fetched>)\d{4}-\d{2}-\d{2}/, Date.today.to_s)
-      end
-
-      it "render addition elements" do
-        xml = subject.to_xml { |b| b.element "test" }
-        expect(xml).to include "<element>test</element>"
-      end
-
-      it "add note to xml" do
-        xml = subject.to_xml note: [{ text: "Note", type: "note" }]
-        expect(xml).to include "<note format=\"text/plain\" type=\"note\">" \
-                               "Note</note>"
-      end
-
-      it "render ext schema-verson" do
-        expect(subject).to receive(:respond_to?).with(:ext_schema).and_return(true).twice
-        expect(subject).to receive(:ext_schema).and_return("v1.0.0").twice
-        expect(subject.to_xml(bibdata: true)).to include "<ext schema-version=\"v1.0.0\">"
-      end
-    end
-
-    it "deals with hashes" do
-      file = "spec/examples/bib_item.yml"
-      h = RelatonBib::HashConverter.hash_to_bib(YAML.load_file(file))
-      b = RelatonBib::BibliographicItem.new(**h)
-      expect(b.to_xml).to be_equivalent_to subject.to_xml
-    end
-
-    context "converts item to hash" do
-      it do
-        hash = subject.to_hash
-        file = "spec/examples/hash.yml"
-        File.write file, hash.to_yaml unless File.exist? file
-        expect(hash).to eq YAML.load_file(file)
-        expect(hash["revdate"]).to eq "2019-04-01"
-      end
-
-      it "with ext schema-version" do
-        expect(subject).to receive(:respond_to?).with(:ext_schema).and_return(true).twice
-        expect(subject).to receive(:ext_schema).and_return("v1.0.0").twice
-        hash = subject.to_hash
-        expect(hash["ext"]["schema-version"]).to eq "v1.0.0"
-      end
-    end
-
-    context "converts to BibTex" do
-      it "standard" do
-        bibtex = subject.to_bibtex
-          .sub(/(?<=timestamp = {)\d{4}-\d{2}-\d{2}/, Date.today.to_s)
-        file = "spec/examples/misc.bib"
-        File.write(file, bibtex, encoding: "utf-8") unless File.exist? file
-        expect(bibtex).to eq File.read(file, encoding: "utf-8")
-          .sub(/(?<=timestamp = {)\d{4}-\d{2}-\d{2}/, Date.today.to_s)
-      end
-
-      it "techreport" do
-        expect(subject).to receive(:type).and_return("techreport")
-          .at_least :once
-        bibtex = subject.to_bibtex
-          .sub(/(?<=timestamp = {)\d{4}-\d{2}-\d{2}/, Date.today.to_s)
-        file = "spec/examples/techreport.bib"
-        File.write(file, bibtex, encoding: "utf-8") unless File.exist? file
-        expect(bibtex).to eq File.read(file, encoding: "utf-8")
-          .sub(/(?<=timestamp = {)\d{4}-\d{2}-\d{2}/, Date.today.to_s)
-      end
-
-      it "manual" do
-        expect(subject).to receive(:type).and_return("manual").at_least :once
-        bibtex = subject.to_bibtex
-          .sub(/(?<=timestamp = {)\d{4}-\d{2}-\d{2}/, Date.today.to_s)
-        file = "spec/examples/manual.bib"
-        File.write(file, bibtex, encoding: "utf-8") unless File.exist? file
-        expect(bibtex).to eq File.read(file, encoding: "utf-8")
-          .sub(/(?<=timestamp = {)\d{4}-\d{2}-\d{2}/, Date.today.to_s)
-      end
-
-      it "phdthesis" do
-        expect(subject).to receive(:type).and_return("phdthesis").at_least :once
-        bibtex = subject.to_bibtex
-        file = "spec/examples/phdthesis.bib"
-        File.write(file, bibtex, encoding: "utf-8") unless File.exist? file
-        expect(bibtex).to eq File.read(file, encoding: "utf-8")
-      end
-    end
-
-    it "convert item to AsciiBib" do
-      file = "spec/examples/asciibib.adoc"
-      bib = subject.to_asciibib
-      File.write file, bib, encoding: "UTF-8" unless File.exist? file
-      expect(bib).to eq File.read(file, encoding: "UTF-8")
-    end
-
-    context "convert item to BibXML" do
-      it "RFC" do
-        file = "spec/examples/rfc.xml"
-        rfc = subject.to_bibxml
-        File.write file, rfc, encoding: "UTF-8" unless File.exist? file
-        expect(rfc).to be_equivalent_to File.read file, encoding: "UTF-8"
-      end
-
-      it "BCP" do
-        hash = YAML.load_file "spec/examples/bcp_item.yml"
-        bcpbib = RelatonBib::BibliographicItem.from_hash(hash)
-        file = "spec/examples/bcp_item.xml"
-        bcpxml = bcpbib.to_bibxml
-        File.write file, bcpxml, encoding: "UTF-8" unless File.exist? file
-        expect(bcpxml).to be_equivalent_to File.read file, encoding: "UTF-8"
-      end
-
-      it "ID" do
-        hash = YAML.load_file "spec/examples/id_item.yml"
-        id = RelatonBib::BibliographicItem.from_hash hash
-        file = "spec/examples/id_item.xml"
-        idxml = id.to_bibxml
-        File.write file, idxml, encoding: "UTF-8" unless File.exist? file
-        expect(idxml).to be_equivalent_to File.read file, encoding: "UTF-8"
-      end
-
-      it "render keywords" do
-        docid = RelatonBib::DocumentIdentifier.new type: "IETF", id: "ID"
-        bibitem = RelatonBib::BibliographicItem.new keyword: ["kw"], docid: [docid]
-        expect(bibitem.to_bibxml(include_keywords: true)).to be_equivalent_to <<~XML
-          <reference anchor="ID">
-            <front>
-              <keyword>kw</keyword>
-            </front>
-          </reference>
-        XML
-      end
-
-      it "render person's forename" do
-        docid = RelatonBib::DocumentIdentifier.new type: "IETF", id: "ID"
-        sname = RelatonBib::LocalizedString.new "Cook"
-        fname = RelatonBib::Forename.new content: "James", initial: "J"
-        name = RelatonBib::FullName.new surname: sname, forename: [fname]
-        entity = RelatonBib::Person.new name: name
-        contrib = RelatonBib::ContributionInfo.new entity: entity
-        bibitem = RelatonBib::BibliographicItem.new docid: [docid], contributor: [contrib]
-        expect(bibitem.to_bibxml).to be_equivalent_to <<~XML
-          <reference anchor="ID">
-            <front>
-              <author fullname="James Cook" initials="J." surname="Cook">
-                <organization/>
-              </author>
-            </front>
-          </reference>
-        XML
-      end
-
-      it "render organization as author name" do
-        docid = RelatonBib::DocumentIdentifier.new type: "IETF", id: "ID"
-        entity = RelatonBib::Organization.new name: "org"
-        role = [{ type: "author", description: ["BibXML author"] }]
-        contrib = RelatonBib::ContributionInfo.new entity: entity, role: role
-        bibitem = RelatonBib::BibliographicItem.new docid: [docid], contributor: [contrib]
-        expect(bibitem.to_bibxml).to be_equivalent_to <<~XML
-          <reference anchor="ID">
-            <front>
-              <author>
-                <organization>org</organization>
-              </author>
-            </front>
-          </reference>
-        XML
-      end
-    end
-
-    it "convert item to citeproc" do
-      file = "spec/examples/citeproc.json"
-      cp = subject.to_citeproc
-      File.write file, cp.to_json, encoding: "UTF-8" unless File.exist? file
-      json = JSON.parse(File.read(file, encoding: "UTF-8"))
-      json[0]["timestamp"] = Date.today.to_s
-      cp[0]["timestamp"] = Date.today.to_s
-      expect(cp).to eq json
-    end
-  end
-
-  it "initialize with copyright object" do
-    org = RelatonBib::Organization.new(
-      name: "Test Org", abbreviation: "TO", url: "test.org",
-    )
-    owner = [RelatonBib::ContributionInfo.new(entity: org)]
-    copyright = RelatonBib::CopyrightAssociation.new(owner: owner, from: "2018")
-    bibitem = RelatonBib::BibliographicItem.new(
-      formattedref: RelatonBib::FormattedRef.new(content: "ISO123"),
-      copyright: [copyright],
-    )
-    expect(bibitem.to_xml).to include(
-      "<formattedref format=\"text/plain\">ISO123</formattedref>",
-    )
-  end
-
-  it "warn invalid type argument error" do
-    expect { RelatonBib::BibliographicItem.new type: "type" }.to output(
-      /\[relaton-bib\] WARN: Type `type` is invalid./,
-    ).to_stderr_from_any_process
-  end
-
-  context RelatonBib::CopyrightAssociation do
-    it "initialise with owner object" do
-      org = RelatonBib::Organization.new(
-        name: "Test Org", abbreviation: "TO", url: "test.org",
-      )
-      owner = [RelatonBib::ContributionInfo.new(entity: org)]
-      copy = RelatonBib::CopyrightAssociation.new owner: owner, from: "2019"
-      expect(copy.owner).to eq owner
-    end
-  end
-
-  it "initialize with string link" do
-    bibitem = RelatonBib::BibliographicItem.new link: ["http://example.com"]
-    expect(bibitem.link[0]).to be_instance_of RelatonBib::TypedUri
-    expect(bibitem.link[0].content).to be_instance_of Addressable::URI
-    expect(bibitem.link[0].content.to_s).to eq "http://example.com"
-  end
-end
diff --git a/spec/relaton_bib/contribution_info_spec.rb b/spec/relaton_bib/contribution_info_spec.rb
deleted file mode 100644
index 88a8594..0000000
--- a/spec/relaton_bib/contribution_info_spec.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-RSpec.describe RelatonBib::ContributorRole do
-  it "raises invalid type argument error" do
-    expect { RelatonBib::ContributorRole.new type: "type" }.to output(
-      /Contributor's type `type` is invalid/,
-    ).to_stderr_from_any_process
-  end
-end
diff --git a/spec/relaton_bib/contributor_spec.rb b/spec/relaton_bib/contributor_spec.rb
deleted file mode 100644
index d4237aa..0000000
--- a/spec/relaton_bib/contributor_spec.rb
+++ /dev/null
@@ -1,228 +0,0 @@
-describe RelatonBib::Address do
-  it "raises ArgumentError if either formatted address or city and country are not provided" do
-    expect { RelatonBib::Address.new }.to raise_error(ArgumentError)
-  end
-
-  context "==" do
-    it "same content" do
-      contrib = RelatonBib::Address.new(formatted_address: "formatted address")
-      other = RelatonBib::Address.new(formatted_address: "formatted address")
-      expect(contrib).to eq other
-    end
-
-    it "different content" do
-      contrib = RelatonBib::Address.new(formatted_address: "formatted address")
-      other = RelatonBib::Address.new(formatted_address: "other formatted address")
-      expect(contrib).not_to eq other
-    end
-  end
-
-  context "render formatted address" do
-    let(:contrib) { RelatonBib::Address.new(formatted_address: "formatted address") }
-
-    it "as XML" do
-      xml = Nokogiri::XML::Builder.new { |b| contrib.to_xml(b) }.doc.root
-      formatted_address = xml.xpath("/address/formattedAddress").text
-      expect(formatted_address).to eq "formatted address"
-    end
-
-    it "as Hash" do
-      hash = contrib.to_hash
-      expect(hash["address"]["formatted_address"]).to eq "formatted address"
-    end
-
-    it "as AsciiBib" do
-      expect(contrib.to_asciibib).to eq "address.formatted_address:: formatted address\n"
-    end
-  end
-
-  context "render address" do
-    let(:contrib) do
-      RelatonBib::Address.new(
-        street: ["street1", "street2"],
-        city: "city",
-        state: "state",
-        country: "country",
-        postcode: "postcode",
-      )
-    end
-
-    it "as XML" do
-      xml = Nokogiri::XML::Builder.new { |b| contrib.to_xml(b) }.doc.root
-      street = xml.xpath("/address/street").map(&:text)
-      expect(street).to eq %w[street1 street2]
-      expect(xml.xpath("/address/city").text).to eq "city"
-      expect(xml.xpath("/address/state").text).to eq "state"
-      expect(xml.xpath("/address/country").text).to eq "country"
-      expect(xml.xpath("/address/postcode").text).to eq "postcode"
-    end
-
-    it "as Hash" do
-      hash = contrib.to_hash
-      expect(hash["address"]["street"]).to eq %w[street1 street2]
-      expect(hash["address"]["city"]).to eq "city"
-      expect(hash["address"]["state"]).to eq "state"
-      expect(hash["address"]["country"]).to eq "country"
-      expect(hash["address"]["postcode"]).to eq "postcode"
-    end
-
-    it "as AsciiBib" do
-      expect(contrib.to_asciibib).to eq <<~ASCIIBIB
-        address.street:: street1
-        address.street:: street2
-        address.city:: city
-        address.state:: state
-        address.country:: country
-        address.postcode:: postcode
-      ASCIIBIB
-    end
-  end
-end
-
-describe RelatonBib::Affiliation do
-  let(:org) { RelatonBib::Organization.new(name: "Org") }
-  let(:name) { RelatonBib::LocalizedString.new("Name", "en") }
-  let(:desc) { RelatonBib::FormattedString.new(content: "Description", language: "en") }
-  subject do
-    description = desc ? [desc] : []
-    described_class.new(organization: org, name: name, description: description)
-  end
-
-  context "==" do
-    it "same content" do
-      other = described_class.new(organization: org, name: name, description: [desc])
-      expect(subject).to eq other
-    end
-
-    it "different content" do
-      name = RelatonBib::LocalizedString.new("Other", "en")
-      other = described_class.new(organization: org, name: name, description: [desc])
-      expect(subject).not_to eq other
-    end
-  end
-
-  context "render affiliation" do
-    context "with all fields" do
-      it "as XML" do
-        xml = Nokogiri::XML::Builder.new { |b| subject.to_xml(builder: b) }.doc.root
-        expect(xml.to_s).to be_equivalent_to <<~XML
-          <affiliation>
-            <name language="en">Name</name>
-            <description format="text/plain" language="en">Description</description>
-            <organization>
-              <name>Org</name>
-            </organization>
-          </affiliation>
-        XML
-      end
-
-      it "as Hash" do
-        hash = subject.to_hash
-        expect(hash["organization"]["name"][0]["content"]).to eq "Org"
-        expect(hash["name"]["content"]).to eq "Name"
-        expect(hash["name"]["language"]).to eq ["en"]
-        expect(hash["description"][0]["content"]).to eq "Description"
-        expect(hash["description"][0]["language"]).to eq ["en"]
-      end
-
-      it "as AsciiBib" do
-        expect(subject.to_asciibib).to eq <<~ASCIIBIB
-          affiliation.name.content:: Name
-          affiliation.name.language:: en
-          affiliation.description.content:: Description
-          affiliation.description.language:: en
-          affiliation.description.format:: text/plain
-          affiliation.organization.name:: Org
-        ASCIIBIB
-      end
-    end
-
-    context "without organization" do
-      let(:org) { nil }
-
-      it "as XML" do
-        xml = Nokogiri::XML::Builder.new { |b| subject.to_xml(builder: b) }.doc.root
-        expect(xml.to_s).to be_equivalent_to <<~XML
-          <affiliation>
-            <name language="en">Name</name>
-            <description format="text/plain" language="en">Description</description>
-          </affiliation>
-        XML
-      end
-
-      it "as Hash" do
-        hash = subject.to_hash
-        expect(hash).not_to have_key "organization"
-      end
-
-      it "as AsciiBib" do
-        expect(subject.to_asciibib).not_to include "affiliation.organization"
-      end
-    end
-
-    context "without name" do
-      let(:name) { nil }
-
-      it "as XML" do
-        xml = Nokogiri::XML::Builder.new { |b| subject.to_xml(builder: b) }.doc.root
-        expect(xml.to_s).to be_equivalent_to <<~XML
-          <affiliation>
-            <description format="text/plain" language="en">Description</description>
-            <organization>
-              <name>Org</name>
-            </organization>
-          </affiliation>
-        XML
-      end
-
-      it "as Hash" do
-        hash = subject.to_hash
-        expect(hash).not_to have_key "name"
-      end
-
-      it "as AsciiBib" do
-        expect(subject.to_asciibib).not_to include "affiliation.name"
-      end
-    end
-
-    context "without description" do
-      let(:desc) { nil }
-
-      it "as XML" do
-        xml = Nokogiri::XML::Builder.new { |b| subject.to_xml(builder: b) }.doc.root
-        expect(xml.to_s).to be_equivalent_to <<~XML
-          <affiliation>
-            <name language="en">Name</name>
-            <organization>
-              <name>Org</name>
-            </organization>
-          </affiliation>
-        XML
-      end
-
-      it "as Hash" do
-        expect(subject.to_hash).not_to have_key "description"
-      end
-
-      it "as AsciiBib" do
-        expect(subject.to_asciibib).not_to include "affiliation.description"
-      end
-    end
-
-    it "without any fields" do
-      xml = Nokogiri::XML::Builder.new { |b| described_class.new.to_xml(builder: b) }.doc.root
-      expect(xml.to_s).to eq ""
-    end
-  end
-
-  context "desctiption" do
-    it "returns all descriptions if language is not specified" do
-      expect(subject.description).to eq [desc]
-    end
-
-    it "returns description with specified language" do
-      expect(subject.description("en")).to eq [desc]
-      expect(subject.description("fr")).to be_empty
-    end
-  end
-end
diff --git a/spec/relaton_bib/copyright_association_spec.rb b/spec/relaton_bib/copyright_association_spec.rb
deleted file mode 100644
index 2f1acac..0000000
--- a/spec/relaton_bib/copyright_association_spec.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-RSpec.describe RelatonBib::CopyrightAssociation do
-  it "raise error if owners is empty" do
-    expect do
-      RelatonBib::CopyrightAssociation.new owner: [], from: "2019"
-    end.to raise_error ArgumentError
-  end
-end
diff --git a/spec/relaton_bib/document_identifier_spec.rb b/spec/relaton_bib/document_identifier_spec.rb
deleted file mode 100644
index c0a30a9..0000000
--- a/spec/relaton_bib/document_identifier_spec.rb
+++ /dev/null
@@ -1,84 +0,0 @@
-RSpec.describe RelatonBib::DocumentIdentifier do
-  context "ISO" do
-    subject do
-      RelatonBib::DocumentIdentifier.new(id: "1111-2:2014", type: "ISO")
-    end
-
-    it "remove part" do
-      subject.remove_part
-      expect(subject.id).to eq "1111:2014"
-      subject.all_parts
-      expect(subject.id).to eq "1111:2014 (all parts)"
-    end
-
-    it "remove date" do
-      subject.remove_date
-      expect(subject.id).to eq "1111-2"
-    end
-  end
-
-  context "URN" do
-    context "ISO" do
-      subject do
-        RelatonBib::DocumentIdentifier.new(
-          type: "URN", id: "urn:iso:std:iso:1111:-1:stage-60.60:ed-1:v1:en,fr",
-        )
-      end
-
-      it "remove part" do
-        subject.remove_part
-        expect(subject.id).to eq "urn:iso:std:iso:1111"
-      end
-    end
-
-    context "IEC" do
-      subject do
-        RelatonBib::DocumentIdentifier.new(
-          type: "URN",
-          id: "urn:iec:std:iec:61058-2-4:1995::csv:en:plus:amd:1:2003",
-        )
-      end
-
-      it "remove part" do
-        subject.remove_part
-        expect(subject.id).to eq "urn:iec:std:iec:61058:1995::csv:en:plus:amd:1:2003"
-      end
-
-      it "remove date" do
-        subject.remove_date
-        expect(subject.id).to eq "urn:iec:std:iec:61058-2-4:::csv:en:plus:amd:1:2003"
-      end
-
-      it "set all parts" do
-        subject.all_parts
-        expect(subject.id).to eq "urn:iec:std:iec:61058-2-4:1995::ser"
-      end
-    end
-  end
-
-  context "GB" do
-    subject do
-      RelatonBib::DocumentIdentifier.new(id: "1111.2-2014", type: "Chinese Standard")
-    end
-
-    it "remove part" do
-      subject.remove_part
-      expect(subject.id).to eq "1111-2014"
-    end
-
-    it "remove date" do
-      subject.remove_date
-      expect(subject.id).to eq "1111.2"
-    end
-  end
-
-  context "#to_xml" do
-    it "with superscription" do
-      subject = RelatonBib::DocumentIdentifier.new(id: "CIPM 43<sup>e</sup> réunion (1950)", type: "BIPM")
-      xml = Nokogiri::XML::Builder.new do |builder|
-        subject.to_xml(builder: builder, lang: "en")
-      end.doc.root
-      expect(xml.to_xml).to eq "<docidentifier type=\"BIPM\">CIPM 43<sup>e</sup> r&#xE9;union (1950)</docidentifier>"
-    end
-  end
-end
diff --git a/spec/relaton_bib/document_relation_collection_spec.rb b/spec/relaton_bib/document_relation_collection_spec.rb
deleted file mode 100644
index f401294..0000000
--- a/spec/relaton_bib/document_relation_collection_spec.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-RSpec.describe RelatonBib::DocRelationCollection do
-  context "instance" do
-    subject do
-      RelatonBib::DocRelationCollection.new(
-        [
-          RelatonBib::DocumentRelation.new(
-            type: "replace",
-            bibitem: RelatonBib::BibliographicItem.new(
-              formattedref: RelatonBib::FormattedRef.new(content: "realtion1"),
-            ),
-          ),
-          RelatonBib::DocumentRelation.new(
-            type: "obsoletes", bibitem: "realtion1",
-          ),
-        ],
-      )
-    end
-
-    it "returns one replace" do
-      expect(subject.replaces.size).to eq 1
-    end
-
-    it "#select" do
-      expect(subject.select { |r| r.type == "replace" }.size).to eq 1
-    end
-  end
-end
diff --git a/spec/relaton_bib/document_relation_spec.rb b/spec/relaton_bib/document_relation_spec.rb
deleted file mode 100644
index d60da8f..0000000
--- a/spec/relaton_bib/document_relation_spec.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-RSpec.describe RelatonBib::DocumentRelation do
-  it "warn when type is invalid" do
-    expect do
-      RelatonBib::DocumentRelation.new type: "invalid", bibitem: nil
-    end.to output(/Invalid relation type/).to_stderr_from_any_process
-  end
-end
diff --git a/spec/relaton_bib/document_status_spec.rb b/spec/relaton_bib/document_status_spec.rb
deleted file mode 100644
index d8c69ff..0000000
--- a/spec/relaton_bib/document_status_spec.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-RSpec.describe RelatonBib::DocumentStatus do
-  it "create with hash" do
-    ds = RelatonBib::DocumentStatus.new stage: { value: "30", abbreviation: "CD" }
-    expect(ds.stage).to be_instance_of RelatonBib::DocumentStatus::Stage
-    expect(ds.stage.value).to eq "30"
-    expect(ds.stage.abbreviation).to eq "CD"
-  end
-
-  it "create with string" do
-    ds = RelatonBib::DocumentStatus.new stage: "30-CD"
-    expect(ds.stage).to be_instance_of RelatonBib::DocumentStatus::Stage
-    expect(ds.stage.value).to eq "30-CD"
-  end
-end
diff --git a/spec/relaton_bib/forename_spec.rb b/spec/relaton_bib/forename_spec.rb
deleted file mode 100644
index 28463d1..0000000
--- a/spec/relaton_bib/forename_spec.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-describe RelatonBib::Forename do
-  subject do
-    described_class.new content: "John", language: "en", script: "Latn", initial: "J"
-  end
-
-  it "initialize" do
-    expect(subject.content).to eq "John"
-    expect(subject.language).to eq ["en"]
-    expect(subject.script).to eq ["Latn"]
-    expect(subject.initial).to eq "J"
-  end
-
-  context "instance methods" do
-    it "#to_xml" do
-      doc = Nokogiri::XML::Builder.new do |builder|
-        builder.name { subject.to_xml builder }
-      end.doc.root
-      expect(doc.to_xml).to be_equivalent_to <<-XML
-        <name>
-          <forename language="en" script="Latn" initial="J">John</forename>
-        </name>
-      XML
-    end
-
-    it "#to_hash" do
-      expect(subject.to_hash).to eq(
-        { "content" => "John", "language" => ["en"], "script" => ["Latn"],
-          "initial" => "J" },
-      )
-    end
-
-    context "#to_asciibib" do
-      it "single forename" do
-        expect(subject.to_asciibib("name", 1)).to eq <<~ASCIIDOC
-          name.forename.content:: John
-          name.forename.language:: en
-          name.forename.script:: Latn
-          name.forename.initial:: J
-        ASCIIDOC
-      end
-
-      it "multiple forenames" do
-        expect(subject.to_asciibib("name", 2)).to eq <<~ASCIIDOC
-          name.forename::
-          name.forename.content:: John
-          name.forename.language:: en
-          name.forename.script:: Latn
-          name.forename.initial:: J
-        ASCIIDOC
-      end
-    end
-  end
-end
diff --git a/spec/relaton_bib/formatted_string_spec.rb b/spec/relaton_bib/formatted_string_spec.rb
deleted file mode 100644
index 93aeb24..0000000
--- a/spec/relaton_bib/formatted_string_spec.rb
+++ /dev/null
@@ -1,118 +0,0 @@
-describe RelatonBib::FormattedString do
-  context "instance" do
-    subject do
-      RelatonBib::FormattedString.new(content: <<-XML, language: "en", script: "Latn", format: "text/html")
-        prefix <p>content <p>< & > characters</p> to escape</p>
-        <p>Text \xC2\xB1 10-4 K</p> suffix
-      XML
-    end
-
-    context "==" do
-      it "same content" do
-        other = RelatonBib::FormattedString.new content: subject.content, language: "en", script: "Latn", format: "text/html"
-        expect(subject).to eq other
-      end
-
-      it "different content" do
-        other = RelatonBib::FormattedString.new content: "other", language: "en", script: "Latn", format: "text/html"
-        expect(subject).not_to eq other
-      end
-    end
-
-    context "escape" do
-      it "&" do
-        xml = Nokogiri::XML::Builder.new do |b|
-          b.formatted_string { subject.to_xml(b) }
-        end
-        expect(xml.doc.root.to_s).to be_equivalent_to <<~XML
-          <formatted_string format="text/html" language="en" script="Latn">
-            prefix<p>content<p>&lt; &amp; &gt; characters</p>to escape</p><p>Text &#xB1; 10-4 K</p> suffix
-          </formatted_string>
-        XML
-      end
-
-      it "incorrect HTML" do
-        ls = RelatonBib::FormattedString.new content: <<~XML, language: "en", script: "Latn", format: "text/html"
-          <p><p>Content</tt></p>
-        XML
-        xml = Nokogiri::XML::Builder.new do |b|
-          b.formatted_string { ls.to_xml(b) }
-        end
-        expect(xml.doc.root.to_s).to be_equivalent_to <<~XML
-          <formatted_string format="text/html" language="en" script="Latn">
-            <p>&lt;p&gt;Content&lt;/tt&gt;</p>
-          </formatted_string>
-        XML
-      end
-
-      it "content with 2 root elements" do
-        ls = RelatonBib::FormattedString.new content: <<~XML, format: "text/html"
-          <p>Content &</p><p>Content</p>
-        XML
-        xml = Nokogiri::XML::Builder.new do |b|
-          b.formatted_string { ls.to_xml(b) }
-        end
-        expect(xml.doc.root.to_s).to be_equivalent_to <<~XML
-          <formatted_string format="text/html">
-            <p>Content &amp;</p><p>Content</p>
-          </formatted_string>
-        XML
-      end
-
-      it "tag with attributes" do
-        ls = RelatonBib::FormattedString.new content: <<~XML, format: "text/html"
-          <p>Content <p id="1">Content</p></p>
-        XML
-        xml = Nokogiri::XML::Builder.new do |b|
-          b.formatted_string { ls.to_xml(b) }
-        end
-        expect(xml.doc.root.to_s).to be_equivalent_to <<~XML
-          <formatted_string format="text/html">
-            <p>Content <p id="1">Content</p></p>
-          </formatted_string>
-        XML
-      end
-
-      it "tag without content" do
-        ls = RelatonBib::FormattedString.new content: <<~XML, format: "text/html"
-          <br/><br />
-        XML
-        xml = Nokogiri::XML::Builder.new do |b|
-          b.formatted_string { ls.to_xml(b) }
-        end
-        expect(xml.doc.root.to_s).to be_equivalent_to <<~XML
-          <formatted_string format="text/html">
-            <br/><br/>
-          </formatted_string>
-        XML
-      end
-
-      it "HTML comment" do
-        ls = RelatonBib::FormattedString.new content: <<~XML, format: "text/html"
-          <p>Content <!-- comment --> Content</p>
-        XML
-        xml = Nokogiri::XML::Builder.new do |b|
-          b.formatted_string { ls.to_xml(b) }
-        end
-        expect(xml.doc.root.to_s).to be_equivalent_to <<~XML
-          <formatted_string format="text/html">
-            <p>Content <!-- comment --> Content</p>
-          </formatted_string>
-        XML
-      end
-    end
-
-    it "cleanup" do
-      fs = described_class.new content: <<~XML, format: "text/html"
-        <i>Italic</i> <b>Bold</b> <u>Underline</u>  <sup>Superscript</sup> <sub>Subscript</sub><br/>
-        <jats:p>Paragraph</jats:p><tt>Monospace</tt><a href="http://example.com">Link</a>
-        <italic>Italic</italic>.
-      XML
-      expect(fs.content).to be_equivalent_to <<~XML
-        <em>Italic</em> <strong>Bold</strong> Underline <sup>Superscript</sup> <sub>Subscript</sub><br/>
-        <p>Paragraph</p><tt>Monospace</tt>Link
-        Italic.
-      XML
-    end
-  end
-end
diff --git a/spec/relaton_bib/full_name_spec.rb b/spec/relaton_bib/full_name_spec.rb
deleted file mode 100644
index 9116b6b..0000000
--- a/spec/relaton_bib/full_name_spec.rb
+++ /dev/null
@@ -1,131 +0,0 @@
-describe RelatonBib::FullName do
-  context "using name parts" do
-    subject do
-      described_class.new(
-        surname: RelatonBib::LocalizedString.new("Doe"),
-        abbreviation: RelatonBib::LocalizedString.new("DJ"),
-        forename: [RelatonBib::Forename.new(content: "John", initial: "J")],
-        initials: RelatonBib::LocalizedString.new("J.D."),
-        addition: [RelatonBib::LocalizedString.new("Jr.")],
-        prefix: [RelatonBib::LocalizedString.new("Dr.")],
-      )
-    end
-
-    context "==" do
-      it "same content" do
-        other = described_class.new(
-          surname: RelatonBib::LocalizedString.new("Doe"),
-          abbreviation: RelatonBib::LocalizedString.new("DJ"),
-          forename: [RelatonBib::Forename.new(content: "John", initial: "J")],
-          initials: RelatonBib::LocalizedString.new("J.D."),
-          addition: [RelatonBib::LocalizedString.new("Jr.")],
-          prefix: [RelatonBib::LocalizedString.new("Dr.")],
-        )
-        expect(subject).to eq other
-      end
-
-      it "different content" do
-        other = described_class.new(
-          surname: RelatonBib::LocalizedString.new("Doe"),
-          abbreviation: RelatonBib::LocalizedString.new("DJ"),
-          forename: [RelatonBib::Forename.new(content: "John", initial: "J")],
-          initials: RelatonBib::LocalizedString.new("J.D."),
-          prefix: [RelatonBib::LocalizedString.new("Dr.")],
-        )
-        expect(subject).not_to eq other
-      end
-    end
-
-    it "to_xml" do
-      builder = Nokogiri::XML::Builder.new
-      subject.to_xml(builder: builder)
-      expect(builder.to_xml).to be_equivalent_to <<~XML
-        <name>
-          <abbreviation>DJ</abbreviation>
-          <prefix>Dr.</prefix>
-          <forename initial="J">John</forename>
-          <formatted-initials>J.D.</formatted-initials>
-          <surname>Doe</surname>
-          <addition>Jr.</addition>
-        </name>
-      XML
-    end
-
-    it "to_hash" do
-      expect(subject.to_hash).to eq(
-        "abbreviation" => { "content" => "DJ" },
-        "given" => {
-          "forename" => [{ "content" => "John", "initial" => "J" }],
-          "formatted_initials" => { "content" => "J.D." },
-        },
-        "surname" => { "content" => "Doe" },
-        "addition" => [{ "content" => "Jr." }],
-        "prefix" => [{ "content" => "Dr." }],
-      )
-    end
-
-    it "to_asciibib" do
-      expect(subject.to_asciibib("name")).to eq <<~ASCIIBIB
-        name.name.abbreviation:: DJ
-        name.given.forename:: John
-        name.given.forename.initial:: J
-        name.given.formatted-initials:: J.D.
-        name.name.surname:: Doe
-        name.name.addition:: Jr.
-        name.name.prefix:: Dr.
-      ASCIIBIB
-    end
-  end
-
-  context "using completename" do
-    subject do
-      described_class.new(
-        completename: RelatonBib::LocalizedString.new("John Doe"),
-      )
-    end
-
-    context "==" do
-      it "same content" do
-        other = described_class.new(
-          completename: RelatonBib::LocalizedString.new("John Doe"),
-        )
-        expect(subject).to eq other
-      end
-
-      it "different content" do
-        other = described_class.new(
-          completename: RelatonBib::LocalizedString.new("Jane Doe"),
-        )
-        expect(subject).not_to eq other
-      end
-    end
-
-    it "to_xml" do
-      builder = Nokogiri::XML::Builder.new
-      subject.to_xml(builder: builder, lang: "en")
-      expect(builder.to_xml).to be_equivalent_to <<~XML
-        <name>
-          <completename>John Doe</completename>
-        </name>
-      XML
-    end
-
-    it "to_hash" do
-      expect(subject.to_hash).to eq(
-        "completename" => { "content" => "John Doe" },
-      )
-    end
-
-    it "to_asciibib" do
-      expect(subject.to_asciibib("name")).to eq <<~ASCIIBIB
-        name.name.completename:: John Doe
-      ASCIIBIB
-    end
-  end
-
-  it "raise ArgumentError" do
-    expect do
-      described_class.new
-    end.to raise_error ArgumentError, "Should be given :surname or :completename"
-  end
-end
diff --git a/spec/relaton_bib/hash_converter_spec.rb b/spec/relaton_bib/hash_converter_spec.rb
deleted file mode 100644
index dd67e32..0000000
--- a/spec/relaton_bib/hash_converter_spec.rb
+++ /dev/null
@@ -1,136 +0,0 @@
-RSpec.describe RelatonBib::HashConverter do
-  it "warn if bibitem missig" do
-    expect do
-      ret = { relation: [type: "updates"] }
-      RelatonBib::HashConverter.relation_bibitem_hash_to_bib ret[:relation][0]
-    end.to output(/Bibitem missing/).to_stderr_from_any_process
-  end
-
-  it "make affiliation description from string" do
-    affiliation = RelatonBib::HashConverter.affiliation_hash_to_bib(
-      affiliation: {
-        description: "Description", organization: { name: "Org" }
-      },
-    )
-    expect(affiliation).to be_instance_of Array
-    expect(affiliation.first).to be_instance_of RelatonBib::Affiliation
-  end
-
-  it "make localized string from hash" do
-    ls = RelatonBib::HashConverter.localizedstring content: "string"
-    expect(ls).to be_instance_of RelatonBib::LocalizedString
-  end
-
-  # it "make localityStack from unwrapped loclaity" do
-  #   hash = { locality: [{ type: "section", reference_from: "1" }] }
-  #   RelatonBib::HashConverter.relation_locality_hash_to_bib hash
-  #   expect(hash[:locality].first).to be_instance_of RelatonBib::LocalityStack
-  # end
-
-  # it "make sourceLocalityStack from unwrapped sourceLoclaity" do
-  #   hash = { source_locality: [{ type: "section", reference_from: "1" }] }
-  #   RelatonBib::HashConverter.relation_source_locality_hash_to_bib hash
-  #   expect(hash[:source_locality].first).to be_instance_of(
-  #     RelatonBib::SourceLocalityStack,
-  #   )
-  # end
-
-  it "parse validity time" do
-    r = RelatonBib::HashConverter.parse_validity_time({ begins: 1999 }, :begins)
-    expect(r.to_s).to match(/^1999-01-01/)
-    r = RelatonBib::HashConverter.parse_validity_time({ ends: 1999 }, :ends)
-    expect(r.to_s).to match(/^1999-12-31/)
-    r = RelatonBib::HashConverter.parse_validity_time(
-      { begins: "1999-02" }, :begins
-    )
-    expect(r.to_s).to match(/^1999-02-01/)
-    r = RelatonBib::HashConverter.parse_validity_time(
-      { ends: "1999-02" }, :ends
-    )
-    expect(r.to_s).to match(/^1999-02-28/)
-  end
-
-  context "contacts_hash_to_bib" do
-    it "create address from old hash" do
-      hash = { contact: [{ street: "Street", city: "City", country: "Country" }] }
-      address = described_class.contacts_hash_to_bib hash
-      expect(address).to be_instance_of Array
-      expect(address.first).to be_instance_of RelatonBib::Address
-      expect(address.first.street).to eq ["Street"]
-      expect(address.first.city).to eq "City"
-      expect(address.first.country).to eq "Country"
-    end
-
-    it "create formatted address" do
-      entity = { contact: [{ address: { formatted_address: "Address" } }] }
-      address = RelatonBib::HashConverter.contacts_hash_to_bib entity
-      expect(address).to be_instance_of Array
-      expect(address.first).to be_instance_of RelatonBib::Address
-      expect(address.first.formatted_address).to eq "Address"
-    end
-
-    it "create formatted address from string" do
-      entity = { contact: [{ address: "Address" }] }
-      address = RelatonBib::HashConverter.contacts_hash_to_bib entity
-      expect(address).to be_instance_of Array
-      expect(address.first).to be_instance_of RelatonBib::Address
-      expect(address.first.formatted_address).to eq "Address"
-    end
-
-    it "create contact from old hash" do
-      hash = { contact: [{ type: "phone", value: "123" }] }
-      contact = described_class.contacts_hash_to_bib hash
-      expect(contact).to be_instance_of Array
-      expect(contact.first).to be_instance_of RelatonBib::Contact
-      expect(contact.first.type).to eq "phone"
-      expect(contact.first.value).to eq "123"
-    end
-
-    it "create phone" do
-      hash = { contact: [{ phone: "223322", type: "mobile" }] }
-      contact = described_class.contacts_hash_to_bib hash
-      expect(contact).to be_instance_of Array
-      expect(contact.first).to be_instance_of RelatonBib::Contact
-      expect(contact.first.type).to eq "phone"
-      expect(contact.first.subtype).to eq "mobile"
-      expect(contact.first.value).to eq "223322"
-    end
-  end
-
-  it "create copyright" do
-    ret = {
-      copyright: {
-        owner: {
-          name: [{ content: "Owner Name" }], abbreviation: { content: "ABBR" },
-          contact: [{ uri: "http://example.com" }]
-        },
-        from: "2022",
-      },
-    }
-    copyright = described_class.copyright_hash_to_bib ret
-    expect(copyright).to be_instance_of Array
-    expect(copyright[0][:owner][0][:name][0][:content]).to eq "Owner Name"
-    expect(copyright[0][:owner][0][:abbreviation][:content]).to eq "ABBR"
-    expect(copyright[0][:owner][0][:contact][0]).to be_instance_of RelatonBib::Contact
-    expect(copyright[0][:owner][0][:contact][0].type).to eq "uri"
-    expect(copyright[0][:owner][0][:contact][0].value).to eq "http://example.com"
-  end
-
-  context "create doctype" do
-    it "from string" do
-      ret = { ext: { doctype: "Doctype" } }
-      described_class.doctype_hash_to_bib ret
-      expect(ret[:doctype]).to be_instance_of RelatonBib::DocumentType
-      expect(ret[:doctype].type).to eq "Doctype"
-      expect(ret[:doctype].abbreviation).to be_nil
-    end
-
-    it "from hash" do
-      ret = { ext: { doctype: { type: "Doctype", abbreviation: "DCT" } } }
-      described_class.doctype_hash_to_bib ret
-      expect(ret[:doctype]).to be_instance_of RelatonBib::DocumentType
-      expect(ret[:doctype].type).to eq "Doctype"
-      expect(ret[:doctype].abbreviation).to eq "DCT"
-    end
-  end
-end
diff --git a/spec/relaton_bib/hit_collection_spec.rb b/spec/relaton_bib/hit_collection_spec.rb
deleted file mode 100644
index bf2b3db..0000000
--- a/spec/relaton_bib/hit_collection_spec.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-RSpec.describe RelatonBib::HitCollection do
-  subject do
-    hits = RelatonBib::HitCollection.new("ref")
-    hit = RelatonBib::Hit.new({})
-    item = double "bibitem"
-    expect(item).to receive(:to_xml).at_most :once
-    expect(hit).to receive(:fetch).and_return(item).at_most :twice
-    hits << hit
-    hits
-  end
-
-  it("fetches all hits") { subject.fetch }
-
-  it "select hits" do
-    expect(subject.select).to be_instance_of RelatonBib::HitCollection
-  end
-
-  it "collection to xml" do
-    expect(subject.to_xml).to eq %{<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<documents/>\n}
-  end
-
-  it "reduce collection" do
-    subject.reduce!([]) { |sum, hit| sum << hit }
-    expect(subject).to be_instance_of RelatonBib::HitCollection 
-  end
-
-  it "returns string" do
-    expect(subject.to_s).to eq(
-      "<RelatonBib::HitCollection:#{format('%#.14x', subject.object_id << 1)} "\
-      "@ref=ref @fetched=false>",
-    )
-  end
-end
diff --git a/spec/relaton_bib/hit_spec.rb b/spec/relaton_bib/hit_spec.rb
deleted file mode 100644
index 301cc35..0000000
--- a/spec/relaton_bib/hit_spec.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-RSpec.describe RelatonBib::Hit do
-  subject { RelatonBib::Hit.new({}) }
-
-  it "returns string" do
-    expect(subject.to_s).to eq(
-      "<RelatonBib::Hit:#{format('%#.14x', subject.object_id << 1)} " \
-      '@text="" @fetched="false" @fullIdentifier="" @title="">',
-    )
-  end
-
-  it "to xml" do
-    item = RelatonBib::BibliographicItem.new
-    expect(subject).to receive(:fetch).and_return item
-    expect(subject.to_xml).to match(/<bibitem schema-version="v\d+\.\d+\.\d+"\/>/)
-  end
-
-  it "raise not implemented" do
-    expect { subject.fetch }.to raise_error "Not implemented"
-  end
-end
diff --git a/spec/relaton_bib/image_spec.rb b/spec/relaton_bib/image_spec.rb
deleted file mode 100644
index 30d7638..0000000
--- a/spec/relaton_bib/image_spec.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-describe RelatonBib::Image do
-  subject do
-    described_class.new(
-      id: "id",
-      src: "src",
-      mimetype: "mime type",
-      filename: "file name",
-      width: "60%",
-      height: "40%",
-      alt: "Alt",
-      title: "Title",
-      longdesc: "long description",
-    )
-  end
-
-  it "initialize" do
-    expect(subject.id).to eq "id"
-    expect(subject.src).to eq "src"
-    expect(subject.mimetype).to eq "mime type"
-    expect(subject.filename).to eq "file name"
-    expect(subject.width).to eq "60%"
-    expect(subject.height).to eq "40%"
-    expect(subject.alt).to eq "Alt"
-    expect(subject.title).to eq "Title"
-    expect(subject.longdesc).to eq "long description"
-  end
-
-  it "to_xml" do
-    builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
-      subject.to_xml xml
-    end
-    xml = builder.doc.root.to_xml
-    expect(xml).to be_equivalent_to <<~XML
-      <image id="id" src="src" mimetype="mime type" filename="file name" width="60%" height="40%" alt="Alt" title="Title" longdesc="long description"/>
-    XML
-  end
-
-  it "to_hash" do
-    expect(subject.to_hash).to eq(
-      "image" => {
-        "id" => "id",
-        "src" => "src",
-        "mimetype" => "mime type",
-        "filename" => "file name",
-        "width" => "60%",
-        "height" => "40%",
-        "alt" => "Alt",
-        "title" => "Title",
-        "longdesc" => "long description",
-      },
-    )
-  end
-
-  it "to_asciibib" do
-    expect(subject.to_asciibib).to eq <<~BIB
-      image.id:: id
-      image.src:: src
-      image.mimetype:: mime type
-      image.filename:: file name
-      image.width:: 60%
-      image.height:: 40%
-      image.alt:: Alt
-      image.title:: Title
-      image.longdesc:: long description
-    BIB
-  end
-end
diff --git a/spec/relaton_bib/localized_string_spec.rb b/spec/relaton_bib/localized_string_spec.rb
deleted file mode 100644
index 5feda89..0000000
--- a/spec/relaton_bib/localized_string_spec.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-RSpec.describe RelatonBib::LocalizedString do
-  it "raise ArgumentError" do
-    expect do
-      RelatonBib::LocalizedString.new []
-    end.to raise_error ArgumentError, "LocalizedString content is empty"
-  end
-
-  it "create with Aray<String> content" do
-    ls = RelatonBib::LocalizedString.new ["Content"]
-    expect(ls.content[0].content).to eq "Content"
-  end
-
-  context "instance" do
-    subject do
-      described_class.new(<<-XML, "en", "Latn")
-        prefix <p>content <p>< & > characters</p> to escape</p>
-        <p>Text</p> suffix
-      XML
-    end
-
-    it "returns false" do
-      expect(subject.empty?).to be false
-    end
-
-    it "escape HTML" do
-      xml = Nokogiri::XML::Builder.new do |b|
-        b.localized_string { subject.to_xml(b) }
-      end
-      expect(xml.doc.root.to_s).to be_equivalent_to <<~XML
-        <localized_string language="en" script="Latn">
-          prefix &lt;p&gt;content &lt;p&gt;&lt; &amp; &gt; characters&lt;/p&gt; to escape&lt;/p&gt;
-          &lt;p&gt;Text&lt;/p&gt; suffix
-        </localized_string>
-      XML
-    end
-
-    it "don't escape HTML entities" do
-      ls = described_class.new "Content &amp;", "en", "Latn"
-      xml = Nokogiri::XML::Builder.new do |b|
-        b.localized_string { ls.to_xml(b) }
-      end
-      expect(xml.doc.root.to_s).to be_equivalent_to <<~XML
-        <localized_string language="en" script="Latn">Content &amp;</localized_string>
-      XML
-    end
-
-    it "escape String content only" do
-      ls = described_class.new [described_class.new("Content <p>Text</p>", "en", "Latn")]
-      xml = Nokogiri::XML::Builder.new do |b|
-        b.localized_string { ls.to_xml(b) }
-      end
-      expect(xml.doc.root.to_s).to be_equivalent_to <<~XML
-        <localized_string>
-          <variant language="en" script="Latn">Content &lt;p&gt;Text&lt;/p&gt;</variant>
-        </localized_string>
-      XML
-    end
-  end
-end
diff --git a/spec/relaton_bib/organization_spec.rb b/spec/relaton_bib/organization_spec.rb
deleted file mode 100644
index dd06f51..0000000
--- a/spec/relaton_bib/organization_spec.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-describe RelatonBib::Organization do
-  subject do
-    described_class.new(
-      name: "Org",
-      abbreviation: "ORG",
-      subdivision: [RelatonBib::LocalizedString.new("Subdivision", "en")],
-      url: "http://example.com",
-      identifier: [RelatonBib::OrgIdentifier.new("uri", "http://example.com")],
-      contact: [RelatonBib::Contact.new(type: "work", value: "http://example.com")],
-      logo: RelatonBib::Image.new(id: "IMG", src: "http://example.com/logo.png", mimetype: "image/png")
-    )
-  end
-
-  context "==" do
-    it "same content" do
-      other = described_class.new(
-        name: "Org",
-        abbreviation: "ORG",
-        subdivision: [RelatonBib::LocalizedString.new("Subdivision", "en")],
-        url: "http://example.com",
-        identifier: [RelatonBib::OrgIdentifier.new("uri", "http://example.com")],
-        contact: [RelatonBib::Contact.new(type: "work", value: "http://example.com")],
-        logo: RelatonBib::Image.new(id: "IMG", src: "http://example.com/logo.png", mimetype: "image/png")
-      )
-      expect(subject).to eq other
-    end
-
-    it "different content" do
-      other = described_class.new(
-        name: "Org",
-        abbreviation: "ORG",
-        subdivision: [RelatonBib::LocalizedString.new("Subdivision", "en")],
-        url: "http://example.com",
-        identifier: [RelatonBib::OrgIdentifier.new("uri", "http://example.com")],
-        contact: [RelatonBib::Contact.new(type: "work", value: "http://example.com")]
-      )
-      expect(subject).not_to eq other
-    end
-  end
-end
-
-describe RelatonBib::OrgIdentifier do
-  # it "raises invalid type argument error" do
-  #   expect { RelatonBib::OrgIdentifier.new "type", "value" }.to raise_error ArgumentError
-  # end
-end
diff --git a/spec/relaton_bib/person_spec.rb b/spec/relaton_bib/person_spec.rb
deleted file mode 100644
index 6712ee0..0000000
--- a/spec/relaton_bib/person_spec.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-RSpec.describe RelatonBib::Person do
-  context RelatonBib::FullName do
-    it "rises name error" do
-      expect do
-        RelatonBib::FullName.new
-      end.to raise_error ArgumentError
-    end
-  end
-
-  context RelatonBib::PersonIdentifier do
-    it "raises type error" do
-      expect do
-        RelatonBib::Person.new(
-          name: RelatonBib::FullName.new(completename: "John Lennon"),
-          identifier: RelatonBib::PersonIdentifier.new("wrong_type", "value"),
-        )
-      end.to raise_error ArgumentError
-    end
-  end
-end
diff --git a/spec/relaton_bib/place_spec.rb b/spec/relaton_bib/place_spec.rb
deleted file mode 100644
index d543de2..0000000
--- a/spec/relaton_bib/place_spec.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-describe RelatonBib::Place do
-  it "raise ArgumentError" do
-    expect do
-      described_class.new
-    end.to raise_error ArgumentError
-  end
-
-  describe RelatonBib::Place::RegionType do
-    context "raise ArgumentError" do
-      it "when name is nil adn ISO code is nil" do
-        expect do
-          described_class.new
-        end.to raise_error ArgumentError
-      end
-
-      it "when name is nil and ISO code is invalid" do
-        expect do
-          described_class.new iso: "invalid"
-        end.to raise_error ArgumentError
-      end
-    end
-
-    context "create instance" do
-      it "with name" do
-        expect(described_class.new(name: "name").name).to eq "name"
-      end
-
-      it "with name and ISO code" do
-        region = described_class.new(name: "name", iso: "WA")
-        expect(region.name).to eq "name"
-        expect(region.iso).to eq "WA"
-      end
-
-      it "with valid ISO code" do
-        region = described_class.new(iso: "WA")
-        expect(region.iso).to eq "WA"
-        expect(region.name).to eq "Washington"
-      end
-    end
-  end
-end
diff --git a/spec/relaton_bib/renderer/bibxml_spec.rb b/spec/relaton_bib/renderer/bibxml_spec.rb
deleted file mode 100644
index 4a3f3cc..0000000
--- a/spec/relaton_bib/renderer/bibxml_spec.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-describe RelatonBib::Renderer::BibXML do
-  context "instance methods" do
-    context "ref_attrs" do
-      it "upcase anchor for IANA" do
-        docid = RelatonBib::DocumentIdentifier.new id: "IANA dns-parameters", type: "IANA"
-        bib = RelatonBib::BibliographicItem.new(docid: [docid])
-        renderer = RelatonBib::Renderer::BibXML.new bib
-        ref_attrs = renderer.ref_attrs
-        expect(ref_attrs).to be_instance_of Hash
-        expect(ref_attrs[:anchor]).to eq "DNS-PARAMETERS"
-      end
-    end
-
-    context "render_seriesinfo" do
-      it "do not render trademark" do
-        docid = [
-          RelatonBib::DocumentIdentifier.new(id: "IEEE 123", type: "IEEE"),
-          RelatonBib::DocumentIdentifier.new(id: "IEEE 123", type: "IEEE", scope: "trademark"),
-        ]
-        bib = RelatonBib::BibliographicItem.new docid: docid
-        renderer = RelatonBib::Renderer::BibXML.new bib
-        builder = double "builder"
-        # expect(builder).to receive(:seriesInfo).with(name: "IEEE", value: "IEEE 123").once
-        renderer.render_seriesinfo builder
-      end
-    end
-  end
-end
diff --git a/spec/relaton_bib/series_spec.rb b/spec/relaton_bib/series_spec.rb
deleted file mode 100644
index 2e66778..0000000
--- a/spec/relaton_bib/series_spec.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.describe RelatonBib::Series do
-  it "raise argument error when title argument missed" do
-    expect { RelatonBib::Series.new }.to raise_error ArgumentError
-  end
-
-  # it "raises invalid type atgument error" do
-  #   expect do
-  #     title = RelatonBib::TypedTitleString.new(content: "title")
-  #     RelatonBib::Series.new title: title, type: "type"
-  #   end.to output(/Series type is invalid: type/).to_stderr
-  # end
-end
diff --git a/spec/relaton_bib/structured_identifier_spec.rb b/spec/relaton_bib/structured_identifier_spec.rb
deleted file mode 100644
index 0b421c1..0000000
--- a/spec/relaton_bib/structured_identifier_spec.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-RSpec.describe RelatonBib::StructuredIdentifier do
-  it "remove data for Chinise Standard" do
-    sid = RelatonBib::StructuredIdentifier.new docnumber: "TEST-1999", type: "Chinese Standard"
-    sid.remove_date
-    expect(sid.docnumber).to eq "TEST"
-  end
-end
diff --git a/spec/relaton_bib/typed_title_string_spec.rb b/spec/relaton_bib/typed_title_string_spec.rb
deleted file mode 100644
index 308197e..0000000
--- a/spec/relaton_bib/typed_title_string_spec.rb
+++ /dev/null
@@ -1,107 +0,0 @@
-RSpec.describe RelatonBib::TypedTitleString do
-  # it "raises invalid type argument error" do
-  #   expect do
-  #     RelatonBib::TypedTitleString.new type: "type", content: "title"
-  #   end.to output(/title type "type" is invalid/).to_stderr
-  # end
-
-  it "raises missed title or content argument error" do
-    expect { RelatonBib::TypedTitleString.new }.to raise_error ArgumentError
-  end
-
-  context "instance" do
-    subject do
-      RelatonBib::TypedTitleString.new(
-        type: "main",
-        title: RelatonBib::FormattedString.new(content: "Title", format: nil),
-      )
-    end
-
-    it "create instance without exeption" do
-      expect(subject).to be_instance_of RelatonBib::TypedTitleString
-    end
-
-    it "create instance with title as hash" do
-      subj = RelatonBib::TypedTitleString.new(
-        title: { content: "Title", language: "en", script: "Latn", format: "text/plain" },
-      )
-      expect(subj.title).to be_instance_of RelatonBib::FormattedString
-      expect(subj.title.content).to eq "Title"
-      expect(subj.title.language).to eq ["en"]
-      expect(subj.title.script).to eq ["Latn"]
-      expect(subj.title.format).to eq "text/plain"
-    end
-
-    it "return hash when title is string" do
-      expect(subject.to_hash).to eq("type" => "main", "content" => "Title")
-    end
-  end
-
-  context "create title-intro, title-main, title-part from string" do
-    it "empty" do
-      t = RelatonBib::TypedTitleString.from_string ""
-      expect(t.size).to eq 2
-      expect(t[0].title.content).to eq ""
-      expect(t[0].type).to eq "title-main"
-      expect(t[1].title.content).to eq ""
-      expect(t[1].type).to eq "main"
-    end
-
-    it "with main" do
-      t = RelatonBib::TypedTitleString.from_string "Main"
-      expect(t.size).to eq 2
-      expect(t[0].title.content).to eq "Main"
-      expect(t[0].type).to eq "title-main"
-      expect(t[1].title.content).to eq "Main"
-      expect(t[1].type).to eq "main"
-    end
-
-    it "with main & part" do
-      t = RelatonBib::TypedTitleString.from_string "Main - Part 1:"
-      expect(t.size).to eq 3
-      expect(t[0].title.content).to eq "Main"
-      expect(t[0].type).to eq "title-main"
-      expect(t[1].title.content).to eq "Part 1:"
-      expect(t[1].type).to eq "title-part"
-      expect(t[2].title.content).to eq "Main - Part 1:"
-      expect(t[2].type).to eq "main"
-    end
-
-    it "with intro & main" do
-      t = RelatonBib::TypedTitleString.from_string "Intro - Main"
-      expect(t.size).to eq 3
-      expect(t[0].title.content).to eq "Intro"
-      expect(t[0].type).to eq "title-intro"
-      expect(t[1].title.content).to eq "Main"
-      expect(t[1].type).to eq "title-main"
-      expect(t[2].title.content).to eq "Intro - Main"
-      expect(t[2].type).to eq "main"
-    end
-
-    it "with intro & main & part" do
-      t = RelatonBib::TypedTitleString.from_string "Intro - Main - Part 1:"
-      expect(t.size).to eq 4
-      expect(t[0].title.content).to eq "Intro"
-      expect(t[0].type).to eq "title-intro"
-      expect(t[1].title.content).to eq "Main"
-      expect(t[1].type).to eq "title-main"
-      expect(t[2].title.content).to eq "Part 1:"
-      expect(t[2].type).to eq "title-part"
-      expect(t[3].title.content).to eq "Intro - Main - Part 1:"
-      expect(t[3].type).to eq "main"
-    end
-
-    it "with extra part" do
-      t = RelatonBib::TypedTitleString.from_string "Intro - Main - Part 1: - Extra"
-      expect(t.size).to eq 4
-      expect(t[0].title.content).to eq "Intro"
-      expect(t[0].type).to eq "title-intro"
-      expect(t[1].title.content).to eq "Main"
-      expect(t[1].type).to eq "title-main"
-      expect(t[2].title.content).to eq "Part 1: -- Extra"
-      expect(t[2].type).to eq "title-part"
-      expect(t[3].title.content).to eq "Intro - Main - Part 1: -- Extra"
-      expect(t[3].type).to eq "main"
-    end
-  end
-end
diff --git a/spec/relaton_bib/typed_uri_spec.rb b/spec/relaton_bib/typed_uri_spec.rb
deleted file mode 100644
index 2da52bc..0000000
--- a/spec/relaton_bib/typed_uri_spec.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-RSpec.describe RelatonBib::TypedUri do
-  it "set content" do
-    uri = RelatonBib::TypedUri.new type: "src", content: nil
-    uri.content = "http://example.com"
-    expect(uri.content).to be_instance_of Addressable::URI
-    expect(uri.content.to_s).to eq "http://example.com"
-  end
-
-  context "instance methods" do
-    subject do
-      described_class.new type: "src", content: "http://example.com", language: "en", script: "Latn"
-    end
-
-    it "#to_xml" do
-      builder = Nokogiri::XML::Builder.new
-      subject.to_xml(builder)
-      expect(builder.doc.root.to_xml).to be_equivalent_to <<~XML
-        <uri type="src" language="en" script="Latn">http://example.com</uri>
-      XML
-    end
-
-    it "#to_asciibib" do
-      expect(subject.to_asciibib("org")).to eq <<~OUTPUT
-        org.link.type:: src
-        org.link.content:: http://example.com
-        org.link.language:: en
-        org.link.script:: Latn
-      OUTPUT
-    end
-
-    it "#to_hash" do
-      expect(subject.to_hash).to eq(
-        "content" => "http://example.com",
-        "type" => "src",
-        "language" => "en",
-        "script" => "Latn",
-      )
-    end
-  end
-end
diff --git a/spec/relaton_bib/workers_pool_spec.rb b/spec/relaton_bib/workers_pool_spec.rb
deleted file mode 100644
index 1cbbf89..0000000
--- a/spec/relaton_bib/workers_pool_spec.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-RSpec.describe RelatonBib::WorkersPool do
-  subject { RelatonBib::WorkersPool.new }
-
-  it { expect(subject).to be_instance_of RelatonBib::WorkersPool }
-
-  it "do jobs" do
-    subject.worker { |n| n * 2 }
-    (1..5).entries.each { |n| subject << n }
-    expect(subject.size).to be_instance_of Integer
-    subject.end
-    result = subject.result
-    expect(result.sort).to eq [2, 4, 6, 8, 10]
-  end
-end
diff --git a/spec/relaton_bib/xml_parser_spec.rb b/spec/relaton_bib/xml_parser_spec.rb
deleted file mode 100644
index 9e96e46..0000000
--- a/spec/relaton_bib/xml_parser_spec.rb
+++ /dev/null
@@ -1,115 +0,0 @@
-RSpec.describe RelatonBib::XMLParser do
-  it "creates item from xml" do
-    xml = File.read "spec/examples/bib_item.xml", encoding: "UTF-8"
-    item = RelatonBib::XMLParser.from_xml xml
-    expect(item.to_xml).to be_equivalent_to xml
-  end
-
-  it "creates item from bibdata xml" do
-    xml = File.read "spec/examples/bibdata_item.xml", encoding: "UTF-8"
-    item = RelatonBib::XMLParser.from_xml xml
-    expect(item.to_xml(bibdata: true)).to be_equivalent_to xml
-  end
-
-  it "parse date from" do
-    xml = <<~XML
-      <bibitem id="id">
-        <title type="main">Title</title>
-        <date type="circulated"><from>2001-02-03</from></date>
-      </bibitem>
-    XML
-    item = RelatonBib::XMLParser.from_xml xml
-    expect(item.date.first.from.to_s).to eq "2001-02-03"
-  end
-
-  it "parse locality not inclosed in localityStack" do
-    xml = <<~XML
-      <bibitem id="id">
-        <title type="main">Title</title>
-        <relation type="updates">
-          <bibitem>
-            <formattedref format="text/plain">ISO 19115</formattedref>
-          </bibitem>
-          <locality type="section">
-            <referenceFrom>Reference from</referenceFrom>
-          </locality>
-        </relation>
-      </bibitem>
-    XML
-    item = RelatonBib::XMLParser.from_xml xml
-    expect(item.relation.first.locality.first).to be_instance_of(
-      RelatonBib::Locality,
-    )
-  end
-
-  it "parse sourceLocality not inclosed in sourceLocalityStack" do
-    xml = <<~XML
-      <bibitem id="id">
-        <title type="main">Title</title>
-        <relation type="updates">
-          <bibitem>
-            <formattedref format="text/plain">ISO 19115</formattedref>
-          </bibitem>
-          <sourceLocality type="section">
-            <referenceFrom>Reference from</referenceFrom>
-          </sourceLocality>
-        </relation>
-      </bibitem>
-    XML
-    item = RelatonBib::XMLParser.from_xml xml
-    expect(item.relation.first.source_locality.first).to be_instance_of(
-      RelatonBib::SourceLocality,
-    )
-  end
-
-  context "parse abstract" do
-    it "with <br/> tag" do
-      xml = <<~XML
-        <bibitem id="id">
-          <title type="main">Title</title>
-          <abstract>Content<br/>Content</abstract>
-        </bibitem>
-      XML
-      doc = Nokogiri::XML(xml).at "/bibitem"
-      abstract = RelatonBib::XMLParser.send :fetch_abstract, doc
-      expect(abstract[0].content).to eq "Content<br/>Content"
-    end
-  end
-
-  it "ignore empty dates" do
-    xml = <<~XML
-      <bibitem id="id">
-        <title type="main">Title</title>
-        <date type="circulated" />
-      </bibitem>
-    XML
-    item = RelatonBib::XMLParser.from_xml xml
-    expect(item.date).to be_empty
-  end
-
-  it "parse formatted address" do
-    xml = <<~XML
-      <bibitem id="id">
-        <title type="main">Title</title>
-        <contributor>
-          <organization>
-            <name>Organization</name>
-            <address>
-              <formattedAddress>Address</formattedAddress>
-            </address>
-          </organization>
-        </contributor>
-      </bibitem>
-    XML
-    item = RelatonBib::XMLParser.from_xml xml
-    expect(item.contributor.first.entity.contact.first.formatted_address).to eq "Address"
-  end
-
-  it "warn if XML doesn't have bibitem or bibdata element" do
-    item = ""
-    expect { item = RelatonBib::XMLParser.from_xml "" }.to output(
-      /Can't find bibitem/,
-    ).to_stderr_from_any_process
-    expect(item).to be_nil
-  end
-end
diff --git a/spec/relaton_bib_spec.rb b/spec/relaton_bib_spec.rb
deleted file mode 100644
index 8f9279d..0000000
--- a/spec/relaton_bib_spec.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-RSpec.describe RelatonBib do
-  it "has a version number" do
-    expect(RelatonBib::VERSION).not_to be nil
-  end
-
-  it "returns grammar hash" do
-    hash = RelatonBib.grammar_hash
-    expect(hash).to be_instance_of String
-    expect(hash.size).to eq 32
-  end
-
-  context "parse date" do
-    it "February 2012" do
-      expect(RelatonBib.parse_date("February 2012")).to eq "2012-02"
-      expect(RelatonBib.parse_date("February 2012", false)).to eq Date.new(2012, 2, 1)
-    end
-
-    it "February 11, 2012" do
-      expect(RelatonBib.parse_date("February 11, 2012")).to eq "2012-02-11"
-      expect(RelatonBib.parse_date("February 11, 2012", false)).to eq Date.new(2012, 2, 11)
-    end
-
-    it "2012-02-11" do
-      expect(RelatonBib.parse_date("2012-02-11")).to eq "2012-02-11"
-      expect(RelatonBib.parse_date("2012-02-11", false)).to eq Date.new(2012, 2, 11)
-    end
-
-    it "2012-2-3" do
-      expect(RelatonBib.parse_date("2012-2-3")).to eq "2012-02-03"
-      expect(RelatonBib.parse_date("2012-2-3", false)).to eq Date.new(2012, 2, 3)
-    end
-
-    it "2012-02" do
-      expect(RelatonBib.parse_date("2012-02")).to eq "2012-02"
-      expect(RelatonBib.parse_date("2012-02", false)).to eq Date.new(2012, 2, 1)
-    end
-
-    it "2012-2" do
-      expect(RelatonBib.parse_date("2012-2")).to eq "2012-02"
-      expect(RelatonBib.parse_date("2012-2", false)).to eq Date.new(2012, 2, 1)
-    end
-
-    it "invalid date" do
-      expect do
-        expect(RelatonBib.parse_date("2012-02-31")).to eq "2012-02-31"
-      end.to output(/invalid date/).to_stderr_from_any_process
-    end
-  end
-
-  it "parse YAML with an old version of Psych" do
-    method = double "params"
-    expect(method).to receive(:parameters).and_return [%i[req yaml]]
-    expect(YAML).to receive(:method).with(:safe_load).and_return method
-    expect(YAML).to receive(:safe_load).with(kind_of(String), [], symbolize_names: false).and_return({})
-    RelatonBib.parse_yaml "key: value"
-  end
-
-  it "parse YAML with a new version of Psych" do
-    method = double "params"
-    expect(method).to receive(:parameters).and_return [%i[req yaml permitted_classes]]
-    expect(YAML).to receive(:method).with(:safe_load).and_return method
-    expect(YAML).to receive(:safe_load)
-      .with(kind_of(String), permitted_classes: [], symbolize_names: false)
-      .and_return({})
-    RelatonBib.parse_yaml "key: value"
-  end
-end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index c683247..e78b555 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -2,9 +2,10 @@
 SimpleCov.start { add_filter "/spec/" }
 
 require "bundler/setup"
-require "relaton_bib"
+require "relaton/bib"
 require "rspec/matchers"
 require "equivalent-xml"
+require "jing"
 
 RSpec.configure do |config|
   # Enable flags like --only-failures and --next-failure