Replace index.html with alternate2.html except examples in intro
authorMarkus Lanthaler <mark_lanthaler@gmx.net>
Tue, 12 Feb 2013 19:50:01 +0100
changeset 1230 1e41c58e5eca
parent 1229 cb2c96483876
child 1231 2ba2c2f8f093
Replace index.html with alternate2.html except examples in intro

I kept the examples that use FOAF and for the time being the old flattening example. I adjusted the indentation of the merged text so that it's easier to see what stayed there unchanged. I also kept the "conflicting indexes" error code instead of "CONFLICTING_ANNOTATIO" as in alternate2.html, and the document head. All the rest has been merged as is was in alternate2.html.

I renamed the old index.html to markus.html.
spec/latest/json-ld-api/alternate2.html
spec/latest/json-ld-api/index.html
spec/latest/json-ld-api/markus.html
spec/latest/json-ld-api/merge-index-alternate2.html
--- a/spec/latest/json-ld-api/alternate2.html	Tue Feb 12 19:04:34 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4940 +0,0 @@
-<html>
-<head>
-<title>JSON-LD 1.0 Processing Algorithms and API</title>
-<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
-<script type="text/javascript" src="../respec-w3c-common.js" class="remove"></script>
-<script type="text/javascript" src="../respec-w3c-extensions.js" class="remove"></script>
-<script type="text/javascript" class="remove">
-//<![CDATA[
-  var respecConfig = {
-      // extend the bibliography entries
-      "localBiblio": localBibliography,
-
-      doRDFa: "1.1",
-      // specification status (e.g. WD, LCWD, NOTE, etc.). If in doubt use ED.
-      specStatus:           "ED",
-      // if you wish the publication date to be other than today, set this
-      //publishDate:          "2012-12-25",
-      copyrightStart:       "2010",
-
-      // the specification's short name, as in http://www.w3.org/TR/short-name/
-      shortName:            "json-ld-api",
-
-      // if there is a previously published draft, uncomment this and set its YYYY-MM-DD date
-      // and its maturity status
-      previousPublishDate:  "2012-09-30",
-      previousMaturity:     "ED",
-      previousURI:          "http://dvcs.w3.org/hg/json-ld/raw-file/66d980964784/spec/ED/json-ld-api/20120930/index.html",
-
-      // if there a publicly available Editor's Draft, this is the link
-      edDraftURI:           "http://json-ld.org/spec/latest/json-ld-api/index.html",
-
-      testSuiteURI:         "http://json-ld.org/test-suite/",
-
-      // if this is a LCWD, uncomment and set the end of its review period
-      // lcEnd: "2009-08-05",
-
-      // if you want to have extra CSS, append them to this list
-      // it is recommended that the respec.css stylesheet be kept
-      // extraCSS: [],
-
-      issueBase: "https://github.com/json-ld/json-ld.org/issues/",
-
-      // editors, add as many as you like
-      // only "name" is required
-      editors:  [
-          { name: "Markus Lanthaler", url: "http://www.markus-lanthaler.com/",
-            company: "Graz University of Technology", companyURL: "http://www.tugraz.at/" },
-          { name: "Gregg Kellogg", url: "http://greggkellogg.net/",
-            company: "Kellogg Associates", companyURL: "http://kellogg-assoc.com/" },
-          { name: "Manu Sporny", url: "http://manu.sporny.org/",
-            company: "Digital Bazaar", companyURL: "http://digitalbazaar.com/" },
-          { name: "Dave Longley", url: "http://digitalbazaar.com/",
-            company: "Digital Bazaar", companyURL: "http://digitalbazaar.com/"}
-      ],
-
-      // authors, add as many as you like.
-      // This is optional, uncomment if you have authors as well as editors.
-      // only "name" is required. Same format as editors.
-
-      authors:  [
-          { name: "Dave Longley", url: "http://digitalbazaar.com/",
-            company: "Digital Bazaar", companyURL: "http://digitalbazaar.com/"},
-          { name: "Gregg Kellogg", url: "http://greggkellogg.net/",
-            company: "Kellogg Associates", companyURL: "http://kellogg-assoc.com/" },
-          { name: "Markus Lanthaler", url: "http://www.markus-lanthaler.com/",
-            company: "Graz University of Technology", companyURL: "http://www.tugraz.at/" },
-          { name: "Manu Sporny", url: "http://manu.sporny.org/",
-            company: "Digital Bazaar", companyURL: "http://digitalbazaar.com/" }
-      ],
-
-      // name of the WG
-      wg:           "RDF Working Group",
-
-      // URI of the public WG page
-      wgURI:        "http://www.w3.org/2011/rdf-wg/",
-
-      // name (with the @w3c.org) of the public mailing to which comments are due
-      wgPublicList: "public-rdf-comments",
-
-      // URI of the patent status for this WG, for Rec-track documents
-      // !!!! IMPORTANT !!!!
-      // This is important for Rec-track documents, do not copy a patent URI from a random
-      // document unless you know what you're doing. If in doubt ask your friendly neighbourhood
-      // Team Contact.
-      wgPatentURI:  "http://www.w3.org/2004/01/pp-impl/46168/status",
-      maxTocLevel: 3,
-      preProcess: [ preProc ],
-      alternateFormats: [ {uri: "diff-20120930.html", label: "diff to previous version"} ],
-  };
-//]]>
-</script>
-<style type="text/css">
-  .diff { font-weight:bold; color:#0a3; }
-</style>
-</head>
-
-<body>
-<section id="abstract">
-
-<p>
-JSON [[!RFC4627]] has proven to be a highly useful object serialization and
-messaging format. JSON-LD [[!JSON-LD]] harmonizes the representation of
-Linked Data in JSON by outlining a common JSON representation format for
-expressing directed graphs, mixing both Linked Data and non-Linked Data in
-a single document. This document outlines an Application Programming
-Interface and a set of algorithms for programmatically transforming
-JSON-LD documents to make them easier to work with in programming
-environments like those that use JavaScript, Python, and Ruby.
-</p>
-
-</section>
-
-<section id="sotd">
-
-<p>
-This document has been under development for over 18 months in the
-JSON for Linking Data Community Group. The document has recently been
-transferred to the RDF Working Group for review, improvement, and publication
-along the Recommendation track. The specification has undergone significant
-development, review, and changes during the course of the last 18 months.
-</p>
-<p>
-There are several independent
-<a href="http://json-ld.org/#impl">interoperable implementations</a> of
-this specification. There is
-a <a href="https://github.com/json-ld/json-ld.org/tree/master/test-suite">fairly complete test suite</a>
-and a <a href="http://json-ld.org/playground/">live JSON-LD editor</a>
-that is capable of demonstrating the features described in
-this document. While there will be continuous development on implementations,
-the test suite, and the live editor, they are believed to be mature enough
-to be integrated into a non-production system at this point in time. There
-is an expectation that they could be used in a production system within the
-year.
-</p>
-<p class="issue">
-It is important for readers to understand that the scope of this document is
-currently under debate and new features may be added to the specification.
-Existing features may be modified heavily or removed entirely from the
-specification upon further review and feedback from the broader community.
-This is a work in progress and publication as a Working Draft
-does not require that all Working Group members agree on the content of the
-document.
-</p>
-
-<p>
-There are a number of ways that you may participate in the development of
-this specification:
-</p>
-
-<ul>
-  <li>If you want to make sure that your feedback is formally addressed by
-    the RDF Working Group, you should send it to public-rdf-comments:
-    <a href="http://lists.w3.org/Archives/Public/public-rdf-comments/">public-rdf-comments@w3.org</a></li>
-
-  <li>Ad-hoc technical discussion primarily occurs on the public community mailing list:
-    <a href="http://lists.w3.org/Archives/Public/public-linked-json/">public-linked-json@w3.org</a></li>
-
-  <li><a href="http://json-ld.org/minutes/">Public JSON-LD Community Group teleconferences</a>
-    are held on Tuesdays at 1500UTC every week. Participation is open to the
-    public.</li>
-
-  <li>RDF Working Group teleconferences are held on Wednesdays at 1500UTC
-    every week. Participation is limited to RDF Working Group members.</li>
-
-  <li>Specification bugs and issues should be reported in the
-    <a href="https://github.com/json-ld/json-ld.org/issues">issue tracker</a>
-    if you do not want to send an email to the public-rdf-comments mailing
-    list.</li>
-
-  <li><a href="https://github.com/json-ld/json-ld.org/tree/master/spec">Source code</a>
-    for the specification can be found on Github.</li>
-
-  <li>The <a href="http://webchat.freenode.net/?channels=json-ld">#json-ld</a>
-    IRC channel is available for real-time discussion on irc.freenode.net.</li>
-</ul>
-
-</section>
-
-<section class="informative">
-<h2>Introduction</h2>
-
-<p>
-This document is a detailed specification for an Application Programming
-Interface for the JSON-LD Syntax. The document is primarily intended for
-the following audiences:
-</p>
-
-<ul>
-  <li>Web authors and developers that want a very detailed view of how
-    a JSON-LD processor and the API operates.</li>
-  <li>Software developers that want to implement processors and APIs for
-    JSON-LD documents.</li>
-</ul>
-
-<p>
-To understand the basics in this specification you must first be familiar with
-JSON, which is detailed in [[!RFC4627]]. You must also understand the
-JSON-LD Syntax [[!JSON-LD]], which is the base syntax used by all of the
-algorithms in this document. To understand the API and how it is
-intended to operate in a programming environment, it is useful to have working
-knowledge of the JavaScript programming language [[ECMA-262]] and
-WebIDL [[!WEBIDL]]. To understand how JSON-LD maps to RDF, it is helpful to be
-familiar with the basic RDF concepts [[!RDF-CONCEPTS]].
-</p>
-
-</section>
-
-<section class="informative">
-<h1>Features</h1>
-
-<p>
-The JSON-LD Syntax specification [[!JSON-LD]] outlines a syntax that may be
-used to express Linked Data in JSON. Because there is more than one way to
-express Linked Data using this syntax, it is often useful to be able to
-transform JSON-LD documents so that they may be more easily consumed by
-specific applications.
-</p>
-
-<p>
-There are four major types of transformation that are discussed in this
-document: expansion, compaction, flattening, and RDF conversion.
-</p>
-
-<section class="informative">
-<h2>Expansion</h2>
-
-<p>
-JSON-LD allows <tref>context</tref> to be applied to JSON data. Applying
-<tref>context</tref> to JSON data allows it to be expressed in a way that
-is specifically tailored to a particular person or application. A common
-use case occurs when an application or person wants to use data that was
-created using a different <tref>context</tref> than they would prefer.
-Therefore, a JSON-LD processor must be able to transform the data from
-one <tref>context</tref> to another. Instead of requiring JSON-LD processors
-to write specific code for every imaginable <tref>context</tref> switching
-scenario, it is much easier to specify a single algorithm that can remove
-any <tref>context</tref> (and another that can subsequently apply any
-<tref>context</tref>). The algorithm that removes <tref>context</tref> is
-called <tdef>expansion</tdef>.
-</p>
-
-<p>
-To get an idea of how context and data structuring affects the same data,
-here is an example of JSON-LD that uses only <tref title="term">terms</tref>
-and is fairly compact:
-</p>
-
-<pre class="example" data-transform="updateExample"
-  title="Sample JSON-LD document">
-<!--
-{
-  "@context": {
-    "name": "http://schema.org/name",
-    "homepage": {
-      "@id": "http://schema.org/url",
-      "@type": "@id"
-    }
-  },
-  "@id": "http://me.markus-lanthaler.com/",
-  "name": "Markus Lanthaler",
-  "homepage": "http://www.markus-lanthaler.com/"
-}
--->
-</pre>
-
-<p>
-The next input example uses one <tref>IRI</tref> to express a property
-and <tref title="array">array</tref> to encapsulate another, but
-leaves the rest of the information untouched.
-</p>
-
-<pre class="example" data-transform="updateExample"
-  title="Sample JSON-LD document using a IRI instead of a term to express a property">
-<!--
-{
-  "@context": {
-    "homepage": {
-      "@id": "http://schema.org/url",
-      "@type": "@id"
-    }
-  },
-  "@id": "http://me.markus-lanthaler.com/",
-  "****http://schema.org/name****": "Markus Lanthaler",
-  "homepage": ****[****"http://www.markus-lanthaler.com/"****]****
-}
--->
-</pre>
-
-<p>
-Note that both inputs are valid JSON-LD and both represent the same
-information. The difference is in their <tref>context</tref> information
-and in the data structures used. A JSON-LD processor can remove
-<tref>context</tref> and ensure that the data is more regular by employing
-<tref>expansion</tref>.
-</p>
-
-<p>
-<tref>Expansion</tref> has two important goals: ensuring all values
-are represented in a regular form, and removing any contextual information
-from the document. These goals are accomplished by expanding all properties
-to <tref title="absolute IRI">absolute IRIs</tref> and by expressing all
-values in <tref title="array">arrays</tref> in
-<tref>expanded form</tref>. <tref>Expanded form</tref> is the most verbose
-and regular way of expressing of values in JSON-LD; all contextual
-information from the document is instead stored locally with each value.
-Running the <a href="#expansion-algorithm">Expansion algorithm</a> against
-the examples provided above results in the following output:
-</p>
-
-<pre class="example" data-transform="updateExample"
-  title="Expanded sample document">
-<!--
-[
-  {
-    "@id": "http://me.markus-lanthaler.com/",
-    "http://schema.org/name": [
-      { "@value": "Markus Lanthaler" }
-    ],
-    "http://schema.org/url": [
-      { "@id": "http://www.markus-lanthaler.com/" }
-    ]
-  }
-]
--->
-</pre>
-
-<p>
-Note that in the output above all <tref>context</tref> definitions have
-been removed, all <tref title="term">terms</tref> and
-<tref title="compact IRI">compact IRIs</tref> have been expanded to absolute
-<tref title="IRI">IRIs</tref>, and all
-<tref title="JSON-LD value">JSON-LD values</tref> are expressed in
-<tref title="array">arrays</tref> in <tref>expanded form</tref>. While the
-output is more verbose and difficult for a human to read, it establishes a
-baseline that makes JSON-LD processing easier because of its very regular
-structure.
-</p>
-
-</section>
-
-<section class="informative">
-<h2>Compaction</h2>
-
-<p>
-While <tref>expansion</tref> removes <tref>context</tref> from a given
-input, <tref title="compaction">compaction's</tref> primary function is to
-perform the opposite operation: to express a given input according to
-a particular <tref>context</tref>. <tdef>Compaction</tdef> applies a
-<tref>context</tref> that specifically tailors the way information is
-expressed for a particular person or application. This simplifies applications
-that consume JSON or JSON-LD by expressing the data in application-specific
-terms, and it makes the data easier to read by humans.
-
-<tref>Compaction</tref> uses a developer-supplied <tref>context</tref> to
-shorten <tref title="IRI">IRIs</tref> to <tref title="term">terms</tref> or
-<tref title="compact IRI">compact IRIs</tref> and
-<tref title="JSON-LD value">JSON-LD values</tref>
-expressed in <tref>expanded form</tref> to simple values such as
-<tref title="string">strings</tref> or
-<tref title="number">numbers</tref>.
-</p>
-
-<p>
-For example, assume the following expanded JSON-LD input document:
-</p>
-
-<pre class="example" data-transform="updateExample"
-  title="Expanded sample document">
-<!--
-[
-  {
-    "@id": "http://me.markus-lanthaler.com/",
-    "http://schema.org/name": [
-      { "@value": "Markus Lanthaler" }
-    ],
-    "http://schema.org/url": [
-      { "@id": "http://www.markus-lanthaler.com/" }
-    ]
-  }
-]
--->
-</pre>
-
-<p>
-Additionally, assume the following developer-supplied JSON-LD <tref>context</tref>:
-</p>
-
-<pre class="example" data-transform="updateExample"
-  title="JSON-LD context">
-<!--
-{
-  "@context": {
-    "name": "http://schema.org/name",
-    "homepage": {
-      "@id": "http://schema.org/url",
-      "@type": "@id"
-    }
-  }
-}
--->
-</pre>
-
-<p>
-Running the <a href="#compaction-algorithm">Compaction Algorithm</a> given
-the context supplied above against the JSON-LD input document provided above
-would result in the following output:
-</p>
-
-<pre class="example" data-transform="updateExample"
-  title="Compacted sample document">
-<!--
-{
-  "@context": {
-    "name": "http://schema.org/name",
-    "homepage": {
-      "@id": "http://schema.org/url",
-      "@type": "@id"
-    }
-  },
-  "@id": "http://me.markus-lanthaler.com/",
-  "name": "Markus Lanthaler",
-  "homepage": "http://www.markus-lanthaler.com/"
-}
--->
-</pre>
-
-<p>
-Note that all <tref title="IRI">IRIs</tref> have been compacted to
-<tref title="term">terms</tref> as specified in the <tref>context</tref>,
-which has been injected into the output. While compacted output is
-useful to humans, it is also used to generate structures that are easy to
-program against. Compaction enables developers to map any expanded document
-into an application-specific compacted document. While the context provided
-above mapped <code>http://schema.org/name</code> to <code>name</code>, it
-could also have been mapped to any other term provided by the developer.
-</p>
-
-</section>
-
-<section class="informative">
-<h2>Flattening</h2>
-
-<p>
-While expansion ensures that a document is in a uniform structure,
-flattening goes a step further to ensure that the shape of the data
-is deterministic. In expanded documents, the properties of a single
-properties of a single <tref>node</tref> may be spread across a number of
-different <tref title="JSON object">JSON objects</tref>. By flattening a
-document, all properties of a <tref>node</tref> are collected in a single
-<tref>JSON object</tref>. This may drastically simplify the code required
-to process JSON-LD data in certain applications.
-</p>
-
-<p>
-For example, assume the following JSON-LD input document:
-</p>
-
-<pre class="example" data-transform="updateExample"
-  title="Sample JSON-LD document">
-<!--
-{
-  "@context": {
-    "name": "http://schema.org/name",
-    "knows": "http://schema.org/knows"
-  },
-  "@id": "http://digitalbazaar.com/people/dlongley",
-  ****"knows"****: {
-    "@id": "http://digitalbazaar.com/people/msporny",
-    "name": "Manu Sporny",
-    "knows": {
-      "@id": "http://digitalbazaar.com/people/dlongley",
-      ****"name"****: "Dave Longley"
-    }
-  }
-}
--->
-</pre>
-
-<p>
-Running the <a href="#flattening-algorithm">Flattening Algorithm</a>
-with a context set to <tref>null</tref> to prevent compaction returns
-the following document:
-</p>
-
-<pre class="example" data-transform="updateExample"
-  title="Flattened sample document in expanded form">
-<!--
-[
-  ****{****
-    "@id": "http://digitalbazaar.com/people/dlongley",
-    ****"http://schema.org/name"****: [
-      { "@value": "Dave Longley" }
-    ],
-    ****"http://schema.org/knows"****: [
-      { "@id": "http://digitalbazaar.com/people/msporny" }
-    ]
-  ****}****,
-  {
-    "@id": "http://digitalbazaar.com/people/msporny",
-    "http://schema.org/name": [
-      { "@value": "Manu Sporny" }
-    ],
-    "http://schema.org/knows": [
-      { "@id": "http://digitalbazaar.com/people/dlongley" }
-    ]
-  }
-]
--->
-</pre>
-
-<p>
-Note how in the output above all properties of a <tref>node</tref> are
-collected in a single <tref>JSON object</tref>.
-</p>
-
-<p>
-To make it easier for humans to read or for certain applications to
-process it, a flattened document can be compacted by passing a context. Using
-the same context as the input document, the flattened and compacted document
-looks as follows:
-</p>
-
-<pre class="example" data-transform="updateExample"
-  title="Flattened and compacted sample document">
-<!--
-{
-  "@context": {
-    "name": "http://schema.org/name",
-    "knows": "http://schema.org/knows"
-  },
-  "@graph": [
-    ****{****
-      "@id": "http://digitalbazaar.com/people/dlongley",
-      ****"name"****: "Dave Longley",
-      ****"knows"****: [
-        { "@id": "http://digitalbazaar.com/people/msporny" }
-      ]
-    ****}****,
-    {
-      "@id": "http://digitalbazaar.com/people/msporny",
-      "name": "Manu Sporny",
-      "knows": {
-        "@id": "http://digitalbazaar.com/people/dlongley"
-      }
-    }
-  ]
-}
--->
-</pre>
-
-<p>
-Please note that the flattened and compacted result will explicitly
-designate the default graph by the <code>@graph</code> member in the
-top-level <tref>JSON object</tref>, except if its value contains just
-one item.
-</p>
-
-</section>
-
-<section class="informative">
-<h2>RDF Conversion</h2>
-
-<p>
-JSON-LD can be used to serialize data expressed in RDF as described in
-[[RDF-CONCEPTS]]. This ensures that data can be round-tripped to and from
-any RDF syntax without any loss in fidelity.
-</p>
-
-<p>
-For example, assume the following RDF input serialized in Turtle [[TURTLE-TR]]:
-</p>
-
-<pre class="example" data-transform="updateExample"
-  title="Sample Turtle document">
-<!--
-<http://me.markus-lanthaler.com/> <http://schema.org/name> "Markus Lanthaler" .
-<http://me.markus-lanthaler.com/> <http://schema.org/url> <http://www.markus-lanthaler.com/> .
--->
-</pre>
-
-<p>
-Using the <a href="#convert-from-rdf-algorithm">Convert from RDF Algorithm</a>
-a developer could transform this document into expanded JSON-LD:
-</p>
-
-<pre class="example" data-transform="updateExample"
-  title="Sample Turtle document converted to JSON-LD">
-<!--
-[
-  {
-    "@id": "http://me.markus-lanthaler.com/",
-    "http://schema.org/name": [
-      {
-        "@value": "Markus Lanthaler"
-      }
-    ],
-    "http://schema.org/url": [
-      {
-        "@id": "http://www.markus-lanthaler.com/"
-      }
-    ]
-  }
-]
--->
-</pre>
-
-<p>
-Note that the output above could easily be compacted using the technique
-outlined in the previous section. It is also possible to transform the
-JSON-LD document back to RDF using the
-<a href="#convert-to-rdf-algorithm">Convert to RDF Algorithm</a>.
-</p>
-
-</section>
-
-<!-- end of Features -->
-</section>
-
-<section>
-<h1>Conformance</h1>
-
-<p>
-All examples and notes as well as sections marked as non-normative in this
-specification are non-normative. Everything else in this specification is
-normative.
-</p>
-
-<p>
-The keywords MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, RECOMMENDED,
-MAY, and OPTIONAL in this specification are to be interpreted as described
-in [[!RFC2119]].
-</p>
-
-<p>
-There are two classes of products that can claim conformance to this
-specification: <tref title="JSON-LD Implementation">JSON-LD Implementations</tref>
-and <tref title="JSON-LD Processor">JSON-LD Processors</tref>.
-</p>
-
-<p>
-A conforming <tdef>JSON-LD Implementation</tdef> is a system capable of
-transforming JSON-LD documents according the algorithms defined in this
-specification.
-</p>
-
-<p>
-A conforming <tdef>JSON-LD Processor</tdef> is a conforming
-<tref>JSON-LD Implementation</tref> that exposes the Application Programming
-Interface (API) defined in this specification.</p>
-
-<p>
-The algorithms in this specification are generally written with more concern
-for clarity than efficiency. Thus, JSON-LD Implementations and Processors
-may implement the algorithms given in this specification in any way desired,
-so long as the end result is indistinguishable from the result that would be
-obtained by the specification's algorithms.
-</p>
-
-<p>
-This specification does not define how JSON-LD Implementations or Processors
-handle non-conforming input documents. This implies that JSON-LD Implementations
-or Processors MUST NOT attempt to correct malformed <tref title="IRI">IRIs</tref>
-or language tags; however, they MAY issue validation warnings. IRIs are not
-modified other than converted between <tref title="relative IRI">relative</tref>
-and <tref title="absolute IRI">absolute IRIs</tref>.
-</p>
-
-<p class="note">
-Implementers can partially check their level of conformance to this
-specification by successfully passing the test cases of the JSON-LD test
-suite [[JSON-LD-TESTS]]. Note, however, that passing all the tests in the test
-suite does not imply complete conformance to this specification. It only
-implies that the implementation conforms to aspects tested by the test suite.
-</p>
-
-</section>
-
-<section>
-<h1>General Terminology</h1>
-
-<p>
-This document uses the following terms as defined in JSON [[!RFC4627]]. Refer
-to the <em>JSON Grammar</em> section in [[!RFC4627]] for formal definitions.</p>
-
-<dl>
-  <dt><tdef>JSON object</tdef></dt>
-  <dd>An object structure is represented as a pair of curly brackets
-    surrounding zero or more key-value pairs. A key is a
-    <tref>string</tref>. A single colon comes after each key, separating the
-    key from the value. A single comma separates a value from a following
-    key.</dd>
-  <dt><tdef>array</tdef></dt>
-  <dd>An array structure is represented as square brackets surrounding zero
-    or more values (or elements). Elements are separated by commas.
-    In JSON, an array is an <em>ordered</em> sequence of zero or more values.
-    While JSON-LD uses the same array representation as JSON,
-    the collection is <em>unordered</em> by default. While order is
-    preserved in regular JSON arrays, it is not in regular JSON-LD arrays
-    unless specific markup is provided (see <a href="#sets-and-lists"></a>).</dd>
-  <dt><tdef>string</tdef></dt>
-  <dd>A string is a sequence of zero or more Unicode characters,
-    wrapped in double quotes, using backslash escapes (if necessary). A
-    character is represented as a single character string.</dd>
-  <dt><tdef>number</tdef></dt>
-  <dd>A number is similar to that used in most programming languages, except
-    that the octal and hexadecimal formats are not used and that leading
-    zeros are not allowed.</dd>
-  <dt><tdef>true</tdef> and <tdef>false</tdef></dt>
-  <dd>Values that are used to express one of two possible boolean states.</dd>
-  <dt><tdef>null</tdef></dt>
-  <dd>The <tref>null</tref> value. A key-value pair in the
-    <code>@context</code> where the value, or the <code>@id</code> of the
-    value, is <tref>null</tref> explicitly decouples a term's association
-    with an IRI. A key-value pair in the body of a JSON-LD document whose
-    value is <tref>null</tref> has the same meaning as if the key-value pair
-    was not defined. If <code>@value</code>, <code>@list</code>, or
-    <code>@set</code> is set to <tref>null</tref> in expanded form, then
-    the entire <tref>JSON object</tref> is ignored.</dd>
-</dl>
-
-<p>Furthermore, the following terminology is used throughout this document:</p>
-
-<dl>
-  <dt><tdef>keyword</tdef></dt>
-  <dd>A JSON key that is specific to JSON-LD, specified in the JSON-LD Syntax specification [[!JSON-LD]]
-    in the section titled <cite><a href="../json-ld-syntax/#syntax-tokens-and-keywords">Syntax Tokens and Keywords</a></cite>.</dd>
-  <dt><tdef>context</tdef></dt>
-  <dd>A a set of rules for interpreting a JSON-LD document as specified in
-    <cite><a href="../json-ld-syntax/#the-context">The Context</a></cite> of the [[JSON-LD]] specification.</dd>
-  <dt><tdef>JSON-LD document</tdef></dt>
-  <dd>A <tref>JSON-LD document</tref> is a serialization of a collection of
-    <tref title="JSON-LD graph">JSON-LD graphs</tref> and comprises exactly one
-    <tref>default graph</tref> and zero or more <tref title="named graph">named graphs</tref>.</dd>
-  <dt><tdef>named graph</tdef></dt>
-  <dd>A named graph is a pair consisting of an <tref>IRI</tref> or <tref>blank node</tref>
-    (the <tdef>graph name</tdef>) and a <tref>JSON-LD graph</tref>.</dd>
-  <dt><tdef>default graph</tdef></dt>
-  <dd>The default graph is the only graph in a JSON-LD document which has no <tref>graph name</tref>.</dd>
-  <dt><tdef>JSON-LD graph</tdef></dt>
-  <dd>A labeled directed graph, i.e., a set of <tref title="node">nodes</tref> connected by <tref title="edge">edges</tref>,
-    as specified in the <cite><a href="../json-ld-syntax/#data-model">Data Model</a></cite> section of the JSON-LD syntax
-    specification [[!JSON-LD]].</dd>
-  <dt><tdef>edge</tdef></dt>
-  <dd>Every <tref>edge</tref> has a direction associated with it and is labeled with
-    an <tref>IRI</tref> or a <tref>blank node identifier</tref>. Within the JSON-LD syntax
-    these edge labels are called <tdef title="property">properties</tdef>. Whenever possible, an
-    <tref>edge</tref> SHOULD be labeled with an <tref>IRI</tref>.</dd>
-  <dt><tdef>node</tdef></dt>
-  <dd>Every <tref>node</tref> is an <tref>IRI</tref>, a <tref>blank node</tref>,
-    a <tref>JSON-LD value</tref>, or a <tref>list</tref>.</dd>
-  <dt><tdef><abbr title="Internationalized Resource Identifier">IRI</abbr></tdef></dt>
-  <dd>An <tref>IRI</tref> (Internationalized Resource Identifier) is a string that conforms to the syntax
-    defined in [[RFC3987]].</dd>
-  <dt><tdef>absolute IRI</tdef></dt>
-  <dd>An absolute IRI is defined in [[!RFC3987]] containing a <em>scheme</em> along with a <em>path</em> and
-    optional <em>query</em> and fragment segments.</dd>
-  <dt><tdef>relative IRI</tdef></dt>
-  <dd>A relative IRI is an IRI that is relative some other <tref>absolute IRI</tref>;
-    in the case of JSON-LD this is the base location of the document.</dd>
-  <dt><tdef>blank node</tdef></dt>
-  <dd>A <tref>node</tref> in a <tref>JSON-LD graph</tref> that does not contain a de-referenceable
-    identifier because it is either ephemeral in nature or does not contain information that needs to be
-    linked to from outside of the JSON-LD graph.</dd>
-  <dt><tdef>blank node identifier</tdef></dt>
-  <dd>A blank node identifier is a string that can be used as an identifier for a <tref>blank node</tref> within
-    the scope of a JSON-LD document. Blank node identifiers begin with <code>_:</code>.</dd>
-  <dt><tdef>JSON-LD value</tdef></dt>
-  <dd>A <tref>JSON-LD value</tref> is a <tref>string</tref>, a <tref>number</tref>,
-    <tref>true</tref> or <tref>false</tref>, a <tref>typed value</tref>, or a
-    <tref>language-tagged string</tref>.</dd>
-  <dt><tdef>typed value</tdef></dt>
-  <dd>A <tref>typed value</tref> consists of a value, which is a string, and a type, which is an <tref>IRI</tref>.</dd>
-  <dt><tdef>language-tagged string</tdef></dt>
-  <dd>A <tref>language-tagged string</tref> consists of a string and a non-empty language
-    tag as defined by [[BCP47]]. The language tag must be well-formed according to section
-    <a href="http://tools.ietf.org/html/bcp47#section-2.2.9">2.2.9</a> of [[BCP47]], and MUST
-    be normalized to lowercase.</dd>
-  <dt><tdef>list</tdef></dt>
-  <dd>A <tref>list</tref> is an ordered sequence of <tref title="IRI">IRIs</tref>,
-    <tref title="blank node">blank nodes</tref>, and
-    <tref title="JSON-LD value">JSON-LD values</tref>.</dd>
-</dl>
-
-</section>
-
-<section>
-<h1>Algorithms</h1>
-
-<p>
-All algorithms described in this section are intended to operate on
-language-native data structures. That is, the serialization to a text-based
-JSON document isn't required as input or output to any of these algorithms and
-language-native data structures MUST be used where applicable.
-</p>
-
-<section>
-<h2>Algorithm Terms</h2>
-
-<dl>
-  <dt><tdef>active graph</tdef></dt>
-  <dd>The name of the currently active graph that the processor should use when
-    processing.</dd>
-  <dt><tdef>active subject</tdef></dt>
-  <dd>The currently active subject that the processor should use when
-    processing.</dd>
-  <dt><tdef>active property</tdef></dt>
-  <dd>The currently active property that the processor should use when
-    processing. The active property is represented in the original lexical form, which
-    is used for finding type mappings in the <tref>active context</tref>.</dd>
-  <dt><tdef>active object</tdef></dt>
-  <dd>The currently active object that the processor should use when
-    processing.</dd>
-  <dt><tdef>active context</tdef></dt>
-  <dd>A context that is used to resolve <tref title="term">terms</tref> while
-    the processing algorithm is running.</dd>
-  <dt><tdef>local context</tdef></dt>
-  <dd>A context that is specified within a <tref>JSON object</tref>,
-    specified via the <code>@context</code> <tref>keyword</tref>.</dd>
-  <dt><tdef>JSON-LD input</tdef></dt>
-  <dd>The JSON-LD data structure that is provided as input to the algorithm.</dd>
-  <dt><tdef>JSON-LD output</tdef></dt>
-  <dd>The JSON-LD data structure that is produced as output by the algorithm.</dd>
-  <dt><tdef>term</tdef></dt>
-  <dd>A <tref>term</tref> is a short word defined in a context that MAY be expanded to an <tref>IRI</tref></dd>
-  <dt><tdef>compact IRI</tdef></dt>
-  <dd>A compact IRI is has the form of <tdef>prefix</tdef>:<em>suffix</em> and is used as a way
-    of expressing an IRI without needing to define separate <tref>term</tref> definitions for
-    each IRI contained within a common vocabulary identified by <tref>prefix</tref>.</dd>
-  <dt><tdef>node object</tdef></dt>
-  <dd>A <tref>node object</tref> represents zero or more properties of a
-    <tref>node</tref> in the <tref>JSON-LD graph</tref> serialized by the
-    JSON-LD document. A <tref>JSON object</tref> is a <tref>node object</tref>
-    if it exists outside of the JSON-LD <tref>context</tref> and:
-    <ul>
-      <li>it does not contain the <code>@value</code>, <code>@list</code>,
-        or <code>@set</code> keywords, or</li>
-      <li>it is not the top-level <tref>JSON object</tref> in the JSON-LD document containing
-        the <code>@graph</code> keyword.</li>
-    </ul>
-  </dd>
-  <dt><tdef>list object</tdef></dt>
-  <dd>A <tref>list object</tref> is a <tref>JSON object</tref> that has an <code>@list</code>
-    member.</dd>
-  <dt><tdef>scalar</tdef></dt>
-  <dd>A scalar is either a JSON <tref>string</tref>, <tref>number</tref>, <tref>true</tref>,
-    or <tref>false</tref>.</dd>
-  <dt><tdef>quad</tdef></dt>
-  <dd>An <em>RDF triple</em> as specified by [[RDF-CONCEPTS]] augmented with
-    a fourth component, a <tref>graph name</tref>.</dd>
-  <dt><tdef>RDF subject</tdef></dt>
-  <dd>A <em>subject</em> as specified by [[RDF-CONCEPTS]].</dd>
-  <dt><tdef>RDF predicate</tdef></dt>
-  <dd>A <em>predicate</em> as specified by [[RDF-CONCEPTS]].</dd>
-  <dt><tdef>RDF object</tdef></dt>
-  <dd>An <em>object</em> as specified by [[RDF-CONCEPTS]].</dd>
-</dl>
-
-</section>
-
-<section>
-<h2 id="remote-context">Remote Context Resolution</h2>
-
-<section>
-<h3>Problem</h3>
-
-<p>
-A JSON-LD document may contain remote <tref title="context">contexts</tref>.
-These <tref title="context">contexts</tref> must be dereferenced before they
-can be processed.
-</p>
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-Dereferencing remote <tref title="context">contexts</tref> can be performed
-either inline with the other JSON-LD algorithms or as a separate, prior step.
-This solution opts to dereference them first, in a prior step, to both
-separate concerns and to better enable <tref>active context</tref> caching.
-By separating concerns, the other JSON-LD algorithms can be described more
-simply. Implementations may also be either simplified or made more efficient
-because there is no need to block or respond to events when remote
-<tref title="context">contexts</tref> are dereferenced over the network. This
-is particularly important for simplifying implementations in asynchronous
-programming environments. Of course, choosing this approach is not a
-requirement.
-</p>
-
-<p>
-The JSON-LD document is searched for remote <tref title="context">contexts</tref>
-recursively, starting with its root <em>element</em>. If the <em>element</em>
-contains an <code>@context</code> key, its value is searched for
-<tref title="string">strings</tref>. The result represents a remote
-<tref>context</tref>, which we add to a map that will ensure we don't
-dereference an already dereferenced remote
-<tref>context</tref> for a given <tref>IRI</tref>.
-</p>
-
-<p>
-When we have finished searching, we dereference each remote
-<tref>context</tref> (or get its already-dereferenced value from our map).
-Each time we dereference a remote <tref>context</tref>, we store its result
-in our map and then recursively search it for more remote
-<tref title="IRI">contexts</tref> as above, checking to ensure there is no
-cyclical reference, which is an error.
-</p>
-
-<p>
-Once all of the remote <tref title="IRI">contexts</tref> have been
-dereferenced, we replace all of their associated <tref>context</tref>
-<tref title="IRI">IRIs</tref> in the JSON-LD document with the
-results from our map.
-</p>
-
-</section>
-
-<!-- end of Remote Context Resolution -->
-</section>
-
-<section>
-<h2 id="context-processing">Context Processing</h2>
-
-<p>
-When processing a JSON-LD data structure, each processing rule is applied
-using information provided by the <tref>active context</tref>. This
-section describes how to produce an <tref>active context</tref>.
-</p>
-
-<p>
-The <tref>active context</tref> contains the active
-<tdef title="term definition">term definitions</tdef> which specify how
-properties and values have to be interpreted as well as the current
-<tdef>vocabulary mapping</tdef> and the <tdef>default language</tdef>. Each
-<tref>term definition</tref> consists of an <tdef>IRI mapping</tdef> and
-optionally a <tdef>type mapping</tdef> from terms to datatypes or
-<tdef>language mapping</tdef> from terms to language codes, and a
-<tdef>container mapping</tdef>. If an <tref>IRI mapping</tref> maps a term
-to multiple <tref="IRI">IRIs</tref> it is said to be a
-<tdef>property generator</tdef>. The <tref>active context</tref> also
-keeps track of <tref>keyword</tref> aliases.
-</p>
-
-<p>
-When processing, the <tref>active context</tref> is initialized
-without any <tref title="term definition">term definitions</tref>,
-<tref>vocabulary mapping</tref>, or <tref>default language</tref>.
-If a <tref>local context</tref> is encountered during processing, a new
-<tref>active context</tref> is created by cloning the existing
-<tref>active context</tref>. Then the information from the
-<tref>local context</tref> is merged into the new <tref>active context</tref>.
-A <tref>local context</tref> is identified within a <tref>JSON object</tref>
-by the value of the <code>@context</code> key, which MUST be a
-<tref>string</tref>, an <tref>array</tref>, or a <tref>JSON object</tref>.
-</p>
-
-<section>
-<h3>Problem</h3>
-
-<p>
-A <tref>local context</tref> needs to be transformed into an
-<tref>active context</tref> so that the <tref>active context</tref> can be
-used when executing other JSON-LD algorithms such as
-<a href="#expansion-algorithm">Expansion</a> or
-<a href="#compaction-algorithm">Compaction</a>. Any remote
-<tref title="context">contexts</tref> in the <tref>local context</tref>
-have already been dereferenced.
-</p>
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-First we prepare a new <tref>active context</tref> <em>result</em> by cloning
-the current <tref>active context</tref>. Next we update the
-<tref>vocabulary mapping</tref> and <tref>default language</tref> by
-processing two specific keywords: <code>@vocab</code> and <code>@language</code>.
-These are handled before any other keys in the <tref>local context</tref> because
-they affect how the other keys are processed.
-</p>
-
-<p>
-Then, for every other key in <tref>local context</tref>, we update
-the <tref>term definition</tref> in <em>result</em>.
-</p>
-
-<p>
-Since <tref title="context">context</tref> values in a
-<tref>local context</tref> may themselves contain
-<tref title="compact IRI">compact IRIs</tref>, we may need to recurse to
-define a <tref>prefix</tref>. When doing so, we must ensure that there is
-no cyclical dependency, which is an error. After we have processed any
-<tref title="term definition">term definition</tref> dependencies, we update
-the current <tref title="term definition">term definition</tref>, which may be
-a keyword alias or consist of <code>@id</code>, <code>@language</code>,
-<code>@type</code>, or <code>@container</code> mappings.
-</p>
-
-<p>
-Finally, we return <em>result</em> as the new <tref>active context</tref>.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-This algorithm specifies how a new <tref>active context</tref> is updated
-with a <tref>local context</tref>. The algorithm takes two input variables:
-an <tref>active context</tref> and a <tref>local context</tref>.
-
-<ol class="algorithm">
-  <li>
-    Initialize <em>result</em> to the result of cloning
-    <tref>active context</tref>.
-  </li>
-  <li>
-    If <tref>local context</tref> is not an <tref>array</tref>, then
-    set it equal to an <tref>array</tref> containing only
-    <tref>local context</tref>.
-  </li>
-  <li>
-    For each item <em>context</em> in <tref>local context</tref>:
-    <ol class="algorithm">
-      <li>
-        If <em>context</em> equals <tref>null</tref>, then set <em>result</em>
-        to a newly-initialized <tref>active context</tref> and continue to the
-        next <em>context</em>.
-      </li>
-      <li>
-        At this point, <em>context</em> MUST be a <tref>JSON object</tref>
-        because all remote <tref title="context">contexts</tref> have already
-        been dereferenced. Otherwise, an invalid value has been detected,
-        which is an error.
-      </li>
-      <li>
-        Create a <tref>JSON object</tref> <em>defined</em> to use to keep
-        track of whether or not a <tref>term</tref> has already been defined
-        or currently being defined during recursion.
-      </li>
-      <li>
-        If <em>context</em> has an <code>@vocab</code> key:
-        <ol class="algorithm">
-          <li>
-            Initialize <em>value</em> to the value associated with the
-            <code>@vocab</code> key.
-          </li>
-          <li>
-            If <em>value</em> equals <tref>null</tref>, then remove
-            any <tref>vocabulary mapping</tref> from <em>result</em>.
-          </li>
-          <li>
-            Otherwise, <em>value</em> MUST be an <tref>absolute IRI</tref>.
-            Otherwise, an invalid value has been detected, which is an error.
-            Set <em>result</em>'s <tref>vocabulary mapping</tref> to
-            <em>value</em>.
-          </li>
-          <li>
-            Set <em>defined</em>'s <code>@vocab</code> key to
-            <tref>true</tref>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        If <em>context</em> has an <code>@language</code> key:
-        <ol class="algorithm">
-          <li>
-            Initialize <em>value</em> to the value associated with the
-            <code>@language</code> key.
-          </li>
-          <li>
-            If <em>value</em> equals <tref>null</tref>, then remove
-            any <tref>default language</tref> from <em>result</em>.
-          </li>
-          <li>
-            Otherwise, <em>value</em> MUST be a <tref>string</tref>.
-            Otherwise, an invalid value has been detected, which is an error.
-            Set <em>result</em>'s <tref>default language</tref> to
-            lowercased <em>value</em>.
-          </li>
-          <li>
-            Set <em>defined</em>'s <code>@language</code> key to
-            <tref>true</tref>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        For each <em>key</em>-<em>value</em> pair in <em>context</em> invoke
-        the <a href="#create-term-definition">Create Term Definition</a>
-        subalgorithm, passing <em>result</em> for <tref>active context</tref>,
-        <em>context</em> for <tref>local context</tref>, <em>key</em>,
-        and <em>defined</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Return <em>result</em>.
-  </li>
-</ol>
-
-</section>
-
-<!-- end of Context Processing algorithm -->
-</section>
-
-<section>
-<h2 id="create-term-definition">Create Term Definition Subalgorithm</h2>
-
-<p>
-This algorithm is called from the
-<a href="#context-processing">Context Processing</a> algorithm to create
-<tref title="term definition">term definitions</tref> in a new
-<tref>active context</tref>.
-</p>
-
-<section>
-<h3>Problem</h3>
-
-A <tref>term definition</tref> must be created for the given
-<tref>term</tref>.
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-<tref title="term definition">Term definitions</tref> are created by
-parsing the information in the given <tref>local context</tref> for the
-given <tref>term</tref>. If the given <tref>term</tref> is a
-<tref>compact IRI</tref> with a <tref>prefix</tref> that is a key in the
-<tref>local context</tref>, then that <tref>prefix</tref> is considered
-a dependency with its own <tref>term definition</tref> that must first
-be created, through recursion, before continuing. Because a
-<tref>term definition</tref> can depend on other
-<tref title="term definition">term definitions</tref>, a mechanism must
-be used to detect cyclical dependencies. The solution employed here
-uses a map, <em>defined</em>, that keeps track of whether or not a
-<tref>term</tref> has been defined or is currently in the process of
-being defined. This map is checked before any recursion is attempted.
-</p>
-
-<p>
-After all dependencies have been defined, the rest of the information
-in the <tref>local context</tref> for the given <tref>term</tref> is
-taken into account, creating the appropriate <tref>IRI mapping</tref>,
-<tref>container mapping</tref>, and <tref>type mapping</tref> or
-<tref>language mapping</tref> for the <tref>term</tref>.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-The algorithm has four required inputs which are:
-an <tref>active context</tref>, a <tref>local context</tref>,
-a <em>term</em>, and a map <em>defined</em>.
-</p>
-
-<ol class="algorithm">
-  <li>
-    If <em>defined</em> contains the key <em>term</em>, then the associated
-    value MUST be <tref>true</tref>, indicating that the
-    <tref>term definition</tref> has already been created, so return.
-    Otherwise, a cyclical <tref>term definition</tref> has been detected,
-    which is an error.
-  </li>
-  <li>
-    Set the value associated with <em>defined</em>'s <em>term</em> key to
-    <tref>false</tref>. This indicates that the <tref>term definition</tref>
-    is now being created but is not yet complete.
-  </li>
-  <li>
-    If <em>term</em> is a <tref>compact IRI</tref> with a <tref>prefix</tref>
-    that is a key in <tref>local context</tref> then a dependency has been
-    found. Use this algorithm recursively passing <tref>active context</tref>,
-    <tref>local context</tref>, the <tref>prefix</tref> as <em>term</em>,
-    and <em>defined</em>.
-  </li>
-  <li>
-    Since <tref title="keyword">keywords</tref> cannot be overridden,
-    <em>term</em> MUST NOT be a <tref>keyword</tref>. Otherwise, an
-    invalid value has been detected, which is an error.
-  </li>
-  <li>
-    If <em>term</em> is a <tref>keyword</tref> alias in
-    <tref>active context</tref>, remove it.
-  </li>
-  <li>
-    Initialize <em>value</em> to the value associated with the key
-    <em>term</em> in <tref>local context</tref>.
-  </li>
-  <li>
-    If <em>value</em> equals <tref>null</tref> or <em>value</em>
-    is a <tref>JSON object</tref> containing the key-value pair
-    (<code>@id</code>-<tref>null</tref>), then set the
-    <tref>term definition</tref> in <tref>active context</tref> to
-    <tref>null</tref>, set the value associated with <em>defined</em>'s
-    key <em>term</em> to <tref>true</tref>, and return.
-  </li>
-  <li>
-    Otherwise, if <em>value</em> is a <tref>string</tref>:
-    <ol class="algorithm">
-      <li>
-        If <em>value</em> is a <tref>keyword</tref>, then <em>value</em>
-        MUST NOT be equal to <code>@context</code> or <code>@preserve</code>.
-        Otherwise an invalid keyword alias has been detected, which is an
-        error. Add <em>term</em> to <tref>active context</tref> as a
-        <tref>keyword</tref> alias for <em>value</em>. If there is more
-        than one <tref>keyword</tref> alias for <em>value</em>, then
-        store its aliases as an <tref>array</tref>, sorted by length,
-        breaking ties lexicographically.
-      </li>
-      <li>
-        Otherwise, expand <em>value</em> by setting it to the result of
-        using the <a href="#iri-expansion">IRI Expansion</a> algorithm,
-        passing <tref>active context</tref>, <em>value</em>,
-        <tref>true</tref> for <em>documentRelative</em>,
-        <tref>local context</tref>, and <em>defined</em>.
-      </li>
-      <li>
-        Set the <tref>IRI mapping</tref> for the <tref>term definition</tref>
-        for <em>term</em> in <tref>active context</tref> to <em>value</em>,
-        set the value associated with <em>defined</em>'s key <em>term</em> to
-        <tref>true</tref>, and return.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Otherwise, <em>value</em> MUST be a <tref>JSON object</tref>, otherwise
-    an invalid value has been detected, which is an error.
-  </li>
-  <li>
-    Create a new <tref>JSON object</tref>, <em>definition</em>.
-  </li>
-  <li>
-   If <em>term</em> is a <tref>compact IRI</tref> and its
-   <tref>prefix</tref> has a <tref>term definition</tref> in
-   <tref>active context</tref>, set <em>definition</em> to a copy of it.
-  </li>
-  <li>
-    If <em>value</em> contains the key <code>@id</code>:
-    <ol class="algorithm">
-      <li>
-        Initialize <em>id</em> to the value associated with the
-        <code>@id</code> key.
-      </li>
-      <li>
-        If <em>id</em> is an <tref>array</tref>, then the
-        <tref>term definition</tref> is for a <tref>property generator</tref>:
-        <ol class="algorithm">
-          <li>
-            Create an empty <tref>array</tref> <em>property generator</em>.
-          <li>
-            For each item <em>iri</em> in <em>id</em>:
-            <ol class="algorithm">
-              <li>
-                <em>iri</em> MUST be a <tref>string</tref> and MUST not
-                equal <code>@type</code>, otherwise an invalid value has
-                been detected, which is an error.
-              </li>
-              <li>
-                Set <em>iri</em> equal to the result of using the
-                <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-                <tref>active context</tref>, <em>iri</em> for <em>value</em>,
-                <tref>true</tref> for <em>documentRelative</em>,
-                <tref>local context</tref>, and <em>defined</em>.
-              </li>
-              <li>
-                Append <em>iri</em> to <em>property generator</em>.
-              </li>
-            </ol>
-          </li>
-          <li>
-            Set the <tref>property generator</tref> <tref>IRI mapping</tref>
-            for <em>definition</em> to the result of sorting
-            <em>property generator</em> lexicographically.
-          </li>
-        </ol>
-      </li>
-      <li>
-        Otherwise <em>id</em> MUST be a <tref>string</tref>, otherwise
-        an invalid value has been detected, which is an error. Set the
-        <tref>IRI mapping</tref> for <em>definition</em>
-        equal to the result of using the
-        <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-        <tref>active context</tref>, <em>id</em> for <em>value</em>,
-        <tref>true</tref> for <em>documentRelative</em>,
-        <tref>local context</tref>, and <em>defined</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Otherwise, if <em>term</em> is not a <tref>compact IRI</tref>,
-    then <tref>active context</tref> MUST have a
-    <tref>vocabulary mapping</tref>, otherwise an invalid value has
-    been detected, which is an error. Set the <tref>IRI mapping</tref>
-    for <em>definition</em> to the result of concatenating the value
-    associated with the <tref>vocabulary mapping</tref> and <em>term</em>.
-  </li>
-  <li>
-    Otherwise, if <em>term</em>'s <tref>prefix</tref> has a
-    <tref>term definition</tref> in <tref>active context</tref>, set
-    the <tref>IRI mapping</tref> for <em>definition</em> to the result of
-    concatenating the value associated with the <tref>prefix</tref>'s
-    <tref>IRI mapping</tref> and the <em>term</em>'s <em>suffix</em>.
-  </li>
-  <li>
-    Otherwise, <em>term</em> is an <tref>absolute IRI</tref>. Set the
-    <tref>IRI mapping</tref> for <em>definition</em> to <em>term</em>.
-  </li>
-  <li>
-    If <em>value</em> contains the key <code>@type</code>:
-    <ol class="algorithm">
-      <li>
-        Initialize <em>type</em> equal to the value associated with the
-        <code>@type</code> key, which MUST be a <tref>string</tref>.
-        Otherwise, an invalid value has been detected, which is an error.
-      </li>
-      <li>
-        If <em>type</em> does not equal <code>@id</code> then set it to
-        the result of using the
-        <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-        <tref>active context</tref>, <em>type</em> for <em>value</em>,
-        <tref>true</tref> for <em>vocabRelative</em>,
-        <tref>true</tref> for <em>documentRelative</em>,
-        <tref>local context</tref>, and <em>defined</em>. Set the
-        <tref>type mapping</tref> for <em>definition</em> to <em>type</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    If <em>value</em> contains the key <code>@container</code>:
-    <ol class="algorithm">
-      <li>
-        Initialize <em>container</em> equal to the value associated with the
-        <code>@container</code> key, which MUST be either:
-        <code>@list</code>, <code>@set</code>, <code>@index</code>,
-        or <code>@language</code>. Otherwise, an invalid value has been
-        detected, which is an error.
-      </li>
-      <li>
-        Set the <tref>container mapping</tref> for <em>definition</em> to
-        <em>container</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    If <em>value</em> contains the key <code>@language</code> and
-    does not contain the key <code>@type</code>:
-    <ol class="algorithm">
-      <li>
-        Initialize <em>language</em> equal to the value associated with the
-        <code>@language</code> key, which MUST be either <tref>null</tref>
-        or a <tref>string</tref>. Otherwise, an invalid value has been
-        detected, which is an error.
-      </li>
-      <li>
-        If <em>language</em> is a <tref>string</tref> set it to
-        lowercased <em>language</em>. Set the <tref>language mapping</tref>
-        for <em>definition</em> to <em>language</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Set the <tref>term definition</tref> for <em>term</em> in
-    <tref>active context</tref> to <em>definition</em> and set the value
-    associated with <em>defined</em>'s key <em>term</em> to
-    <tref>true</tref>.
-  </li>
-</ol>
-
-</section>
-
-<!-- end of Term Creation subalgorithm -->
-</section>
-
-<section>
-<h2>Expansion Algorithm</h2>
-
-<section>
-<h3>Problem</h3>
-
-<p>
-A JSON-LD document needs to be expanded, such that all <tref>context</tref>
-definitions have been removed, all <tref title="term">terms</tref> and
-<tref title="compact IRI">compact IRIs</tref> have been expanded to absolute
-<tref title="IRI">IRIs</tref>, and all
-<tref title="JSON-LD value">JSON-LD values</tref> are expressed in
-<tref title="array">arrays</tref> in <tref>expanded form</tref>.
-</p>
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-Starting with its root <em>element</em>, we can process the
-JSON-LD document recursively, until we have a fully
-<tref title="expansion">expanded</tref> <em>result</em>. When
-<tref title="expansion">expanding</tref> an <em>element</em>, we can treat
-each one differently according to its type, in order to break down the
-problem:
-</p>
-
-<ol>
-  <li>
-    If the <em>element</em> is <tref>null</tref>, there is nothing
-    to expand.
-  </li>
-  <li>
-    If the <em>element</em> is an <tref>array</tref>, then we expand
-    each of its items recursively and return them in a new
-    <tref>array</tref>.
-  </li>
-  <li>
-    If the <em>element</em> is a <tref>JSON object</tref>,
-    then we expand each of its keys, adding them to our <em>result</em>,
-    and then we expand each value for each key recursively. Some of the keys
-    will be
-    <tref title="term">terms</tref> or
-    <tref title="compact IRI">compact IRIs</tref> and others will be
-    <tref title="keyword">keywords</tref> or simply ignored because
-    they do not have definitions in the <tref>context</tref>. Any
-    <tref title="IRI">IRIs</tref> will be expanded using the
-    <a href="#iri-expansion">IRI Expansion</a> algorithm.
-  </li>
-  <li>
-    Otherwise, the <em>element</em> is a <tref>scalar</tref>, which
-    we expand according to the <a href="#value-expansion">Value Expansion</a>
-    subalgorithm.
-  </li>
-</ol>
-
-<p>
-Finally, after ensuring <em>result</em> is in an <tref>array</tref>,
-we return <em>result</em>.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-The algorithm takes four input variables: an <tref>active context</tref>,
-an <tref>active property</tref>, an <em>element</em> to be expanded, and
-an <em>insideList</em> flag. To begin, the <tref>active context</tref> is set
-to the result of performing, <a
-href="#context-processing">Context Processing</a> on the passed
-<code class="idlMemberName"><a href="#widl-JsonLdOptions-expandContext">expandContext</a></code>,
-or empty if <code class="idlMemberName"><a href="#widl-JsonLdOptions-expandContext">expandContext</a></code>
-is <tref>null</tref>, <tref>active property</tref> is set to <tref>null</tref>,
-<em>element</em> is set to the <tref>JSON-LD input</tref>, and <em>insideList</em>
-is set to <tref>false</tref>. This algorithm expects the
-<tref>JSON-LD input</tref> to be a well-formed JSON-LD document as defined in
-[[!JSON-LD]].
-
-The algorithm outputs the result of expanding <em>element</em>.
-</p>
-
-<ol class="algorithm">
-  <li>
-    If <em>element</em> is <tref>null</tref>, return <tref>null</tref>.
-  </li>
-  <li>If <em>element</em> is an <tref>array</tref>,
-    <ol class="algorithm">
-      <li>
-        Initialize an empty array, <em>result</em>.
-      </li>
-      <li>For each <em>item</em> in <em>element</em>:
-        <ol class="algorithm">
-          <li>
-            Initialize <em>expanded item</em> to the result of using this
-            algorithm recursively, passing <tref>active context</tref>,
-            <tref>active property</tref>, <em>item</em> as <em>element</em>,
-            and <em>insideList</em>.
-          </li>
-          <li>
-            If <em>insideList</em> equals <tref>true</tref> then
-            <em>expanded item</em> MUST NOT be an <tref>array</tref> or a
-            <tref>list object</tref>, otherwise a list of lists has been
-            detected, which is an error.
-          </li>
-          <li>
-            If <em>expanded item</em> is an <tref>array</tref>, append each
-            of its items to <em>result</em>. Otherwise, if
-            <em>expanded item</em> is not null, append it to <em>result</em>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        Return <em>result</em>.
-      </li>
-    </ol>
-  </li>
-  <li>If <em>element</em> is a <tref>JSON object</tref>,
-    <ol class="algorithm">
-      <li>
-        If <em>element</em> contains the key <code>@context</code>, set
-        <tref>active context</tref> equal to the result of the
-        <a href="#context-processing">Context Processing</a> algorithm,
-        passing <tref>active context</tref> and the value of the
-        <code>@context</code> key as <tref>local context</tref>.
-      </li>
-      <li>
-        Initialize <em>expanded active property</em> to the result of the
-        <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-        <tref>active context</tref> and <tref>active property</tref> for
-        <em>value</em>.
-      <li>
-        Initialize an empty <tref>JSON object</tref>, <em>result</em>.
-      </li>
-      <li>
-        For each <em>key</em> and <em>value</em> in <em>element</em>,
-        ordered lexicographically by <em>key</em>:
-        <ol class="algorithm">
-          <li>
-            If <em>key</em> is mapped to a <tref>property generator</tref>
-            in <tref>active context</tref>, set <em>expanded property</em>
-            to an array containing its <tref title="IRI">IRIs</tref>.
-            Otherwise, set <em>expanded property</em> to the result of
-            using the <a href="#iri-expansion">IRI Expansion</a> algorithm,
-            passing <tref>active context</tref>, <em>key</em> for
-            <em>value</em>, and <tref>true</tref> for <em>vocabRelative</em>.
-          </li>
-          <li>
-            If <em>expanded property</em> is either <tref>null</tref> or
-            is: not an <tref>array</tref>, an <tref>absolute IRI</tref> or
-            a <tref>keyword</tref>, then drop <em>key</em> by
-            continuing to the next <em>key</em>.
-          </li>
-          <li>
-            Validate <em>expanded property</em> against <em>value</em>
-            as follows:
-            <ol class="algorithm">
-              <li>
-                If <em>expanded property</em> is <code>@id</code> then
-                <em>value</em> MUST be a <tref>string</tref>, otherwise
-                an invalid value has been detected, which is an error.
-              </li>
-              <li>
-                If <em>expanded property</em> is <code>@type</code> then
-                <em>value</em> MUST be a <tref>string</tref> or an <tref>array</tref>
-                of strings, otherwise an invalid value has been detected, which
-                is an error.
-              </li>
-              <li>
-                If <em>expanded property</em> is <code>@graph</code> then
-                <em>value</em> MUST be a <tref>JSON object</tref> or an
-                <tref>array</tref>, otherwise an invalid value has been
-                detected, which is an error.
-              </li>
-              <li>
-                If <em>expanded property</em> is <code>@value</code> then
-                <em>value</em> MUST NOT be a <tref>JSON object</tref> or
-                an <tref>array</tref>, otherwise an invalid value has been
-                detected, which is an error.
-              </li>
-              <li>
-                If <em>expanded property</em> is <code>@language</code> then
-                <em>value</em> MUST be a <tref>string</tref>, otherwise an
-                invalid value has been detected, which is an error. Set
-                <em>expanded value</em> to lowercased <em>value</em>.
-              </li>
-              <li>
-                If <em>expanded property</em> is <code>@index</code>
-                then <em>value</em> MUST be a <tref>string</tref>, otherwise an
-                invalid value has been detected, which is an error.
-              </li>
-            </ol>
-          </li>
-          <li>
-            If <em>key</em>'s <tref>container mapping</tref> in
-            <tref>active context</tref> is <code>@language</code> and
-            <em>value</em> is a <tref>JSON object</tref> then <em>value</em>
-            is expanded from a <tref>language map</tref> as follows:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>expanded value</em> to an empty
-                <tref>array</tref>.
-              </li>
-              <li>
-                For each key <em>language</em> and value <em>language value</em>
-                in <em>value</em>, ordered lexicographically by
-                <em>language</em>:
-                <ol class="algorithm">
-                  <li>
-                    If <em>language value</em> is not an <tref>array</tref>
-                    set it to an <tref>array</tref> containing only
-                    <em>language value</em>.
-                  </li>
-                  <li>
-                    For each <em>item</em> in <em>language value</em>:
-                    <ol class="algorithm">
-                      <li>
-                        <em>item</em> MUST be a <tref>string</tref>,
-                        otherwise an invalid value has been detected,
-                        which is an error.
-                      </li>
-                      <li>
-                        Append a <tref>JSON object</tref> to
-                        <em>expanded value</em> that consists of two
-                        key-value pairs: (<code>@value</code>-<em>item</em>)
-                        and (<code>@language</code>-lowercased
-                        <em>language</em>).
-                      </li>
-                    </ol>
-                  </li>
-                </ol>
-              </li>
-            </ol>
-          </li>
-          <li>
-            If <em>key</em>'s <tref>container mapping</tref> in
-            <tref>active context</tref> is <code>@index</code> and
-            <em>value</em> is a <tref>JSON object</tref> then <em>value</em>
-            is expanded from an index map as follows:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>expanded value</em> to an empty
-                <tref>array</tref>.
-              </li>
-              <li>
-                For each key <em>index</em> and value
-                <em>index value</em> in <em>value</em>, ordered
-                lexicographically by <em>index</em>:
-                <ol class="algorithm">
-                  <li>
-                    If <em>index value</em> is not an <tref>array</tref>
-                    set it to an <tref>array</tref> containing only
-                    <em>index value</em>.
-                  </li>
-                  <li>
-                    Initialize <em>index value</em> to the result of
-                    using this algorithm recursively, passing
-                    <tref>active context</tref>, <tref>active property</tref>,
-                    <em>index value</em> as <em>element</em>, and
-                    <tref>false</tref> for <em>insideList</em>.
-                  <li>
-                    For each <em>item</em> in <em>index value</em>:
-                    <ol class="algorithm">
-                      <li>
-                        If <em>item</em> does not have the key
-                        <code>@index</code>, add the key-value pair
-                        (<code>@index</code>-<em>index</em>) to
-                        <em>item</em>.
-                      </li>
-                      <li>
-                        Append <em>item</em> to <em>expanded value</em>.
-                      </li>
-                    </ol>
-                  </li>
-                </ol>
-              </li>
-            </ol>
-          </li>
-          <li>
-            Otherwise, if <em>expanded property</em> equals <code>@list</code>
-            or <code>@set</code>, initialize <em>expanded value</em> to the
-            result of using this algorithm recursively passing
-            <tref>active context</tref>, <tref>null</tref> for
-            <tref>active property</tref> if <em>expanded property</em> equals
-            <code>@list</code> and <em>expanded active property</em> equals
-            <code>@graph</code> otherwise <tref>active property</tref>,
-            <em>value</em> for <em>element</em>, and <tref>true</tref>
-            for <em>insideList</em> if <em>expanded property</em> equals
-            <code>@list</code> otherwise <tref>false</tref>.
-            If <em>expanded property</em> equals <code>@list</code>
-            then <em>expanded value</em> MUST NOT be a
-            <tref>list object</tref>, otherwise a list of lists has been
-            detected, which is an error.
-          </li>
-          <li>
-            Otherwise, initialize <em>expanded value</em> to the result of
-            using this algorithm recursively, passing
-            <tref>active context</tref>, <em>key</em> for
-            <tref>active property</tref>, <em>value</em>
-            for <em>element</em>, and <tref>false</tref> for
-            <em>insideList</em>.
-          </li>
-          <li>
-            If <em>expanded value</em> equals <tref>null</tref> and
-            <em>expanded property</em> is not <code>@value</code> then
-            drop <em>key</em> by continuing to the next key.
-          </li>
-          <li>
-            If <em>expanded property</em> is not <code>@list</code> and
-            <em>expanded value</em> is not a <tref>list object</tref> and
-            <em>key</em>'s <tref>container mapping</tref> in
-            <tref>active context</tref> is <code>@list</code> then convert
-            <em>expanded value</em> to a <tref>list object</tref> by first
-            setting it to an <tref>array</tref> containing only
-            <em>expanded value</em> if it is not already an
-            <tref>array</tref>, and then by setting it to a
-            <tref>JSON object</tref> containing the key-value pair
-            (<code>@list</code>-<em>expanded value</em>).
-          </li>
-          <li>
-            If <em>expanded property</em> is an <tref>array</tref>:
-            <ol class="algorithm">
-              <li>
-                Invoke the
-                <a href="#label-blank-nodes-algorithm">Label Blank Nodes</a>
-                subalgorithm, passing <tref>active context</tref> and
-                <em>expanded value</em> as <em>element</em>.
-              </li>
-              <li>
-                For each item <em>iri</em> in <em>expanded property</em>:
-                <ol class="algorithm">
-                  <li>
-                    If <em>result</em> does not have the key <em>iri</em>,
-                    set this key's value in <em>result</em> to an empty
-                    <tref>array</tref>. Append a copy of
-                    <em>expanded value</em> to the <tref>array</tref> value
-                    associated with <em>result</em>'s <em>iri</em> key.
-                  </li>
-                </ol>
-              </li>
-            </ol>
-          </li>
-          <li>
-            Otherwise, if <em>expanded property</em> is
-            <code>@index</code>, <code>@id</code>, <code>@type</code>,
-            <code>@value</code>, or <code>@language</code>, then
-            set key <em>expanded property</em>'s value to
-            <em>expanded value</em> in <em>result</em>.
-          </li>
-          <li>
-            Otherwise, if <em>result</em> does not have the key
-            <em>expanded property</em>, set this key's value in <em>result</em>
-            to an empty <tref>array</tref>. Append <em>expanded value</em>
-            to the <tref>array</tref> value associated with <em>result</em>'s
-            <em>expanded property</em> key.
-          </li>
-        </ol>
-      </li>
-      <li>
-        If <em>result</em> contains the key <code>@value</code>:
-        <ol class="algorithm">
-          <li>
-            The <em>result</em> MUST NOT contain any keys other than
-            <code>@value</code>, <code>@language</code>, <code>@type</code>,
-            and <code>@index</code>. It MUST NOT contain both the
-            <code>@language</code> key and the <code>@type</code> key.
-            Otherwise, an invalid value has been detected, which is an error.
-          </li>
-          <li>
-            If the value of <em>result</em>'s <code>@value</code> key is
-            <tref>null</tref>, then set <em>result</em> to <tref>null</tref>.
-          </li>
-          <li>
-            Otherwise, if <em>result</em> contains the key
-            <code>@language</code> and the value of <em>result</em>'s
-            <code>@value</code> key is not a <tref>string</tref>, then remove
-            the <code>@language</code> key from <em>result</em>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        Otherwise, if <em>result</em> contains the key <code>@type</code>
-        and its associated value is not an <tref>array</tref>, set it to
-        an <tref>array</tref> containing only the associated value.
-      </li>
-      <li>
-        Otherwise, if <em>result</em> contains the key <code>@set</code>
-        or <code>@list</code>:
-        <ol class="algorithm">
-          <li>
-            The <em>result</em> MUST contain at most one other key and that
-            key MUST be <code>@index</code>. Otherwise, an invalid
-            value has been detected, which is an error.
-          </li>
-          <li>
-            If <em>result</em> contains the key <code>@set</code>, then
-            set <em>result</em> to the key's associated value.
-          </li>
-        </ol>
-      </li>
-      <li>
-        Otherwise, if <em>result</em> contains only the key
-        <code>@language</code>, set <em>result</em> to <tref>null</tref>.
-      </li>
-      <li>
-        If <em>insideList</em> equals false and either
-        <tref>active property</tref> equals <tref>null</tref> or
-        <em>expanded active property</em> equals <code>@graph</code>, then
-        drop free-floating values as follows:
-        <ol class="algorithm">
-          <li>
-            If <em>result</em> contains no keys or contains the key
-            <code>@value</code>, setting <em>result</em> to
-            <tref>null</tref>.
-          <li>
-            Otherwise, if <em>result</em>'s keys are only keywords and none
-            of the keys are <code>@graph</code>, <code>@type</code>, or
-            <code>@list</code> then set <em>result</em> to <tref>null</tref>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        Return <em>result</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Otherwise, <em>element</em> must be a <tref>scalar</tref>,
-    <ol class="algorithm">
-      <li>
-        If <em>insideList</em> equals <tref>false</tref> and
-        either <tref>active property</tref> equals <tref>null</tref> or
-        the result of expanding <tref>active property</tref> using the
-        <a href="#iri-expansion">IRI Expansion</a> algorithm is
-        <code>@graph</code>, then drop the top-level
-        <tref>scalar</tref> by returning <tref>null</tref>.
-      </li>
-      <li>
-        Return the result of the
-        <a href="#value-expansion">Value Expansion</a> algorithm, passing the
-        <tref>active context</tref>, <tref>active property</tref>, and
-        <em>element</em> as <em>value</em>.
-      </li>
-    </ol>
-  </li>
-</ol>
-
-<p>
-If, after the above algorithm is run, the result is a
-<tref>JSON object</tref> that contains only an <code>@graph</code> key, set the
-result to the value of <code>@graph</code>'s value. Otherwise, if the result
-is <tref>null</tref>, set it to an empty <tref>array</tref>. Finally, if
-the result is not an <tref>array</tref>, then set the result to an
-<tref>array</tref> containing only the result.
-</p>
-
-</section>
-
-<!-- end of Expansion Algorithm -->
-</section>
-
-<section>
-<h2>IRI Expansion</h2>
-
-<p>
-In JSON-LD documents, some keys and values may represent
-<tref title="IRI">IRIs</tref>. This section defines an algorithm for
-transforming a <tref>string</tref> that represents an <tref>IRI</tref> into
-an <tref>absolute IRI</tref>. It also covers transforming <tref>keyword</tref>
-aliases into <tref title="keyword">keywords</tref>.
-</p>
-
-<p>
-<tref>IRI</tref> expansion may occur during context processing or during
-any of the other JSON-LD algorithms. If IRI expansion occurs during context
-processing, then the <tref>local context</tref> and its related
-<em>defined</em> map from the
-<a href="#context-processing">Context Processing</a> algorithm are passed
-to this algorithm. This allows for <tref>term definition</tref> dependencies
-to be processed via the context processing subalgorithm,
-<a href="#create-term-definition">Create Term Definition</a>.
-</p>
-
-<p>
-After application of this algorithm, values processed by this algorithm are
-said to be in <tdef>expanded IRI form</tdef> (Advanced note: this form
-may also include
-<tref title="blank node identifier">blank node identifiers</tref> and
-JSON-LD <tref title="keyword">keywords</tref>).
-</p>
-
-<section>
-<h3>Problem</h3>
-
-We have a value that needs to be expanded to an <tref>absolute IRI</tref>
-or a <tref>keyword</tref>, if it can be and if it is not already one. The
-given value may be <tref>null</tref>, a <tref>term</tref>, a
-<tref>keyword</tref> alias, a <tref>compact IRI</tref>,
-a <tref>relative IRI</tref>, or an <tref>absolute IRI</tref>.
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-In order to expand <em>value</em> to an <tref>absolute IRI</tref>, we must
-first determine if it is <tref>null</tref>, a <tref>term</tref>, a
-<tref>keyword</tref>, or some form of <tref>IRI</tref>. While inspecting
-<em>value</em> we may also find that we need to create
-<tref>term definition</tref> dependencies because we're running this
-algorithm during <a href="#context-processing">Context Processing</a>. We can
-tell whether or not we're running during
-<a href="#context-processing">Context Processing</a> by checking
-<tref>local context</tref> against <tref>null</tref>.
-We know we need to create a <tref>term definition</tref> in the
-<tref>active context</tref> when <em>value</em> is
-a key in the <tref>local context</tref> and the <em>defined</em> map
-does not have a key for <em>value</em> with an associated value of
-<tref>true</tref>. The <em>defined</em> map is used during
-<a href="#context-processing">Context Processing</a> to keep track of
-which <tref title="term">terms</tref> have already been defined or are
-in the process of being defined. We create a
-<tref>term definition</tref> by using the
-<a href="#create-term-definition">Create Term Definition</a> subalgorithm.
-</p>
-
-<p>
-To begin, we handle the simplest case, where <em>value</em> is
-<tref>null</tref>. Here all we do is return <tref>null</tref> as there is
-nothing to expand.
-</p>
-
-<p>
-Next, we create a <tref>term definition</tref> for <em>value</em> if
-we need to. This ensures that when we look in the <tref>active context</tref>,
-any information associated with <em>value</em> will be ready.
-</p>
-
-<p>
-Now we initialize our <em>result</em> to <em>value</em> and then we
-look in the <tref>active context</tref> for <em>value</em>:
-
-<ol>
-  <li>
-    If it indicates that <em>value</em> is explicitly mapped to
-    <tref>null</tref>, then we return <tref>null</tref> which has the effect
-    of dropping the <em>value</em> from our expanded output.
-  </li>
-  <li>
-    If it indicates that <em>value</em> is a <tref>keyword</tref> alias,
-    then we return the associated <tref>keyword</tref>.
-  </li>
-  <li>
-    If it has a <tref>term definition</tref> that is a
-    <tref>property generator</tref> when the <tref>local context</tref> is
-    not <tref>null</tref>, then we trigger an error because a
-    <tref>term definition</tref> cannot have a
-    <tref>property generator</tref> as a dependency.
-  </li>
-  <li>
-    Otherwise, if it has <tref>term definition</tref> that is not a
-    <tref>property generator</tref> we update <em>result</em> by setting
-    it to the associated <tref>IRI mapping</tref>. If this is the case
-    then we also know that <em>result</em> is now an
-    <tref>absolute IRI</tref> (or a <tref>blank node identifier</tref>).
-  </li>
-</ol>
-
-</p>
-
-<p>
-At this point, if we know that <em>result</em> is not an
-<tref>absolute IRI</tref> or <tref>blank node identifier</tref>, then it
-may be a <tref>compact IRI</tref>. If it has a colon (<code>:</code>) in it
-then we parse it into <tref>prefix</tref>:<em>suffix</em>. If the resulting
-<tref>prefix</tref> is <code>_</code> or the <em>suffix</em>
-is <code>//</code>, then <em>result</em> is already an
-<tref>absolute IRI</tref>. Otherwise, if the <tref>prefix</tref> is a key in
-the <tref>local context</tref>, and we need to create a
-<tref>term definition</tref>, then we do so. If the
-<tref>term definition</tref> for the <tref>prefix</tref> in the
-<tref>active context</tref> is not a <tref>property generator</tref>, then
-we replace <em>result</em> with the concatenation of the associated
-<tref>IRI mapping</tref> and <em>suffix</em>.
-</p>
-
-<p>
-Finally, if <em>result</em> is now a <tref>blank node identifier</tref>,
-we relabel it by setting it to the result of the
-<a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a>
-algorithm. Otherwise, if it is not an <tref>absolute IRI</tref>, we resolve
-it against either the <tref title="active context">active context's</tref>
-<tref>vocabulary mapping</tref> or the document base, given the
-<em>vocabRelative</em> and <em>documentRelative</em> flag values and
-the existence of a <tref>vocabulary mapping</tref>. Then we return
-<em>result</em>.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-The algorithm takes two required and four optional input variables. The
-required inputs are an <tref>active context</tref> and a <em>value</em>
-to be expanded. The optional inputs are two flags,
-<em>documentRelative</em> and <em>vocabRelative</em>, that specifying
-whether <em>value</em> can be interpreted as a <tref>relative IRI</tref>
-against the document's base <tref>IRI</tref> or the
-<tref title="active context">active context's</tref>
-<tref>vocabulary mapping</tref>, respectively, and
-a <tref>local context</tref> and map <em>defined</em> to be used when
-this algorithm is used during
-<a href="#context-processing">Context Processing</a>. If not passed, the
-two flags are set to <code>false</code> and <tref>local context</tref> and
-<em>defined</em> are initialized to <tref>null</tref>.
-</p>
-
-<ol class="algorithm">
-  <li>
-    If <em>value</em> equals <tref>null</tref>, then return <tref>null</tref>.
-  </li>
-  <li>
-    If <tref>local context</tref> is not <tref>null</tref>, it contains
-    a key that equals <em>value</em>, and the value associated with the key
-    that equals <em>value</em> in <em>defined</em> is not <tref>true</tref>,
-    then invoke the
-    <a href="#create-term-definition">Create Term Definition</a>
-    subalgorithm, passing <tref>active context</tref>,
-    <tref>local context</tref>, <em>value</em> as <em>term</em>, and
-    <em>defined</em>. This will ensure that a <tref>term definition</tref>
-    is created for <em>value</em> in <tref>active context</tref> during
-    <a href="#context-processing">Context Processing</a>.
-  </li>
-  <li>
-    If <tref>local context</tref> is not <tref>null</tref> then
-    <tref>active context</tref> MUST NOT have a <tref>term definition</tref>
-    for <em>value</em> that is a <tref>property generator</tref>.
-    Otherwise, an invalid error has been detected, which is an error.
-  </li>
-  <li>
-    If <em>value</em> has a <tref>null</tref> mapping in
-    <tref>active context</tref>, then explicitly ignore <em>value</em>
-    by returning <tref>null</tref>.
-  </li>
-  <li>
-    If <tref>active context</tref> indicates that <em>value</em> is a
-    <tref>keyword</tref> alias then return the associated
-    <tref>keyword</tref>.
-  </li>
-  <li>
-    Initialize <em>result</em> to <em>value</em> and <em>isAbsoluteIri</em>
-    to <tref>false</tref>.
-  </li>
-  <li>
-    If <tref>active context</tref> has a <tref>term definition</tref> for
-    <em>value</em>, then set <em>result</em> to the associated
-    <tref>IRI mapping</tref> and <em>isAbsoluteIri</em> to <tref>true</tref>.
-  </li>
-  <li>
-    If <em>isAbsoluteIri</em> equals <tref>false</tref> and <em>result</em>
-    contains a colon (<code>:</code>), then it is either an
-    <tref>absolute IRI</tref> or a <tref>compact IRI</tref>:
-    <ol class="algorithm">
-      <li>
-        Split <em>result</em> into a <tref>prefix</tref> and <em>suffix</em>
-        at the first occurence of a colon (<code>:</code>).
-      </li>
-      <li>
-        If <tref>prefix</tref> does not equal underscore (<code>_</code>)
-        and <em>suffix</em> does not begin with double-forward-slash
-        (<code>//</code>), then it may be a <tref>compact IRI</tref>:
-        <ol class="algorithm">
-          <li>
-            If <tref>local context</tref> is not <tref>null</tref>, it
-            contains a key that equals <tref>prefix</tref>, and the value
-            associated with the key that equals <tref>prefix</tref> in
-            <em>defined</em> is not <tref>true</tref>, then invoke the
-            <a href="#create-term-definition">Create Term Definition</a>
-            subalgorithm, passing <tref>active context</tref>,
-            <tref>local context</tref>, <em>prefix</em> as <em>term</em>,
-            and <em>defined</em>. This will ensure that a
-            <tref>term definition</tref> is created for <tref>prefix</tref>
-            in <tref>active context</tref> during
-            <a href="#context-processing">Context Processing</a>.
-          </li>
-          <li>
-            If <tref>active context</tref> contains a
-            <tref>term definition</tref> for <tref>prefix</tref> that is
-            not a <tref>property generator</tref> then set <em>result</em>
-            to the result of concatenating the value associated with the
-            <tref>prefix</tref>'s <tref>IRI mapping</tref> and
-            <em>suffix</em>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        Set <em>isAbsoluteIri</em> to <tref>true</tref>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    If <em>isAbsoluteIri</em> equals <tref>true</tref>:
-    <ol class="algorithm">
-      <li>
-        If <tref>local context</tref> equals <tref>null</tref> and
-        <em>result</em> begins with and underscore and colon
-        (<code>_:</code>) then <em>result</em> is a
-        <tref>blank node identifier</tref>. Set <em>result</em> to the
-        result of the
-        <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a>
-        algorithm, passing <tref>active context</tref> and <em>result</em>
-        for <em>identifier</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Otherwise, if <em>vocabRelative</em> equals <tref>true</tref> and
-    <tref>active context</tref> has a <tref>vocabulary mapping</tref>,
-    then set <em>result</em> to the result of concatenating the
-    <tref>vocabulary mapping</tref> with <em>result</em>.
-  </li>
-  <li>
-    Otherwise, if <em>documentRelative</em> equals <tref>true</tref>,
-    set <em>result</em> to the result of resolving <em>result</em> against
-    the document base as per [RFC3986]. Only the basic algorithm in
-    section 5.2 of [RFC3986] is used; neither Syntax-Based Normalization
-    nor Scheme-Based Normalization (as described in sections 6.2.2 and
-    6.2.3 of [RFC3986]) are performed. Characters additionally allowed in
-    IRI references are treated in the same way that unreserved characters
-    are treated in URI references, per section 6.5 of [RFC3987].
-  </li>
-  <li>
-    If <tref>local context</tref> is not <tref>null</tref> then
-    <em>result</em> MUST be an <tref>absolute IRI</tref>. Otherwise,
-    an invalid context value has been detected, which is an error. Return
-    <em>result</em>.
-  </li>
-</li>
-
-</section>
-
-<!-- end of IRI Expansion -->
-</section>
-
-<section>
-<h2>Value Expansion</h2>
-
-<p>
-Some values in JSON-LD can be expressed in a <tref>compacted form</tref>.
-These values are required to be <tref title="expansion">expanded</tref> at
-times when processing JSON-LD documents. A value is said to be in
-<tdef>expanded form</tdef> after the application of this algorithm.
-</p>
-
-<section>
-<h3>Problem</h3>
-
-A <em>value</em> associated with an <tref>active property</tref> must
-be <tref title="expansion">expanded</tref> to <tref>expanded form</tref>.
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-Other than the simple case where <em>value</em> is <tref>null</tref>, for
-which we return <tref>null</tref>, we must primarily look at <em>value</em>'s
-associated <tref>active property</tref> to determine how to expand it.
-</p>
-
-<p>
-First we <tref title="expansion">expand</tref> the
-<tref>active property</tref> itself, so that we can resolve
-<tref>keyword</tref> aliases. Then, for certain
-<tref title="keyword">keywords</tref> like <code>@id</code> and
-<code>@type</code>, we simply expand <em>value</em>
-using the <a href="#iri-expansion">IRI Expansion</a> algorithm and return
-the result.
-</p>
-
-<p>
-Next, we check to see if <tref>active property</tref> has a
-<tref>type mapping</tref> in the <tref>active context</tref> that would alter
-what we return. If it has one that is <code>@type</code> or if the
-<em>expanded property</em> is <code>@graph</code> then we return
-a <tref>JSON object</tref> with a single key-pair of <code>@id</code>
-and the result of using the <a href="#iri-expansion">IRI Expansion</a>
-algorithm on <em>value</em>.
-</p>
-
-<p>
-If we haven't returned yet and the <em>expanded property</em> is a
-<tref>keyword</tref>, then there is no special <tref>expansion</tref> to be
-performed on the <em>value</em>, so we return it as is.
-</p>
-
-<p>
-Otherwise, we'll our result will be a <tref>JSON object</tref> containing
-the key <code>@value</code> with the value the <em>value</em>. Additionally,
-a <code>@type</code> key-value pair will be included if there is a
-<tref>type mapping</tref> associated with the <tref>active property</tref>
-or a <code>@language</code> key-value pair if <em>value</em> is a
-<tref>string</tref> and there is <tref>language mapping</tref>.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-The algorithm takes three required inputs: an <tref>active context</tref>,
-an <tref>active property</tref>, and a <em>value</em> to expand.
-</p>
-
-<ol class="algorithm">
-  <li>
-    If <em>value</em> equals <tref>null</tref>, then return <tref>null</tref>.
-  </li>
-  <li>
-    Initialize <em>expanded property</em> to the result of using the
-    <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-    <tref>active context</tref>, <tref>active property</tref> for
-    <em>value</em>, and <tref>true</tref> for <em>vocabRelative</em>.
-  </li>
-  <li>
-    If <em>expanded property</em> equals <code>@id</code> then return
-    the result of using the
-    <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-    <tref>active context</tref>, <em>value</em>, and <tref>true</tref>
-    for <em>documentRelative</em>.
-  </li>
-  <li>
-    If <em>expanded property</em> equals <code>@type</code> then
-    return the result of using the
-    <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-    <tref>active context</tref>, <em>value</em>, <tref>true</tref> for
-    <em>vocabRelative</em>, and <tref>true</tref> for
-    <em>documentRelative</em>.
-  </li>
-  <li>
-    If <tref>active property</tref> has a <tref>type mapping</tref> in
-    <tref>active context</tref> that is <code>@id</code> or if
-    <em>expanded property</em> equals <code>@graph</code>, then return
-    a new <tref>JSON object</tref> containing a single key-value pair
-    where the key is <code>@id</code> and the value is the result of
-    using the
-    <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-    <tref>active context</tref>, <em>value</em>, and <tref>true</tref> for
-    <em>documentRelative</em>.
-  </li>
-  <li>
-    If <em>expanded property</em> is a <tref>keyword</tref> return
-    <em>value</em> as is.
-  </li>
-  <li>
-    Otherwise, initialize <em>result</em> to an empty
-    <tref>JSON object</tref>.
-  </li>
-  <li>
-    If <tref>active property</tref> has a <tref>type mapping</tref> in
-    <tref>active context</tref>:
-    <ol class="algorithm">
-      <li>
-        Initialize <em>type</em> to the value associated with the
-        <tref>type mapping</tref>.
-      </li>
-      <li>
-        If <em>type</em> is a <tref>blank node identifier</tref> (it
-        begins with <code>_:</code>), then set it to the result of the
-        <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a>
-        algorithm, passing <tref>active context</tref> and <em>type</em> for
-        <em>identifier</em>.
-      </li>
-      <li>
-        Add the key-value pair, (<code>@type</code>-<em>type</em>), to
-        <em>result</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Otherwise, if <em>value</em> is a <tref>string</tref>:
-    <ol class="algorithm">
-      <li>
-        If <em>value</em> has a <tref>language mapping</tref> in
-        <tref>active context</tref> that is not <tref>null</tref>, then
-        add a key-value pair to <em>result</em> where the key is
-        <code>@language</code> and the value is the value associated with
-        the <tref>language mapping</tref>.
-      </li>
-      <li>
-        Otherwise, if <em>value</em> has no <tref>language mapping</tref> in
-        <tref>active context</tref> and <tref>active context</tref> has a
-        <tref>default language</tref>, then add a key-value pair to
-        <em>result</em> where the key is <code>@language</code> and the value
-        is the <tref>default language</tref>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Finally, add the key-value pair, (<code>@value</code>-<em>value</em>), to
-    <em>result</em> and return <em>result</em>.
-  </li>
-</ol>
-
-</section>
-
-<!-- end of Value Expansion -->
-</section>
-
-<section>
-<h2>Label Blank Nodes Subalgorithm</h2>
-
-<p>
-During <tref>expansion</tref>, it is sometimes necessary to ensure
-all <tref title="blank node">blank nodes</tref> have been labeled. This
-occurs when a <tref>property generator</tref> is used to copy a single
-property's values across multiple properties. This step is necessary to
-ensure that these duplicated values can be later
-<tref title="compaction">recompacted</tref>. Because new labels will
-be assigned to <tref title="blank node">blank nodes</tref>, it is
-important to relabel any existing <tref title="blank node">blank nodes</tref>
-to avoid conflicting names.
-</p>
-
-<p>
-The algorithm takes two required inputs: an <tref>active context</tref>,
-and an <em>element</em> to be labeled with
-<tref title="blank node identifier">blank node identifiers</tref>.
-</p>
-
-<ol class="algorithm">
-  <li>
-    If <em>element</em> is an <tref>array</tref>, then for each
-    <em>item</em> in <em>element</em>:
-    <ol class="algorithm">
-      <li>
-        Replace <em>item</em> with the result of using this algorithm
-        recursively, passing <tref>active context</tref> and <em>item</em>
-        for <em>element</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Otherwise, if <em>element</em> is a <tref>list object</tref>, then
-    replace the value of the <code>@list</code> key in <em>element</em>
-    with the result of using this algorithm recursively, passing
-    <tref>active context</tref> and the value of the <code>@list</code> key
-    for <em>element</em>.
-  </li>
-  <li>
-    Otherwise, if <em>element</em> is a <tref>JSON object</tref>:
-    <ol class="algorithm">
-      <li>
-        If <em>element</em> is a <em>blank node</em>, then set the value
-        of its <code>@id</code> key to the result of using the
-        <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a>
-        algorithm, passing the value for <em>identifier</em>, using
-        <tref>null</tref> instead if <em>element</em> has no key
-        <code>@id</code>.
-      </li>
-      <li>
-        For each <em>key</em>-<em>value</em> pair ordered lexicographically
-        by <em>key</em>:
-        <ol class="algorithm">
-          <li>
-            If <em>key</em> does not equal <code>@id</code>, then replace
-            <em>value</em> in <em>element</em> with the result of using
-            this algorithm recursively, passing <tref>active context</tref>
-            and <em>value</em> for <em>element</em>.
-          </li>
-        </ol>
-      </li>
-    </ol>
-  </li>
-  <li>
-    Otherwise, if <em>element</em> is a <tref>string</tref> and <em>isId</em>
-    equals <tref>true</tref>, and <em>element</em> is a
-    <tref>blank node identifier</tref>, then set <em>element</em> to
-    the result of using the
-    <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a>
-    algorithm, passing <em>element</em> for <em>identifier</em>.
-  </li>
-  <li>
-    Return <em>element</em>.
-  </li>
-</ol>
-
-</section>
-
-<section>
-<h2>Generate Blank Node Identifier</h2>
-
-<p>
-This algorithm is used to generate new
-<tref title="blank node identifier">blank node identifiers</tref> or to
-relabel an existing
-<tref>blank node identifier</tref> to avoid collision by the introduction
-of new ones. It needs to keep an <em>identifier map</em>, a <em>counter</em>,
-and a <em>prefix</em> between its executions to be able to generate new
-<tref title="blank node identifier">blank node identifiers</tref>. Note
-that it may be most convenient to keep this state information in the
-<tref>active context</tref>, so long as it is preserved (shared) when the
-<tref>active context</tref> is cloned during
-<a href="#context-processing">Context Processing</a>. The <em>counter</em> is
-initialized to <code>0</code> and <em>prefix</em> is set to <code>_:t</code>
-by default.
-</p>
-
-<p>
-The algorithm takes a single input variable <em>identifier</em> which may
-be <tref>null</tref>.
-</p>
-
-<ol class="algorithm">
-  <li>
-    If the <em>identifier</em> is not <tref>null</tref> and is in the
-    <em>identifier map</em>, return the mapped identifier.
-  </li>
-  <li>
-    Otherwise, generate a new <em>blankNodeIdentifier</em> by concatenating
-    <em>prefix</em> and <em>counter</em>.
-  </li>
-  <li>
-    Increment <em>counter</em> by <code>1</code>.
-  </li>
-  <li>
-    If <em>identifier</em> is not <tref>null</tref>, create a new entry in
-    <em>identifier map</em> set to <em>blankNodeIdentifer</em>.
-  </li>
-  <li>
-    Return <em>blankNodeIdentifier</em>.
-  </li>
-</ol>
-
-</section>
-
-<section>
-<h2>Compaction Algorithm</h2>
-
-<section>
-<h3>Problem</h3>
-
-<p>
-A JSON-LD document needs to be compacted, such that the given
-<tref>context</tref> is applied. This must result in shortening
-any applicable <tref title="IRI">IRIs</tref> to
-<tref title="term">terms</tref> or
-<tref title="compact IRI">compact IRIs</tref> and
-any applicable <tref title="JSON-LD value">JSON-LD values</tref>
-expressed in <tref>expanded form</tref> to simple values such as
-<tref title="string">strings</tref> or
-<tref title="number">numbers</tref>.
-</p>
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-Starting with its root <em>element</em>, we can process the
-JSON-LD document recursively, until we have a fully
-<tref title="compaction">compacted</tref> <em>result</em>. When
-<tref title="compaction">compacting</tref> an <em>element</em>, we can treat
-each one differently according to its type, in order to break down the
-problem:
-</p>
-
-<ol>
-  <li>
-    If the <em>element</em> is an <tref>array</tref>, then we compact
-    each of its items recursively and return them in a new
-    <tref>array</tref>.
-  </li>
-  <li>
-    If the <em>element</em> is a <tref>JSON object</tref>,
-    then we start by creating a shallow copy of it and each of its
-    key's <tref>array</tref> values. This is done so that if any key
-    is compacted to a <tref>property generator</tref> <tref>term</tref>,
-    we can remove duplicate values without modifying the original
-    <em>element</em>. Then, we compact each value in the shallow copy
-    for each key recursively. Some of the keys will be
-    compacted, using the
-    <a href="#iri-compaction">IRI Compaction</a> algorithm,
-    to <tref title="term">terms</tref> or
-    <tref title="compact IRI">compact IRIs</tref> and others will be
-    compacted from <tref title="keyword">keywords</tref> to
-    <tref>keyword</tref> aliases or simply left unchanged because
-    they do not have definitions in the <tref>context</tref>. Values will
-    be converted to <tref>compacted form</tref> via the
-    <a href="#value-compaction">Value Compaction</a> algorithm. Some data
-    will be reshaped based on
-    <tref title="container mapping">container mappings</tref> specified
-    in the context such as <code>@index</code> or <code>@language</code>
-    maps.
-  </li>
-  <li>
-    Otherwise, the <em>element</em> is a <tref>scalar</tref>, it is
-    already in <tref>compacted form</tref>, so we simply return.
-  </li>
-</ol>
-
-<p>
-The final output is a <tref>JSON object</tref> with a <code>@context</code>
-key, if a <tref>context</tref> was given, where the <tref>JSON object</tref>
-is either <em>result</em> or a wrapper for it where <em>result</em> appears
-as the value of an aliased <code>@graph</code> key because <em>result</em>
-contained two or more items in an <tref>array</tref>. If no
-<tref>context</tref> was given, the <em>result</em> is only simplified
-from an <tref>array</tref> to a <tref>JSON object</tref> if it has one or
-fewer items.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-The algorithm takes four required input variables: an
-<tref>active context</tref>, an <tref>active property</tref>, and an
-<em>element</em> to be compacted. To begin, the <tref>active context</tref>
-is set to the result of performing
-<a href="#context-processing">Context Processing</a> on the passed
-<em>context</em>, the <tref>active property</tref> is set to
-<tref>null</tref>, and <em>element</em> is set to the result of performing
-the <a href="#expansion-algorithm">Expansion Algorithm</a> on the
-<tref>JSON-LD input</tref>.
-</p>
-
-<ol class="algorithm">
-  <li>
-    If <em>element</em> is an <tref>array</tref>:
-    <ol class="algorithm">
-      <li>
-        Initialize <em>result</em> to an empty <tref>array</tref>.
-      </li>
-      <li>
-        For each <em>item</em> in <em>element</em>:
-        <ol class="algorithm">
-          <li>
-            Initialize <em>compacted item</em> to the result of using this
-            algorithm recursively, passing <tref>active context</tref>,
-            <tref>active property</tref>, and <em>item</em> for
-            <em>element</em>.
-          </li>
-          <li>
-            If <em>compacted item</em> is not <tref>null</tref>, then append
-            it to <em>result</em>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        If <em>result</em> contains only one item (it has a length of
-        <code>1</code>) and <tref>active property</tref> has no
-        <tref>container mapping</tref> in <tref>active context</tref>,
-        then set <em>result</em> to its only item.
-      </li>
-      <li>
-        Return <em>result</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    If <em>element</em> is an <tref>JSON object</tref>:
-    <ol class="algorithm">
-      <li>
-        If <em>element</em> contains the key <code>@value</code> or
-        if it contains only one key and that key is <code>@id</code>,
-        then return the result of using the
-        <a href="#value-compaction">Value Compaction</a> algorithm,
-        passing <tref>active context</tref>, <tref>active property</tref>,
-        and <em>element</em> as <em>value</em>.
-      </li>
-      <li>
-        Create a shallow copy of <em>element</em> and each <tref>array</tref>
-        associated with its keys so that duplicate values can be removed
-        during <tref>property generator</tref> <tref>compaction</tref>:
-        <ol class="algorithm">
-          <li>
-            Initialize <em>shallow</em> to an empty <tref>JSON object</tref>.
-          </li>
-          <li>
-            For each <em>key</em>-<em>value</em> pair in <em>element</em>:
-            <ol class="algorithm">
-              <li>
-                If <em>value</em> is an <tref>array</tref>, then add
-                a key-value pair to <em>shallow</em> where the key
-                is <em>key</em> and the value is a shallow copy of
-                <em>value</em>.
-              </li>
-              <li>
-                Otherwise, add the key-value pair, <em>key</em>-<em>value</em>
-                to <em>shallow</em>.
-              </li>
-            </ol>
-          </li>
-        </ol>
-      </li>
-      <li>
-        Initialize <em>result</em> to an empty <tref>JSON object</tref>.
-      </li>
-      <li>
-        Initialize <em>keys</em> to an <tref>array</tref> containing
-        all of the keys in <em>element</em>, ordered lexicographically.
-      </li>
-      <li>
-        For each key <em>expanded property</em> in <em>keys</em>:
-        <ol class="algorithm">
-          <li>
-            If <em>shallow</em> does not contain a key that equals
-            <em>expanded property</em>, then continue to the next
-            <em>expanded property</em>.
-          </li>
-          <li>
-            Initialize <em>expanded value</em> to the value associated
-            with the key that equals <em>expanded property</em> in
-            <em>shallow</em>.
-          </li>
-          <li>
-            If <em>expanded property</em> equals <code>@id</code> or
-            <code>@type</code>:
-              <ol class="algorithm">
-                <li>
-                  If <em>expanded value</em> is a <tref>string</tref>,
-                  then initialize <em>compacted value</em> to the result
-                  of using the
-                  <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                  algorithm, passing <tref>active context</tref>,
-                  <em>expanded value</em> for <em>iri</em>,
-                  and <tref>true</tref> for <em>vocabRelative</em> if
-                  <em>expanded property</em> equals <code>@type</code>,
-                  <tref>false</tref> otherwise.
-                </li>
-                <li>
-                  Otherwise, <em>expanded value</em> must be a
-                  <code>@type</code> <tref>array</tref>:
-                  <ol class="algorithm">
-                    <li>
-                      Initialize <em>compacted value</em> to an empty
-                      <tref>array</tref>.
-                    </li>
-                    <li>
-                      For each item <em>expanded type</em> in
-                      <em>expanded value</em>, append the result of
-                      of using the
-                      <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                      algorithm, passing <tref>active context</tref>,
-                      <em>expanded type</em> for <em>iri</em>, and
-                      <tref>true</tref> for <em>vocabRelative</em>,
-                      to <em>compacted value</em>.
-                    </li>
-                    <li>
-                      If <em>compacted value</em> contains only one
-                      item (it has a length of <code>1</code>), then
-                      set <em>compacted value</em> to its only item.
-                    </li>
-                  </ol>
-                </li>
-                <li>
-                  Initialize <em>alias</em> to the result of using the
-                  <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                  algorithm, passing <tref>active context</tref> and
-                  <em>expanded property</em> for <em>iri</em>.
-                </li>
-                <li>
-                  Add the key-value pair,
-                  (<em>alias</em>-<em>compacted value</em>) to
-                  <em>result</em> and continue to the next
-                  <em>expanded property</em>.
-                </li>
-              </ol>
-            </li>
-          <li>
-            If <em>expanded property</em> equals <code>@index</code>:
-            <ol class="algorithm">
-              <li>
-                If <tref>active property</tref> has a
-                <tref>container mapping</tref> in <tref>active context</tref>
-                that equals <code>@index</code>, then the compacted
-                result will be inside of an <code>@index</code>
-                container, so simply drop the <code>@index</code>
-                property by continuing to the next
-                <em>expanded property</em>.
-              </li>
-              <li>
-                Otherwise, initialize <em>alias</em> to the result of using
-                the <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                algorithm, passing <tref>active context</tref> and
-                <em>expanded property</em> for <em>iri</em>.
-              </li>
-              <li>
-                Add the key-value pair,
-                (<em>alias</em>-<em>expanded value</em>) to
-                <em>result</em> and continue to the next
-                <em>expanded property</em>.
-              </li>
-            </ol>
-          </li>
-          <li>
-            If <em>expanded value</em> is an empty <tref>array</tref>:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>item active property</em> to the result of
-                using the
-                <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                algorithm, passing <tref>active context</tref>,
-                <em>expanded property</em> for <em>iri</em>,
-                <em>expanded value</em> for <em>value</em>,
-                <tref>true</tref> for <em>vocabRelative</em>, and
-                <em>shallow</em> for <em>parent</em>.
-              </li>
-              <li>
-                If <em>result</em> does not have the key that equals
-                <em>item active property</em>, set this key's value in
-                <em>result</em> to an empty <tref>array</tref>. Otherwise, if
-                the key's value is not an <tref>array</tref>, then set it
-                equal to one containing only the value.
-              </li>
-            </ol>
-          </li>
-          <li>
-            At this point, <em>expanded value</em> must be an
-            <tref>array</tref> due to the
-            <a href="#expansion-algorithm">Expansion algorithm</a>.
-            For each item <em>expanded item</em> in <em>expanded value</em>:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>item active property</em> to the result of using
-                the <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                algorithm, passing <tref>active context</tref>,
-                <em>expanded property</em> for <em>iri</em>,
-                <em>expanded item</em> for <em>value</em>,
-                <tref>true</tref> for <em>vocabRelative</em>, and
-                <em>shallow</em> for <em>parent</em>.
-              </li>
-              <li>
-                Initialize <em>container</em> to <tref>null</tref>. If there
-                is a <tref>container mapping</tref> for
-                <em>item active property</em> in <tref>active context</tref>,
-                set <em>container</em> to its value.
-              </li>
-              <li>
-                If there is a <tref>term definition</tref> for
-                <em>item active property</em> in <tref>active context</tref>
-                that is a <tref>property generator</tref>, then invoke the
-                <a href="#find-property-generator-duplicates">Find Property Generator Duplicates</a>
-                algorithm, passing <tref>active context</tref>,
-                <em>shallow</em> for <em>element</em>,
-                <em>expanded property</em>, <em>expanded item</em> for
-                <em>value</em>, <em>item active property</em> for
-                <tref>active property</tref>, and
-                <tref>true</tref> for <em>remove</em>.
-              </li>
-              <li>
-                Initialize <em>compacted item</em> to the result of using
-                this algorithm recursively, passing
-                <tref>active context</tref>, <em>item active property</em>
-                for </tref>active property</tref>,
-                <em>expanded item</em> for <em>element</em> if it does
-                not contain the key <code>@list</code>, otherwise pass
-                the key's associated value for <em>element</em>.
-              </li>
-              <li>
-                If <em>expanded item</em> is a <tref>list object</tref>:
-                <ol class="algorithm">
-                  <li>
-                    If <em>compacted item</em> is not an <tref>array</tref>,
-                    then set it to an <tref>array</tref> containing only
-                    <em>compacted item</em>.
-                  </li>
-                  <li>
-                    If <em>container</em> does not equal <code>@list</code>:
-                    <ol class="algorithm">
-                      <li>
-                        Convert <em>compacted item</em> to a
-                        <tref>list object</tref> by setting it to a
-                        <tref>JSON object</tref> containing key-value pair
-                        where the key is the result of the
-                        <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                        algorithm, passing <tref>active context</tref> and
-                        <code>@list</code> for <em>iri</em>, and the
-                        value is <em>compacted item</em>.
-                      </li>
-                      <li>
-                        If <em>expanded item</em> contains the key
-                        <code>@index</code>, then add a key-value pair
-                        to <em>compacted item</em> where the key is the
-                        result of the
-                        <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                        algorithm, passing <tref>active context</tref> and
-                        <code>@index</code> for <em>iri</em>, and the
-                        value is the value associated with the
-                        <code>@index</code> key in
-                        <em>expanded item</em>.
-                      </li>
-                    </ol>
-                  </li>
-                  <li>
-                    Otherwise, <em>item active property</em> MUST NOT be a key
-                    in <em>result</em> because there cannot be two
-                    <tref title="list object">list objects</tref> associated
-                    with an <tref>active property</tref> that has a
-                    <tref>container mapping</tref>; this is an error.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                If <em>container</em> equals <code>@language</code> or
-                <code>@index</code>:
-                <ol class="algorithm">
-                  <li>
-                    If <em>item active property</em> is a key in
-                    <em>result</em>, then initialize <em>map object</em> to
-                    its associated value, otherwise initialize it to an empty
-                    <tref>JSON object</tref>.
-                  </li>
-                  <li>
-                    If <em>container</em> is <code>@language</code> and
-                    <em>compacted item</em> contains the key
-                    <code>@value</code>, then set <em>compacted item</em>
-                    to the value associated with its <code>@value</code> key.
-                  </li>
-                  <li>
-                    Initialize <em>map key</em> to the value associated with
-                    with the key that equals <em>container</em> in
-                    <em>expanded item</em>.
-                  </li>
-                  <li>
-                    If <em>map key</em> is not a key in <em>map object</em>,
-                    then set this key's value in <em>map object</em>
-                    to <em>compacted item</em>. Otherwise, if the value
-                    is not an <tref>array</tref>, then set it equal to one
-                    containing only the value and then append
-                    <em>compacted item</em> to it.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                Otherwise,
-                <ol class="algorithm">
-                  <li>
-                    Initialize <em>useArray</em> to <tref>false</tref>. If
-                    <em>container</em> equals <code>@set</code> or
-                    <code>@list</code>, or <em>compacted item</em> is
-                    an empty <tref>array</tref>, or
-                    <em>expanded property</em> equals <code>@list</code> or
-                    <code>@graph</code>, then set <em>useArray</em>
-                    to <tref>true</tref>.
-                  </li>
-                  <li>
-                    If <em>useArray</em> is <tref>true</tref> and
-                    <em>compacted item</em> is not an <tref>array</tref>,
-                    then set it equal to a new <tref>array</tref>
-                    containing only <em>compacted item</em>.
-                  </li>
-                  <li>
-                    If <em>item active property</em> is not a key in
-                    <em>result</em> then add the key-value pair,
-                    (<em>item active property</em>-<em>compacted item</em>),
-                    to <em>result</em>.
-                  </li>
-                  <li>
-                    Otherwise, if the value associated with the key that
-                    equals <em>item active property</em> in <em>result</em>
-                    is not an <tref>array</tref>, set it equal to a new
-                    <tref>array</tref> containing only the value. Then
-                    append <em>compacted item</em> to the value if
-                    <em>compacted item</em> is not an <tref>array</tref>,
-                    otherwise, concatenate it.
-                  </li>
-                </ol>
-              </li>
-            </ol>
-          </li>
-        </ol>
-      </li>
-      <li>
-        Return <em>result</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    At this point, <em>element</em> must a be <tref>scalar</tref>, which
-    is already compact, so simply return <em>element</em>.
-  </li>
-</ol>
-
-<p>
-If, after the algorithm outlined above is run, the result <em>result</em> is
-an <tref>array</tref> with two or more items and a <em>context</em> has
-been passed, replace it with a new <tref>JSON object</tref> with a single
-key-value pair where the key is the result of using the
-<a href="#iri-compaction-algorithm">IRI Compaction</a> algorithm, passing
-<tref>active context</tref> and <code>@graph</code> for <em>iri</em>, and
-the value is <em>result</em>. Otherwise, if <em>result</em> is an
-<tref>array</tref> with only one item, set <em>result</em> to that item.
-Otherwise, if <em>result</em> is an <tref>array</tref> with zero items,
-replace it with an empty <tref>JSON object</tref>. Finally, if a
-<em>context</em> has been passed, add an <code>@context</code> property to
-<em>result</em> and set its value to the initially passed
-<em>context</em>.
-</p>
-
-</section>
-
-<!-- end of Compaction -->
-</section>
-
-<section>
-<h2>IRI Compaction Algorithm</h2>
-
-<p>
-This section defines an algorithm for transforming an <tref>IRI</tref>
-to a <tref>term</tref> or <tref>compact IRI</tref>, or a <tref>keyword</tref>
-alias to a <tref>keyword</tref>. A value that is associated with the
-<tref>IRI</tref> may be passed in order to assist in selecting the most
-context-appropriate <tref>term</tref>.
-</p>
-
-<section>
-<h3>Problem</h3>
-
-We have an <tref>IRI</tref> (or <tref>keyword</tref>) that we may
-be able to compact to <tref>term</tref>, <tref>compact IRI</tref>, or
-<tref>keyword</tref> alias.
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-First, we handle the simple cases: if the value given as an <tref>IRI</tref>
-is <tref>null</tref>, we simply return <tref>null</tref> and if it is a
-<tref>keyword</tref> we return its associated alias.
-</p>
-
-<p>
-Otherwise, we first try to find a <tref>term</tref> that the
-<tref>IRI</tref> can be <tref title="compaction">compacted</tref> to. In
-order to select a <tref>term</tref>, we have to collect information about
-the <tref title="IRI">IRI's</tref> associated value. This information
-includes which <tref title="container mapping">container mappings</tref>
-would be preferred for expressing the value, and what its
-<tref>type mapping</tref> or <tref>language mapping</tref> is. For
-JSON-LD lists, the <tref>type mapping</tref> or <tref>language mapping</tref>
-will be chosen based on the most specific values that work for all items in
-the list. Once this information is gathered, it is passed to the
-<a href="#term-selection">Term Selection</a> subalgorithm, which will
-return the most appropriate <tref>term</tref> to use.</p>
-
-<p>
-If no <tref>term</tref> was found that could be used to compact the
-<tref>IRI</tref>, then an attempt is made to find a <tref>compact IRI</tref>
-to use. If there is no appropriate <tref>compact IRI</tref>, then
-the <tref title="active context">active context's</tref>
-<tref>vocabulary mapping</tref> is used. Finally, if the <tref>IRI</tref>
-still could not be compacted, we simply return it as is.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-This algorithm takes three required inputs and three optional inputs.
-The required inputs an <tref>active context</tref> and the <em>iri</em> to
-be compacted. The optional inputs are: a <em>value</em> associated with
-the <em>iri</em>, a <em>vocabRelative</em> flag which specifies whether the
-passed <em>iri</em> should be compacted using the
-<tref title="active context">active context's</tref>
-<tref>vocabulary mapping</tref>, and the <em>parent</em> element for
-the <em>value</em>. If not passed, <em>value</em> is set to
-<tref>null</tref>, <em>vocabRelative</em> is set to <code>false</code>, and
-<em>parent</em> is set to <tref>null</tref>.
-</p>
-
-<ol class="algorithm">
-  <li>
-    If <em>iri</em> is <tref>null</tref>, return <tref>null</tref>.
-  </li>
-  <li>
-    If <em>iri</em> is a <tref>keyword</tref> and does not have a
-    <tref>keyword</tref> alias, return <em>iri</em>, otherwise return
-    its first associated <tref>keyword</tref> alias from
-    <tref>active context</tref>.
-  </li>
-  <li>
-    If <tref>active context</tref> has no associated
-    <tref>inverse context</tref>, then generate it using the
-    <a href="#inverse-context-creation">Inverse Context Creation</a>
-    algorithm. Set <em>inverse context</em> to the
-    <tref>inverse context</tref> associated with <tref>active context</tref>.
-  </li>
-  <li>
-    Initialize <em>defaultLanguage</em> to
-    <tref title="active context">active context's</tref>
-    <tref>default language</tref>, if it has one, otherwise to
-    <code>@none</code>.
-  </li>
-  <li>
-    If <em>iri</em> is a key in <em>inverse context</em>:
-    <ol class="algorithm">
-      <li>
-        Initialize <em>entry</em> to the value in <em>inverse context</em>
-        associated with the key that equals <em>iri</em>.
-      </li>
-      <li>
-        Initialize <em>containers</em> to an empty <tref>array</tref>. This
-        <tref>array</tref> will be used to keep track of an ordered list of
-        preferred <tref title="container mapping">container mappings</tref>
-        for a <tref>term</tref>, based on what is compatible with
-        <em>value</em>.
-      </li>
-      <li>
-        If <em>value</em> is a <tref>JSON object</tref> that contains the
-        key <code>@index</code>, then append the value <code>@index</code>
-        to <em>containers</em>.
-      </li>
-      <li>
-        Initialize <em>typeOrLanguage</em> to <code>@language</code>,
-        and <em>typeOrLanguageValue</em> to <code>@null</code>. These two
-        variables will keep track of the preferred
-        <tref>type mapping</tref> or <tref>language mapping</tref> for
-        a <tref>term</tref>, based on what is compatible with <em>value</em>.
-      </li>
-        If <em>value</em> is a <tref>list object</tref>, then set
-        <em>typeOrLanguage</em> and <em>typeOrLanguageValue</em>
-        to the most specific values that work for all items in
-        the list as follows:
-        <ol class="algorithm">
-          <li>
-            If <code>@index</code> is a not key in <em>value</em>, then
-            append <code>@list</code> to <em>containers</em>.
-          </li>
-          <li>
-            Initialize <em>list</em> to the <tref>array</tref> associated
-            with the key <code>@list</code> in <em>value</em>.
-          </li>
-          <li>
-            Initialize <em>commonLanguage</em> to <tref>null</tref>. If
-            <em>list</em> is empty, set <em>commonLanguage</em> to
-            <em>defaultLanguage</em>.
-          </li>
-          <li>
-            For each <em>item</em> in <em>list</em>:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>itemLanguage</em> to <code>@none</code> and
-                <em>itemType</em> to <code>@none</code>.
-              </li>
-              <li>
-                If <em>item</em> contains the key <code>@value</code>:
-                <ol class="algorithm">
-                  <li>
-                    If <em>item</em> contains the key <code>@language</code>,
-                    then set <em>itemLanguage</em> to its associated
-                    value.
-                  </li>
-                  <li>
-                    Otherwise, if <em>item</em> contains the key
-                    <code>@type</code>, set <em>itemType</em> to its
-                    associated value.
-                  </li>
-                  <li>
-                    Otherwise, set <em>itemLanguage</em> to
-                    <code>@null</code>.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                Otherwise, set <em>itemType</em> to <code>@id</code>.
-              </li>
-              <li>
-                If <em>commonLanguage</em> is <tref>null</tref>, set it
-                to <em>itemLanguage</em>.
-              </li>
-              <li>
-                Otherwise, if <em>itemLanguage</em> does not equal
-                <em>commonLanguage</em> and <em>item</em> contains the
-                key <code>@value</code>, then set <em>commonLanguage</em>
-                to <code>@none</code> because list items have conflicting
-                languages.
-              </li>
-              <li>
-                If <em>commonType</em> is <tref>null</tref>, set it
-                to <em>itemType</em>.
-              </li>
-              <li>
-                Otherwise, if <em>itemType</em> does not equal
-                <em>commonType</em>, then set <em>commonType</em>
-                to <code>@none</code> because list items have conflicting
-                types.
-              </li>
-              <li>
-                If <em>commonLanguage</em> equals <code>@none</code> and
-                <em>commonType</em> equals <code>@none</code>, then
-                stop processing items in the list because it has been
-                detected that there is no common language or type amongst
-                the items.
-              </li>
-            </ol>
-          </li>
-          <li>
-            If <em>commonLanguage</em> is <tref>null</tref>, set it to
-            <code>@none</code>.
-          </li>
-          <li>
-            If <em>commonType</em> is <tref>null</tref>, set it to
-            <code>@none</code>.
-          </li>
-          <li>
-            If <em>commonType</em> is not <code>@none</code> then set
-            <em>typeOrLanguage</em> to <code>@type</code> and
-            <em>typeOrLanguageValue</em> to <em>commonType</em>.
-          </li>
-          <li>
-            Otherwise, set <em>typeOrLanguageValue</em> to
-            <em>commonLanguage</em>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        Otherwise:
-        <ol class="algorithm">
-          <li>
-            If <em>value</em> contains the key <code>@value</code>:
-            <ol class="algorithm">
-              <li>
-                If <em>value</em> contains the key <code>@language</code>,
-                then set <em>typeOrLanguageValue</em> to its associated
-                value and append <code>@language</code> to
-                <em>containers</em>.
-              </li>
-              <li>
-                Otherwise, if <em>value</em> contains the key
-                <code>@type</code>, then set <em>typeOrLanguageValue</em> to
-                its associated value and set <em>typeOrLanguage</em> to
-                <code>@type</code>.
-              </li>
-            </ol>
-          </li>
-          <li>
-            Otherwise, set <em>typeOrLanguage</em> to <code>@type</code>
-            and set <em>typeOrLanguageValue</em> to <code>@id</code>.
-          </li>
-          <li>
-            Append <code>@set</code> to <em>containers</em>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        Initialize <em>term</em> to the result of the
-        <a href="#term-selection">Term Selection</a> subalgorithm, passing
-        <tref>active context</tref>, <em>value</em>, <em>parent</em>,
-        <em>entry</em>, <em>containers</em>, <em>typeOrLanguage</em>, and
-        <em>typeOrLangaugeValue</em>.
-      </li>
-      <li>
-        If <em>term</em> is not <tref>null</tref>, return <em>term</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    At this point, there is no simple <tref>term</tref> that <em>iri</em>
-    can be compacted to. Instead, try to choose a <tref>compact IRI</tref>,
-    starting by initializing <em>choice</em> to <tref>null</tref>. This
-    variable will be used to store the chosen <tref>compact IRI</tref> to
-    use, if any.
-  </li>
-  <li>
-    For each key <tref>term</tref> and value <tref>term definition</tref> in
-    the <tref>active context</tref>:
-    <ol class="algorithm">
-      <li>
-        If the <tref>term</tref> contains a colon (<code>:</code>),
-        then continue to the next <tref>term</tref> because
-        <tref title="term">terms</tref> with colons can't be
-        used as <tref title="prefix">prefixes</tref>.
-      </li>
-      <li>
-        If the <tref>term definition</tref> is <tref>null</tref>
-        or for a <tref>property generator</tref> or its
-        <tref>IRI mapping</tref> equals <em>iri</em> or is not
-        a substring at the beginning of <em>iri</em>, then the
-        <tref>term</tref> cannot be used as a <tref>prefix</tref>
-        because it is not a partial match with <em>iri</em>. So
-        continue to the next <tref>term</tref>.
-      </li>
-      <li>
-        Initialize <em>curie</em> by concatenating <tref>term</tref>,
-        a colon (<code>:</code>), and the substring of <em>iri</em>
-        that follows after the value of the
-        <tref title="term definition">term definition's</tref>
-        <tref>IRI mapping</tref>.
-      </li>
-      <li>
-        Initialize <em>isUsableCurie</em> to <tref>false</tref>. If
-        <em>curie</em> does not have a <tref>term definition</tref> in
-        <tref>active context</tref> or if the
-        <tref>term definition</tref> has an <tref>IRI mapping</tref>
-        that equals <em>iri</em> and <em>value</em> is <tref>null</tref>,
-        then set <em>isUsableCurie</em> to <tref>true</tref>.
-      </li>
-      <li>
-        If <em>isUsableCurie</em> equals <tref>true</tref> and either
-        <em>choice</em> is <tref>null</tref> or <em>curie</em> is shorter
-        or the same length but lexicographically less than
-        <em>choice</em>, set <em>choice</em> to <em>curie</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    If <em>choice</em> is not <tref>null</tref>, return <em>choice</em>.
-  </li>
-  <li>
-    At this point, there is no <tref>compact IRI</tref> that <em>iri</em>
-    can be compacted to, so if <em>vocabRelative</em> equals
-    <tref>true</tref> and <tref>active context</tref> has a
-    <tref>vocabulary mapping</tref>:
-    <ol class="algorithm">
-      <li>
-        If <em>iri</em> begins with the
-        <tref title="vocabulary mapping">vocabulary mapping's</tref> value
-        but is longer, then initialize <em>suffix</em> to the substring
-        of <em>iri</em> that does not match. If <em>suffix</em> does not
-        have a <tref>term definition</tref> in <tref>active context</tref>,
-        then return <em>suffix</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    There are no <tref>compaction</tref> options for <em>iri</em> so
-    return <em>iri</em> as is.
-  </li>
-</ol>
-
-</section>
-
-<!-- end of IRI Compaction -->
-</section>
-
-<section>
-<h2>Inverse Context Creation Subalgorithm</h2>
-
-<p>
-When there is more than one <tref>term</tref> that could be chosen
-to compact an <tref>IRI</tref>, we want to ensure that our <tref>term</tref>
-selection is both deterministic and not unexpected, representing the most
-context-appropriate choice whilst taking into consideration algorithmic
-complexity.
-</p>
-
-<p>
-In order to make <tref>term</tref> selections the concept of an
-<tref>inverse context</tref> is introduced. An <tdef>inverse context</tdef>
-is essentially a reverse lookup table that maps
-<tref title="container mapping">container mappings</tref>,
-<tref title="type mapping">type mappings</tref>, and
-<tref title="language mapping">language mappings</tref> to a simple
-<tref>term</tref> and, if applicable, an <tref>array</tref> of potential
-<tref>property generator</tref> <tref title="term">terms</tref> for
-a given <tref>active context</tref>. A <tref>inverse context</tref> only
-needs to be generated for an <tref>active context</tref> if it is being
-used for <tref>compaction</tref>.
-</p>
-
-<p>
-To make use of an <tref>inverse context</tref>, a list of preferred
-<tref title="container mapping">container mappings</tref> and the
-<tref>type mapping</tref> or <tref>language mapping</tref> are gathered
-for a particular value associated with an <tref>IRI</tref>. These parameters
-are then fed to the <a href="#term-selection">Term Selection</a>
-subalgorithm, which will find the <tref>term</tref> that most appropriately
-matches the value's mappings.
-</p>
-
-<section>
-<h3>Problem</h3>
-
-An <tref>inverse context</tref> must be created for the given
-<tref>active context</tref>.
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-To create an <tref>inverse context</tref> for a given
-<tref>active context</tref>, each <tref>term</tref> in the
-<tref>active context</tref> is visited, ordered by length, shortest
-first (ties are broken by choosing the lexicographically least
-<tref>term</tref>). For each <tref>term</tref>, an entry is added to
-the <tref>inverse context</tref> for each possible combination of
-<tref>container mapping</tref> and <tref>type mapping</tref>
-or <tref>language mapping</tref> that would legally match the
-<tref>term</tref>. Illegal matches include differences between a
-value's <tref>type mapping</tref> or <tref>language mapping</tref> and
-that of the <tref>term</tref>. If a <tref>term</tref> has no
-<tref>container mapping</tref>, <tref>type mapping</tref>, or
-<tref>language mapping</tref> (or some combination of these), then it
-will have an entry in the <tref>inverse context</tref> using the special
-key <code>@none</code>. This allows the
-<a href="#term-selection">Term Selection</a> subalgorithm to fall back
-to choosing more generic <tref title="term">terms</tref> when a more
-specificly-matching <tref>term</tref> is not available for a particular
-<tref>IRI</tref> and value combination.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-The algorithm takes one required input: the <tref>active context</tref> that
-the <tref>inverse context</tref> is being created for.
-</p>
-
-<ol class="algorithm">
-  <li>
-    Initialize <em>result</em> to an empty <tref>JSON object</tref>.
-  <li>
-    Initialize <em>defaultLanguage</em> to <code>@none</code>. If the
-    <tref>active context</tref> has a <tref>default language</tref>, then
-    set <em>defaultLanguage</em> to it.
-  </li>
-  <li>
-    For each key <tref>term</tref> and value <term>term definition</tref> in
-    the <tref>active context</tref>, ordered by shortest <tref>term</tref>
-    first (breaking ties by choosing the lexicographically least
-    <tref>term</tref>):
-    <ol class="algorithm">
-      <li>
-        If the <tref>term definition</tref> is <tref>null</tref>, then
-        <tref>term</tref> cannot be selected during <tref>compaction</tref>,
-        so continue to the next <tref>term</tref>.
-      </li>
-      <li>
-        Initialize <em>container</em> to <code>@none</code>. If there
-        is a <tref>container mapping</tref> in
-        <tref>term definition</tref>, then set <em>container</em> to
-        its associated value.
-      </li>
-      <li>
-        Initialize <em>iris</em> to the value of the <tref>IRI mapping</tref>
-        for the <tref>term definition</tref>. If <em>iris</em> is not an
-        <tref>array</tref>, then set it to an <tref>array</tref> containing
-        only <em>iris</em>.
-      </li>
-      <li>
-        For each item <em>iri</em> in <em>iris</em>:
-        <ol class="algorithm">
-          <li>
-            If <em>iri</em> is not a key in <em>result</em>, then add
-            a key-value pair where the key is <em>iri</em> and the value
-            is an empty <tref>JSON object</tref> to <em>result</em>.
-          </li>
-          <li>
-            Initialize <em>container map</em> to the value associated with
-            the <em>iri</em> key in <em>result</em>.
-          </li>
-          <li>
-            If <em>container</em> is not a key in <em>container map</em>,
-            then initialize <em>typeOrLanguage map</em> to a new
-            <tref>JSON object</tref>. Add two key-value pairs to
-            <em>typeOrLanguage map</em>, where the first's key is
-            <code>@language</code> and its value is a new
-            <tref>JSON object</tref> and where the second's key is
-            <code>@type</code> and its value is a new
-            <tref>JSON object</tref>. Set the value of the key
-            <em>defaultLanguage</em> in the value associated with the
-            key <code>@language</code> in <em>typeOrLanguage map</em>
-            to a new <tref>JSON object</tref> containing a key-value pair
-            where the key is <code>term</code> and the value is
-            <tref>null</tref>.
-          </li>
-          <li>
-            Set <em>typeOrLanguage map</em> to the value associated with
-            the key <em>container</em> in <em>container map</em>.
-          </li>
-          <li>
-            If there is no <tref>type mapping</tref> in the
-            <tref>term definition</tref>:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>language map</em> to the value associated
-                with the key <code>@language</code> in
-                <em>typeOrLanguage map</em>.
-              </li>
-              <li>
-                If there is a <tref>language mapping</tref> in the
-                <tref>term definition</tref>:
-                <ol class="algorithm">
-                  <li>
-                    If the value of the <tref>language mapping</tref>
-                    is <tref>null</tref> initialize <em>language</em>
-                    to <code>@null</code>, otherwise initialize it to the
-                    value.
-                  </li>
-                  <li>
-                    If <em>language</em> is not a key in
-                    <em>language map</em>, then add a key-value
-                    pair to <em>language map</em> where the key is
-                    <em>language</em> and the value is a new
-                    <tref>JSON object</tref> with two key-value
-                    pairs, where the first's key is <code>term</code>
-                    and its value is <tref>null</tref>, and the second's
-                    key is <code>propertyGenerators</code> and the
-                    value is an empty <tref>array</tref>.
-                  </li>
-                  <li>
-                    Initialize <em>entry</em> to the value associated with
-                    the key <em>language</em> in <em>language map</em>.
-                  </li>
-                  <li>
-                    If <tref>term definition</tref> is a
-                    <tref>property generator</tref>, append the
-                    <tref>term</tref> to the <tref>array</tref> associated
-                    with the <code>propertyGenerators</code> key in
-                    <em>entry</em>.
-                  </li>
-                  <li>
-                    Otherwise, if the value associated with the key
-                    <code>term</code> in <em>entry</em> is <tref>null</tref>,
-                    set it to the <tref>term</tref>.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                Otherwise:
-                <ol class="algorithm">
-                  <li>
-                    If <em>defaultLanguage</em> is not a key in
-                    <em>language map</em>, then add a key-value
-                    pair to <em>language map</em> where the key is
-                    <em>defaultLanguage</em> and the value is a new
-                    <tref>JSON object</tref> with two key-value
-                    pairs, where the first's key is <code>term</code>
-                    and its value is <tref>null</tref>, and the second's
-                    key is <code>propertyGenerators</code> and the
-                    value is an empty <tref>array</tref>.
-                  </li>
-                  <li>
-                    Initialize <em>entry</em> to the value associated with
-                    the key <em>defaultLanguage</em> in <em>language map</em>.
-                  </li>
-                  <li>
-                    If <tref>term definition</tref> is a
-                    <tref>property generator</tref>, append the
-                    <tref>term</tref> to the <tref>array</tref> associated
-                    with the <code>propertyGenerators</code> key in
-                    <em>entry</em>.
-                  </li>
-                  <li>
-                    Otherwise, if the value associated with the key
-                    <code>term</code> in <em>entry</em> is <tref>null</tref>,
-                    set it to the <tref>term</tref>.
-                  </li>
-                  <li>
-                    If <code>@none</code> is not a key in
-                    <em>language map</em>, then add a key-value
-                    pair to <em>language map</em> where the key is
-                    <code>@none</code> and the value is a new
-                    <tref>JSON object</tref> with two key-value
-                    pairs, where the first's key is <code>term</code>
-                    and its value is <tref>null</tref>, and the second's
-                    key is <code>propertyGenerators</code> and the
-                    value is an empty <tref>array</tref>.
-                  </li>
-                  <li>
-                    Set <em>entry</em> to the value associated with
-                    the key <code>@none</code> in <em>language map</em>.
-                  </li>
-                  <li>
-                    If <tref>term definition</tref> is a
-                    <tref>property generator</tref>, append the
-                    <tref>term</tref> to the <tref>array</tref> associated
-                    with the <code>propertyGenerators</code> key in
-                    <em>entry</em>.
-                  </li>
-                  <li>
-                    Otherwise, if the value associated with the key
-                    <code>term</code> in <em>entry</em> is <tref>null</tref>,
-                    set it to the <tref>term</tref>.
-                  </li>
-                </ol>
-              </li>
-            </ol>
-          </li>
-          <li>
-            If there is no <tref>language mapping</tref> in the
-            <tref>term definition</tref>:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>type map</em> to the value associated
-                with the key <code>@type</code> in
-                <em>typeOrLanguage map</em>.
-              </li>
-              <li>
-                If there is a <tref>type mapping</tref> in the
-                <tref>term definition</tref> then initialize <em>type</em>
-                to its value, otherwise initialize it to
-                to <code>@none</code>.
-              </li>
-              <li>
-                If <em>type</em> is not a key in <em>type map</em>, then
-                add a key-value pair to <em>type map</em> where the key is
-                <em>type</em> and the value is a new <tref>JSON object</tref>
-                with two key-value pairs, where the first's key is
-                <code>term</code> and its value is <tref>null</tref>, and the
-                second's key is <code>propertyGenerators</code> and the
-                value is an empty <tref>array</tref>.
-              </li>
-              <li>
-                Initialize <em>entry</em> to the value associated with
-                the key <em>type</em> in <em>type map</em>.
-              </li>
-              <li>
-                If <tref>term definition</tref> is a
-                <tref>property generator</tref>, append the
-                <tref>term</tref> to the <tref>array</tref> associated
-                with the <code>propertyGenerators</code> key in
-                <em>entry</em>.
-              </li>
-              <li>
-                Otherwise, if the value associated with the key
-                <code>term</code> in <em>entry</em> is <tref>null</tref>,
-                set it to the <tref>term</tref>.
-              </li>
-            </ol>
-          </li>
-        </ol>
-      </li>
-    </ol>
-  </li>
-  <li>
-    Return <em>result</em>.
-  </li>
-</ol>
-
-</section>
-
-<!-- end of Inverse Context Creation subalgorithm -->
-</section>
-
-<section>
-<h2>Term Selection Subalgorithm</h2>
-
-<p>
-This subalgorithm, invoked via the
-<a href="#iri-compaction-algorithm">IRI Compaction</a> algorithm, makes use
-of an <tref title="active context">active context's</tref>
-<tref>inverse context</tref> to find the <tref>term</tref> that is best
-used to <tref title="compaction">compact</tref> an <tref>IRI</tref>. Other
-information about a value associated with the <tref>IRI</tref> is given,
-including which <tref title="container mapping">container mappings</tref>
-and which <tref>type mapping</tref> or <tref>language mapping</tref> would
-be best used to express the value.
-</p>
-
-<section>
-<h3>Problem</h3>
-
-An <tref>IRI</tref> with an associated <em>value</em> should be compacted
-to the most appropriate <tref>term</tref> in the <tref>active context</tref>.
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-The <tref title="inverse context">inverse context's</tref> entry for
-the <tref>IRI</tref> will be first searched according to the preferred
-<tref title="container mapping">container mappings</tref>, in the order
-that they are given. Amongst <tref title="term">terms</tref> with a matching
-<tref>container mapping</tref>, preference will be given to those
-with a matching <tref>type mapping</tref> or <tref>language mapping</tref>,
-over those without a <tref>type mapping</tref> or
-<tref>language mapping</tref>. If there is no <tref>term</tref>
-with a matching <tref>container mapping</tref> then the <tref>term</tref>
-without a <tref>container mapping</tref> that matches the given
-<tref>type mapping</tref> or <tref>language mapping</tref> is selected. If
-there is still no selected <tref>term</tref>, then a <tref>term</tref>
-with no <tref>type mapping</tref> or <tref>language mapping</tref> will
-be selected if available. No <tref>term</tref> will be selected that
-has a conflicting <tref>type mapping</tref> or <tref>language mapping</tref>.
-Ties between <tref title="term">terms</tref> that have the same
-mappings are resolved by first choosing the shortest terms, and then by
-choosing the lexicographically least term. Note that these ties are
-resolved automatically because they were previously resolved when the
-<a href="#inverse-context-creation">Inverse Context Creation algorithm</a>
-was used to create the <tref>inverse context</tref>.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-This subalgorithm has seven required inputs. They are:
-an <tref>active context</tref>, an <tref>IRI</tref> <em>iri</em>,
-a <em>value</em> associated with the <tref>IRI</tref>, the expanded
-<em>parent</em> element for <em>value</em> (which may be a
-<tref>JSON object</tref>, an <tref>array</tref>, or <tref>null</tref>), an
-<tref>array</tref> <em>containers</em> that represents ordered list of
-preferred <tref title="container mapping">container mappings</tref>, a
-<tref>string</tref> <em>typeOrLanguage</em> that indicates whether
-to look for a <tref>term</tref> with a matching <tref>type mapping</tref>
-or <tref>language mapping</tref>, and a <tref>string</tref>
-<em>typeOrLanguageValue</em> with the associated value for the
-<tref>type mapping</tref> or <tref>language mapping</tref> to look for.
-</p>
-
-<ol class="algorithm">
-  <li>
-    Append <code>@none</code> to <em>containers</em>. This represents
-    the non-existence of a <tref>container mapping</tref>, and it will
-    be the last <tref>container mapping</tref> value to be checked as it
-    is the most generic.
-  </li>
-  <li>
-    Initialize <em>container map</em> to the value associated with
-    <em>iri</em> in the <tref>inverse context</tref>.
-  </li>
-  <li>
-    If <em>typeOrLanguageValue</em> is <tref>null</tref>, set it to
-    <code>@null</code>. This is the key under which <tref>null</tref> values
-    are stored in the <tref>inverse context</tref> <em>entry</em>.
-  </li>
-  <li>
-    Initialize <em>preferred values</em> to an <tref>array</tref> containing
-    <em>typeOrLangageValue</em> and <code>@none</code>, in that order. This
-    <tref>array</tref> indicates, in order, the preferred values for
-    a <tref title="term">term's</tref> <tref>type mapping</tref> or
-    <tref>language mapping</tref>.
-  </li>
-  <li>
-    Initialize <em>selected term</em> to <tref>null</tref>.
-  </li>
-  <li>
-    For each item <em>container</em> in <em>containers</em> while
-    <em>selected term</em> is <tref>null</tref>:
-    <ol class="algorithm">
-      <li>
-        If <em>container</em> is not a key in <em>container map</em>, then
-        there is no <tref>term</tref> with a matching
-        <tref>container mapping</tref> for it, so continue to the next
-        <em>container</em>.
-      </li>
-      <li>
-        Initialize <em>typeOrLanguage map</em> to the value associated
-        with <em>container</em> in <em>container map</em>.
-      </li>
-      <li>
-        Initialize <em>typeOrLanguageValue map</em> to the value associated
-        with <em>typeOrLanguage</em> in <em>typeOrLanguage map</em>.
-      </li>
-      <li>
-        For each <em>item</em> in <em>preferred values</em> while
-        <em>selected term</em> is <tref>null</tref>:
-        <ol class="algorithm">
-          <li>
-            If <em>item</em> is not a key in <em>typeOrLanguageValue map</em>,
-            then there is no <tref>term</tref> with a matching
-            <tref>type mapping</tref> or <tref>language mapping</tref>,
-            so continue to the next <em>item</em>.
-          </li>
-          <li>
-            Initialize <em>termInfo</em> to the value associated with
-            <em>item</em> in <em>typeOrLanguageValue map</em>.
-          </li>
-          <li>
-            If <em>parent</em> is a <tref>JSON object</tref>,
-            then for each <tref>property generator</tref> <tref>term</tref>
-            <em>propertyGeneratorTerm</em> in <em>termInfo</em> while
-            <em>selected term</em> is <tref>null</tref>:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>match</em> to the result of using the
-                <a href="#find-property-generator-duplicates">Find Property Generator Duplicates</a>
-                algorithm, passing <tref>active context</tref>,
-                <em>parent</em> for <em>element</em>, <em>iri</em> for
-                <em>expanded property</em>, <em>value</em>,
-                <em>propertyGeneratorTerm</em> for <em>activeProperty</em>,
-                and <tref>false</tref> for <em>remove</em>.
-              </li>
-              <li>
-                If <em>match</em> equals <tref>true</tref>, then set
-                <em>selected term</em> to <em>propertyGeneratorTerm</em>.
-              </li>
-            </ol>
-          </li>
-          <li>
-            If <em>selected term</em> is <tref>null</tref>, then no
-            <tref>property generator</tref> match was found, so set
-            <em>selected term</em> to the non-<tref>property generator</tref>
-            <tref>term</tref> in <em>termInfo</em>, which may be
-            <tref>null</tref>.
-          </li>
-        </ol>
-      </li>
-    </ol>
-  </li>
-  <li>
-    Return <em>selected term</em>.
-  </li>
-</ol>
-
-</section>
-
-<!-- end of Term Selection subalgorithm -->
-</section>
-
-<section>
-<h2>Value Compaction</h2>
-
-<p>
-<tref>Expansion</tref> transforms all values into <tref>expanded form</tref>
-in JSON-LD. This algorithm performs the opposite operation, transforming
-a value into <tdef>compacted form</tdef>. This algorithm compacts a
-value according to the <tref>term definition</tref> in the given
-<tref>active context</tref> that is associated with the value's associated
-<tref>active property</tref>.
-</p>
-
-<section>
-<h3>Problem</h3>
-
-A <em>value</em> associated with an <tref>active property</tref> must
-be <tref title="compaction">compacted</tref> to <tref>compacted form</tref>.
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-The <em>value</em> to compact either contains the key <code>@value</code>
-or the key <code>@id</code>.
-</p>
-
-<p>
-We start with the former case, first trying to compact the
-<em>value</em> into just the value associated with its
-<code>@value</code> key. This can be done if the <em>value</em> is not
-going to be contained by an <code>@index</code> container and if the
-<tref>active property</tref> has a matching <tref>type mapping</tref> or
-<tref>language mapping</tref>. It can also be done if <code>@value</code>
-is the only key in <em>value</em> and either its associated value is
-not a <tref>string</tref>, there's no <tref>default language</tref>, or
-there's an explicit <tref>null</tref> <tref>language mapping</tref> for
-the <tref>active property</tref>.
-</p>
-
-<p>
-If we couldn't do the above optimal compaction, then we simply replace
-<tref title="keyword">keywords</tref> with aliases and compact any
-<tref title="IRI">IRIs</tref>.
-</p>
-
-<p>
-For the latter case, where the key <code>@id</code> appears in <em>value</em>,
-we compact the associated value using the
-<a href="#iri-compaction-algorithm">IRI Compaction</a> algorithm, and
-use its value if the <tref>type mapping</tref> associated with the
-<tref>active property</tref> is <code>@id</code> or the expanded value for
-the <tref>active property</tref> is <code>@graph</code>. Otherwise, we
-replace the <code>@id</code> key with its alias and its associated value
-with its compacted version.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-This algorithm has three required inputs: an <tref>active context</tref>, an
-an <tref>active property</tref>, and a <em>value</em> to be compacted.
-</p>
-
-<ol class="algorithm">
-  <li>
-    If <em>value</em> contains the key <code>@value</code>:
-    <ol class="algorithm">
-      <li>
-        Initialize <em>preserveIndex</em> to <tref>false</tref>. If
-        <code>@index</code> is a key in <em>value</em> and
-        <tref>active property</tref> does not have a
-        <tref>container mapping</tref> in <tref>active context</tref> that
-        equals <code>@index</code>, set <em>preserveIndex</em> to
-        <tref>true</tref>.
-      </li>
-      <li>
-        If <em>preserveIndex</em> equals <tref>false</tref> and either
-        <em>value</em> has a <code>@type</code> key with a value that
-        matches <tref title="active property">active property's</tref>
-        <tref>type mapping</tref> in <tref>active context</tref> or
-        <em>value</em> has a <code>@language</code> key with a value that
-        matches <tref title="active property">active property's</tref>
-        <tref>language mapping</tref> in <tref>active context</tref>, then
-        return the value associated with the <code>@value</code> key in
-        <em>value</em>.
-      </li>
-      <li>
-        If <code>@value</code> is the only key in <em>value</em> or
-        <em>preserveIndex</em> equals <tref>false</tref> and either
-        there is no <tref>default language</tref> in
-        <tref>active context</tref>, the value associated with the
-        <code>@value</code> key in <em>value</em> is not a
-        <tref>string</tref>, or <tref>active property</tref>
-        has a <tref>null</tref> <tref>language mapping</tref> in
-        <tref>active context</tref>, then return the value
-        associated with the <code>@value</code> key in <em>value</em>.
-      </li>
-      <li>
-        Initialize <em>result</em> to an empty <tref>JSON object</tref>.
-      </li>
-      <li>
-        If <em>preserveIndex</em> equals <tref>true</tref>, then add
-        a key-value pair to <em>result</em> where the key is the result
-        using the <a href="#iri-compaction-algorithm">IRI compaction</a>
-        algorithm, passing <tref>active context</tref> and
-        <code>@index</code> for <em>iri</em>, and the value is
-        the value associated with the <code>@index</code> key in
-        <em>value</em>.
-      </li>
-      <li>
-        If <em>value</em> contains the key <code>@type</code>, then add
-        a key-value pair to <em>result</em> where the key is the result
-        using the <a href="#iri-compaction-algorithm">IRI compaction</a>
-        algorithm, passing <tref>active context</tref> and
-        <code>@type</code> for <em>iri</em>, and the value is the result
-        of using the <a href="#iri-compaction-algorithm">IRI compaction</a>
-        algorithm, passing <tref>active context</tref>, the value associated
-        with the <code>@type</code> key in <em>value</em> for <em>iri</em>,
-        <tref>true</tref> for <em>vocabRelative</em>, and
-        <tref>true</tref> for <em>documentRelative</em>.
-      </li>
-      <li>
-        Otherwise, if <em>value</em> contains the key <code>@language</code>,
-        then add a key-value pair to <em>result</em> where the key is the
-        result using the
-        <a href="#iri-compaction-algorithm">IRI compaction</a>
-        algorithm, passing <tref>active context</tref> and
-        <code>@language</code> for <em>iri</em>, and the value is the
-        value associated with the <code>@language</code> key in
-        <em>value</em>.
-      </li>
-      <li>
-        Add a key-value pair to <em>result</em> where the key is the result
-        using the <a href="#iri-compaction-algorithm">IRI compaction</a>
-        algorithm, passing <tref>active context</tref> and
-        <code>@value</code> for <em>iri</em>, and the value is the value
-        associated with the <code>@value</code> key in <em>value</em>.
-      </li>
-      <li>
-        Return <em>result</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Otherwise, <em>value</em> must contain the single key <code>@id</code>.
-    Initialize <em>expanded property</em> to the result of using the
-    <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-    <tref>active context</tref> and <em>value</em>.
-  </li>
-  <li>
-    Initialize <em>term</em> to the result of using the
-    <a href="#iri-compaction-algorithm">IRI compaction</a> algorithm,
-    passing <tref>active context</tref>, the value associated with
-    the key <code>@id</code> in <em>value</em> for <em>iri</em>,
-    and <tref>true</tref> for <em>documentRelative</em>.
-  </li>
-  <li>
-    If <tref>active property</tref> has a <tref>type mapping</tref> in
-    the <tref>active context</tref> that is equal to <code>@id</code> or
-    <em>expanded property</em> equals <code>@graph</code>, then return
-    <em>term</em>.
-  </li>
-  <li>
-    Initialize <em>result</em> to an empty <tref>JSON object</tref>. Add
-    a key-value pair to <em>result</em> where the key is the result of
-    using the <a href="#iri-compaction-algorithm">IRI compaction</a>
-    algorithm, passing <tref>active context</tref>, and <code>@id</code> for
-    <em>iri</em>, and the value is <em>term</em>.
-  </li>
-  <li>
-    Return <em>result</em>.
-  </li>
-</ol>
-
-</section>
-
-<!-- end of Value Compaction algorithm -->
-</section>
-
-<section>
-<h2>Find Property Generator Duplicates Subalgorithm</h2>
-
-<p>
-This algorithm checks if a specific value exists for all
-<tref title="IRI">IRIs</tref> associated with a
-<tref>property generator</tref> and, if specified, it removes them.
-The algorithm takes six required inputs: an <tref>active context</tref>,
-<em>element</em>, <em>expanded property</em>, <em>value</em>,
-<tref>active property</tref>, and a flag <em>remove</em>, that indicates
-whether or not to remove the duplicate values. It returns <tref>true</tref>
-if the required duplicate values were found and <tref>false</tref> if not.
-</p>
-
-<ol class="algorithm">
-  <li>
-    Initialize <em>result</em> to <tref>true</tref>.
-  </li>
-  <li>
-    Initialize <em>iris</em> to the <tref>array</tref> associated with the
-    <tref>IRI mapping</tref> for <tref>active property</tref> in
-    <tref>active context</tref>.
-  </li>
-  <li>
-    For each <em>iri</em> in <em>iris</em>:
-    <ol class="algorithm">
-      <li>
-        If <em>iri</em> equals <em>expanded property</em>, then this
-        is the <em>iri</em> that is to be preserved, so continue to the next
-        <em>iri</em>.
-      </li>
-      <li>
-        Set <em>result</em> to <tref>false</tref>.
-      </li>
-      <li>
-        If <em>element</em> contains a key that equals <em>iri</em>:
-        <ol class="algorithm">
-          <li>
-            Initialize <em>prospects</em> to the value associated with the
-            key that equals <em>iri</em> in <em>element</em>. This
-            <tref>array</tref> will be checked for a value that matches
-            the <tref>property generator</tref> <em>value</em>.
-          </li>
-          <li>
-            If <em>value</em> is an empty <tref>array</tref>:
-            <ol class="algorithm">
-              <li>
-                Set <em>result</em> to <tref>true</tref>.
-              </li>
-              <li>
-                If <em>remove</em> is <tref>true</tref>, remove <em>iri</em>
-                from <em>element</em>.
-              </li>
-              <li>
-                Continue to the next <em>iri</em>.
-              </li>
-            </ol>
-          </li>
-          <li>
-            For each item <em>prospect</em> in <em>prospects</em>, until
-            a <tref>property generator</tref> duplicate is found for
-            <em>value</em>:
-            <ol class="algorithm">
-              <li>
-                Check to see if <em>prospect</em> and <em>value</em> are
-                <tref>property generator</tref> duplicates:
-                <ol class="algorithm">
-                  <li>
-                    If their types and values are equal, then they are
-                    duplicates.
-                  </li>
-                  <li>
-                    Otherwise, if they are both
-                    <tref title="JSON object">JSON objects</tref> that contain
-                    the key <code>@value</code> and they both have the same
-                    key-value pairs for the keys <code>@value</code>,
-                    <code>@type</code>, <code>@language</code>, and
-                    <code>@index</code>, then they are duplicates.
-                  </li>
-                  <li>
-                    Otherwise, if they are both
-                    <tref title="list object">list objects</tref> with the same
-                    key-value pairs for the key <code>@index</code>, and the
-                    <tref title="array">arrays</tref> associated with their
-                    <code>@list</code> keys have the same length and their
-                    corresponding items, by index, are duplicates, then they
-                    are duplicates.
-                  </li>
-                  <li>
-                    Otherwise, if they are both
-                    <tref title="JSON object">JSON objects</tref> that contain
-                    the key <code>@id</code> and the values associated with
-                    those keys are equal, then they are duplicates.
-                  </li>
-                  <li>
-                    Otherwise, they are not duplicates.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                If <em>prospect</em> and <em>value</em> are
-                <tref>property generator</tref> duplicates:
-                <ol class="algorithm">
-                  <li>
-                    Set <em>result</em> to <tref>true</tref>.
-                  </li>
-                  <li>
-                    If <em>remove</em> is <tref>true</tref>, then remove
-                    <em>prospect</em> from <em>prospects</em> and, if
-                    <em>prospects</em> is now empty, remove <em>iri</em>
-                    from <em>element</em>.
-                  </li>
-                </ol>
-              </li>
-            </ol>
-          </li>
-        </ol>
-      </li>
-    </ol>
-  </li>
-  <li>
-    Return <em>result</em>.
-  </li>
-</ol>
-
-</section>
-
-<!-- FIXME -->
-<section>
-  <h2>Flattening Algorithm</h2>
-
-  <p>The algorithm takes two input variables, an <em>element</em> to flatten and a
-    <em>context</em> used to compact the flattened document.</p>
-
-  <ol class="algorithm">
-    <li>Expand <em>element</em> according the
-      <a href="#expansion-algorithm">Expansion algorithm</a>.</li>
-    <li>Generate a <em>nodeMap</em> according the
-      <a href="#node-map-generation">Node Map Generation algorithm</a>.</li>
-    <li>Let <em>defaultGraph</em> be the value of the <code>@default</code> member of
-      <em>nodeMap</em>; a <tref>JSON object</tref> representing the <tref>default graph</tref>.</li>
-    <li>For each other <em>graphName</em>-<em>graph</em> pair in <em>nodeMap</em>
-      perform the following steps:
-      <ol class="algorithm">
-        <li>If <em>defaultGraph</em> does not have a <em>graphName</em> member, create
-          one and initialize its value to a <tref>JSON object</tref> consisting of an
-          <code>@id</code> member whose value is set to <em>graphName</em>.</li>
-        <li>Add an <code>@graph</code> member set to an empty <tref>array</tref>
-          (referred to as <em>nodes</em>) to the <tref>JSON object</tref> which is the
-          value of the <em>graphName</em> member of <em>nodeMap</em>.</li>
-        <li>For each <em>id</em>-<em>node</em> pair in <em>graph</em> ordered by <em>id</em>,
-          add <em>node</em> to the <em>nodes</em> <tref>array</tref>.</li>
-      </ol>
-    </li>
-    <li>Initialize an empty <tref>array</tref> flattened.</li>
-    <li>For each <em>id</em>-<em>node</em> pair in <em>defaultGraph</em> ordered by <em>id</em>,
-      add <em>node</em> to <em>flattened</em>.</li>
-    <li>If <em>context</em> equals <tref>null</tref>, return <em>flattened</em>.</li>
-    <li>Otherwise, return the result of compacting <em>flattened</em> according the
-      <a href="#compaction-algorithm">Compaction algorithm</a> passing <em>context</em>
-      ensuring that the compaction result uses the <code>@graph</code> keyword (or its alias)
-      at the top-level, even if the context is empty or if there is only one element to
-      put in the <code>@graph</code> <tref>array</tref>. This ensures that the returned
-      document has a deterministic structure.</li>
-  </ol>
-</section>
-
-<!-- FIXME -->
-<section>
-  <h2>Node Map Generation</h2>
-
-  <p>This algorithm creates a <tref>JSON object</tref> <em>nodeMap</em> holding an indexed
-    representation of the <tref title="JSON-LD graph">graphs</tref> and <tref title="node">nodes</tref>
-    represented in the passed, expanded document. All <tref title="node">nodes</tref> that are not
-    uniquely identified by an IRI get assigned a (new) <tref>blank node identifier</tref>.
-    The resulting <em>nodeMap</em> will have a member for every graph in the document whose
-    value is another object with a member for every <tref>node</tref> represented in the document.
-    The default graph is stored under the <code>@default</code> member, all other graphs are
-    stored under their graph name</tref>.</p>
-
-  <p>The algorithm takes as input an expanded JSON-LD document <em>element</em> and a reference to
-    a <tref>JSON object</tref> <em>nodeMap</em>. Furthermore it has the optional parameters
-    <tref>active graph</tref> (which defaults to <code>@default</code>), an <tref>active subject</tref>,
-    <tref>active property</tref>, and a reference to a <tref>JSON object</tref> <em>list</em>. The
-    <em>nodeMap</em> must be initialized to a <tref>JSON object</tref> consisting of a single member
-    whose name corresponds with <tref>active graph</tref> and whose value is an empty <tref>JSON object</tref>.</p>
-
-  <ol class="algorithm">
-    <li>If <em>element</em> is an array, process each entry in <em>element</em> recursively, using this algorithm
-      and return.</li>
-    <li>Otherwise <em>element</em> is a <tref>JSON object</tref>. Let <em>activeGraph</em> be the
-      <tref>JSON object</tref> which is the value of the <tref>active graph</tref> member of
-      <em>nodeMap</em>.</li>
-    <li>If it has an <code>@type</code> member, perform for each <em>item</em> the following
-      steps:
-      <ol class="algorithm">
-        <li>If <em>item</em> is a <tref>blank node identifier</tref>, replace it with a
-          <a href="#generate-blank-node-identifier">new blank node identifier</a>.</li>
-        <li>If <em>activeGraph</em> has no member <em>item</em>, create it and initialize its
-          value to a <tref>JSON object</tref> consisting of a single member <code>@id</code>
-          with the value <em>item</em>.</li>
-      </ol>
-    </li>
-    <li>If <em>element</em> has an <code>@value</code> member, perform the following steps:
-      <ol class="algorithm">
-        <li>If no <em>list</em> has been passed, merge <em>element</em> into the
-          <tref>active property</tref> member of the <tref>active subject</tref> in
-          <em>activeGraph</em>.</li>
-        <li>Otherwise, append <em>element</em> to the <code>@list</code> member of <em>list</em>.</li>
-      </ol>
-    </li>
-    <li>Otherwise, if <em>element</em> has an <code>@list</code> member, perform
-      the following steps:
-      <ol class="algorithm">
-        <li>Initialize a new <tref>JSON object</tref> <em>result</em> having a single member
-          <code>@list</code> whose value is initialized to an empty <tref>array</tref>.</li>
-        <li>Recursively call this algorithm passing the value of <em>element's</em>
-          <code>@list</code> member as new <em>element</em> and <em>result</em> as <em>list</em>.</li>
-        <li>If <tref>active property</tref> equals <tref>null</tref> or <code>@graph</code>,
-          <a href="#generate-blank-node-identifier">generate a blank node identifier</a> <em>id</em>
-          and store <em>result</em> as value of the member <em>id</em> in <em>activeGraph</em>.</li>
-        <li>Otherwise, add <em>result</em> to the the value of the <tref>active property</tref> member
-          of the <tref>active subject</tref> in <em>activeGraph</em>.</li>
-      </ol>
-    </li>
-    <li>Otherwise <em>element</em> is a <tref>node object</tref>, perform the following
-      steps:
-      <ol class="algorithm">
-        <li>If <em>element</em> has an <code>@id</code> member, store its value in <em>id</em> and remove
-          the member from <em>element</em>. If <em>id</em> is a <tref>blank node identifier</tref>, replace it with
-          <a href="#generate-blank-node-identifier">a new blank node identifier</a>.</li>
-        <li>Otherwise <a href="#generate-blank-node-identifier">generate a new blank node identifier</a>
-          and store it as <em>id</em>.</li>
-        <li>If <em>activeGraph</em> does not contain a member <em>id</em>, create one and initialize
-          it to a <tref>JSON object</tref> consisting of a single member <code>@id</code> whose
-          value is set to <em>id</em>.</li>
-        <li>If <tref>active property</tref> is not <tref>null</tref>, perform the following steps:
-          <ol class="algorithm">
-            <li>Create a new <tref>JSON object</tref> <em>reference</em> consisting of a single member
-              <code>@id</code> whose value is <em>id</em>.</li>
-            <li>If no <em>list</em> has been passed, merge <em>element</em> into the
-              <tref>active property</tref> member of the <tref>active subject</tref> in
-              <em>activeGraph</em>.</li>
-            <li>Otherwise, append <em>element</em> to the <code>@list</code> member of <em>list</em>.</li>
-          </ol>
-        </li>
-        <li>If <em>element</em> has an <code>@type</code> member, merge each value into the <code>@type</code>
-          of <tref>active subject</tref> in <em>activeGraph</em>. Then remove the <code>@type</code> member
-          from <em>element</em>.</li>
-        <li>If <em>element</em> has an <code>@index</code> member, set the <code>@index</code>
-          of <tref>active subject</tref> in <em>activeGraph</em> to its value. If such a member already
-          exists in <tref>active subject</tref> and has a different value, raise a
-          <code class="error">CONFLICTING_ANNOTATION</code> error. Otherwise continue and remove the
-          <code>@index</code> from <em>element</em>.</li>
-        <li>If <em>element</em> has an <code>@graph</code> member, recursively invoke this algorithm passing
-          the value of the <code>@graph</code> member as new <em>element</em> and <em>id</em> as new
-          <tref>active subject</tref>. Then remove the <code>@graph</code> member from <em>element</em>.</li>
-        <li>Finally for each <em>property</em>-<em>value</em> pair in <em>element</em> ordered by
-          <em>property</em> perform the following steps:
-          <ol class="algorithm">
-            <li>If no <em>property</em> member exists in the <tref>JSON object</tref> which is the
-              value of the <em>id</em> member of <em>activeGraph</em> create the member and initialize
-              its value to an empty <tref>array</tref>.</li>
-            <li>Recursively invoke this algorithm passing <em>value</em> as new <em>element</em>, <em>id</em>
-              as new <tref>active subject</tref>, and <em>property</em> as new <tref>active property</tref>.</li>
-          </ol>
-        </li>
-      </ol>
-    </li>
-  </ol>
-</section>
-
-<!-- FIXME -->
-<section>
-<h2>RDF Conversion Algorithms</h2>
-
-<p>
-This section describes algorithms to transform JSON-LD documents to an array
-of RDF <tref title="quad">quads</tref> and vice-versa. Note that many uses of
-JSON-LD may not require generation of RDF.
-</p>
-
-<p>
-The processing algorithms described in this section are provided in order to
-demonstrate how one might implement a JSON-LD to RDF processor. Conformant
-implementations are only required to produce the same type and number of
-<tref title="quad">quads</tref> but are not required to implement the
-algorithm exactly as described.
-</p>
-
-<section>
-<h3>Convert to RDF Algorithm</h3>
-
-<p>
-The algorithm below is designed for in-memory implementations with random
-access to <tref>JSON object</tref> elements.
-</p>
-
-<p>
-A conforming JSON-LD processor implementing RDF conversion MUST implement a
-processing algorithm that results in the same set of RDF
-<tref title="quad">quads</tref> that the following algorithm generates.
-</p>
-
-<p>
-The algorithm takes five input variables: an <em>element</em> to be converted,
-an <tref>active subject</tref>, an <tref>active property</tref>, a
-<tref>graph name</tref>, and an <tref>array</tref> <em>quads</em> of
-<tref title="quad">Quads</tref>. To begin, the <tref>active subject</tref>,
-<tref>active property</tref>, and <tref>graph name</tref>
-are set to <tref>null</tref>, <em>quads</em> is set to an empty
-<tref>array</tref>, and <em>element</em> is set to the result of
-performing the <a href="#expansion-algorithm">Expansion Algorithm</a> on the
-<tref>JSON-LD input</tref> which is expected to be a a well-formed JSON-LD
-document as defined in [[!JSON-LD]].
-</p>
-
-<p class="issue">This algorithm hasn't been updated to use [[!RDF-CONCEPTS]]
-yet.</p>
-<p class="issue">This algorithm needs some clarification on its details.</p>
-
-<ol class="algorithm">
-  <li>
-    If <em>element</em> is an <tref>array</tref>, then for each <em>item</em>
-    in <em>element</em> invoke this algorithm recursively, passing
-    <em>item</em> for <em>element</em>, <tref>active subject</tref>,
-    <tref>active property</tref>, <tref>graph name</tref>, and <em>quads</em>.
-  </li>
-  <li>
-    Otherwise, if <em>element</em> is a <tref>string</tref>, then
-    generate a <tref>quad</tref> using <tref>active subject</tref>,
-    <tref>active property</tref>, an <tref>IRI</tref> with the value
-    of <em>element</em> for <tref>RDF object</tref>, and
-    <tref>graph name</tref>. Append the <tref>quad</tref> to
-    <em>quads</em>.
-  </li>
-  <li>
-    Otherwise, if <em>element</em> is a <tref>list object</tref>:
-    <ol class="algorithm">
-      <li>
-        Initialize <em>list</em> to the result of the
-        <a href="#list-conversion">List Conversion</a> algorithm, passing
-        the value associated with the <code>@list</code> key.
-      </li>
-      <li>
-        Invoke this algorithm recursively, passing <em>list</em> for
-        <em>element</em>, <tref>active subject</tref>,
-        <tref>active property</tref>, <tref>graph name</tref>, and
-        <em>quads</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Otherwise, if <em>element</em> is a <tref>JSON object</tref> that
-    contains the key <code>@value</code>:
-    <ol class="algorithm">
-      <li>
-        Initialize <em>value</em> to the value associated with the
-        <code>@value</code> key in <em>element</em>. Initialize
-        <em>datatype</em> to the value associated with the <code>@type</code>
-        key in <em>element</em>, or <tref>null</tref> if <em>element</em>
-        does not contain that key.
-      </li>
-      <li>
-        Otherwise, if <em>value</em> equals <tref>true</tref> or
-        <tref>false</tref>, then set <em>value</em> its
-        <tref>canonical lexical form</tref> as defined
-        in the section <a href="#data-round-tripping">Data Round Tripping</a>.
-        If <em>datatype</em> is <tref>null</tref>, set it to
-        <code>xsd:boolean</code>.
-      </li>
-      <li>
-        Otherwise, if <em>value</em> is a <tref>number</tref>, then set
-        <em>value</em> to its <tref>canonical lexical form</tref> as defined
-        in the section <a href="#data-round-tripping">Data Round Tripping</a>.
-        If <em>datatype</em> is <tref>null</tref>, set it to either
-        <code>xsd:integer</code> or <code>xsd:double</code>, depending
-        on if the value contains a fractional and/or an exponential
-        component.
-      </li>
-      <li>
-        Otherwise, if <em>datatype</em> is <tref>null</tref>, set it to
-        <code>xsd:string</code>.
-      </li>
-      <li>
-        Initialize <tref>active object</tref> using <em>value</em> and
-        <em>datatype</em>. If <em>element</em> has the key
-        <code>@language</code> and <em>datatype</em> equals
-        <code>xsd:string</code>, then add the value associated with the
-        <code>@language</code> key as the language of the
-        <tref>active object</tref>.
-      </li>
-      <li>
-        Generate a <tref>quad</tref> using <tref>active subject</tref>,
-        <tref>active property</tref>, <tref>active object</tref>, and
-        <tref>graph name</tref>. Append the <tref>quad</tref> to
-        <em>quads</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Otherwise, <em>element</em> must represent the next
-    <tref>RDF subject</tref> to be processed:
-    <ol class="algorithm">
-      <li>
-        If <em>element</em> contains the key <code>@id</code>, then
-        initialize <em>id</em> to its associated value, otherwise initialize
-        it to <tref>null</tref>. If <em>element</em> is a
-        <tref>blank node</tref>, then set <em>id</em> to the result of
-        using the
-        <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a>
-        algorithm, passing <em>id</em> for <em>identifier</em>.
-      </li>
-      <li>
-        Initialize <tref>active object</tref> to an <tref>IRI</tref> or
-        <tref>blank node</tref>, as appropriate, with the value of
-        <em>element</em>.
-      </li>
-      <li>
-        If <tref>active subject</tref> is not <tref>null</tref>, then
-        generate a <tref>quad</tref> using <tref>active subject</tref>,
-        <tref>active property</tref>, <tref>active object</tref>, and
-        <tref>graph name</tref>. Append the <tref>quad</tref> to
-        <em>quads</em>.
-      </li>
-      <li>
-        Set <tref>active subject</tref> to <tref>active object</tref>.
-      </li>
-      <li>
-        For each <em>key</em>-<em>value</em> pair in <em>element</em>,
-        sorted lexicographically by <em>key</em>:
-        <ol class="algorithm">
-          <li>
-            Set <tref>active property</tref> to <em>value</em>.
-          </li>
-          <li>
-            If <tref>active property</tref> equals <code>@graph</code>, then
-            use this algorithm recursively, passing <em>value</em> for
-            <em>element</em>, <tref>null</tref> for
-            <tref>active subject</tref> and <tref>active property</tref>,
-            <tref>active subject</tref> for <tref>graph name</tref>,
-            and <em>quads</em>. Then continue to the next <em>key</em>.
-          </li>
-          <li>
-            If <em>key</em> equals <code>@type</code>, then set
-            <tref>active property</tref> to <code>rdf:type</code>.
-          </li>
-          <li>
-            If <tref>active property</tref> is a <tref>keyword</tref>,
-            then continue to the next <em>key</em>.
-          </li>
-          <li>
-            Use this algorithm recursively, passing <em>value</em> for
-            <em>element</em>, <tref>active subject</tref>,
-            <tref>active property</tref>, <tref>graph name</tref>,
-            and <em>quads</em>.
-          </li>
-        </ol>
-      </li>
-    </ol>
-  </li>
-</ol>
-
-</section>
-
-<section id="list-conversion">
-<h3>List Conversion</h3>
-
-<p>
-List Conversion is the process of taking an <tref>array</tref> of values and
-converting it to a JSON-LD linked list of
-<tref title="JSON object">JSON objects</tref>. Each element of the list is
-linked by using <code>rdf:first</code> and <code>rdf:rest</code>, terminating
-the list with <code>rdf:nil</code>.
-</p>
-
-<p>
-The algorithm takes a single input: an <tref>array</tref> <em>list</em>.
-</p>
-
-<div class="note">This algorithm does not support lists containing lists.</div>
-
-<ol class="algorithm">
-  <li>
-    Initialize <em>length</em> to the length of <em>list</em>.
-  </li>
-  <li>
-    Initialize <em>tail</em> to a <tref>JSON object</tref> containing
-    one key-value pair, (<code>@id</code>-<code>rdf:nil</code>).
-  </li>
-  <li>
-    Starting <em>itr</em> at <em>length</em> minus <code>1</code>, loop
-    until <em>itr</em> is <code>0</code> (inclusive):
-    <ol class="algorithm">
-      <li>
-        Initialize <em>element</em> to an empty <tref>JSON object</tref>.
-      </li>
-      <li>
-        Add a key-value pair to <em>element</em> where the key is
-        <code>rdf:first</code> and the value is an <tref>array</tref>
-        containing the value associated with the index <em>itr</em>
-        in <em>list</em>.
-      </li>
-      <li>
-        Add a key-value pair to <em>element</em> where the key is
-        <code>rdf:rest</code> and the value is an <tref>array</tref>
-        containing <em>tail</em>.
-      </li>
-      <li>
-        Set <em>tail</em> to <em>element</em>.
-      </li>
-      <li>
-        Decrement <em>itr</em> by <code>1</code>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Return <em>tail</em>.
-  </li>
-</ol>
-
-</section>
-
-<!-- FIXME -->
-<section>
-  <h2>Convert from RDF Algorithm</h2>
-  <p>In some cases, data exists natively in the form of triples or or <tref title="quad">quads</tref>;
-    for example, if the data was originally represented in an RDF graph or triple/quad store. This
-    algorithm is designed to simply translate an array of <tref title="quad">quads</tref> into a
-    JSON-LD document.</p>
-  <p>When expanding <tref title="typed value">typed values</tref> having a datatype of <code>xsd:string</code>,
-    the <code>@type</code> MUST NOT be set to <code>xsd:string</code> and the resulting value
-    MUST have only an <code>@value</code> property.</p>
-
-  <p>The conversion algorithm takes a single parameter <em>input</em> in the form of an
-    array of <tref>Quad</tref> representations.</p>
-
-  <p class="issue">This algorithm hasn't been updated to use [[!RDF-CONCEPTS]] yet.</p>
-
-  <ol class="algorithm">
-    <li id="new_graph">Construct <em>defaultGraph</em> as a <tref>JSON object</tref>
-      containing <em>nodes</em> and <em>listMap</em>, each an empty <tref>JSON object</tref>.</li>
-    <li>Construct <em>graphs</em> as a <tref>JSON object</tref> containing <em>defaultGraph</em>
-      identified by
-      an empty <tref>string</tref>.</li>
-    <li>For each <tref>quad</tref> in <em>input</em>:
-      <ol class="algorithm">
-        <li>Set <em>graph</em> to the entry in <em>graphs</em> identified
-          by <em>name</em>, initializing it to a new entry using the mechanism
-          described in <a href="#new_graph">Step 1</a>.</li>
-        <li>If <em>property</em> is <code>rdf:first</code>,
-          use the entry in <em>graph.listMap</em> indexed by <em>subject</em>,
-          initializing it to a new <tref>JSON object</tref> if nesessary. Represent
-          <em>object</em> in <tref>expanded form</tref>, as described in
-          <a href="#value-expansion">Value Expansion</a>. Add the
-          resulting <em>object representation</em> to the entry indexed by
-          <em>first</em>, and skip to the next <tref>quad</tref>.</li>
-        <li>If <em>property</em> is <code>rdf:rest</code>:
-          <ol class="algorithm">
-            <li>If <em>object</em> is a <tref>blank node</tref>, use the entry in
-              <em>graph.listMap</em> indexed by <em>subject</em>, initializing it
-              to a new <tref>JSON object</tref> if necessary. Add the <em>nominalValue</em> of
-              <em>object</em> to the entry indexed by <em>rest</em>.
-            </li>
-            <li>Skip to the next <tref>quad</tref>.</li>
-          </ol>
-        </li>
-        <li>If <em>name</em> is not <tref>null</tref>, and <em>defaultGraph.nodes</em>
-          does not contain an entry for <em>name</em>,
-          create a new entry for <em>name</em> from a new
-          <tref>JSON object</tref> with key/value pair of <code>@id</code> and
-          <em>name</em> represented in <tref>expanded IRI form</tref>.</li>
-        <li>Set <em>value</em> as the entry from <em>graph.nodes</em> for
-          <em>subject</em>, initializing it to a new
-          <tref>JSON object</tref> with key/value pair of <code>@id</code> and
-          <em>subject</em> represented in <tref>expanded IRI form</tref> if necessary.</li>
-        <li>If <em>property</em> is <code>rdf:type</code>, <em>object</em> is not a <tref>JSON-LD value</tref>, and the
-          <code class="idlMemberName"><a href="#widl-JsonLdOptions-useRdfType">useRdfType</a></code>
-          option is not present or <tref>false</tref>:
-          <ol class="algorithm">
-            <li>Append <em>object</em> represented in <tref>expanded IRI form</tref> to the array value for the
-              key <code>@type</code>, creating an entry in <em>value</em> if necessary.</li>
-          </ol>
-        </li>
-
-        <li>Otherwise, if <em>object</em> is a <tref>typed value</tref> and the
-          <code class="idlMemberName"><a href="#widl-JsonLdOptions-useNativeTypes">useNativeTypes</a></code>
-          option is set to <tref>true</tref>:
-          <ol class="algorithm">
-            <li>Generate a <em>converted value</em>:
-              <ol class="algorithm">
-                <li>If the literal's type is <code>xsd:boolean</code>, the
-                  <em>converted value</em> is <tref>true</tref> if the literal
-                  matches the value <code>true</code> or <code>false</code> if
-                  the literal matches the value <code>false</code>.</li>
-                <li>If the literal's type is <code>xsd:integer</code> or
-                  <code>xsd:double</code>, try to convert the literal to a
-                  JSON <tref>number</tref>. If the conversion is successful,
-                  store the result in <em>converted value</em>, otherwise
-                  set <em>converted value</em> to <em>value</em>.</li>
-                <li>Otherwise, do not perform a conversion. Set
-                  the <em>converted value</em> to the <em>value</em>.</li>
-              </ol>
-            </li>
-            <li>Append the <em>converted value</em> to the array value for the
-              key, creating an entry in <em>value</em> if necessary.</li>
-          </ol>
-        </li>
-
-        <li>Otherwise, if <em>object</em> is <code>rdf:nil</code>:
-          <ol class="algorithm">
-            <li>Let <em>key</em> be <em>property</em> expressed in <tref>expanded IRI form</tref>.</li>
-            <li>Append an empty <code>@list</code> representation to the array value for
-              <em>key</em>, creating an entry in <em>value</em> if necessary.</li>
-          </ol>
-        </li>
-        <li>Otherwise,
-          <ol class="algorithm">
-            <li>Let <em>key</em> be <em>property</em> expressed in <tref>expanded IRI form</tref> and let
-              <em>object representation</em>
-              be <em>object</em> represented in <tref>expanded form</tref> as described in
-              <a href="#value-expansion">Value Expansion</a>.</li>
-            <li>If <em>object</em> is a <tref>blank node</tref>,
-              use the entry in <em>graph.listMap</em> indexed by <em>object</em>,
-              initializing it to a new <tref>JSON object</tref> if nesessary.
-              Add an entry for <em>head</em> with <em>object representation</em>.</li>
-            <li>Append <em>object representation</em> to the array value for
-              <em>key</em>, creating an entry in <em>value</em> if necessary.</li>
-          </ol>
-        </li>
-      </ol>
-    </li>
-    <li>For each <em>name</em> and <em>graph</em> in <em>graphs</em>:
-      <ol class="algorithm">
-        <li>For each <em>subject</em> and <em>entry</em> in <em>graph</em>
-          where <em>entry</em> has both <em>head</em> and <em>first</em> keys:
-          <ol class="algorithm">
-            <li>Set <em>value</em> to the value of <em>head</em> in <em>entry</em>.</li>
-            <li>Remove the entry for <code>@id</code> in <em>value</em>.</li>
-            <li>Add an entry to <em>value</em> for <code>@list</code> initialized to a new array
-              containing the value of <em>first</em> from <em>entry</em>.</li>
-            <li>While <em>entry</em> has a key for <em>rest</em>:
-              <ol class="algorithm">
-                <li>Set <em>entry</em> to the value of <em>graph.listMap</em> for <em>entry.rest</em>.</li>
-                <li>Add the value for <em>entry.first</em> to the list array.</li>
-              </ol>
-            </li>
-          </ol>
-        </li>
-      </ol>
-    </li>
-    <li>Create <em>array</em> as an empty <tref>array</tref>.</li>
-    <li>For each <em>subject</em> and <em>entry</em> in <em>defaultGraph.nodes</em>
-      ordered by <em>subject</em>:
-      <ol class="algorithm">
-        <li>Add <em>entry</em> to <em>array</em>.</li>
-        <li>If <em>graphs</em> has an entry for <em>subject</em>, add a property
-          <code>@graph</code> in <em>entry</em> containing the ordered entries
-          from <em>graphs[subject].nodes</em>.</li>
-      </ol>
-    </li>
-    <li>Return <em>array</em> as the result.</li>
-  </ol>
-</section>
-
-<!-- FIXME -->
-<section>
-  <h3>Data Round Tripping</h3>
-
-  <p>When <a href="#rdf-conversion">converting JSON-LD to RDF</a> JSON-native types such as
-    <em>numbers</em> and <em>booleans</em> are automatically coerced to <strong>xsd:integer</strong>,
-    <strong>xsd:double</strong>, or <strong>xsd:boolean</strong>. Implementers MUST ensure that the
-    result is in <tref>canonical lexical form</tref>. A
-    <tdef>canonical lexical form</tdef> is a set of literals from among the valid set of literals for
-    a datatype such that there is a one-to-one mapping between the <tref>canonical lexical form</tref> and a value
-    in the value space as defined in [[!XMLSCHEMA11-2]]. In other words, every value MUST be converted
-    to a deterministic <tref>string</tref> representation.</p>
-
-  <p>The canonical lexical form of an <em>integer</em>, i.e., a number without fractions
-    or a number coerced to <strong>xsd:integer</strong>, is a finite-length sequence of decimal
-    digits (<code>0-9</code>) with an optional leading minus sign; leading zeroes are prohibited.
-    To convert the number in JavaScript, implementers can use the following snippet of code:</p>
-
-  <pre class="example" data-transform="updateExample"
-        title="Sample integer serialization implementation in JavaScript">
-  <!--
-  (value).toFixed(0).toString()
-  -->
-  </pre>
-
-  <p>The canonical lexical form of a <em>double</em>, i.e., a number with fractions
-    or a number coerced to <strong>xsd:double</strong>, consists of a mantissa followed by the
-    character "E", followed by an exponent. The mantissa MUST be a decimal number. The exponent
-    MUST be an integer. Leading zeroes and a preceding plus sign (<code>+</code>) are prohibited
-    in the exponent. If the exponent is zero, it must be indicated by <code>E0</code>.
-    For the mantissa, the preceding optional plus sign is prohibited and the decimal point is
-    required. Leading and trailing zeroes are prohibited subject to the following: number
-    representations must be normalized such that there is a single digit which is non-zero to the
-    left of the decimal point and at least a single digit to the right of the decimal point unless
-    the value being represented is zero. The canonical representation for zero is <code>0.0E0</code>.
-    <strong>xsd:double</strong>'s value space is defined by the IEEE double-precision 64-bit
-    floating point type [[!IEEE-754-1985]]; in JSON-LD the mantissa is rounded to 15 digits after the
-    decimal point.</p>
-
-  <p>To convert the number in JavaScript, implementers can use the following snippet of code:</p>
-
-  <pre class="example" data-transform="updateExample"
-        title="Sample floating point number serialization implementation in JavaScript">
-  <!--
-  (value).toExponential(15).replace(/(\d)0*e\+?/,'$1E')
-  -->
-  </pre>
-
-  <p class="note">When data such as decimals need to be normalized, JSON-LD authors should
-    not use values that are going to undergo automatic conversion. This is due to the lossy nature
-    of <strong>xsd:double</strong> values. Authors should instead use the expanded object form to
-    set the canonical lexical form directly.</p>
-
-  <p>The canonical lexical form of the <em>boolean</em> values <code>true</code> and <code>false</code>
-    are the strings <strong>true</strong> and <strong>false</strong>.</p>
-
-  <p>When JSON-native <tref>number</tref>s, are type coerced, lossless data round-tripping can not
-    be guaranted as rounding errors might occur. Additionally, only literals typed as
-    <strong>xsd:integer</strong>, <strong>xsd:double</strong>, and  <strong>xsd:boolean</strong> are
-    automatically converted back to their JSON-native counterparts in when
-    <a href="#rdf-conversion">converting from RDF</a>.</p>
-
-  <p>Some JSON serializers, such as PHP's native implementation in some versions,
-    backslash-escape the forward slash character. For example, the value
-    <code>http://example.com/</code> would be serialized as <code>http:\/\/example.com\/</code>.
-    This is problematic as other JSON parsers might not understand those escaping characters.
-    There is no need to backslash-escape forward slashes in JSON-LD. To aid interoperability
-    between JSON-LD processors, a JSON-LD serializer MUST NOT backslash-escape forward slashes.</p>
-</section>
-
-<!-- end of RDF algorithms -->
-</section>
-
-<!-- end of Algorithms -->
-</section>
-
-<section>
-  <h2>The Application Programming Interface</h2>
-
-  <p>This API provides a clean mechanism that enables developers to convert
-  JSON-LD data into a a variety of output formats that are easier to work
-  with in JavaScript. If a JavaScript JSON-LD API is provided, the entirety
-  of the following API MUST be implemented.</p>
-
-  <section>
-    <h3>JsonLdProcessor</h3>
-
-    <p>The JSON-LD Processor interface is the high-level programming structure
-      that developers use to access the JSON-LD transformation methods.</p>
-
-    <p>It is important to highlight that conformant <tref title="JSON-LD Processor">JSON-LD processors</tref>
-      MUST NOT modify the input parameters.</p>
-
-    <dl title="[Constructor] interface JsonLdProcessor" class="idl">
-
-      <dt>void expand()</dt>
-      <dd>
-        <a href="#expansion">Expands</a> the given <code>input</code> according to
-        the steps in the <a href="#expansion-algorithm">Expansion Algorithm</a>.
-
-        <dl class="parameters">
-          <dt>(object or object[] or DOMString) input</dt>
-          <dd>The JSON-LD object or array of JSON-LD objects to perform the expansion upon or an
-            <tref>IRI</tref> referencing the JSON-LD document to expand.</dd>
-          <dt>JsonLdCallback callback</dt>
-          <dd>A callback that is called when processing completed successfully
-            on the given <code>input</code>, or a fatal error prevented
-            processing from completing.</dd>
-          <dt>optional JsonLdOptions? options</dt>
-          <dd>A set of options to configure the used algorithms such. This allows, e.g.,
-            to set the input document's base <tref>IRI</tref>.</dd>
-        </dl>
-      </dd>
-
-      <dt>void compact()</dt>
-      <dd>
-        <a href="#compaction">Compacts</a> the given <code>input</code> using the
-        <code>context</code> according to the steps in the
-        <a href="#compaction-algorithm">Compaction Algorithm</a>.
-
-        <dl class="parameters">
-          <dt>(object or object[] or DOMString) input</dt>
-           <dd>The JSON-LD object or array of JSON-LD objects to perform the compaction upon or an
-            <tref>IRI</tref> referencing the JSON-LD document to compact.</dd>
-          <dt>(object or DOMString) context</dt>
-          <dd>The context to use when compacting the <code>input</code>; either in the
-            form of an <tref>JSON object</tref> or as <tref>IRI</tref>.</dd>
-          <dt>JsonLdCallback callback</dt>
-          <dd>A callback that is called when processing completed successfully
-            on the given <code>input</code>, or a fatal error prevented
-            processing from completing.</dd>
-          <dt>optional JsonLdOptions? options</dt>
-          <dd>A set of options to configure the used algorithms such. This allows, e.g.,
-            to set the input document's base <tref>IRI</tref>. This also includes
-            the <code>optimize</code> flag, which, if set, will allow processor-specific
-            optimization.</dd>
-        </dl>
-      </dd>
-
-      <dt>void flatten()</dt>
-      <dd>
-        <a href="#flattening">Flattens</a> the given <code>input</code> and
-        <a href="#compaction">compacts</a> it using the passed <code>context</code>
-          according to the steps in the <a href="#flattening-algorithm">Flattening Algorithm</a>.
-
-        <dl class="parameters">
-          <dt>(object or object[] or DOMString) input</dt>
-           <dd>The JSON-LD object or array of JSON-LD objects or an <tref>IRI</tref>
-            referencing the JSON-LD document to flatten.</dd>
-          <dt>(object or DOMString)? context</dt>
-          <dd>The context to use when compacting the flattened <code>input</code>; either
-            in the form of an <tref>JSON object</tref> or as <tref>IRI</tref>. If
-            <tref>null</tref> is passed, the result will not be compacted but keept
-            in expanded form.</dd>
-          <dt>JsonLdCallback callback</dt>
-          <dd>A callback that is called when processing completed successfully
-            on the given <code>input</code>, or a fatal error prevented
-            processing from completing.</dd>
-          <dt>optional JsonLdOptions? options</dt>
-          <dd>A set of options to configure the used algorithms such. This allows, e.g.,
-            to set the input document's base <tref>IRI</tref>.</dd>
-        </dl>
-      </dd>
-    </dl>
-
-  </section>
-
-  <section>
-    <h3>Callbacks</h3>
-
-    <p>JSON-LD processors utilize callbacks in order to return information in an
-      asynchronous manner to calling applications. This section details the
-      parameters sent to those callbacks.</p>
-
-    <section>
-      <h3>JsonLdCallback</h3>
-      <p>The <a>JsonLdCallback</a> is called when an API method of
-        <a>JsonLdProcessor</a> has been completed, either successfully or
-        by a fatal error.</p>
-
-      <dl title="callback JsonLdCallback = void" class="idl">
-        <dt>JsonLdError error</dt>
-        <dd>If the value is <tref>null</tref>, then no issue was detected
-          during processing. Otherwise, a processing issue was detected and
-          the details are contained within the <em>error</em> object.</dd>
-        <dt>object or object[] document</dt>
-        <dd>The processed JSON-LD document.</dd>
-      </dl>
-    </section>
-  </section>
-
-  <section>
-    <h3>Data Structures</h3>
-    <p>This section describes datatype definitions used within the JSON-LD API.</p>
-
-    <section>
-      <h3>JsonLdOptions</h3>
-      <p>The <a>JsonLdOptions</a> type is used to pass various options to the <a>JsonLdProcessor</a> methods.</p>
-      <dl title="dictionary JsonLdOptions" class="idl">
-        <dt>DOMString base</dt>
-        <dd>The Base IRI to use when expanding the document. This overrides the value of
-          <em>input</em> if it is a <a>IRI</a>. If not specified and <em>input</em> is not
-          an <a>IRI</a>, the base IRI defaults to the current document IRI if in a browser context,
-          or the empty string if there is no document context.
-          <p class="issue atrisk" title="Feature at risk">The default value of this option
-            implies that all IRIs that cannot be compacted otherwise are transformed to relative IRIs
-            during compaction. To avoid that data is being lost, developers thus have to store the
-            base IRI along with the compacted document. This might be problematic in practice and
-            thus the default behavior might be changed in future.</p>
-        </dd>
-        <dt>object or DOMString expandContext = null</dt>
-        <dd>A context that is used to initialize the active context when expanding a document.</dd>
-        <dt>boolean compactArrays = true</dt>
-        <dd>If set to <code>true</code>, the JSON-LD processor replaces arrays with just
-          one element with that element during compaction. If set to <code>false</code>,
-          all arrays will remain arrays even if they have just one element.
-        </dd>
-        <dt>boolean optimize = false</dt>
-        <dd>If set to <code>true</code>, the JSON-LD processor is allowed to
-          optimize the output of the <a href="#compaction-algorithm">Compaction Algorithm</a>
-          to produce even compacter representations. The algorithm for compaction
-          optimization is beyond the scope of this specification and thus
-          not defined. Consequently, different implementations MAY implement
-          different optimization algorithms.
-        </dd>
-        <dt>boolean useRdfType = false</dt>
-        <dd>If set to <code>true</code>, the JSON-LD processor will use the
-          expanded <code>rdf:type</code> IRI as the property instead of
-          <code>@type</code> when <a href="#convert-from-rdf-algorithm">converting from RDF</a>.
-        </dd>
-        <dt>boolean useNativeTypes = true</dt>
-        <dd>If set to <code>true</code>, the JSON-LD processor will try to convert
-          <tref title="typed value">typed values</tref> to JSON native types instead of using the
-          expanded object form when <a href="#convert-from-rdf-algorithm">converting from RDF</a>.
-          <code>xsd:boolean</code> values will be converted to <tref>true</tref> or <tref>false</tref>.
-          <code>xsd:integer</code> and <code>xsd:double</code> values will be
-          converted to
-          <tref title="number">JSON numbers</tref>.
-        </dd>
-      </dl>
-    </section>
-
-    <section>
-      <h3>JsonLdError</h3>
-
-      <p>The <a>JsonLdError</a> type is used to report processing errors
-        to a <a>JsonLdCallback</a>.</p>
-
-      <dl title="dictionary JsonLdError" class="idl">
-        <dt>JsonLdErrorCode code</dt>
-        <dd>a string representing the particular error type, as described in
-          the various algorithms in this document.</dd>
-        <dt>DOMString? message</dt>
-        <dd>an optional error message containing additional debugging information.
-          The specific contents of error messages are outside the scope of this
-          specification.</dd>
-      </dl>
-    </section>
-
-    <section>
-      <h3>JsonLdErrorCode</h3>
-      <p>The <a>JsonLdErrorCode</a> represents the collection of valid JSON-LD error
-        codes.</p>
-
-      <dl title="enum JsonLdErrorCode" class="idl">
-        <dt>invalid syntax</dt>
-        <dd>The document could not be parsed as JSON.</dd>
-        <dt>list of lists detected</dt>
-        <dd>A list of lists was detected. List of lists are not supported in
-          this version of JSON-LD due to the algorithmic complexity associated
-          with conversion to RDF.</dd>
-        <dt>invalid @index value</dt>
-        <dd>An <code>@index</code> member was encountered whose value was
-          not a <tref>string</tref>.</dd>
-        <dt>invalid @id value</dt>
-        <dd>An <code>@id</code> member was encountered whose value was not a
-          <tref>string</tref>.</dd>
-        <dt>invalid local context</dt>
-        <dd>In invalid <tref>local context</tref> was detected.</dd>
-        <dt>loading remote context failed</dt>
-        <dd>There was a problem encountered loading a remote context.</dd>
-        <dt>invalid remote context</dt>
-        <dd>No valid context document has been found for a referenced,
-         remote context.</dd>
-        <dt>recursive context inclusion</dt>
-        <dd>A cycle in remote context inclusions has been detected.</dd>
-        <dt>invalid default language</dt>
-        <dd>The value of the <tref>default language</tref> is not a <tref>string</tref>
-          or <tref>null</tref> and thus invalid.</dd>
-        <dt>invalid vocab mapping</dt>
-        <dd>An invalid <tref>vocabulary mapping</tref> has been detected, i.e.,
-          it is neither an <tref>absolute IRI</tref> nor <tref>null</tref>.</dd>
-        <dt>keyword redefinition</dt>
-        <dd>A <tref>keyword</tref> redefinition has been detected.</dd>
-        <dt>invalid term definition</dt>
-        <dd>An invalid <tref>term definition</tref> has been detected.</dd>
-        <dt>invalid term IRI mapping</dt>
-        <dd>A <tref>local context</tref> contains a <tref>term</tref> that
-          has not been mapped to an <tref>absolute IRI</tref>.</dd>
-        <dt>cyclic IRI mapping</dt>
-        <dd>A cycle in <tref title="IRI mapping">IRI mappings</tref> has been detected.</dd>
-        <dt>invalid type mapping</dt>
-        <dd>An <code>@type</code> member in a <tref>term definition</tref>
-          was encountered whose value could not be expanded to an
-          <tref>absolute IRI</tref>.</dd>
-        <dt>invalid language mapping</dt>
-        <dd>An <code>@language</code> member in a <tref>term definition</tref>
-          was encountered whose value was neither a <tref>string</tref> nor
-          <tref>null</tref> and thus invalid.</dd>
-        <dt>invalid container mapping</dt>
-        <dd>An <code>@container</code> member was encountered whose value was
-          not one of the following <tref title="string">strings</tref>:
-          <code>@list</code>, <code>@set</code>, or <code>@index</code>.</dd>
-        <dt>invalid property generator</dt>
-        <dd>A non-<tref>string</tref> value has been detected in a
-          <tref title="property generator">property generator's</tref>
-          <tref>IRI mapping</tref>.</dd>
-        <dt>invalid property generator IRI mapping</dt>
-        <dd>Expanding all values of a
-          <tref title="property generator">property generator's</tref>
-          <tref>IRI mapping</tref> to <tref>absolute IRI</tref> failed.</dd>
-        <dt>property generator in term definition</dt>
-        <dd>A <tref>property generator</tref> was used in the
-          <tref>IRI mapping</tref> of another <tref>term</tref> or
-          <tref>property generator</tref>.</dd>
-        <dt>invalid type value</dt>
-        <dd>An invalid value for an <code>@type</code> member has been detected,
-          i.e., the value was neither a <tref>string</tref> nor an <tref>array</tref>
-          of <tref title="string">strings</tref>.</dd>
-        <dt>invalid value object</dt>
-        <dd>A <tdef>value object</tdef> with disallowed members has been
-          detected.</dd>
-        <dt>invalid value object value</dt>
-        <dd>An invalid value for the <code>@value</code> member of a
-          <tref>value object</tref> has been detected, i.e., it is neither
-          a <tref>scalar</tref> nor <tref>null</tref>.</dd>
-        <dt>invalid language tagged string</dt>
-        <dd>A <tref>language-tagged string</tref> with disallowed members has
-          been detected.</dd>
-        <dt>invalid language value</dt>
-        <dd>A <tref>language-tagged string</tref> with an invalid language
-          value was detected.</dd>
-        <dt>invalid typed value</dt>
-        <dd>A <tref>typed value</tref> with disallowed members has been
-          detected.</dd>
-        <dt>invalid set or list object</dt>
-        <dd>A <tdef>set object</tref> or <tref>list object</tref> with
-          disallowed members has been detected.</dd>
-        <dt>language map invalid value</dt>
-        <dd>An invalid value in a <tdef>language map</tdef> was detected. It has
-          to be a <tref>string</tref> or an <tref>array</tref> of
-          <tref title="string">strings</tref>.</dd>
-        <dt>compaction to list of lists</dt>
-        <dd>The compacted document contains a list of lists as multiple
-          lists have been compacted to the same term.</dd>
-      </dl>
-    </section>
-
-  </section>
-</section>
-
-<section class="appendix">
-  <h1>Acknowledgements</h1>
-
-  <p>A large amount of thanks goes out to the JSON-LD Community Group
-    participants who worked through many of the technical issues on the mailing
-    list and the weekly telecons - of special mention are Niklas Lindström,
-    François Daoust, Lin Clark, and Zdenko 'Denny' Vrandečić.
-    The editors would like to thank Mark Birbeck, who provided a great deal of
-    the initial push behind the JSON-LD work via his work on RDFj.
-    The work of Dave Lehn and Mike Johnson are appreciated for reviewing,
-    and performing several implementations of the specification. Ian Davis is
-    thanked for his work on RDF/JSON. Thanks also to Nathan Rixham,
-    Bradley P. Allen, Kingsley Idehen, Glenn McDonald, Alexandre Passant,
-    Danny Ayers, Ted Thibodeau Jr., Olivier Grisel, Josh Mandel, Eric Prud'hommeaux,
-    David Wood, Guus Schreiber, Pat Hayes, Sandro Hawke, and Richard Cyganiak
-    or their input on the specification.</p>
-</section>
-
-</body>
-</html>
--- a/spec/latest/json-ld-api/index.html	Tue Feb 12 19:04:34 2013 +0100
+++ b/spec/latest/json-ld-api/index.html	Tue Feb 12 19:50:01 2013 +0100
@@ -95,451 +95,473 @@
 
 <body>
 <section id="abstract">
-<p>
-JSON [[!RFC4627]] has proven to be a highly useful object serialization and
-messaging format. JSON-LD [[!JSON-LD]] harmonizes the representation of
-Linked Data in JSON by outlining a common JSON representation format for
-expressing directed graphs, mixing both Linked Data and non-Linked Data in
-a single document. This document outlines an Application Programming
-Interface and a set of algorithms for programmatically transforming
-JSON-LD documents to make them easier to work with in programming
-environments like those that use JavaScript, Python, and Ruby.
-</p>
+  <p>JSON [[!RFC4627]] has proven to be a highly useful object serialization and
+    messaging format. JSON-LD [[!JSON-LD]] harmonizes the representation of
+    Linked Data in JSON by outlining a common JSON representation format for
+    expressing directed graphs, mixing both Linked Data and non-Linked Data in
+    a single document. This document outlines an Application Programming
+    Interface and a set of algorithms for programmatically transforming
+    JSON-LD documents to make them easier to work with in programming
+    environments like those that use JavaScript, Python, and Ruby.</p>
 </section>
 
 <section id="sotd">
-<p>This document has been under development for over 18 months in the
-JSON for Linking Data Community Group. The document has recently been
-transferred to the RDF Working Group for review, improvement, and publication
-along the Recommendation track. The specification has undergone significant
-development, review, and changes during the course of the last 18 months.
-</p>
-<p>There are several independent
-<a href="http://json-ld.org/#impl">interoperable implementations</a> of
-this specification. There is
-a <a href="https://github.com/json-ld/json-ld.org/tree/master/test-suite">fairly complete test suite</a>
-and a <a href="http://json-ld.org/playground/">live JSON-LD editor</a>
-that is capable of demonstrating the features described in
-this document. While development on implementations, the test suite
-and the live editor will continue, they are believed to be mature enough
-to be integrated into a non-production system at this point in time with
-the expectation that they could be used in a production system within the
-next year.
-</p>
-<p class="issue">
-It is important for readers to understand that the scope of this document is
-currently under debate and new features may be added to the specification.
-Existing features may be modified heavily or removed entirely from the
-specification upon further review and feedback from the broader community.
-This is a work in progress and publication as a Working Draft
-does not require that all Working Group members agree on the content of the
-document.
-</p>
-
-<p>There are a number of ways that one may participate in the development of
-  this specification:</p>
-
-<ul>
-  <li>If you want to make sure that your feedback is formally addressed by
-    the RDF Working Group, you should send it to public-rdf-comments:
-    <a href="http://lists.w3.org/Archives/Public/public-rdf-comments/">public-rdf-comments@w3.org</a></li>
-
-  <li>Ad-hoc technical discussion primarily occurs on the public community mailing list:
-    <a href="http://lists.w3.org/Archives/Public/public-linked-json/">public-linked-json@w3.org</a></li>
-
-  <li><a href="http://json-ld.org/minutes/">Public JSON-LD Community Group teleconferences</a>
-    are held on Tuesdays at 1500UTC every week. Participation is open to the
-    public.</li>
-
-  <li>RDF Working Group teleconferences are held on Wednesdays at 1500UTC
-    every week. Participation is limited to RDF Working Group members.</li>
-
-  <li>Specification bugs and issues should be reported in the
-    <a href="https://github.com/json-ld/json-ld.org/issues">issue tracker</a>
-    if you do not want to send an e-mail to the public-rdf-comments mailing
-    list.</li>
-
-  <li><a href="https://github.com/json-ld/json-ld.org/tree/master/spec">Source code</a>
-    for the specification can be found on Github.</li>
-
-  <li>The <a href="http://webchat.freenode.net/?channels=json-ld">#json-ld</a>
-    IRC channel is available for real-time discussion on irc.freenode.net.</li>
-</ul>
-
-</section>
-
-<section class="informative">
-<h2>Introduction</h2>
-
-<p>
-This document is a detailed specification for an Application Programming
-Interface for the JSON-LD Syntax. The document is primarily intended for
-the following audiences:
-</p>
-
-<ul>
-  <li>Web authors and developers that want a very detailed view of how
-    a JSON-LD processor and the API operates.</li>
-  <li>Software developers that want to implement processors and APIs for
-    JSON-LD documents.</li>
-</ul>
-
-<p>
-To understand the basics in this specification you must first be familiar with
-JSON, which is detailed in [[!RFC4627]]. You must also understand the
-JSON-LD Syntax [[!JSON-LD]], which is the base syntax used by all of the
-algorithms in this document. To understand the API and how it is
-intended to operate in a programming environment, it is useful to have working
-knowledge of the JavaScript programming language [[ECMA-262]] and
-WebIDL [[!WEBIDL]]. To understand how JSON-LD maps to RDF, it is helpful to be
-familiar with the basic RDF concepts [[!RDF-CONCEPTS]].</p>
-
+  <p>This document has been under development for over 18 months in the
+    JSON for Linking Data Community Group. The document has recently been
+    transferred to the RDF Working Group for review, improvement, and publication
+    along the Recommendation track. The specification has undergone significant
+    development, review, and changes during the course of the last 18 months.</p>
+
+  <p>There are several independent
+    <a href="http://json-ld.org/#impl">interoperable implementations</a> of
+    this specification. There is
+    a <a href="https://github.com/json-ld/json-ld.org/tree/master/test-suite">fairly complete test suite</a>
+    and a <a href="http://json-ld.org/playground/">live JSON-LD editor</a>
+    that is capable of demonstrating the features described in
+    this document. While there will be continuous development on implementations,
+    the test suite, and the live editor, they are believed to be mature enough
+    to be integrated into a non-production system at this point in time. There
+    is an expectation that they could be used in a production system within the
+    year.</p>
+
+  <p class="issue">It is important for readers to understand that the scope of this
+    document is currently under debate and new features may be added to the specification.
+    Existing features may be modified heavily or removed entirely from the
+    specification upon further review and feedback from the broader community.
+    This is a work in progress and publication as a Working Draft
+    does not require that all Working Group members agree on the content of the
+    document.</p>
+
+  <p>There are a number of ways that one may participate in the development of
+    this specification:</p>
+
+  <ul>
+    <li>If you want to make sure that your feedback is formally addressed by
+      the RDF Working Group, you should send it to public-rdf-comments:
+      <a href="http://lists.w3.org/Archives/Public/public-rdf-comments/">public-rdf-comments@w3.org</a></li>
+
+    <li>Ad-hoc technical discussion primarily occurs on the public community mailing list:
+      <a href="http://lists.w3.org/Archives/Public/public-linked-json/">public-linked-json@w3.org</a></li>
+
+    <li><a href="http://json-ld.org/minutes/">Public JSON-LD Community Group teleconferences</a>
+      are held on Tuesdays at 1500UTC every week. Participation is open to the
+      public.</li>
+
+    <li>RDF Working Group teleconferences are held on Wednesdays at 1500UTC
+      every week. Participation is limited to RDF Working Group members.</li>
+
+    <li>Specification bugs and issues should be reported in the
+      <a href="https://github.com/json-ld/json-ld.org/issues">issue tracker</a>
+      if you do not want to send an email to the public-rdf-comments mailing
+      list.</li>
+
+    <li><a href="https://github.com/json-ld/json-ld.org/tree/master/spec">Source code</a>
+      for the specification can be found on Github.</li>
+
+    <li>The <a href="http://webchat.freenode.net/?channels=json-ld">#json-ld</a>
+      IRC channel is available for real-time discussion on irc.freenode.net.</li>
+  </ul>
 </section>
 
 <section class="informative">
-<h1>Features</h1>
-
-<p>The JSON-LD Syntax specification [[!JSON-LD]] outlines a language that may be
-  used to express Linked Data in JSON. Often, it is useful to be able to transform
-  JSON-LD documents so that they may be easily processed in various programming
-  environments.</p>
-
-<p>There are four major types of transformation that are discussed in this document:
-  expansion, compaction, flattening, and RDF conversion.</p>
-
-<section class="informative">
-  <h2>Expansion</h2>
-  <p>Software algorithms are easiest to write when the data that they are processing
-    have a regular form. Since information can be represented by JSON-LD in a
-    variety of different ways, transforming all of these methods into a uniform
-    structure allows the developer to simplify their processing code. For example,
-    note that the following input uses only <tref>term</tref>s and is fairly
-    compact:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Sample JSON-LD document">
-  <!--
-  {
-    "@context": {
-      "name": "http://xmlns.com/foaf/0.1/name",
-      "homepage": {
-        "@id": "http://xmlns.com/foaf/0.1/homepage",
-        "@type": "@id"
-      }
-    },
-    "@id": "http://me.markus-lanthaler.com/",
-    "name": "Markus Lanthaler",
-    "homepage": "http://www.markus-lanthaler.com/"
-  }
-  -->
-  </pre>
-
-  <p>The next input example uses one <tref>IRI</tref> to express a property, but leaves
-    the rest of the information untouched.</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Sample JSON-LD document using a IRI instead of a term to express a property">
-  <!--
-  {
-    "@context": {
-      "homepage": {
-        "@id": "http://xmlns.com/foaf/0.1/homepage",
-        "@type": "@id"
-      }
-    },
-    "@id": "http://me.markus-lanthaler.com/",
-    "****http://xmlns.com/foaf/0.1/name****": "Markus Lanthaler",
-    "homepage": "http://www.markus-lanthaler.com/"
-  }
-  -->
-  </pre>
-
-  <p>While both inputs are valid JSON-LD, writing a program to handle every
-    permutation of possible inputs can be difficult, especially when the incoming
-    context could change as well. To ensure that the data can be given a more
-    uniform structure, JSON-LD introduces the notion of expansion. <tdef>Expansion</tdef>
-    performs two important operations. The first is to expand all values that represent
-    <tref title="IRI">IRIs</tref> to <tref title="absolute IRI">absolute IRIs</tref>.
-    The second is to express all values in <tref>expanded form</tref>. Running the
-    <a href="#expansion-algorithm">Expansion algorithm</a> against the examples provided
-    above results in the following output:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Expanded sample document">
-  <!--
-  [
-    {
-      "@id": "http://me.markus-lanthaler.com/",
-      "http://xmlns.com/foaf/0.1/name": [
-        { "@value": "Markus Lanthaler" }
-      ],
-      "http://xmlns.com/foaf/0.1/homepage": [
-        { "@id": "http://www.markus-lanthaler.com/" }
-      ]
-    }
-  ]
-  -->
-  </pre>
-
-  <p>Note that in the output above all <tref>context</tref> definitions have
-    been removed, all <tref title="term">terms</tref> and <tref title="prefix">prefixes</tref>
-    have been expanded to absolute <tref title="IRI">IRIs</tref>, and all
-    <tref title="JSON-LD value">JSON-LD values</tref> are expressed in <tref>expanded form</tref>.
-    While the output is more difficult for a human to read, it is easier for a
-    software program to process because of its very regular structure.</p>
+  <h1>Introduction</h1>
+
+  <p>This document is a detailed specification for an Application Programming
+    Interface for the JSON-LD Syntax. The document is primarily intended for
+    the following audiences:</p>
+
+  <ul>
+    <li>Web authors and developers that want a very detailed view of how
+      a JSON-LD processor and the API operates.</li>
+    <li>Software developers that want to implement processors and APIs for
+      JSON-LD documents.</li>
+  </ul>
+
+  <p>To understand the basics in this specification you must first be familiar with
+    JSON, which is detailed in [[!RFC4627]]. You must also understand the
+    JSON-LD Syntax [[!JSON-LD]], which is the base syntax used by all of the
+    algorithms in this document. To understand the API and how it is
+    intended to operate in a programming environment, it is useful to have working
+    knowledge of the JavaScript programming language [[ECMA-262]] and
+    WebIDL [[!WEBIDL]]. To understand how JSON-LD maps to RDF, it is helpful to be
+    familiar with the basic RDF concepts [[!RDF-CONCEPTS]].</p>
 </section>
 
 <section class="informative">
-  <h2>Compaction</h2>
-  <p>While expansion expands a given input as much as possible, compaction performs
-    the opposite operation: it expresses a given input as succinctly as possible. In contrast
-    to expansion which is meant to produce something that is easy to process by software
-    programs, compaction is meant to produce something that is easy to read by software
-    developers. Compaction uses a developer-supplied <tref>context</tref> to compress
-    <tref title="IRI">IRIs</tref> to <tref title="term">terms</tref> or
-    <tref title="compact IRI">compact IRIs</tref> and <tref title="JSON-LD value">JSON-LD values</tref>
-    expressed in <tref>expanded form</tref> to simple values such as
-    <tref title="string">strings</tref> or <tref title="number">numbers</tref>.</p>
-
-  <p>For example, assume the following expanded JSON-LD input document:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Expanded sample document">
-  <!--
-  [
+  <h1>Features</h1>
+
+  <p>The JSON-LD Syntax specification [[!JSON-LD]] outlines a syntax that may be
+    used to express Linked Data in JSON. Because there is more than one way to
+    express Linked Data using this syntax, it is often useful to be able to
+    transform JSON-LD documents so that they may be more easily consumed by
+    specific applications.</p>
+
+  <p>There are four major types of transformation that are discussed in this
+    document: expansion, compaction, flattening, and RDF conversion.</p>
+
+  <section class="informative">
+    <h2>Expansion</h2>
+
+    <p>JSON-LD allows <tref>context</tref> to be applied to JSON data. Applying
+      <tref>context</tref> to JSON data allows it to be expressed in a way that
+      is specifically tailored to a particular person or application. A common
+      use case occurs when an application or person wants to use data that was
+      created using a different <tref>context</tref> than they would prefer.
+      Therefore, a JSON-LD processor must be able to transform the data from
+      one <tref>context</tref> to another. Instead of requiring JSON-LD processors
+      to write specific code for every imaginable <tref>context</tref> switching
+      scenario, it is much easier to specify a single algorithm that can remove
+      any <tref>context</tref> (and another that can subsequently apply any
+      <tref>context</tref>). The algorithm that removes <tref>context</tref> is
+      called <tdef>expansion</tdef>.</p>
+
+    <p>To get an idea of how context and data structuring affects the same data,
+      here is an example of JSON-LD that uses only <tref title="term">terms</tref>
+      and is fairly compact:</p>
+
+    <pre class="example" data-transform="updateExample"
+         title="Sample JSON-LD document">
+    <!--
     {
+      "@context": {
+        "name": "http://xmlns.com/foaf/0.1/name",
+        "homepage": {
+          "@id": "http://xmlns.com/foaf/0.1/homepage",
+          "@type": "@id"
+        }
+      },
       "@id": "http://me.markus-lanthaler.com/",
-      "http://xmlns.com/foaf/0.1/name": [
-        { "@value": "Markus Lanthaler" }
-      ],
-      "http://xmlns.com/foaf/0.1/homepage": [
-        { "@id": "http://www.markus-lanthaler.com/" }
-      ]
+      "name": "Markus Lanthaler",
+      "homepage": "http://www.markus-lanthaler.com/"
     }
-  ]
-  -->
-  </pre>
-
-  <p>Additionally, assume the following developer-supplied JSON-LD <tref>context</tref>:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="JSON-LD context">
-  <!--
-  {
-    "@context": {
-      "name": "http://xmlns.com/foaf/0.1/name",
-      "homepage": {
-        "@id": "http://xmlns.com/foaf/0.1/homepage",
-        "@type": "@id"
+    -->
+    </pre>
+
+    <p>The next input example uses one <tref>IRI</tref> to express a property
+    and <tref title="array">array</tref> to encapsulate another, but
+    leaves the rest of the information untouched.</p>
+
+    <pre class="example" data-transform="updateExample"
+         title="Sample JSON-LD document using a IRI instead of a term to express a property">
+    <!--
+    {
+      "@context": {
+        "homepage": {
+          "@id": "http://xmlns.com/foaf/0.1/homepage",
+          "@type": "@id"
+        }
+      },
+      "@id": "http://me.markus-lanthaler.com/",
+      "****http://xmlns.com/foaf/0.1/name****": "Markus Lanthaler",
+      "homepage": ****[**** "http://www.markus-lanthaler.com/" ****]****
+    }
+    -->
+    </pre>
+
+    <p>Note that both inputs are valid JSON-LD and both represent the same
+      information. The difference is in their <tref>context</tref> information
+      and in the data structures used. A JSON-LD processor can remove
+      <tref>context</tref> and ensure that the data is more regular by employing
+      <tref>expansion</tref>.</p>
+
+    <p><tref>Expansion</tref> has two important goals: ensuring all values
+      are represented in a regular form, and removing any contextual information
+      from the document. These goals are accomplished by expanding all properties
+      to <tref title="absolute IRI">absolute IRIs</tref> and by expressing all
+      values in <tref title="array">arrays</tref> in
+      <tref>expanded form</tref>. <tref>Expanded form</tref> is the most verbose
+      and regular way of expressing of values in JSON-LD; all contextual
+      information from the document is instead stored locally with each value.
+      Running the <a href="#expansion-algorithm">Expansion algorithm</a> against
+      the examples provided above results in the following output:</p>
+
+    <pre class="example" data-transform="updateExample"
+         title="Expanded sample document">
+    <!--
+    [
+      {
+        "@id": "http://me.markus-lanthaler.com/",
+        "http://xmlns.com/foaf/0.1/name": [
+          { "@value": "Markus Lanthaler" }
+        ],
+        "http://xmlns.com/foaf/0.1/homepage": [
+          { "@id": "http://www.markus-lanthaler.com/" }
+        ]
+      }
+    ]
+    -->
+    </pre>
+
+    <p>Note that in the output above all <tref>context</tref> definitions have
+      been removed, all <tref title="term">terms</tref> and
+      <tref title="compact IRI">compact IRIs</tref> have been expanded to absolute
+      <tref title="IRI">IRIs</tref>, and all
+      <tref title="JSON-LD value">JSON-LD values</tref> are expressed in
+      <tref title="array">arrays</tref> in <tref>expanded form</tref>. While the
+      output is more verbose and difficult for a human to read, it establishes a
+      baseline that makes JSON-LD processing easier because of its very regular
+      structure.</p>
+  </section>
+
+  <section class="informative">
+    <h2>Compaction</h2>
+
+    <p>While <tref>expansion</tref> removes <tref>context</tref> from a given
+      input, <tref title="compaction">compaction's</tref> primary function is to
+      perform the opposite operation: to express a given input according to
+      a particular <tref>context</tref>. <tdef>Compaction</tdef> applies a
+      <tref>context</tref> that specifically tailors the way information is
+      expressed for a particular person or application. This simplifies applications
+      that consume JSON or JSON-LD by expressing the data in application-specific
+      terms, and it makes the data easier to read by humans.</p>
+
+    <tref>Compaction</tref> uses a developer-supplied <tref>context</tref> to
+      shorten <tref title="IRI">IRIs</tref> to <tref title="term">terms</tref> or
+      <tref title="compact IRI">compact IRIs</tref> and
+      <tref title="JSON-LD value">JSON-LD values</tref> expressed in
+      <tref>expanded form</tref> to simple values such as <tref title="string">strings</tref>
+      or <tref title="number">numbers</tref>.</p>
+
+    <p>For example, assume the following expanded JSON-LD input document:</p>
+
+    <pre class="example" data-transform="updateExample"
+         title="Expanded sample document">
+    <!--
+    [
+      {
+        "@id": "http://me.markus-lanthaler.com/",
+        "http://xmlns.com/foaf/0.1/name": [
+          { "@value": "Markus Lanthaler" }
+        ],
+        "http://xmlns.com/foaf/0.1/homepage": [
+          { "@id": "http://www.markus-lanthaler.com/" }
+        ]
+      }
+    ]
+    -->
+    </pre>
+
+    <p>Additionally, assume the following developer-supplied JSON-LD
+      <tref>context</tref>:</p>
+
+    <pre class="example" data-transform="updateExample"
+         title="JSON-LD context">
+    <!--
+    {
+      "@context": {
+        "name": "http://xmlns.com/foaf/0.1/name",
+        "homepage": {
+          "@id": "http://xmlns.com/foaf/0.1/homepage",
+          "@type": "@id"
+        }
       }
     }
-  }
-  -->
-  </pre>
-
-  <p>Running the <a href="#compaction-algorithm">Compaction Algorithm</a> given the context
-    supplied above against the JSON-LD input document provided above would result in the
-    following output:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Compacted sample document">
-  <!--
-  {
-    "@context": {
-      "name": "http://xmlns.com/foaf/0.1/name",
-      "homepage": {
-        "@id": "http://xmlns.com/foaf/0.1/homepage",
-        "@type": "@id"
-      }
-    },
-    "@id": "http://me.markus-lanthaler.com/",
-    "name": "Markus Lanthaler",
-    "homepage": "http://www.markus-lanthaler.com/"
-  }
-  -->
-  </pre>
-
-  <p>Note that all <tref title="IRI">IRIs</tref> have been compacted to
-    <tref title="term">terms</tref> as specified in the <tref>context</tref>
-    which consequently has been injected into the output. While compacted
-    output is most useful to humans, it can often also be used to generate
-    structures that are easy to program against. Compaction enables developers
-    to map any expanded document into an application-specific compacted document.
-    While the context provided above mapped <code>http://xmlns.com/foaf/0.1/name</code>
-    to <code>name</code>, it could have also have been mapped to any other term
-    provided by the developer.</p>
-
-</section>
-
-<section class="informative">
-  <h2>Flattening</h2>
-  <p>While expansion ensures that a document is in a uniform structure, flattening
-    goes a step further and ensures that also the shape of the data is deterministic.
-    In expanded documents properties of a single <tref>node</tref> may still be
-    spread across a number of different <tref title="JSON object">JSON objects</tref>.
-    By flattening a document, all properties of a <tref>node</tref> are collected in a
-    single <tref>JSON object</tref> and all <tref title="blank node">blank nodes</tref>
-    are labeled with a <tref>blank node identifier</tref>. Often this drastically
-    simplifies the code to process JSON-LD data.</p>
-
-  <p>For example, assume the following JSON-LD input document:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Sample JSON-LD document">
-  <!--
-  {
-    "@context": {
-      "name": "http://xmlns.com/foaf/0.1/name",
-      "knows": "http://xmlns.com/foaf/0.1/knows"
-    },
-    "@id": "http://me.markus-lanthaler.com/",
-    "name": "Markus Lanthaler",
-    "knows": [
-      {
-        "name": "Manu Sporny",
-        "knows": {
-          "@id": "http://greggkellogg.net/foaf#me"
+    -->
+    </pre>
+
+    <p>Running the <a href="#compaction-algorithm">Compaction Algorithm</a> given
+      the context supplied above against the JSON-LD input document provided above
+      would result in the following output:</p>
+
+    <pre class="example" data-transform="updateExample"
+         title="Compacted sample document">
+    <!--
+    {
+      "@context": {
+        "name": "http://xmlns.com/foaf/0.1/name",
+        "homepage": {
+          "@id": "http://xmlns.com/foaf/0.1/homepage",
+          "@type": "@id"
         }
       },
-      {
-        "@id": "http://greggkellogg.net/foaf#me",
-        "name": "Gregg Kellogg"
-      }
-    ]
-  }
-  -->
-  </pre>
-
-  <p>Running the <a href="#flattening-algorithm">Flattening Algorithm</a>
-    with a context set to <tref>null</tref> to prevent compaction returns
-    the following document:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Flattened sample document in expanded form">
-  <!--
-  [
-    {
       "@id": "http://me.markus-lanthaler.com/",
-      "http://xmlns.com/foaf/0.1/name": [
-        { "@value": "Markus Lanthaler" }
-      ],
-      "http://xmlns.com/foaf/0.1/knows": [
-        { "@id": "_:t0" },
-        { "@id": "http://greggkellogg.net/foaf#me" }
-      ]
-    },
+      "name": "Markus Lanthaler",
+      "homepage": "http://www.markus-lanthaler.com/"
+    }
+    -->
+    </pre>
+
+    <p>Note that all <tref title="IRI">IRIs</tref> have been compacted to
+      <tref title="term">terms</tref> as specified in the <tref>context</tref>,
+      which has been injected into the output. While compacted output is
+      useful to humans, it is also used to generate structures that are easy to
+      program against. Compaction enables developers to map any expanded document
+      into an application-specific compacted document. While the context provided
+      above mapped <code>http://xmlns.com/foaf/0.1/nam</code> to <code>name</code>, it
+      could also have been mapped to any other term provided by the developer.</p>
+  </section>
+
+  <section class="informative">
+    <h2>Flattening</h2>
+
+    <p>While expansion ensures that a document is in a uniform structure,
+      flattening goes a step further to ensure that the shape of the data
+      is deterministic. In expanded documents, the properties of a single
+      properties of a single <tref>node</tref> may be spread across a number of
+      different <tref title="JSON object">JSON objects</tref>. By flattening a
+      document, all properties of a <tref>node</tref> are collected in a single
+      <tref>JSON object</tref> and all <tref title="blank node">blank nodes</tref>
+      are labeled with a <tref>blank node identifier</tref>. This may drastically
+      simplify the code required to process JSON-LD data in certain applications.</p>
+
+    <p>For example, assume the following JSON-LD input document:</p>
+
+    <pre class="example" data-transform="updateExample"
+         title="Sample JSON-LD document">
+    <!--
     {
-      "@id": "_:t0",
-      "http://xmlns.com/foaf/0.1/name": [
-        { "@value": "Manu Sporny" }
-      ],
-      "http://xmlns.com/foaf/0.1/knows": [
-        { "@id": "http://greggkellogg.net/foaf#me" }
-      ]
-    },
-    {
-      "@id": "http://greggkellogg.net/foaf#me",
-      "http://xmlns.com/foaf/0.1/name": [
-        { "@value": "Gregg Kellogg" }
+      "@context": {
+        "name": "http://xmlns.com/foaf/0.1/name",
+        "knows": "http://xmlns.com/foaf/0.1/knows"
+      },
+      "@id": "http://me.markus-lanthaler.com/",
+      "name": "Markus Lanthaler",
+      "knows": [
+        {
+          "name": "Manu Sporny",
+          "knows": {
+            "@id": "http://greggkellogg.net/foaf#me"
+          }
+        },
+        {
+          "@id": "http://greggkellogg.net/foaf#me",
+          "name": "Gregg Kellogg"
+        }
       ]
     }
-  ]
-  -->
-  </pre>
-
-  <p>Note how in the output above all properties of a <tref>node</tref> are collected in a
-    single <tref>JSON object</tref> and how the <tref>blank node</tref> representing
-    &quot;Manu Sporny&quot; has been assigned the <tref>blank node identifier</tref>
-    <code>_:t0</code>.</p>
-
-  <p>To make it easier for humans to read such a flattened document can be compacted by
-    passing a context. Using the same context as the input document, the flattened
-    and compacted document looks as follows:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Flattened and compacted sample document">
-  <!--
-  {
-    "@context": {
-      "name": "http://xmlns.com/foaf/0.1/name",
-      "knows": "http://xmlns.com/foaf/0.1/knows"
-    },
-    "@graph": [
+    -->
+    </pre>
+
+    <p>Running the <a href="#flattening-algorithm">Flattening Algorithm</a>
+      with a context set to <tref>null</tref> to prevent compaction returns
+      the following document:</p>
+
+    <pre class="example" data-transform="updateExample"
+         title="Flattened sample document in expanded form">
+    <!--
+    [
       {
         "@id": "http://me.markus-lanthaler.com/",
-        "name": "Markus Lanthaler",
-        "knows": [
+        "http://xmlns.com/foaf/0.1/name": [
+          { "@value": "Markus Lanthaler" }
+        ],
+        "http://xmlns.com/foaf/0.1/knows": [
           { "@id": "_:t0" },
           { "@id": "http://greggkellogg.net/foaf#me" }
         ]
       },
       {
         "@id": "_:t0",
-        "name": "Manu Sporny",
-        "knows": {
-          "@id": "http://greggkellogg.net/foaf#me"
-        }
+        "http://xmlns.com/foaf/0.1/name": [
+          { "@value": "Manu Sporny" }
+        ],
+        "http://xmlns.com/foaf/0.1/knows": [
+          { "@id": "http://greggkellogg.net/foaf#me" }
+        ]
       },
       {
         "@id": "http://greggkellogg.net/foaf#me",
-        "name": "Gregg Kellogg"
+        "http://xmlns.com/foaf/0.1/name": [
+          { "@value": "Gregg Kellogg" }
+        ]
       }
     ]
-  }
-  -->
-  </pre>
-
-  <p>Please note that the flattened and compacted result will explicitly
-    designate the default graph by the <code>@graph</code> member in the top-level
-    <tref>JSON object</tref>, except if its value contains just one item.</p>
-
-</section>
-
-<section class="informative">
-  <h2>RDF Conversion</h2>
-  <p>JSON-LD can be used to serialize data expressed in RDF as described in
-    [[RDF-CONCEPTS]]. This ensures that data can be round-tripped to and from
-    any RDF syntax without any loss in fidelity.</p>
-
-  <p>For example, assume the following RDF input serialized in Turtle [[TURTLE-TR]]:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Sample Turtle document">
-  <!--
-  <http://me.markus-lanthaler.com/> <http://xmlns.com/foaf/0.1/name> "Markus Lanthaler" .
-  <http://me.markus-lanthaler.com/> <http://xmlns.com/foaf/0.1/homepage> <http://www.markus-lanthaler.com/> .
-  -->
-  </pre>
-
-  <p>Using the <a href="#convert-from-rdf-algorithm">Convert from RDF Algorithm</a> a
-    developer could transform this document into expanded JSON-LD:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Sample Turtle document converted to JSON-LD">
-  <!--
-  [
+    -->
+    </pre>
+
+    <p>Note how in the output above all properties of a <tref>node</tref> are collected in a
+      single <tref>JSON object</tref> and how the <tref>blank node</tref> representing
+      &quot;Manu Sporny&quot; has been assigned the <tref>blank node identifier</tref>
+      <code>_:t0</code>.</p>
+
+    <p>To make it easier for humans to read or for certain applications to
+      process it, a flattened document can be compacted by passing a context. Using
+      the same context as the input document, the flattened and compacted document
+      looks as follows:</p>
+
+    <pre class="example" data-transform="updateExample"
+         title="Flattened and compacted sample document">
+    <!--
     {
-      "@id": "http://me.markus-lanthaler.com/",
-      "http://xmlns.com/foaf/0.1/name": [
+      "@context": {
+        "name": "http://xmlns.com/foaf/0.1/name",
+        "knows": "http://xmlns.com/foaf/0.1/knows"
+      },
+      "@graph": [
         {
-          "@value": "Markus Lanthaler"
-        }
-      ],
-      "http://xmlns.com/foaf/0.1/homepage": [
+          "@id": "http://me.markus-lanthaler.com/",
+          "name": "Markus Lanthaler",
+          "knows": [
+            { "@id": "_:t0" },
+            { "@id": "http://greggkellogg.net/foaf#me" }
+          ]
+        },
         {
-          "@id": "http://www.markus-lanthaler.com/"
+          "@id": "_:t0",
+          "name": "Manu Sporny",
+          "knows": {
+            "@id": "http://greggkellogg.net/foaf#me"
+          }
+        },
+        {
+          "@id": "http://greggkellogg.net/foaf#me",
+          "name": "Gregg Kellogg"
         }
       ]
     }
-  ]
-  -->
-  </pre>
-
-  <p>Note that the output above could easily be compacted using the technique outlined
-    in the previous section. It is also possible to transform the JSON-LD document back
-    to RDF using the <a href="#convert-to-rdf-algorithm">Convert to RDF Algorithm</a>.</p>
+    -->
+    </pre>
+
+    <p>Please note that the flattened and compacted result will explicitly
+      designate the default graph by the <code>@graph</code> member in the top-level
+      <tref>JSON object</tref>, except if its value contains just one item.</p>
   </section>
 
+  <section class="informative">
+    <h2>RDF Conversion</h2>
+
+    <p>JSON-LD can be used to serialize data expressed in RDF as described in
+      [[RDF-CONCEPTS]]. This ensures that data can be round-tripped to and from
+      any RDF syntax without any loss in fidelity.</p>
+
+    <p>For example, assume the following RDF input serialized in Turtle [[TURTLE-TR]]:</p>
+
+    <pre class="example" data-transform="updateExample"
+         title="Sample Turtle document">
+    <!--
+    <http://me.markus-lanthaler.com/> <http://xmlns.com/foaf/0.1/name> "Markus Lanthaler" .
+    <http://me.markus-lanthaler.com/> <http://xmlns.com/foaf/0.1/homepage> <http://www.markus-lanthaler.com/> .
+    -->
+    </pre>
+
+    <p>Using the <a href="#convert-from-rdf-algorithm">Convert from RDF Algorithm</a> a
+      developer could transform this document into expanded JSON-LD:</p>
+
+    <pre class="example" data-transform="updateExample"
+         title="Sample Turtle document converted to JSON-LD">
+    <!--
+    [
+      {
+        "@id": "http://me.markus-lanthaler.com/",
+        "http://xmlns.com/foaf/0.1/name": [
+          {
+            "@value": "Markus Lanthaler"
+          }
+        ],
+        "http://xmlns.com/foaf/0.1/homepage": [
+          {
+            "@id": "http://www.markus-lanthaler.com/"
+          }
+        ]
+      }
+    ]
+    -->
+    </pre>
+
+    <p>Note that the output above could easily be compacted using the technique outlined
+      in the previous section. It is also possible to transform the JSON-LD document back
+      to RDF using the <a href="#convert-to-rdf-algorithm">Convert to RDF Algorithm</a>.</p>
+  </section>
 </section>
 
 <section>
@@ -690,12 +712,12 @@
 </section>
 
 <section>
-<h1>Algorithms</h1>
-
-<p>All algorithms described in this section are intended to operate on
-  language-native data structures. That is, the serialization to a text-based
-  JSON document isn't required as input or output to any of these algorithms and
-  language-native data structures MUST be used where applicable.</p>
+  <h1>Algorithms</h1>
+
+  <p>All algorithms described in this section are intended to operate on
+    language-native data structures. That is, the serialization to a text-based
+    JSON document isn't required as input or output to any of these algorithms and
+    language-native data structures MUST be used where applicable.</p>
 
 <section>
   <h2>Algorithm Terms</h2>
@@ -720,13 +742,6 @@
     <dt><tdef>local context</tdef></dt>
     <dd>A context that is specified within a <tref>JSON object</tref>,
       specified via the <code>@context</code> <tref>keyword</tref>.</dd>
-    <dt><tdef>processor state</tdef></dt>
-    <dd>The <tref>processor state</tref>, which includes the <tref>active
-      context</tref>, <tref>active subject</tref>, and
-      <tref>active property</tref>. The <tref>processor state</tref> is managed
-      as a stack with elements from the previous <tref>processor state</tref>
-      copied into a new <tref>processor state</tref> when entering a new
-      <tref>JSON object</tref>.</dd>
     <dt><tdef>JSON-LD input</tdef></dt>
     <dd>The JSON-LD data structure that is provided as input to the algorithm.</dd>
     <dt><tdef>JSON-LD output</tdef></dt>
@@ -758,1084 +773,3171 @@
     <dt><tdef>quad</tdef></dt>
     <dd>An <em>RDF triple</em> as specified by [[RDF-CONCEPTS]] augmented with
       a fourth component, a <tref>graph name</tref>.</dd>
+  <dt><tdef>RDF subject</tdef></dt>
+  <dd>A <em>subject</em> as specified by [[RDF-CONCEPTS]].</dd>
+  <dt><tdef>RDF predicate</tdef></dt>
+  <dd>A <em>predicate</em> as specified by [[RDF-CONCEPTS]].</dd>
+  <dt><tdef>RDF object</tdef></dt>
+  <dd>An <em>object</em> as specified by [[RDF-CONCEPTS]].</dd>
   </dl>
-</section>
-
-<section>
-  <h2>Expansion Algorithm</h2>
-
-  <p>The algorithm takes three input variables: an <tref>active context</tref>,
-    an <tref>active property</tref>, and an <em>element</em> to be expanded. To
-    begin, the <tref>active context</tref> is set to the result of performing, <a
-    href="#context-processing">Context Processing</a> on the passed
-    <code class="idlMemberName"><a href="#widl-JsonLdOptions-expandContext">expandContext</a></code>,
-    or empty if <code class="idlMemberName"><a href="#widl-JsonLdOptions-expandContext">expandContext</a></code>
-    is <tref>null</tref>, <tref>active property</tref> is set to <tref>null</tref>, and
-    <em>element</em> is set to the <tref>JSON-LD input</tref>. This algorithm expects the
-    <tref>JSON-LD input</tref> to be a well-formed JSON-LD document as defined in [[!JSON-LD]].</p>
-
-  <ol class="algorithm">
-    <li>If <em>element</em> is a <tref>scalar</tref>, expand it according to the
-      <a href="#value-expansion">Value Expansion</a> algorithm, passing copies of the
-      <tref>active context</tref> and <tref>active property</tref> and return. If the
-      <tref>active property</tref> equals <tref>null</tref> or <code>@graph</code>
-      set <em>element</em> to <tref>null</tref> instead and return.</li>
-    <li>If <em>element</em> is <tref>null</tref>, return.</li>
-    <li>If <em>element</em> is an <tref>array</tref>,
-      <ol class="algorithm">
-        <li>initialize an empty array <em>result</em>.</li>
-        <li>Expand each <em>item</em> by recursively using this algorithm, passing copies of
-          the <tref>active context</tref> and <tref>active property</tref>.</li>
-        <li>If the <tref title="active property">active property's</tref>
-          <tref>container mapping</tref> is set to <code>@list</code> and the expanded
-          <em>item</em> is an <tref>array</tref> or a <tref>list object</tref> trigger
-          a <code class="error">list of lists detected</code> error.</li>
-        <li>If the expanded <em>item</em> is <tref>null</tref>, drop it.</li>
-        <li>Otherwise, if the expanded <em>item</em> is an <tref>array</tref>, merge its
-          entries with <em>result's</em> entries.</li>
-        <li>Otherwise, append <em>item</em> to <em>result</em>.</li>
-        <li>Finally, set <em>element</em> to <em>result</em> and return.</li>
-      </ol>
-    </li>
-    <li>Otherwise, <em>element</em> must be an object.
-      <ol class="algorithm">
-        <li>If <em>element</em> has a <code>@context</code> member, update the
-          <tref>active context</tref> according to the steps outlined in
-          <a href="#context-processing">Context Processing</a> and remove the
-          <code>@context</code> member.</li>
-        <li>Initialize an empty <tref>JSON object</tref> <em>result</em> and</li>
-        <li>then process each <em>property</em> and <em>value</em> in <em>element</em>
-          ordered by <em>property</em> as follows:
-          <ol class="algorithm">
-            <li>If the <tref>active context</tref> contains a <tref>property generator</tref> for
-               <em>property</em> set <em>expanded property</em> to its <tref title="IRI">IRIs</tref>,
-               otherwise set it to the result of expanding <em>property</em> according to the steps
-               outlined in <a href="#iri-expansion">IRI Expansion</a> (passing <code>true</code> for
-               the <em>vocabRelative</em> flag).</li>
-            <li>If <em>expanded property</em> is a <tref>keyword</tref>, process it as
-              follows:
-              <ol class="algorithm">
-                <li>If <em>expanded property</em> equals <code>@id</code>, set the <code>@id</code>
-                  member of <em>result</em> to the result of expanding <em>value</em>
-                  according the <a href="#iri-expansion">IRI Expansion algorithm</a> (passing <code>true</code>
-                  for the <em>documentRelative</em> flag). If <em>value</em> is not a <tref>string</tref>
-                  trigger an <code class="error">invalid @id value</code> error.</li>
-                <li>If <em>expanded property</em> equals <code>@type</code>, set the <code>@type</code>
-                  member of <em>result</em> to the result of expanding <em>value</em>
-                  according the <a href="#iri-expansion">IRI Expansion algorithm</a> (passing <code>true</code>
-                  for both the <em>documentRelative</em> and the <em>vocabRelative</em> flag). If <em>value</em>
-                  is neither a <tref>string</tref> nor an <tref>array</tref> of
-                  <tref title="string">strings</tref> trigger an <code class="error">invalid type value</code>
-                  error. Empty <tref title="array">arrays</tref> are ignored.</li>
-                <li>If <em>expanded property</em> equals <code>@value</code>, set the <code>@value</code>
-                  member of <em>result</em> to <em>value</em>. If <em>value</em> is neither a <tref>scalar</tref>
-                  nor <tref>null</tref> trigger an <code class="error">invalid value object value</code> error.</li>
-                <li>If <em>expanded property</em> equals <code>@language</code>, set the <code>@language</code>
-                  member of <em>result</em> to the lowercased <em>value</em>. If <em>value</em> is not
-                  a <tref>string</tref>, trigger an <code class="error">invalid language value</code> error.</li>
-                <li>If <em>expanded property</em> equals <code>@index</code>, set the <code>@index</code>
-                  member of <em>result</em> to <em>value</em>. If <em>value</em> is not a <tref>string</tref>
-                  trigger an <code class="error">invalid @index value</code> error.</li>
-                <li>If <em>expanded property</em> equals <code>@set</code> set the <em>expanded property</em>
-                  member of <em>result</em> to the result of expanding <em>value</em> by
-                  recursively using this algorithm, passing copies of the <tref>active context</tref> and
-                  <tref>active property</tref>.</li>
-                <li>If <em>expanded property</em> equals <code>@list</code>, set the <em>expanded property</em>
-                  member of <em>result</em> to the result of expanding <em>value</em> by
-                  recursively using this algorithm, passing copies of the <tref>active context</tref> and
-                  <tref>active property</tref>; if <tref>active property</tref> equals <tref>null</tref> or
-                  <code>@graph</code>, pass <code>@list</code> as <tref>active property</tref> instead.</li>
-                <li>If <em>expanded property</em> equals <code>@graph</code>, set the <code>@graph</code>
-                  member of <em>result</em> to the result of expanding <em>value</em> by
-                  recursively using this algorithm, passing copies of the <tref>active context</tref> and
-                  <code>@graph</code> as <tref>active property</tref>.</li>
-                <li>Continue with the next <em>property</em>-<em>value</em> pair from <em>element</em>.</li>
-              </ol>
-            </li>
-            <li>If <em>expanded property</em> is neither a <tref>blank node identifier</tref> nor an
-              <tref>absolute IRI</tref>,i.e., it is <tref>null</tref> or does not contain a colon
-              (<code>:</code>), continue with the next member from <em>element</em>.</li>
-            <li>Otherwise, if <em>property's</em> <tref>container mapping</tref> is set to
-              <code>@language</code>
-              <ol class="algorithm">
-                <li>Initialize a new empty <tref>array</tref> <em>language map values</em>.</li>
-                <li>Process each <em>key</em>-<em>val</em> pair of <em>value</em> ordered by
-                  <em>key</em> as follows:
-                  <ol class="algorithm">
-                    <li>If <em>val</em> is not an array, transform it to one.</li>
-                    <li>For each item of <em>val</em>, construct a new <tref>JSON object</tref>
-                      consisting of two members: <code>@value</code> set to the currently
-                      processed item and <code>@language</code> set to the lowercased <em>key</em>.
-                      If <em>val</em> is not a <tref>string</tref>, trigger a
-                      <code class="error">language map invalid value</code> error. Otherwise append
-                      the object to <em>language map values</em>.</li>
-                  </ol>
-                </li>
-                <li>Set <em>value</em> to <em>language map values</em>.</li>
-              </ol>
-            </li>
-            <li>Otherwise, if <em>property's</em> <tref>container mapping</tref> is set to
-              <code>@index</code>
-              <ol class="algorithm">
-                <li>Initialize a new empty <tref>array</tref> <em>index map values</em>.</li>
-                <li>Process each <em>key</em>-<em>val</em> pair of <em>value</em> ordered by
-                  <em>key</em> as follows:
-                  <ol class="algorithm">
-                    <li>If <em>val</em> is not an array, transform it to one.</li>
-                    <li>Expand <em>val</em> by recursively using this algorithm, passing copies of
-                      the <tref>active context</tref> and <em>property</em> as
-                      <tref>active property</tref>.</li>
-                    <li>Add to each item of <em>val</em> a member <code>@index</code> set to
-                      <em>key</em> if no such member exists yet and append the resulting
-                      <tref>JSON object</tref> to <em>index map values</em>.</li>
-                  </ol>
-                </li>
-                <li>Set <em>value</em> to <em>index map values</em>.</li>
-              </ol>
-            </li>
-            <li>Otherwise, expand <em>value</em> by recursively using this algorithm, passing
-              copies of the <tref>active context</tref> and <em>property</em> as
-              <tref>active property</tref>.</li>
-            <li>If the expanded <em>value</em> equals <tref>null</tref>, continue with the next
-              <em>property</em>-<em>value</em> pair from <em>element</em>.</li>
-            <li>If <em>property's</em> <tref>container mapping</tref> is set to <code>@list</code> and
-              <em>value</em> is either not an <tref>JSON object</tref> or a <tref>JSON object</tref>
-              without an <code>@list</code> member, replace <em>value</em> with a
-              <tref>JSON object</tref> with an <code>@list</code> member whose value is set to
-              <em>value</em> (wrapped in an <tref>array</tref> if it is not already one).</li>
-            <li>If <em>expanded property</em> is an <tref>array</tref>,
-              <ol class="algorithm">
-                <li>label all <tref title="blank node">blank nodes</tref> in <em>value</em> with
-                  <tref title="blank node identifier">blank node identifiers</tref> by using the
-                  <a href="#label-blank-nodes-algorithm">Label Blank Nodes Algorithm</a>.</li>
-                <li>Then, for each <em>iri</em> of <em>expanded property</em> merge a copy
-                  of <em>value</em> into the <em>iri</em> member of the <em>result</em>
-                  <tref>JSON object</tref>.</li>
-              </ol>
-            </li>
-            <li>Otherwise, merge <em>value</em> into the <em>iri</em> member of the <em>result</em>
-              <tref>JSON object</tref>.</li>
-          </ol>
-        </li>
-        <li>Set <em>element</em> to <em>result</em> and <em>numProperties</em> to the number of members
-          of <em>result</em>.</li>
-        <li>If <em>element</em> has an <code>@index</code> member, decrease <em>numProperties</em>
-          by 1.</li>
-        <li>If the <tref>active property</tref> equals <tref>null</tref> or <code>@graph</code> and
-          <em>element</em> has an <code>@value</code> member, <em>numProperties</em> equals <code>0</code>,
-          or <em>element</em> consists of only an <code>@id</code> member, set <em>element</em> to
-          <tref>null</tref> and return.</li>
-        <li>If <em>element</em> has an <code>@value</code> member,
-          <ol class="algorithm">
-            <li>decrease <em>numProperties</em> by 1.</li>
-            <li>If <em>element</em> has an <code>@language</code> member, decrease <em>numProperties</em>
-              by 1 and check that the value of the <code>@value</code> member is a string. If not,
-              trigger an <code class="error">invalid language tagged string</code> error.</li>
-            <li>Otherwise, if <em>element</em> has an <code>@type</code> member, decrease
-              <em>numProperties</em> by 1 and check that the value of the <code>@type</code> member is a
-              string. If not, trigger an <code class="error">invalid typed value</code> error.</li>
-            <li>If <em>numProperties</em> is greater than 0, trigger an
-              <code class="error">invalid value object</code> error.</li>
-            <li>If the value of the <code>@value</code> member equals <tref>null</tref>, set
-              <em>element</em> to <tref>null</tref>.</li>
-            <li>Return.</li>
-          </ol>
-        </li>
-        <li>If <em>element</em> has an <code>@type</code> member whose value is not an <tref>array</tref>,
-          transform it to an <tref>array</tref>.</li>
-        <li>If <em>element</em> has an <code>@list</code> or <code>@set</code> member and
-          <em>numProperties</em> is greater than 1, trigger an
-          <code class="error">invalid set or list object</code> error.</li>
-        <li>Otherwise, if <em>element</em> has an <code>@set</code> member, set <em>element</em> to
-          the value of that member.</li>
-        <li>Otherwise, if <em>element</em> has just an <code>@language</code> member, set <em>element</em>
-          to null.</li>
-      </ol>
-    </li>
-  </ol>
-
-  <p>If, after the algorithm outlined above is run, the resulting <em>element</em> is an
-    <tref>JSON object</tref> with just a <code>@graph</code> member, <em>element</em> is set to
-    the value of <code>@graph</code>'s value. Finally, if <em>element</em> is a <tref>JSON object</tref>,
-    it is wrapped into an <tref>array</tref>, if <em>element</em> equals <tref>null</tref>, an empty
-    <tref>array</tref> is returned.</p>
-</section>
-
-<section>
-  <h2 id="context">Context Processing</h2>
-
-  <p>Processing of JSON-LD data structure is managed recursively. During processing, each
-    rule is applied using information provided by the <tref>active context</tref>.</p>
-
-  <p>The <tref>active context</tref> contains the active <tdef title="term definition">term definitions</tdef>
-    which specify how properties and values have to be interpreted as well as the current
-    <tdef>vocabulary mapping</tdef> and the <tdef>default language</tdef>. Each <tref>term definition</tref> consists
-    of an <tdef>IRI mapping</tdef> and optionally a <tdef>type mapping</tdef> from terms to datatypes or
-    <tdef>language mapping</tdef> from terms to language codes, and a <tdef>container mapping</tdef>. If an
-    <tref>IRI mapping</tref> maps a term to multiple <tref="IRI">IRIs</tref> it is said to be a
-    <tdef>property generator</tdef>.</p>
-
-  <p>If a <tref>local context</tref> is encountered, information from the <tref>local context</tref>
-    is merged into the <tref>active context</tref>. A <tref>local context</tref> is identified within
-    a <tref>JSON object</tref> having a <code>@context</code> member with a <tref>string</tref>,
-    <tref>array</tref> or a <tref>JSON object</tref> value.</p>
-
-  <p>This algorithm specifies how the <tref>active context</tref> is updated with a
-    <tref>local context</tref>. The algorithm takes three input variables: an <tref>active context</tref>,
-    a <tref>local context</tref>, and an array of already included remote contexts <em>remoteContexts</em>. To
-    begin, <em>remoteContexts</em> is initialized to an empty array.</p>
-
-  <p>All calls of the <a href="#iri-expansion">IRI Expansion algorithm</a> pass the value specified in the
-    algorithm along with the <tref>active context</tref>, the currently being processed <tref>local context</tref>,
-    and <code>true</code> for the <em>vocabRelative</em> flag.</p>
-
-  <ol class="algorithm">
-    <li>If the <tref>local context</tref> is not an array, transform it to one.</li>
-    <li>Process each item <em>context</em> of the <tref>local context</tref> as follows:
-      <ol class="algorithm">
-        <li>If <em>context</em> equals <tref>null</tref>, reset the <tref>active context</tref>
-          and continue with the next item.</li>
-        <li>If <em>context</em> is a <tref>string</tref>:
-          <ol class="algorithm">
-            <li>Expand <em>context</em> according to <a href="#iri-expansion">IRI Expansion</a>.</li>
-            <li>If <em>context</em> is in the <em>remoteContexts</em> array, raise an
-              <code class="error">recursive context inclusion</code> error. Otherwise, add
-              <em>context</em> to <em>remoteContexts</em>.</li>
-            <li>Dereference <em>context</em>.</li>
-            <li>If the resulting document is a JSON document consisting of a top-level
-              <tref>JSON object</tref> that has a <code>@context</code> member recursively invoke
-              this algorithm passing a copy of <tref>active context</tref>, the value of the
-              <code>@context</code> member as <tref>local context</tref>, and a copy of
-                the <em>remoteContexts</em> array. <tref title="relative IRI">Relative IRIs</tref>
-                are expanded using the remote context's IRI. Otherwise raise an
-                <code class="error">invalid remote context</code> error.</li>
-            <li>Continue with the next item from <em>context</em>.</li>
-          </ol>
-        </li>
-        <li>If <em>context</em> is not a <tref>JSON object</tref>, raise an
-          <code class="error">invalid local context</code> error.</li>
-        <li>Otherwise, if <em>context</em> is an <tref>JSON object</tref>, perform the following steps:
-          <ol class="algorithm">
-            <li>If <em>context</em> has a <code>@vocab</code> member: if its value is neither
-              an <tref>absolute IRI</tref>, i.e., it does not contain a colon (<code>:</code>),
-              nor <tref>null</tref>, trigger an <code class="error">invalid vocab mapping</code>
-              error; otherwise set the <tref title="active context">active context's</tref>
-              <tref>vocabulary mapping</tref> to its value and remove the <code>@vocab</code>
-              member from <em>context</em>.</li>
-            <li>If <em>context</em> has a <code>@language</code> member: if its value is neither
-              a <tref>string</tref> nor <tref>null</tref>, trigger an
-              <code class="error">invalid default language</code> error; otherwise set the
-              <tref title="active context">active context's</tref> <tref>default language</tref> to
-              its value and remove the <code>@language</code> member from <em>context</em>.</li>
-            <li>For each other <em>key</em>-<em>value</em> pair in <em>context</em> perform the
-              following steps:
-              <ol class="algorithm">
-                <li>Remove the <em>key</em>-<em>value</em> pair from <em>context</em>.</li>
-                <li>If <em>key</em> is a JSON-LD <tref>keyword</tref>, raise a
-                  <code class="error">keyword redefinition</code> error.</li>
-                <li>If <em>value</em> equals <tref>null</tref>, replace the <tref>term definition</tref>
-                  for <em>key</em> in the <tref>active context</tref> with an <tref>IRI mapping</tref>
-                  set to <tref>null</tref> and continue with the next <em>key</em>-<em>value</em> pair.</li>
-                <li>If <em>value</em> is a <tref>string</tref>, expand it according to the
-                  <a href="#iri-expansion">IRI Expansion algorithm</a> and replace the
-                  <tref>term definition</tref> for <em>key</em> in the <tref>active context</tref> with
-                  an <tref>IRI mapping</tref> set to the expanded <em>value</em>. Continue with
-                  the next <em>key</em>-<em>value</em> pair.</li>
-                <li>If <em>value</em> is not a <tref>JSON object</tref>, trigger an
-                  <code class="error">invalid term definition</code> error</li>
-                <li>If <tref>term definition</tref> for <em>key</em> exists in the
-                  <tref>active context</tref>, remove it.</li>
-                <li>Initialize a new, empty <tref>term definition</tref> <em>definition</em>.</li>
-                <li>If <em>value</em> has an <code>@id</code> member with a value <em>val</em>:
-                  <ol class="algorithm">
-                    <li>if <em>val</em> is an <tref>array</tref>,:
-                      <ol class="algorithm">
-                        <li>expand each <em>item</em> in the array according the
-                          <a href="#iri-expansion">IRI Expansion algorithm</a> if it is a
-                          <tref>string</tref>. If am <em>item</em> is not a <tref>string</tref>,
-                          raise an <code class="error">invalid property generator</code> error; if
-                          <em>item</em> does not expand to an <tref>absolute IRI</tref> or
-                          <tref>blank node identifier</tref>, i.e., it does not contain a colon
-                          (<code>:</code>) after expansion, raise an
-                          <code class="error">invalid property generator IRI mapping</code> error.</li>
-                        <li>Lexicographically sort <em>val</em> and set the <tref>IRI mapping</tref>
-                          of <em>definition</em> to <em>val</em>.</li>
-                      </ol>
-                    <li>Otherwise, expand <em>val</em> according the
-                      <a href="#iri-expansion">IRI Expansion algorithm</a> and set the
-                      <tref>IRI mapping</tref> of <em>definition</em> to <em>val</em>.</li>
-                  </ol>
-                </li>
-                <li>Otherwise, set the <tref>IRI mapping</tref> of <em>definition</em> to the result of
-                  expanding <em>key</em> according the <a href="#iri-expansion">IRI Expansion algorithm</a>.</li>
-                <li>If the <tref>IRI mapping</tref> of <em>definition</em> is set to <tref>null</tref> or a
-                  <tref>keyword</tref>, store <em>definition</em> as the <tref>term definition</tref>
-                  for <em>key</em> in the <tref>active context</tref> and continue with the next
-                  <em>key</em>-<em>value</em> pair from <em>context</em>.</li>
-                <li>Otherwise, if the <tref>IRI mapping</tref> of <em>definition</em> is set to
-                  a <tref>string</tref> which does not contain a colon (<code>:</code>), i.e., it is
-                  neither an <tref>absolute IRI</tref> nor a <tref>blank node identifier</tref>,
-                  raise an <code class="error">invalid term IRI mapping</code> error.</li>
-                <li>If <em>value</em> has an <code>@type</code> member with a value <em>val</em> and <em>val</em>
-                  is not a <tref>string</tref> or does not expand to an <tref>absolute IRI</tref> using the
-                  <a href="#iri-expansion">IRI Expansion algorithm</a>, raise an
-                  <code class="error">invalid type mapping</code> error. Otherwise set the
-                  <tref>IRI mapping</tref> of <em>definition</em> to the expanded <em>val</em>.</li>
-                <li>Otherwise, if <em>value</em> has an <code>@language</code> member with a value <em>val</em>
-                  that is a <tref>string</tref> or <tref>null</tref>, set the <tref>language mapping</tref> of
-                  <em>definition</em> to the lowercased <em>val</em>. If <em>val</em> is neither a
-                  <tref>string</tref> nor <tref>null</tref>, raise an
-                  <code class="error">invalid language mapping</code> error.</li>
-                <li>If <em>value</em> has an <code>@container</code> member with a value <em>val</em> that
-                  equals <code>@list</code>, <code>@set</code>, <code>@language</code>, or <code>@index</code>,
-                  set the <tref>container mapping</tref> of <em>definition</em> to <em>val</em>.
-                  If <em>val</em> is not one of those values, raise an
-                  <code class="error">invalid container mapping</code> error.</li>
-              </ol>
-            </li>
-          </ol>
-        </li>
-      </ol>
-    </li>
-  </ol>
-</section>
-
-<section>
-  <h2>IRI Expansion</h2>
-
-  <p>In JSON-LD documents keys and some values are evaluated to produce an <tref>IRI</tref>.
-    This section defines an algorithm for transforming strings representing an IRI into an
-    <tref>absolute IRI</tref>. If IRI expansion occurs during context processing, the
-    <tref>local context</tref> that is being processed is passed to this algorithm.
-    After application of this algorithm, values processed by this algorithm are said to be
-    in <tdef>expanded IRI form</tdef>, although this may also include
-    <tref title="blank node identifier">blank node identifiers</tref> and
-    JSON-LD <tref title="keyword">keywords</tref>.</p>
-
-  <p>The algorithm takes two mandatory and four optional input variables: a <em>value</em>
-    to be expanded, an <tref>active context</tref>, two flags <em>documentRelative</em> and
-    <em>vocabRelative</em> specifying whether <em>value</em> should be interpreted as
-    <tref>relative IRI</tref> against the document's base IRI or the
-    <tref title="active context">active context's</tref> <tref>vocabulary mapping</tref>,
-    along with an <tref>local context</tref> passed when this algorithm is used in
-    <a href="#context-processing">Context Processing</a>, and finally an array
-    <em>path</em> which is used to detect cyclic <tref title="IRI mapping">IRI mappings</tref>.
-    If not passed, the two flags are set to <code>false</code> and <em>path</em> is
-    initialized to an empty <tref>array</tref> by default.</p>
-
-  <p>The algorithm for generating an IRI is:</p>
-
-  <ol class="algorithm">
-    <li>If <em>value</em> is <tref>null</tref> or a JSON-LD <tref>keyword</tref>, return
-      <em>value</em> as is.</li>
-    <li>If a <tref>local context</tref> has been passed
-      <ol class="algorithm">
-        <li>and <em>value</em> is in the <em>path</em> array, raise a
-          <code class="error">cyclic IRI mapping</code> error. Otherwise append <em>value</em>
-          to <em>path</em>.</li>
-        <li>If <tref>local context</tref> contains an <tref>IRI mapping</tref> for <em>value</em>
-          that is not a <tref>property generator</tref> return the result of recursively calling
-          this algorithm passing the <tref>IRI</tref> of the <tref>IRI mapping</tref> as new
-          <em>value</em>, the <tref>active context</tref> and <tref>local context</tref>,
-          <em>path</em>, and <code>true</code> for the <em>vocabRelative</em> flag. If the result
-          is a <tref>property generator</tref>, raise an
-          <code class="error">property generator in term definition</code> error.</li>
-      </ol>
-    </li>
-    <li>If the <em>vocabRelative</em> flag is set to <code>true</code> and an <tref>IRI mapping</tref>
-      exists for <em>value</em> in the <tref>active context</tref> that is not a
-      <tref>property generator</tref>, return the value of the <tref>IRI mapping</tref>.</li>
-    <li>If <em>value</em> contains a colon (<code>:</code>), perform the following steps:
-      <ol class="algorithm">
-        <li>Split <em>value</em> into a <em>prefix</em> and <em>suffix</em> at the first occurrence of
-          a colon (<code>:</code>).</li>
-        <li>If <em>suffix</em> begins with <code>//</code> or <em>prefix</em> equals <code>_</code>,
-          return <em>value</em> as is.</li>
-        <li>If a <tref>local context</tref> has been passed, expand <em>prefix</em> by recursively
-          invoking this algorithm passing <em>prefix</em> as <em>value</em>, the <tref>active context</tref>
-          and <tref>local context</tref>, <em>path</em>, and <code>true</code> for the
-          <em>vocabRelative</em> flag. If the expanded <em>prefix</em> contains a colon (<code>:</code>)
-          generate and return an <tref>IRI</tref> by prepending the expanded <em>prefix</em> to the
-          (possibly empty) <em>suffix</em> using textual concatenation.</li>
-        <li>Otherwise, if the <tref>active context</tref> contains an <tref>IRI mapping</tref> for
-          <em>prefix</em> that is not a <tref>property generator</tref>, generate and return an
-          <tref>IRI</tref> by prepending the <tref>IRI</tref> mapped to <em>prefix</em> to the
-          (possibly empty) <em>suffix</em> using textual concatenation.</li>
-      </ol>
-    </li>
-    <li>Otherwise, if the <em>vocabRelative</em> flag is set to <code>true</code> and the
-      <tref>active context</tref> contains a <tref>vocabulary mapping</tref>, generate and return an
-      <tref>IRI</tref> by prepending the <tref>IRI</tref> of the <tref>vocabulary mapping</tref>
-      to the <em>value</em> using textual concatenation.</li>
-    <li>Otherwise, if the <em>documentRelative</em> flag is set to <code>true</code>, resolve <em>value</em>
-      against the base IRI as per [[!RFC3986]] and return the resulting <tref>IRI</tref>. Only the basic
-      algorithm in section&nbsp;5.2 of [[!RFC3986]] is used; neither <em>Syntax-Based Normalization</em>
-      nor <em>Scheme-Based Normalization</em> (as described in sections&nbsp;6.2.2 and&nbsp;6.2.3 of [[!RFC3986]])
-      are performed. Characters additionally allowed in IRI references are treated in the same way that
-      unreserved characters are treated in URI references, per section&nbsp;6.5 of [[!RFC3987]]</li>
-    <li>Otherwise return <em>value</em> as is.</li>
-  </ol>
-
-  <p>If the result of the algorithm above is a <tref>blank node identifier</tref>, i.e., a string that begins with
-    <code>_:</code>, and no <tref>local context</tref> has been passed,
-    <a href="#generate-blank-node-identifier">generated a new blank node identifier</a> before returning the
-    final result.</p>
-</section>
-
-<section>
-  <h2>Value Expansion</h2>
-
-  <p>Some values in JSON-LD can be expressed in a <tref>compacted form</tref>. These values
-    are required to be expanded at times when processing JSON-LD documents.
-    A value is said to be in <tdef>expanded form</tdef> after
-    the application of this algorithm.</p>
-
-  <p>The algorithm for expanding a <em>value</em> takes an <tref>active property</tref>
-    and <tref>active context</tref>. It is implemented as follows:</p>
-
-  <ol class="algorithm">
-    <li>If <em>value</em> is <tref>null</tref>, return <tref>null</tref>.</li>
-    <li>Initialize an empty object <em>result</em>.</li>
-    <li>If <tref>active property</tref> is <code>@graph</code> or the
-      <tref title="active property">active property's</tref> <tref>type mapping</tref> is set to
-      <code>@id</code>, add a key-value pair to <em>result</em> where the key is <code>@id</code>
-      and the value is the result of expanding <em>value</em> according to the
-      <a href="#iri-expansion">IRI Expansion algorithm</a> passing <code>true</code> for the
-      <em>documentRelative</em> flag. Then return <em>result</em>.</li>
-    <li>Add a key-value pair to <em>result</em> where the key is <code>@value</code>
-      and the value is <em>value</em>.</li>
-    <li>If the <tref>active property</tref> has a <tref>type mapping</tref>, add a key-value
-      pair to <em>result</em> where the key is <code>@type</code> and the value is the
-      <tref>IRI</tref> associated with the <tref>type mapping</tref> or a newly
-      <a href="#generate-blank-node-identifier">generated blank node identifier</a> if the
-      <tref>type mapping</tref> is set to a <tref>blank node identifier</tref>.</li>
-    <li>Otherwise, if <em>value</em> is a <tref>string</tref> and the <tref>active property</tref> has a
-      <tref>language mapping</tref> or an <tref>default language</tref> is set in the <tref>active context</tref>,
-      add a key-value pair to <em>result</em> where the key is <code>@language</code> and the value is the
-      language tag associated with the <tref>language mapping</tref> or the <tref>active property</tref> or the
-      <tref>default language</tref>.</li>
-    <li>Return <em>result</em>.</li>
-  </ol>
-</section>
-
-<section>
-  <h2>Label Blank Nodes Algorithm</h2>
-
-  <p>The algorithm takes a single input variable: an <em>element</em> to be labeled with
-    <tref title="blank node identifier">blank node identifiers</tref>.</p>
-
-  <ol class="algorithm">
-    <li>If <em>element</em> is an <tref>array</tref>, recursively apply this
-      algorithm to all its items.</li>
-    <li>Otherwise, if <em>element</em> is a <tref>JSON object</tref> with a
-      <code>@list</code> member, recursively apply this algorithm to all items
-      of the <code>@list</code> member's value.</li>
-    <li>Otherwise, if <em>element</em> is a <tref>JSON object</tref>
-      <ol class="algorithm">
-        <li>For each <em>key</em>-<em>value</em> pair ordered by <em>key</em>
-          recursively apply this algorithm to <em>value</em>.</li>
-        <li>If <em>element</em> is a <tref>node object</tref> without an <code>@id</code> member,
-          create a new <code>@id</code> member and assign it a new
-          <tref>blank node identifier</tref> according the
-          <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a> algorithm.</li>
-      </ol>
-    </li>
-  </ol>
-</section>
-
-<section>
-  <h2>Generate Blank Node Identifier</h2>
-
-  <p>This algorithm is used to generate new
-    <tref title="blank node identifier">blank node identifiers</tref> or to relabel existing
-    <tref title="blank node identifier">blank node identifiers</tref> with a new one to avoid
-    collision by the introduction of new ones. It needs to keep an <em>identifier map</em>,
-    a <em>counter</em>, and a <em>prefix</em> between its executions to be able to generate new
-    <tref title="blank node identifier">blank node identifiers</tref>. The <em>counter</em>
-    is initialized to <code>0</code> and <em>prefix</em> is set to <code>_:t</code> by default.</p>
-
-  <p>The algorithm takes a single input variable <em>identifier</em> which might be
-    <tref>null</tref>.</p>
-
-  <ol class="algorithm">
-    <li>If the <em>identifier</em> is not <tref>null</tref> and is in the <em>identifier map</em>,
-      return the mapped identifier.</li>
-    <li>Otherwise, generate a new <em>blankNodeIdentifier</em> by concatenating <em>prefix</em>
-      and <em>counter</em>.</li>
-    <li>Increment <em>counter</em> by <code>1</code>.</li>
-    <li>If <em>identifier</em> is not <tref>null</tref>, create a new entry in
-      <em>identifier map</em> set to <em>blankNodeIdentifer</em>.</li>
-    <li>Return <em>blankNodeIdentifier</em>.</li>
-  </ol>
+
 </section>
 
 <section>
-  <h2>Compaction Algorithm</h2>
-
-  <p>The algorithm takes four input variables: an <tref>active context</tref>,
-    an <tref>inverse context</tref>, an <tref>active property</tref>, and an <em>element</em>
-    to be compacted. To begin, the <tref>active context</tref> is set to the result of performing
-    <a href="#context-processing">Context Processing</a> on the passed <em>context</em>,
-    <tref>inverse context</tref> is set to the result of
-    <a href="#context-processing">creating an inverse context</a> from the <tref>active context</tref>,
-    <tref>active property</tref> is set to <tref>null</tref>, and <em>element</em> is set to
-    the result of performing the <a href="#expansion-algorithm">Expansion Algorithm</a>
-    on the <tref>JSON-LD input</tref>.</p>
-
-  <ol class="algorithm">
-    <li>If <em>element</em> is an <tref>array</tref>,
-      <ol class="algorithm">
-        <li>Initialize a new empty array <em>result</em>.</li>
-        <li>Process each item in <em>element</em> recursively using this algorithm,
-          passing a copy of the <tref>active context</tref>, <tref>inverse context</tref>,
-          and the <tref>active property</tref>. Add each compacted item to <em>result</em>
-          unless it is <tref>null</tref>.</li>
-        <li>If <em>result</em> has a single item and the
-          <code class="idlMemberName"><a href="#widl-JsonLdOptions-compactArrays">compactArrays</a></code>
-          option is set to <code>true</code>, return that item; otherwise return
-          <em>result</em>.</li>
-      </ol>
-    </li>
-    <li>If <em>element</em> is not a <tref>JSON object</tref> it is already in
-      compact form, return it as is.</li>
-    <li>If <em>element</em> has an <code>@value</code> or <code>@id</code> member,
-      replace <em>element</em> with the result of the
-      <a href="#value-compaction">Value Compaction algorithm</a>. If the updated
-      <em>element</em> is a <tref>scalar</tref>, return it as it cannot be further
-      compacted.</li>
-    <li>Initialize a new empty <tref>JSON object</tref> result.</li>
-    <li>Process each <em>property</em> and <em>value</em> in <em>element</em> ordered
-      by <em>property</em> as follows:
-      <ol class="algorithm">
-        <li>If <em>property</em> is a JSON-LD <tref>keyword</tref>
-          <ol class="algorithm">
-            <li>and <em>property</em> equals <code>@id</code>, compact <em>value</em>
-              according the rules of the <a href="#iri-compaction-algorithm">IRI Compaction algorithm</a>.</li>
-            <li>Otherwise, if <em>property</em> equals <code>@type</code>, compact <em>value</em>
-              (or each item of <em>value</em> if it is an <tref>array</tref>) according the rules of the
-              <a href="#iri-compaction-algorithm">IRI Compaction algorithm</a> with the
-              <em>vocabRelative</em> flag set to <code>true</code>. If <em>value</em> is an
-              <tref>array</tref> consisting of just one item, replace <em>value</em> with that item.</li>
-            <li>Otherwise, if <em>property</em> equals <code>@graph</code> or <code>@list</code>, compact <em>value</em>
-              by recursively invoking this algorithm, passing a copy of the <tref>active context</tref>,
-              <tref>inverse context</tref>, and <em>property</em> as <tref>active property</tref>
-              ensuring that the result is an <tref>array</tref>.</li>
-            <li>Set <tref>active property</tref> to the result of performing
-              <a href="#iri-compaction-algorithm">IRI Compaction</a> on <em>property</em>.</li>
-            <li>Set the <tref>active property</tref> member of <em>result</em> to <em>value</em>.</li>
-            <li>Continue with the next <em>property</em>-<em>value</em> pair from <em>element</em>.</li>
-        </li>
-      </ol>
-    </li>
-    <li>If <em>value</em> is an empty <tref>array</tref>,
-      <ol class="algorithm">
-        <li>set <tref>active property</tref> to the result of performing
-          <a href="#iri-compaction-algorithm">IRI Compaction</a> on <em>property</em> with the
-          <em>vocabRelative</em> flag set to <code>true</code>.</li>
-        <li>If <tref>active property</tref> is a <tref>JSON object</tref>, i.e., it is a
-          <tref>property generator</tref>, set <tref>active property</tref> to the result of performing the
-          <a href="#find-and-remove-property-generator-duplicates">Find and Remove Property Generator Duplicates</a>
-          algorithm passing <em>element</em>, <em>property</em>, <tref>null</tref> for value, the
-          <tref>active context</tref>, and <tref>active property</tref>.</li>
-        <li>Ensure that <em>result</em> has an <tref>active property</tref> member; if not create it
-          and set its value to an empty <tref>array</tref>.</li>
-        <li>Continue with the next <em>property</em>-<em>value</em> pair from <em>element</em>.</li>
-      </ol>
-    </li>
-    <li>Otherwise perform the following steps for each <em>item</em> of <em>value</em>:
-      <ol class="algorithm">
-        <li>Set <tref>active property</tref> to the result of performing
-          <a href="#iri-compaction-algorithm">IRI Compaction</a> on <em>property</em> with the
-              <em>vocabRelative</em> flag set to <code>true</code>.</li>
-        <li>If <tref>active property</tref> is a <tref>JSON object</tref>, i.e., it is a
-          <tref>property generator</tref>, set <tref>active property</tref> to the result of performing the
-          <a href="#find-and-remove-property-generator-duplicates">Find and Remove Property Generator Duplicates</a>
-          algorithm passing <em>element</em>, <em>property</em>, <em>item</em>, the
-          <tref>active context</tref>, and <tref>active property</tref>.</li>
-        </li>
-        <li>If the <tref title="active property">active property's</tref> <tref>container mapping</tref>
-          is set to <code>@language</code> or <code>@index</code>
-          <ol class="algorithm">
-            <li>Unless <em>result</em> has already an <tref>active property</tref> member, create one and
-              initialize its value to an empty <tref>JSON object</tref>. This object is called <em>mapObject</em>.</li>
-            <li>Set <em>index</em> to the value of the <code>@language</code> or
-              <code>@index</code> member of <em>item</em> (depending on the value of the
-              <tref title="active property">active property's</tref> <tref>container mapping</tref>).</li>
-            <li>First compact <em>item</em> using the <a href="#value-compaction">Value Compaction algorithm</a>
-              passing <em>index</em> as <em>containerValue</em>, then compact it by recursively invoking this
-              algorithm passing a copy of the <tref>active context</tref>, <tref>inverse context</tref>, and the
-              <tref>active property</tref>.</li>
-            <li>If no <em>index</em> member exists in the <em>mapObject</em> create one and set its value
-              to <em>item</em>; otherwise append <em>item</em> to the <em>index</em> member (converting it to
-              an array if it is not one already).</li>
-            <li>Continue with the next <em>property</em>-<em>value</em> pair from <em>element</em>.</li>
-          </ol>
-        </li>
-        <li>If <em>item</em> is a <tref>JSON object</tref> having a <code>@list</code> member,
-          <ol class="algorithm">
-            <li>compact the value of that member by recursively invoking this algorithm passing
-              a copy of the <tref>active context</tref>, <tref>inverse context</tref>, and the
-              <tref>active property</tref> ensuring that the result is an <tref>array</tref>.</li>
-            <li>If the <tref title="active property">active property's</tref> <tref>container mapping</tref>
-              is set to <code>@list</code>, set the <tref>active property</tref> member of <em>result</em>
-              to the value of <em>item's</em> <code>@list</code> member. If such an member already exists
-              in result, raise an <code class="error">compaction to list of lists</code> error; otherwise
-              continue with the next <em>property</em>-<em>value</em> pair from <em>element</em>.</li>
-          </ol>
-        </li>
-        <li>If <em>item</em> is a <tref>JSON object</tref>, compact it by recursively
-          invoking this algorithm passing a copy of the <tref>active context</tref>,
-          <tref>inverse context</tref>, and the <tref>active property</tref>.</li>
-        <li>If no <tref>active property</tref> member exists in <em>result</em> create one and set its value
-          to <em>item</em>; otherwise append <em>item</em> to the <tref>active property</tref> member
-          (converting it to an <tref>array</tref> if it is not one already).</li>
-        <li>If the <code class="idlMemberName"><a href="#widl-JsonLdOptions-compactArrays">compactArrays</a></code>
-          option is set to <code>false</code> or the <tref title="active property">active property's</tref>
-          <tref>container mapping</tref> is set to <code>@list</code> or <code>@set</code>, convert the
-          value of the <tref>active property</tref> member of <em>result</em> to an <tref>array</tref> if
-          it is not one already.</li>
-      </ol>
-    </li>
-  </ol>
-
-  <p>If, after the algorithm outlined above is run, the resulting <em>element</em> is an <tref>array</tref>
-    with one or more items, replace it with a new <tref>JSON object</tref> with a single member whose name
-    is the result of compacting the value <code>@graph</code> with the
-    <a href="#iri-compaction-algorithm">IRI Compaction algorithm</a> and whose value is <em>element</em>. If
-    the resulting <em>element</em> is an <tref>array</tref> with zero items, replace it with an empty
-    <tref>JSON object</tref>. Finally, if a <em>context</em> has been passed, add a <code>@context</code>
-    property to <em>element</em> and set its value to the initially passed <em>context</em>.</p>
-</section>
+  <h2 id="remote-context">Remote Context Resolution</h2>
 
 <section>
-  <h2>IRI Compaction Algorithm</h2>
-
-  <p>This section defines an algorithm for transforming an <tref>IRI</tref> to a
-    <tref>term</tref> or <tref>compact IRI</tref>. If a <em>value</em> is passed
-    it is used to choose the best matching <tref>term</tref>.</p>
-
-  <p>This algorithm takes three mandatory and three optional parameters. The mandatory
-    parameters are the <em>iri</em> to be compacted, an <tref>active context</tref>,
-    and an <tref>inverse context</tref>. Optionally it is possible to pass a <em>value</em>,
-    and a <em>vocabRelative</em> flag which specifies whether the passed <em>iri</em>
-    should be compacted using the <tref title="active context">active context's</tref>
-    <tref>vocabulary mapping</tref>, and a base <tref>IRI</tref> which, when passed, is used
-    to transform the passed <em>iri</em> to a <tref title="relative IRI">relative IRIs</tref>
-    if the <em>vocabRelative</em> flag is set to false (which is its default value).</p>
-
-  <p>The algorithm for generating a <tref>compact IRI</tref> is:</p>
-
-  <ol class="algorithm">
-    <li>Initialize a variable <em>result</em> to <tref>null</tref>.</li>
-    <li>If the <em>vocabRelative</em> flag is set to <code>true</code> and an entry for
-      <em>iri</em> exists in the <tref>inverse context</tref>, perform the following steps:
-      <ol class="algorithm">
-        <li>If a <em>value</em> has been passed, perform the following steps:
-          <ol class="algorithm">
-            <li>Initialize <em>queryPath</em>, which will be used to query the
-              <tref>inverse context</tref>, to an empty <tref>array</tref></li>
-            <li id="calculate-value-profile-algorithm">Initialize <em>container</em>
-              to <code>@set</code>, <em>typeOrLanguage</em>, and <em>typeLanguageValue</em>
-              to <tref>null</tref>.</li>
-            <li>If <em>value</em> is a <tref>JSON object</tref>
-              <ol class="algorithm">
-                <li>and it has an <code>@index</code> member, set <em>container</em> to
-                  <code>@index</code>.</li>
-                <li>If <em>value</em> has an <code>@id</code> member, set
-                  <em>typeOrLanguage</em> to <code>@type</code> and <em>typeLanguageValue</em>
-                  to <code>@id</code>.</li>
-                <li>Otherwise, if <em>value</em> has an <code>@value</code> member,
-                  <ol class="algorithm">
-                    <li>and an <code>@type</code> member, set <em>typeOrLanguage</em> to
-                      <code>@type</code> and <em>typeLanguageValue</em> to the value of the
-                      <code>@type</code> member of <em>value</em>.</li>
-                    <li>Otherwise, if it has an <code>@language</code> member, set
-                      <em>typeOrLanguage</em> to <code>@language</code> and
-                      <em>typeLanguageValue</em> to the value of the <code>@language</code>
-                      member of <em>value</em>. If <em>value</em> has no <code>@index</code>
-                      member, set <em>container</em> to <code>@language</code></li>
-                    <li>Otherwise, set <em>typeOrLanguage</em> to <code>@language</code> and
-                      <em>typeLanguageValue</em> to <code>@null</code>.</li>
-                  </ol>
-                </li>
-                <li>Otherwise, if <em>value</em> has an <code>@list</code> member,
-                  <ol class="algorithm">
-                    <li>If the <code>@list</code> member has at least one item, update
-                      <em>container</em>, <em>typeOrLanguage</em>, and
-                      <em>typeLanguageValue</em> by recursively running the steps
-                      <a href="#calculate-value-profile-algorithm">2.1.2</a> to
-                      2.1.3.4 (which will never be true since list of lists are not
-                      allowed) of this algorithm passing the first item of <em>value's</em>
-                      <code>@list</code> member as new <em>value</em>.</li>
-                    <li>If <em>value</em> has no <code>@index</code> member, set
-                      <em>container</em> to <code>@list</code>.</li>
-                    <li>Starting from the second item of <em>value's</em> <code>@list</code>
-                      member, recursively run the steps
-                      <a href="#calculate-value-profile-algorithm">2.1.2</a> to
-                      2.1.3.4 (which will never be true since list of lists are not
-                      allowed) of this algorithm passing the item as new <em>value</em>. If
-                      the resulting <em>typeOrLanguage</em> or <em>typeLanguageValue</em>
-                      differ from the current value of <em>typeOrLanguage</em> or
-                      <em>typeLanguageValue</em>, set both to <tref>null</tref> and stop
-                      processing the <code>@list</code> items.</li>
-                  </ol>
-                </li>
-              </ol>
-            </li>
-            <li>If the <em>container</em> equals <code>@list</code>, set the first item of
-              <em>queryPath</em> to an <tref>array</tref> consisting of the two elements
-              <code>@list</code> and <code>null</code>; otherwise set it to an array
-              consisting of three elements where the first element is the value of <em>container</em>
-               and the other two elements are <code>@set</code> and <code>@null</code>.</li>
-            <li>If <em>typeOrLanguage</em> is <tref>null</tref>, set the second and the the
-              third item of <em>queryPath</em> to an <tref>array</tref> consisting of a
-              single element <code>@null</code>.</li>
-            <li>Otherwise, set the second item of <em>queryPath</em> to an <tref>array</tref>
-              consisting of two elements where the first element is the value of
-              <em>typeOrLanguage</em> and the second element is <code>@null</code>. Set the
-              third item of <em>queryPath</em> to an <tref>array</tref> whose first element
-              <em>typeLanguageValue</em> and whose second element is <code>@null</code>.</li>
-            <li><a href="#inverse-context-query-algorithm">Query the inverse context</a> and
-              store the result in <em>result</em>.</li>
-            <li>If <em>result</em> is a a <tref>string</tref> or a <tref>JSON object</tref> with a
-              <code>term</code> member, return <em>result</em>.</li>
-          </ol>
-        </li>
-        <li>Otherwise, if the entry for <em>iri</em> in the <tref>inverse context</tref>
-          has a <code>term</code> member, return its value.</li>
-      </ol>
-    </li>
-    <li>For each <em>termIri</em>-<em>termDefinition</em> pair in <tref>inverse context</tref>
-      sorted in reverse order by <em>termIri</em> the (longest <em>termIri</em> comes first),
-      perform the following steps:
-      <ol class="algorithm">
-        <li>If <em>termDefinition</em> does not have a <code>term</code> member, i.e., it is
-          a property generator, continue with the next <em>termIri</em>-<em>termDefinition</em>
-          pair from <tref>inverse context</tref>.</li>
-        <li>Otherwise, if <em>iri</em> begins with <em>termIri</em> and is longer than
-          <em>termIri</em>, generate a <tref>compact IRI</tref> by concatenating the value
-          of the <code>term</code> member of <em>termDefinition</em> with a colon
-          (<code>:</code>) character and the unmatched part of <em>iri</em>.</li>
-        <li>If the resulting <tref>compact IRI</tref> has an entry in the <tref>active context</tref>
-          and the <em>vocabRelative</em> flag is set to <code>true</code> or the <tref>IRI mapping</tref>
-          does not correspond to <em>iri</em>, continue with the next <em>termIri</em>-<em>termDefinition</em>
-          pair from <tref>inverse context</tref> as the <tref>compact IRI</tref> cannot be used.</li>
-        <li>Otherwise, if result is <tref>null</tref>, return the <tref>compact IRI</tref>; if it is
-          not null, set the <code>term</code> member of <em>result</em> to the <tref>compact IRI</tref>
-          and return <em>result</em>.</li>
-      </ol>
-    </li>
-    <li>If the <em>vocabRelative</em> flag is set to <code>false</code> and a base <tref>IRI</tref> has
-       been passed, transform <em>iri</em> to a <tref>relative IRI</tref>.</li>
-    <li>Otherwise, if the <em>vocabRelative</em> flag is set to <code>true</code>, the
-      <tref>active context</tref> has a <tref>vocabulary mapping</tref>, and <em>iri</em>
-      begins with the IRI of the <tref>vocabulary mapping</tref> but is longer
-      <ol class="algorithm">
-        <li>Set <em>vocabIri</em> to the unmatched part of <em>iri</em>.</li>
-        <li>If there does not exist an entry for <em>vocabIri</em> in the <tref>active context</tref>,
-          return <em>vocabIri</em> if <em>result</em> is <tref>null</tref>; if it is not
-          <tref>null</tref> set the <code>term</code> member of <em>result</em> to
-          <em>vocabIri</em> and return <em>result</em>.</li>
-      </ol>
-    </li>
-    <li>If <em>result</em> is <tref>null</tref>, return <em>iri</em> as is.</li>
-    <li>Otherwise set the <code>term</code> member of <em>result</em> to <em>iri</em> and
-      return <em>result</em>.</li>
-  </ol>
+  <h3>Problem</h3>
+
+<p>A JSON-LD document may contain remote <tref title="context">contexts</tref>.
+These <tref title="context">contexts</tref> must be dereferenced before they
+can be processed.</p>
+
 </section>
 
 <section>
-  <h2>Inverse Context Creation</h2>
-
-  <p>An <tref>active context</tref> as produced by the
-    <a href="#context-processing">Context Processing</a> algorithm is very
-    efficient for <a href="#iri-expansion">expanding</a>
-    <tref title="term">terms</tref> and <tref title="compact IRI">compact IRIs</tref>
-    to <tref title="IRI">IRIs</tref> but is of limited use for the opposite
-    operation: <a href="#iri-compaction-algorithm">IRI compaction</a>. Hence,
-    this algorithm introduces the notion of an <tref>inverse context</tref>
-    which brings the same efficiency to <a href="#iri-compaction-algorithm">IRI compaction</a>.
-    An <tdef>inverse context</tdef> is a tree of <tref title="JSON object">JSON objects</tref>
-    which allow to efficiently select a <tref>term</tref> for a <tref>IRI</tref>-value
-    pair. Consider the following <tref>context</tref>:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="A context containing of two terms and a property generator">
-  <!--
-  {
-    "@context": {
-      ****"name"****: "http://xmlns.com/foaf/0.1/name",
-      ****"homepage"****: {
-        "@id": "http://xmlns.com/foaf/0.1/homepage",
-        "@type": "@id"
-      },
-      ****"gender"****: {
-        "@id": [ "http://xmlns.com/foaf/0.1/gender", "http://schema.org/gender" ],
-        "@language": "en"
-      }
-    }
-  }
-  -->
-  </pre>
-
-  <p>The corresponding <tref>inverse context</tref> looks as shown below. All entries of
-    the <tref>context</tref> above are first indexed by <tref>IRI</tref>, followed by
-    their <tref>container mapping</tref>, and finally by their
-    <tref title="language mapping">language</tref> or <tref>type mapping</tref>. If a
-    specific mapping is not set or <tref>null</tref>, the entry is indexed under the
-     respective <code>@null</code> member instead.</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="The inverse context corresponding to the context above">
-  <!--
-  {
-    "http://xmlns.com/foaf/0.1/homepage": {
-      "term": "homepage",
-      "@null": {
-        "@type": {
-          "@id": {
-            "term": ****"homepage"****
-          }
-        }
-      }
-    },
-    "http://xmlns.com/foaf/0.1/gender": {
-      "@null": {
-        "@language": {
-          "en": {
-            "propertyGenerators": [ ****"gender"**** ]
-          }
-        }
-      }
-    },
-    "http://xmlns.com/foaf/0.1/name": {
-      "term": "name",
-      "@null": {
-        "@language": {
-          "@null": {
-            "term": ****"name"****
-          }
-        },
-        "@null": {
-          "@null": {
-            "term": ****"name"****
-          }
-        }
-      }
-    },
-    "http://schema.org/gender": {
-      "@null": {
-        "@language": {
-          "en": {
-            "propertyGenerators": [ ****"gender"**** ]
-          }
-        }
-      }
-    }
-  }
-  -->
-  </pre>
-
-  <p>Please note that the <tref>property generator</tref> <code>gender</code> and the <tref>term</tref>
-    <code>name</code> are included twice in <tref>inverse context</tref>. While <code>gender</code>
-    is included once for each <tref>IRI</tref> it is mapped to, <code>name</code> is included
-    twice since it has neither a <tref>type mapping</tref> nor a <tref>language mapping</tref>.
-    It can thus be used for <tref title="string">strings</tref> without an associated language
-    (the first entry), or all other (untyped) <tref title="JSON-LD value">values</tref>.</p>
-
-  <p>The following algorithm takes an <tref>active context</tref> and returns the corresponding
-    <tref>inverse context</tref>.</p>
-
-  <ol class="algorithm">
-    <li>Set <em>defaultLanguage</em> to <tref title="active context">active context's</tref>
-      <tref>default language</tref> if there is one; otherwise set it to <code>@null</code>.</li>
-    <li>For each <tref>term definition</tref> in the <tref>active context</tref>
-      perform the following steps:
-      <ol class="algorithm">
-        <li>If the <tref title="term">term's</tref> <tref>IRI mapping</tref> is set to
-          <tref>null</tref> continue with the next <tref>term definition</tref>.</li>
-        <li>Set <em>container</em> to the value of the <tref title="term">term's</tref>
-          <tref>container mapping</tref> or <code>@null</code> if no such mapping exists.</li>
-        <li>If the <tref>term</tref> is a <tref>property generator</tref>, set <em>termType</em>
-          to <code>propertyGenerators</code>.</li>
-        <li>Otherwise set  set <em>termType</em> to <code>term</code> and append the
-          <tref>term</tref> to the <code>term</code> member of the <tref>JSON object</tref> for
-          the <tref title="term">term's</tref> IRI in <tref>inverse context</tref>
-          (append <em>term</em> to <code>inverseContext[iri]['term']</code>).</li>
-        <li>For each <em>iri</em> mapped to the <tref>term</tref>, perform the following steps:
-          <ol class="algorithm">
-            <li>If the <tref>term</tref> has a <tref>type mapping</tref> to <em>type</em>,
-              append the <tref>term</tref> to
-              <code>inverseContext[iri][container]['@type'][type][termType]</code> (e.g.,
-              <code>inverseContext['http://...']['@list']['@type']['http://...']['term']</code>).</li>
-            <li>Otherwise, if the <tref>term</tref> has a <tref>language mapping</tref> store the
-              associated language in <em>language</em>, replacing <tref>null</tref> with
-              <code>@null</code>. Then append the <tref>term</tref> to
-              <code>inverseContext[iri][container]['@language'][language][termType]</code> (e.g.,
-              <code>inverseContext['http://...']['@list']['@language']['de']['term']</code>).</li>
-            <li>Otherwise append the <tref>term</tref> to
-              <code>inverseContext[iri][container]['@null']['@null'][termType]</code> as well as
-              <code>inverseContext[iri][container]['@language'][defaultLanguage][termType]</code>
-              to take the <tref>default language</tref> into consideration for terms without
-              explicit <tref>language mapping</tref>.</li>
-          </ol>
-        </li>
-      </ol>
-    </li>
-    <li>Remove all but the shortest and lexicographically least <tref>term</tref> in each
-      <code>term</code> member in <tref>inverse context</tref>. The result is thus a single
-      <tref>string</tref> value.</li>
-    <li>Finally, sort the <tref>array</tref> associated with every <code>propertyGenerators</code> member in
-      <tref>inverse context</tref> lexicographically (shortest <tref title="term">terms</tref> come
-      first).</li>
-  </ol>
+<h3>General Solution</h3>
+
+<p>Dereferencing remote <tref title="context">contexts</tref> can be performed
+  either inline with the other JSON-LD algorithms or as a separate, prior step.
+  This solution opts to dereference them first, in a prior step, to both
+  separate concerns and to better enable <tref>active context</tref> caching.
+  By separating concerns, the other JSON-LD algorithms can be described more
+  simply. Implementations may also be either simplified or made more efficient
+  because there is no need to block or respond to events when remote
+  <tref title="context">contexts</tref> are dereferenced over the network. This
+  is particularly important for simplifying implementations in asynchronous
+  programming environments. Of course, choosing this approach is not a
+  requirement.</p>
+
+<p>The JSON-LD document is searched for remote <tref title="context">contexts</tref>
+  recursively, starting with its root <em>element</em>. If the <em>element</em>
+  contains an <code>@context</code> key, its value is searched for
+  <tref title="string">strings</tref>. The result represents a remote
+  <tref>context</tref>, which we add to a map that will ensure we don't
+  dereference an already dereferenced remote <tref>context</tref> for a given
+  <tref>IRI</tref>.</p>
+
+<p>When we have finished searching, we dereference each remote
+  <tref>context</tref> (or get its already-dereferenced value from our map).
+  Each time we dereference a remote <tref>context</tref>, we store its result
+  in our map and then recursively search it for more remote
+  <tref title="IRI">contexts</tref> as above, checking to ensure there is no
+  cyclical reference, which is an error.</p>
+
+<p>
+Once all of the remote <tref title="IRI">contexts</tref> have been
+dereferenced, we replace all of their associated <tref>context</tref>
+<tref title="IRI">IRIs</tref> in the JSON-LD document with the
+results from our map.
+</p>
+
+</section>
+
+<!-- end of Remote Context Resolution -->
 </section>
 
 <section>
-  <h2>Inverse Context Query Algorithm</h2>
-
-  <p>It is possible that multiple <tref title="term">terms</tref> that differ
-    in their <tref title="container mapping">container</tref>,
-    <tref title="type mapping">type</tref>, or <tref>language mapping</tref> are
-    mapped to the same <tref>IRI</tref>. The purpose of this algorithm is to query
-    the <tref>inverse context</tref> to return either the best matching <tref>term</tref>,
-    or a list of potential <tref title="property generator">property generators</tref>
-    along with a <tref>term</tref> to fall back to if none of the
-    <tref title="property generator">property generators</tref> can be applied.</p>
-
-  <p>This algorithm takes an <em>inverseContextSubtree</em>, a <em>queryPath</em>
-    as generated by the <a href="#iri-compaction-algorithm">IRI Compaction algorithm</a>
-    and a <em>level</em> parameter which is initialized to <code>0</code> if nothing else
-    is passed. The algorithm returns either a <tref>string</tref> representing the best matching
-    <tref>term</tref> or a <tref>JSON object</tref> consisting of a
-    <code>propertyGenerators</code> member, containing a sorted <tref>array</tref> of
-    potential <tref title="property generator">property generators</tref>,
-    and an optional <code>term</code> member containing a <tref>term</tref> to fall back
-    to if none of the <tref title="property generator">property generators</tref>
-    can be applied.</p>
-
-  <ol class="algorithm">
-    <li>Initialize <em>result</em> to <tref>null</tref>.</li>
-    <li>If <em>level</em> equals <code>3</code>, i.e., the deepest nested
-      <tref>JSON object</tref> in the <tref>inverse context</tref> has been reached,
-      perform the following steps:
-      <ol class="algorithm">
-        <li>If <em>inverseContextSubtree</em> has a <code>propertyGenerators</code> member,
-          copy that member into a new <tref>JSON object</tref> and store that object in
-          <em>result</em>.</li>
-        <li>If <em>inverseContextSubtree</em> has a <code>term</code> member and
-          <em>result</em> is <tref>null</tref>, return the value of that member;
-          otherwise <em>result</em> is a <tref>JSON object</tref>, copy the <code>term</code>
-          member into <em>result</em> and return <em>result</em>.</li>
-      </ol>
-    </li>
-    <li>Otherwise, for each <em>entry</em> of the <tref>array</tref> in <em>queryPath's</em>
-      <em>level'd</em> position (<code>queryPath[level]</code>), perform the following steps:
-      <ol class="algorithm">
-        <li>If <em>inverseContextSubtree</em> has no <em>entry</em> member, continue with
-          the next <em>entry</em>.</li>
-        <li>Otherwise set <em>tmpResult</em> to the result of recursively invoking this
-          algorithm passing the <em>entry</em> member of <em>inverseContextSubtree</em> as
-          new <em>inverseContextSubtree</em>, <em>queryPath</em>, and <em>level</em> + <code>1</code>
-          as new <em>level</em>.</li>
-        <li>If <em>tmpResult</em> is a <tref>string</tref> and <em>result</em> is
-          <tref>null</tref>, return <em>tmpResult</em>; otherwise, if <em>result</em> is
-          not <tref>null</tref>, transform <em>tmpResult</em> to a <tref>JSON object</tref>
-          whose <code>propertyGenerators</code> member is set to an empty <tref>array</tref>
-          and whose <code>term</code> member is set to <em>tmpResult</em>.</li>
-        <li>If <em>result</em> is <tref>null</tref>, replace it with <em>tmpResult</em>.</li>
-        <li>Otherwise, append each item of the <code>propertyGenerator</code> member of
-          <em>tmpResult</em> to the <code>propertyGenerator</code> member of <em>result</em>
-          unless it is already in <em>result's</em> member. If <em>result</em> has no
-          <code>term</code> member but <em>tmpResult</em> does, copy <em>tmpResult's</em>
-          <code>term</code> member into <em>result</em>.</li>
-      </ol>
-    </li>
-    <li>Return <em>result</em>.</li>
-  </ol>
+<h2 id="context-processing">Context Processing</h2>
+
+<p>
+When processing a JSON-LD data structure, each processing rule is applied
+using information provided by the <tref>active context</tref>. This
+section describes how to produce an <tref>active context</tref>.
+</p>
+
+<p>
+The <tref>active context</tref> contains the active
+<tdef title="term definition">term definitions</tdef> which specify how
+properties and values have to be interpreted as well as the current
+<tdef>vocabulary mapping</tdef> and the <tdef>default language</tdef>. Each
+<tref>term definition</tref> consists of an <tdef>IRI mapping</tdef> and
+optionally a <tdef>type mapping</tdef> from terms to datatypes or
+<tdef>language mapping</tdef> from terms to language codes, and a
+<tdef>container mapping</tdef>. If an <tref>IRI mapping</tref> maps a term
+to multiple <tref="IRI">IRIs</tref> it is said to be a
+<tdef>property generator</tdef>. The <tref>active context</tref> also
+keeps track of <tref>keyword</tref> aliases.
+</p>
+
+<p>
+When processing, the <tref>active context</tref> is initialized
+without any <tref title="term definition">term definitions</tref>,
+<tref>vocabulary mapping</tref>, or <tref>default language</tref>.
+If a <tref>local context</tref> is encountered during processing, a new
+<tref>active context</tref> is created by cloning the existing
+<tref>active context</tref>. Then the information from the
+<tref>local context</tref> is merged into the new <tref>active context</tref>.
+A <tref>local context</tref> is identified within a <tref>JSON object</tref>
+by the value of the <code>@context</code> key, which MUST be a
+<tref>string</tref>, an <tref>array</tref>, or a <tref>JSON object</tref>.
+</p>
+
+<section>
+<h3>Problem</h3>
+
+<p>
+A <tref>local context</tref> needs to be transformed into an
+<tref>active context</tref> so that the <tref>active context</tref> can be
+used when executing other JSON-LD algorithms such as
+<a href="#expansion-algorithm">Expansion</a> or
+<a href="#compaction-algorithm">Compaction</a>. Any remote
+<tref title="context">contexts</tref> in the <tref>local context</tref>
+have already been dereferenced.
+</p>
+
 </section>
 
 <section>
-  <h2>Value Compaction</h2>
-
-  <p>Expansion transforms all values into <tref>expanded form</tref>in JSON-LD. This algorithm
-    does the opposite, it compacts an algorithm according the <tref>term definition</tref>
-    of the passed <tref>active property</tref>. After the application of this algorithm a value
-    is said to be in <tdef>compacted form</tdef>.</p>
-
-  <p>This algorithm takes a <em>value</em>, an <tref>active context</tref>, an
-    <tref>inverse context</tref>, an <tref>active property</tref>, and an optional
-    <em>containerValue</em>.</p>
-
-  <ol class="algorithm">
-    <li>If a <em>containerValue</em> has been passed, the <tref>active property</tref> has a
-      <tref>container mapping</tref> set to <code>@index</code> and <em>value</em>
-      has an <code>@index</code> member which equals <em>containerValue</em>, remove that member.</li>
-    <li>If <em>value</em> is a <tref>JSON object</tref> having a single member <code>@id</code>,
-      return the result of performing <a href="#iri-compaction-algorithm">IRI Compaction</a> on that
-      member's value.</li>
-    <li>Otherwise, if <em>value</em> is a <tref>JSON object</tref> having a <code>@value</code>
-      member, perform the following steps:
-      <ol class="algorithm">
-        <li>If the <tref>active property</tref> has a <tref>type mapping</tref> and <em>value</em>
-          has a corresponding <code>@type</code> member, remove the <code>@type</code> member
-          from <em>value</em>.</li>
-        <li>Otherwise, if the <tref>active property</tref> has a <tref>language mapping</tref> and
-          <em>value</em> has a corresponding <code>@language</code> member, remove the
-          <code>@language</code> member from <em>value</em>.</li>
-        <li>Otherwise, if a <em>containerValue</em> has been passed, the <tref>active property</tref>
-          has a <tref>container mapping</tref> set to <code>@language</code>, and <em>value</em> has
-          a <code>@language</code> member which equals <em>containerValue</em>, remove the
-          <code>@language</code> member from <em>value</em>.</li>
-        <li>Otherwise, if the <tref>active context</tref> has a <tref>default language</tref>
-          <ol class="algorithm">
-            <li>and the <em>value</em> has a corresponding <code>@language</code> member, remove the
-              <code>@language</code> member from <em>value</em>.</li>
-            <li>Otherwise, or if the value of <em>value's</em> <code>@value</code> member is a
-              <tref>string</tref>, return <em>value</em>.</li>
-          </ol>
-        </li>
-        <li>If <em>value</em> has just a <code>@value</code> member, return the value of that
-          member.</li>
-      </ol>
-    </li>
-    <li>Return <em>value</em> as is.</li>
-  </ol>
+<h3>General Solution</h3>
+
+<p>
+First we prepare a new <tref>active context</tref> <em>result</em> by cloning
+the current <tref>active context</tref>. Next we update the
+<tref>vocabulary mapping</tref> and <tref>default language</tref> by
+processing two specific keywords: <code>@vocab</code> and <code>@language</code>.
+These are handled before any other keys in the <tref>local context</tref> because
+they affect how the other keys are processed.
+</p>
+
+<p>
+Then, for every other key in <tref>local context</tref>, we update
+the <tref>term definition</tref> in <em>result</em>.
+</p>
+
+<p>
+Since <tref title="context">context</tref> values in a
+<tref>local context</tref> may themselves contain
+<tref title="compact IRI">compact IRIs</tref>, we may need to recurse to
+define a <tref>prefix</tref>. When doing so, we must ensure that there is
+no cyclical dependency, which is an error. After we have processed any
+<tref title="term definition">term definition</tref> dependencies, we update
+the current <tref title="term definition">term definition</tref>, which may be
+a keyword alias or consist of <code>@id</code>, <code>@language</code>,
+<code>@type</code>, or <code>@container</code> mappings.
+</p>
+
+<p>
+Finally, we return <em>result</em> as the new <tref>active context</tref>.
+</p>
+
 </section>
 
 <section>
-  <h2>Find and Remove Property Generator Duplicates</h2>
-
-  <p>This algorithm checks if a specific value exists for all <tref title="IRI">IRIs</tref>
-    associated with a <tref>property generator</tref> and if so, it removes them. The
-    algorithm takes five parameters: <em>element</em>, <em>property</em>, <em>value</em>,
-    <tref>active context</tref>, <tref>active property</tref>.</p>
-
-  <ol class="algorithm">
-    <li>For each item <em>propertyGenerator</em> of the <tref>array</tref> which is the
-      value of the <code>propertyGenerators</code> member of <tref>active property</tref> perform
-      the following steps:
-      <ol class="algorithm">
-        <li>Check that a member exists for each <tref>IRI</tref> associated with the
-          <em>propertyGenerator</em>. If <em>value</em> is not <tref>null</tref> also check
-          whether each of those members contains <em>value</em>. Values are considered to be equal
-          if they are of the same type and have the same value(s); <tref title="node object">node objects</tref>
-          are considered to be equal if all members match, except if no <code>@id</code> member exists (i.e., it is
-          an unlabeled <tref>blank node</tref>, in that case <tref title="node object">node objects</tref> are never
-          considered to be equal.
+<h3>Algorithm</h3>
+
+<p>
+This algorithm specifies how a new <tref>active context</tref> is updated
+with a <tref>local context</tref>. The algorithm takes two input variables:
+an <tref>active context</tref> and a <tref>local context</tref>.
+
+<ol class="algorithm">
+  <li>
+    Initialize <em>result</em> to the result of cloning
+    <tref>active context</tref>.
+  </li>
+  <li>
+    If <tref>local context</tref> is not an <tref>array</tref>, then
+    set it equal to an <tref>array</tref> containing only
+    <tref>local context</tref>.
+  </li>
+  <li>
+    For each item <em>context</em> in <tref>local context</tref>:
+    <ol class="algorithm">
+      <li>
+        If <em>context</em> equals <tref>null</tref>, then set <em>result</em>
+        to a newly-initialized <tref>active context</tref> and continue to the
+        next <em>context</em>.
+      </li>
+      <li>
+        At this point, <em>context</em> MUST be a <tref>JSON object</tref>
+        because all remote <tref title="context">contexts</tref> have already
+        been dereferenced. Otherwise, an invalid value has been detected,
+        which is an error.
+      </li>
+      <li>
+        Create a <tref>JSON object</tref> <em>defined</em> to use to keep
+        track of whether or not a <tref>term</tref> has already been defined
+        or currently being defined during recursion.
+      </li>
+      <li>
+        If <em>context</em> has an <code>@vocab</code> key:
+        <ol class="algorithm">
+          <li>
+            Initialize <em>value</em> to the value associated with the
+            <code>@vocab</code> key.
           </li>
-        <li>If that's not the case, continue with the next <em>propertyGenerator</em>.</li>
-        <li>Otherwise, remove <em>value</em> from every member. If the resulting value
-          of a member is an empty <tref>array</tref>, remove the member altogether
-          from <em>element</em>.</li>
-        <li>Return <em>propertyGenerator</em>.</li>
-      </ol>
-    </li>
-    <li>Return the value of the <code>term</code> member of <tref>active property</tref>
-      since no matching <tref>property generator</tref> has been found.</li>
-  </ol>
+          <li>
+            If <em>value</em> equals <tref>null</tref>, then remove
+            any <tref>vocabulary mapping</tref> from <em>result</em>.
+          </li>
+          <li>
+            Otherwise, <em>value</em> MUST be an <tref>absolute IRI</tref>.
+            Otherwise, an invalid value has been detected, which is an error.
+            Set <em>result</em>'s <tref>vocabulary mapping</tref> to
+            <em>value</em>.
+          </li>
+          <li>
+            Set <em>defined</em>'s <code>@vocab</code> key to
+            <tref>true</tref>.
+          </li>
+        </ol>
+      </li>
+      <li>
+        If <em>context</em> has an <code>@language</code> key:
+        <ol class="algorithm">
+          <li>
+            Initialize <em>value</em> to the value associated with the
+            <code>@language</code> key.
+          </li>
+          <li>
+            If <em>value</em> equals <tref>null</tref>, then remove
+            any <tref>default language</tref> from <em>result</em>.
+          </li>
+          <li>
+            Otherwise, <em>value</em> MUST be a <tref>string</tref>.
+            Otherwise, an invalid value has been detected, which is an error.
+            Set <em>result</em>'s <tref>default language</tref> to
+            lowercased <em>value</em>.
+          </li>
+          <li>
+            Set <em>defined</em>'s <code>@language</code> key to
+            <tref>true</tref>.
+          </li>
+        </ol>
+      </li>
+      <li>
+        For each <em>key</em>-<em>value</em> pair in <em>context</em> invoke
+        the <a href="#create-term-definition">Create Term Definition</a>
+        subalgorithm, passing <em>result</em> for <tref>active context</tref>,
+        <em>context</em> for <tref>local context</tref>, <em>key</em>,
+        and <em>defined</em>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    Return <em>result</em>.
+  </li>
+</ol>
+
 </section>
 
+<!-- end of Context Processing algorithm -->
+</section>
+
+<section>
+<h2 id="create-term-definition">Create Term Definition Subalgorithm</h2>
+
+<p>
+This algorithm is called from the
+<a href="#context-processing">Context Processing</a> algorithm to create
+<tref title="term definition">term definitions</tref> in a new
+<tref>active context</tref>.
+</p>
+
+<section>
+<h3>Problem</h3>
+
+A <tref>term definition</tref> must be created for the given
+<tref>term</tref>.
+
+</section>
+
+<section>
+<h3>General Solution</h3>
+
+<p>
+<tref title="term definition">Term definitions</tref> are created by
+parsing the information in the given <tref>local context</tref> for the
+given <tref>term</tref>. If the given <tref>term</tref> is a
+<tref>compact IRI</tref> with a <tref>prefix</tref> that is a key in the
+<tref>local context</tref>, then that <tref>prefix</tref> is considered
+a dependency with its own <tref>term definition</tref> that must first
+be created, through recursion, before continuing. Because a
+<tref>term definition</tref> can depend on other
+<tref title="term definition">term definitions</tref>, a mechanism must
+be used to detect cyclical dependencies. The solution employed here
+uses a map, <em>defined</em>, that keeps track of whether or not a
+<tref>term</tref> has been defined or is currently in the process of
+being defined. This map is checked before any recursion is attempted.
+</p>
+
+<p>
+After all dependencies have been defined, the rest of the information
+in the <tref>local context</tref> for the given <tref>term</tref> is
+taken into account, creating the appropriate <tref>IRI mapping</tref>,
+<tref>container mapping</tref>, and <tref>type mapping</tref> or
+<tref>language mapping</tref> for the <tref>term</tref>.
+</p>
+
+</section>
+
+<section>
+<h3>Algorithm</h3>
+
+<p>
+The algorithm has four required inputs which are:
+an <tref>active context</tref>, a <tref>local context</tref>,
+a <em>term</em>, and a map <em>defined</em>.
+</p>
+
+<ol class="algorithm">
+  <li>
+    If <em>defined</em> contains the key <em>term</em>, then the associated
+    value MUST be <tref>true</tref>, indicating that the
+    <tref>term definition</tref> has already been created, so return.
+    Otherwise, a cyclical <tref>term definition</tref> has been detected,
+    which is an error.
+  </li>
+  <li>
+    Set the value associated with <em>defined</em>'s <em>term</em> key to
+    <tref>false</tref>. This indicates that the <tref>term definition</tref>
+    is now being created but is not yet complete.
+  </li>
+  <li>
+    If <em>term</em> is a <tref>compact IRI</tref> with a <tref>prefix</tref>
+    that is a key in <tref>local context</tref> then a dependency has been
+    found. Use this algorithm recursively passing <tref>active context</tref>,
+    <tref>local context</tref>, the <tref>prefix</tref> as <em>term</em>,
+    and <em>defined</em>.
+  </li>
+  <li>
+    Since <tref title="keyword">keywords</tref> cannot be overridden,
+    <em>term</em> MUST NOT be a <tref>keyword</tref>. Otherwise, an
+    invalid value has been detected, which is an error.
+  </li>
+  <li>
+    If <em>term</em> is a <tref>keyword</tref> alias in
+    <tref>active context</tref>, remove it.
+  </li>
+  <li>
+    Initialize <em>value</em> to the value associated with the key
+    <em>term</em> in <tref>local context</tref>.
+  </li>
+  <li>
+    If <em>value</em> equals <tref>null</tref> or <em>value</em>
+    is a <tref>JSON object</tref> containing the key-value pair
+    (<code>@id</code>-<tref>null</tref>), then set the
+    <tref>term definition</tref> in <tref>active context</tref> to
+    <tref>null</tref>, set the value associated with <em>defined</em>'s
+    key <em>term</em> to <tref>true</tref>, and return.
+  </li>
+  <li>
+    Otherwise, if <em>value</em> is a <tref>string</tref>:
+    <ol class="algorithm">
+      <li>
+        If <em>value</em> is a <tref>keyword</tref>, then <em>value</em>
+        MUST NOT be equal to <code>@context</code> or <code>@preserve</code>.
+        Otherwise an invalid keyword alias has been detected, which is an
+        error. Add <em>term</em> to <tref>active context</tref> as a
+        <tref>keyword</tref> alias for <em>value</em>. If there is more
+        than one <tref>keyword</tref> alias for <em>value</em>, then
+        store its aliases as an <tref>array</tref>, sorted by length,
+        breaking ties lexicographically.
+      </li>
+      <li>
+        Otherwise, expand <em>value</em> by setting it to the result of
+        using the <a href="#iri-expansion">IRI Expansion</a> algorithm,
+        passing <tref>active context</tref>, <em>value</em>,
+        <tref>true</tref> for <em>documentRelative</em>,
+        <tref>local context</tref>, and <em>defined</em>.
+      </li>
+      <li>
+        Set the <tref>IRI mapping</tref> for the <tref>term definition</tref>
+        for <em>term</em> in <tref>active context</tref> to <em>value</em>,
+        set the value associated with <em>defined</em>'s key <em>term</em> to
+        <tref>true</tref>, and return.
+      </li>
+    </ol>
+  </li>
+  <li>
+    Otherwise, <em>value</em> MUST be a <tref>JSON object</tref>, otherwise
+    an invalid value has been detected, which is an error.
+  </li>
+  <li>
+    Create a new <tref>JSON object</tref>, <em>definition</em>.
+  </li>
+  <li>
+   If <em>term</em> is a <tref>compact IRI</tref> and its
+   <tref>prefix</tref> has a <tref>term definition</tref> in
+   <tref>active context</tref>, set <em>definition</em> to a copy of it.
+  </li>
+  <li>
+    If <em>value</em> contains the key <code>@id</code>:
+    <ol class="algorithm">
+      <li>
+        Initialize <em>id</em> to the value associated with the
+        <code>@id</code> key.
+      </li>
+      <li>
+        If <em>id</em> is an <tref>array</tref>, then the
+        <tref>term definition</tref> is for a <tref>property generator</tref>:
+        <ol class="algorithm">
+          <li>
+            Create an empty <tref>array</tref> <em>property generator</em>.
+          <li>
+            For each item <em>iri</em> in <em>id</em>:
+            <ol class="algorithm">
+              <li>
+                <em>iri</em> MUST be a <tref>string</tref> and MUST not
+                equal <code>@type</code>, otherwise an invalid value has
+                been detected, which is an error.
+              </li>
+              <li>
+                Set <em>iri</em> equal to the result of using the
+                <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
+                <tref>active context</tref>, <em>iri</em> for <em>value</em>,
+                <tref>true</tref> for <em>documentRelative</em>,
+                <tref>local context</tref>, and <em>defined</em>.
+              </li>
+              <li>
+                Append <em>iri</em> to <em>property generator</em>.
+              </li>
+            </ol>
+          </li>
+          <li>
+            Set the <tref>property generator</tref> <tref>IRI mapping</tref>
+            for <em>definition</em> to the result of sorting
+            <em>property generator</em> lexicographically.
+          </li>
+        </ol>
+      </li>
+      <li>
+        Otherwise <em>id</em> MUST be a <tref>string</tref>, otherwise
+        an invalid value has been detected, which is an error. Set the
+        <tref>IRI mapping</tref> for <em>definition</em>
+        equal to the result of using the
+        <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
+        <tref>active context</tref>, <em>id</em> for <em>value</em>,
+        <tref>true</tref> for <em>documentRelative</em>,
+        <tref>local context</tref>, and <em>defined</em>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    Otherwise, if <em>term</em> is not a <tref>compact IRI</tref>,
+    then <tref>active context</tref> MUST have a
+    <tref>vocabulary mapping</tref>, otherwise an invalid value has
+    been detected, which is an error. Set the <tref>IRI mapping</tref>
+    for <em>definition</em> to the result of concatenating the value
+    associated with the <tref>vocabulary mapping</tref> and <em>term</em>.
+  </li>
+  <li>
+    Otherwise, if <em>term</em>'s <tref>prefix</tref> has a
+    <tref>term definition</tref> in <tref>active context</tref>, set
+    the <tref>IRI mapping</tref> for <em>definition</em> to the result of
+    concatenating the value associated with the <tref>prefix</tref>'s
+    <tref>IRI mapping</tref> and the <em>term</em>'s <em>suffix</em>.
+  </li>
+  <li>
+    Otherwise, <em>term</em> is an <tref>absolute IRI</tref>. Set the
+    <tref>IRI mapping</tref> for <em>definition</em> to <em>term</em>.
+  </li>
+  <li>
+    If <em>value</em> contains the key <code>@type</code>:
+    <ol class="algorithm">
+      <li>
+        Initialize <em>type</em> equal to the value associated with the
+        <code>@type</code> key, which MUST be a <tref>string</tref>.
+        Otherwise, an invalid value has been detected, which is an error.
+      </li>
+      <li>
+        If <em>type</em> does not equal <code>@id</code> then set it to
+        the result of using the
+        <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
+        <tref>active context</tref>, <em>type</em> for <em>value</em>,
+        <tref>true</tref> for <em>vocabRelative</em>,
+        <tref>true</tref> for <em>documentRelative</em>,
+        <tref>local context</tref>, and <em>defined</em>. Set the
+        <tref>type mapping</tref> for <em>definition</em> to <em>type</em>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    If <em>value</em> contains the key <code>@container</code>:
+    <ol class="algorithm">
+      <li>
+        Initialize <em>container</em> equal to the value associated with the
+        <code>@container</code> key, which MUST be either:
+        <code>@list</code>, <code>@set</code>, <code>@index</code>,
+        or <code>@language</code>. Otherwise, an invalid value has been
+        detected, which is an error.
+      </li>
+      <li>
+        Set the <tref>container mapping</tref> for <em>definition</em> to
+        <em>container</em>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    If <em>value</em> contains the key <code>@language</code> and
+    does not contain the key <code>@type</code>:
+    <ol class="algorithm">
+      <li>
+        Initialize <em>language</em> equal to the value associated with the
+        <code>@language</code> key, which MUST be either <tref>null</tref>
+        or a <tref>string</tref>. Otherwise, an invalid value has been
+        detected, which is an error.
+      </li>
+      <li>
+        If <em>language</em> is a <tref>string</tref> set it to
+        lowercased <em>language</em>. Set the <tref>language mapping</tref>
+        for <em>definition</em> to <em>language</em>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    Set the <tref>term definition</tref> for <em>term</em> in
+    <tref>active context</tref> to <em>definition</em> and set the value
+    associated with <em>defined</em>'s key <em>term</em> to
+    <tref>true</tref>.
+  </li>
+</ol>
+
+</section>
+
+<!-- end of Term Creation subalgorithm -->
+</section>
+
+<section>
+<h2>Expansion Algorithm</h2>
+
+<section>
+<h3>Problem</h3>
+
+<p>
+A JSON-LD document needs to be expanded, such that all <tref>context</tref>
+definitions have been removed, all <tref title="term">terms</tref> and
+<tref title="compact IRI">compact IRIs</tref> have been expanded to absolute
+<tref title="IRI">IRIs</tref>, and all
+<tref title="JSON-LD value">JSON-LD values</tref> are expressed in
+<tref title="array">arrays</tref> in <tref>expanded form</tref>.
+</p>
+
+</section>
+
+<section>
+<h3>General Solution</h3>
+
+<p>
+Starting with its root <em>element</em>, we can process the
+JSON-LD document recursively, until we have a fully
+<tref title="expansion">expanded</tref> <em>result</em>. When
+<tref title="expansion">expanding</tref> an <em>element</em>, we can treat
+each one differently according to its type, in order to break down the
+problem:
+</p>
+
+<ol>
+  <li>
+    If the <em>element</em> is <tref>null</tref>, there is nothing
+    to expand.
+  </li>
+  <li>
+    If the <em>element</em> is an <tref>array</tref>, then we expand
+    each of its items recursively and return them in a new
+    <tref>array</tref>.
+  </li>
+  <li>
+    If the <em>element</em> is a <tref>JSON object</tref>,
+    then we expand each of its keys, adding them to our <em>result</em>,
+    and then we expand each value for each key recursively. Some of the keys
+    will be
+    <tref title="term">terms</tref> or
+    <tref title="compact IRI">compact IRIs</tref> and others will be
+    <tref title="keyword">keywords</tref> or simply ignored because
+    they do not have definitions in the <tref>context</tref>. Any
+    <tref title="IRI">IRIs</tref> will be expanded using the
+    <a href="#iri-expansion">IRI Expansion</a> algorithm.
+  </li>
+  <li>
+    Otherwise, the <em>element</em> is a <tref>scalar</tref>, which
+    we expand according to the <a href="#value-expansion">Value Expansion</a>
+    subalgorithm.
+  </li>
+</ol>
+
+<p>
+Finally, after ensuring <em>result</em> is in an <tref>array</tref>,
+we return <em>result</em>.
+</p>
+
+</section>
+
+<section>
+<h3>Algorithm</h3>
+
+<p>
+The algorithm takes four input variables: an <tref>active context</tref>,
+an <tref>active property</tref>, an <em>element</em> to be expanded, and
+an <em>insideList</em> flag. To begin, the <tref>active context</tref> is set
+to the result of performing, <a
+href="#context-processing">Context Processing</a> on the passed
+<code class="idlMemberName"><a href="#widl-JsonLdOptions-expandContext">expandContext</a></code>,
+or empty if <code class="idlMemberName"><a href="#widl-JsonLdOptions-expandContext">expandContext</a></code>
+is <tref>null</tref>, <tref>active property</tref> is set to <tref>null</tref>,
+<em>element</em> is set to the <tref>JSON-LD input</tref>, and <em>insideList</em>
+is set to <tref>false</tref>. This algorithm expects the
+<tref>JSON-LD input</tref> to be a well-formed JSON-LD document as defined in
+[[!JSON-LD]].
+
+The algorithm outputs the result of expanding <em>element</em>.
+</p>
+
+<ol class="algorithm">
+  <li>
+    If <em>element</em> is <tref>null</tref>, return <tref>null</tref>.
+  </li>
+  <li>If <em>element</em> is an <tref>array</tref>,
+    <ol class="algorithm">
+      <li>
+        Initialize an empty array, <em>result</em>.
+      </li>
+      <li>For each <em>item</em> in <em>element</em>:
+        <ol class="algorithm">
+          <li>
+            Initialize <em>expanded item</em> to the result of using this
+            algorithm recursively, passing <tref>active context</tref>,
+            <tref>active property</tref>, <em>item</em> as <em>element</em>,
+            and <em>insideList</em>.
+          </li>
+          <li>
+            If <em>insideList</em> equals <tref>true</tref> then
+            <em>expanded item</em> MUST NOT be an <tref>array</tref> or a
+            <tref>list object</tref>, otherwise a list of lists has been
+            detected, which is an error.
+          </li>
+          <li>
+            If <em>expanded item</em> is an <tref>array</tref>, append each
+            of its items to <em>result</em>. Otherwise, if
+            <em>expanded item</em> is not null, append it to <em>result</em>.
+          </li>
+        </ol>
+      </li>
+      <li>
+        Return <em>result</em>.
+      </li>
+    </ol>
+  </li>
+  <li>If <em>element</em> is a <tref>JSON object</tref>,
+    <ol class="algorithm">
+      <li>
+        If <em>element</em> contains the key <code>@context</code>, set
+        <tref>active context</tref> equal to the result of the
+        <a href="#context-processing">Context Processing</a> algorithm,
+        passing <tref>active context</tref> and the value of the
+        <code>@context</code> key as <tref>local context</tref>.
+      </li>
+      <li>
+        Initialize <em>expanded active property</em> to the result of the
+        <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
+        <tref>active context</tref> and <tref>active property</tref> for
+        <em>value</em>.
+      <li>
+        Initialize an empty <tref>JSON object</tref>, <em>result</em>.
+      </li>
+      <li>
+        For each <em>key</em> and <em>value</em> in <em>element</em>,
+        ordered lexicographically by <em>key</em>:
+        <ol class="algorithm">
+          <li>
+            If <em>key</em> is mapped to a <tref>property generator</tref>
+            in <tref>active context</tref>, set <em>expanded property</em>
+            to an array containing its <tref title="IRI">IRIs</tref>.
+            Otherwise, set <em>expanded property</em> to the result of
+            using the <a href="#iri-expansion">IRI Expansion</a> algorithm,
+            passing <tref>active context</tref>, <em>key</em> for
+            <em>value</em>, and <tref>true</tref> for <em>vocabRelative</em>.
+          </li>
+          <li>
+            If <em>expanded property</em> is either <tref>null</tref> or
+            is: not an <tref>array</tref>, an <tref>absolute IRI</tref> or
+            a <tref>keyword</tref>, then drop <em>key</em> by
+            continuing to the next <em>key</em>.
+          </li>
+          <li>
+            Validate <em>expanded property</em> against <em>value</em>
+            as follows:
+            <ol class="algorithm">
+              <li>
+                If <em>expanded property</em> is <code>@id</code> then
+                <em>value</em> MUST be a <tref>string</tref>, otherwise
+                an invalid value has been detected, which is an error.
+              </li>
+              <li>
+                If <em>expanded property</em> is <code>@type</code> then
+                <em>value</em> MUST be a <tref>string</tref> or an <tref>array</tref>
+                of strings, otherwise an invalid value has been detected, which
+                is an error.
+              </li>
+              <li>
+                If <em>expanded property</em> is <code>@graph</code> then
+                <em>value</em> MUST be a <tref>JSON object</tref> or an
+                <tref>array</tref>, otherwise an invalid value has been
+                detected, which is an error.
+              </li>
+              <li>
+                If <em>expanded property</em> is <code>@value</code> then
+                <em>value</em> MUST NOT be a <tref>JSON object</tref> or
+                an <tref>array</tref>, otherwise an invalid value has been
+                detected, which is an error.
+              </li>
+              <li>
+                If <em>expanded property</em> is <code>@language</code> then
+                <em>value</em> MUST be a <tref>string</tref>, otherwise an
+                invalid value has been detected, which is an error. Set
+                <em>expanded value</em> to lowercased <em>value</em>.
+              </li>
+              <li>
+                If <em>expanded property</em> is <code>@index</code>
+                then <em>value</em> MUST be a <tref>string</tref>, otherwise an
+                invalid value has been detected, which is an error.
+              </li>
+            </ol>
+          </li>
+          <li>
+            If <em>key</em>'s <tref>container mapping</tref> in
+            <tref>active context</tref> is <code>@language</code> and
+            <em>value</em> is a <tref>JSON object</tref> then <em>value</em>
+            is expanded from a <tref>language map</tref> as follows:
+            <ol class="algorithm">
+              <li>
+                Initialize <em>expanded value</em> to an empty
+                <tref>array</tref>.
+              </li>
+              <li>
+                For each key <em>language</em> and value <em>language value</em>
+                in <em>value</em>, ordered lexicographically by
+                <em>language</em>:
+                <ol class="algorithm">
+                  <li>
+                    If <em>language value</em> is not an <tref>array</tref>
+                    set it to an <tref>array</tref> containing only
+                    <em>language value</em>.
+                  </li>
+                  <li>
+                    For each <em>item</em> in <em>language value</em>:
+                    <ol class="algorithm">
+                      <li>
+                        <em>item</em> MUST be a <tref>string</tref>,
+                        otherwise an invalid value has been detected,
+                        which is an error.
+                      </li>
+                      <li>
+                        Append a <tref>JSON object</tref> to
+                        <em>expanded value</em> that consists of two
+                        key-value pairs: (<code>@value</code>-<em>item</em>)
+                        and (<code>@language</code>-lowercased
+                        <em>language</em>).
+                      </li>
+                    </ol>
+                  </li>
+                </ol>
+              </li>
+            </ol>
+          </li>
+          <li>
+            If <em>key</em>'s <tref>container mapping</tref> in
+            <tref>active context</tref> is <code>@index</code> and
+            <em>value</em> is a <tref>JSON object</tref> then <em>value</em>
+            is expanded from an index map as follows:
+            <ol class="algorithm">
+              <li>
+                Initialize <em>expanded value</em> to an empty
+                <tref>array</tref>.
+              </li>
+              <li>
+                For each key <em>index</em> and value
+                <em>index value</em> in <em>value</em>, ordered
+                lexicographically by <em>index</em>:
+                <ol class="algorithm">
+                  <li>
+                    If <em>index value</em> is not an <tref>array</tref>
+                    set it to an <tref>array</tref> containing only
+                    <em>index value</em>.
+                  </li>
+                  <li>
+                    Initialize <em>index value</em> to the result of
+                    using this algorithm recursively, passing
+                    <tref>active context</tref>, <tref>active property</tref>,
+                    <em>index value</em> as <em>element</em>, and
+                    <tref>false</tref> for <em>insideList</em>.
+                  <li>
+                    For each <em>item</em> in <em>index value</em>:
+                    <ol class="algorithm">
+                      <li>
+                        If <em>item</em> does not have the key
+                        <code>@index</code>, add the key-value pair
+                        (<code>@index</code>-<em>index</em>) to
+                        <em>item</em>.
+                      </li>
+                      <li>
+                        Append <em>item</em> to <em>expanded value</em>.
+                      </li>
+                    </ol>
+                  </li>
+                </ol>
+              </li>
+            </ol>
+          </li>
+          <li>
+            Otherwise, if <em>expanded property</em> equals <code>@list</code>
+            or <code>@set</code>, initialize <em>expanded value</em> to the
+            result of using this algorithm recursively passing
+            <tref>active context</tref>, <tref>null</tref> for
+            <tref>active property</tref> if <em>expanded property</em> equals
+            <code>@list</code> and <em>expanded active property</em> equals
+            <code>@graph</code> otherwise <tref>active property</tref>,
+            <em>value</em> for <em>element</em>, and <tref>true</tref>
+            for <em>insideList</em> if <em>expanded property</em> equals
+            <code>@list</code> otherwise <tref>false</tref>.
+            If <em>expanded property</em> equals <code>@list</code>
+            then <em>expanded value</em> MUST NOT be a
+            <tref>list object</tref>, otherwise a list of lists has been
+            detected, which is an error.
+          </li>
+          <li>
+            Otherwise, initialize <em>expanded value</em> to the result of
+            using this algorithm recursively, passing
+            <tref>active context</tref>, <em>key</em> for
+            <tref>active property</tref>, <em>value</em>
+            for <em>element</em>, and <tref>false</tref> for
+            <em>insideList</em>.
+          </li>
+          <li>
+            If <em>expanded value</em> equals <tref>null</tref> and
+            <em>expanded property</em> is not <code>@value</code> then
+            drop <em>key</em> by continuing to the next key.
+          </li>
+          <li>
+            If <em>expanded property</em> is not <code>@list</code> and
+            <em>expanded value</em> is not a <tref>list object</tref> and
+            <em>key</em>'s <tref>container mapping</tref> in
+            <tref>active context</tref> is <code>@list</code> then convert
+            <em>expanded value</em> to a <tref>list object</tref> by first
+            setting it to an <tref>array</tref> containing only
+            <em>expanded value</em> if it is not already an
+            <tref>array</tref>, and then by setting it to a
+            <tref>JSON object</tref> containing the key-value pair
+            (<code>@list</code>-<em>expanded value</em>).
+          </li>
+          <li>
+            If <em>expanded property</em> is an <tref>array</tref>:
+            <ol class="algorithm">
+              <li>
+                Invoke the
+                <a href="#label-blank-nodes-algorithm">Label Blank Nodes</a>
+                subalgorithm, passing <tref>active context</tref> and
+                <em>expanded value</em> as <em>element</em>.
+              </li>
+              <li>
+                For each item <em>iri</em> in <em>expanded property</em>:
+                <ol class="algorithm">
+                  <li>
+                    If <em>result</em> does not have the key <em>iri</em>,
+                    set this key's value in <em>result</em> to an empty
+                    <tref>array</tref>. Append a copy of
+                    <em>expanded value</em> to the <tref>array</tref> value
+                    associated with <em>result</em>'s <em>iri</em> key.
+                  </li>
+                </ol>
+              </li>
+            </ol>
+          </li>
+          <li>
+            Otherwise, if <em>expanded property</em> is
+            <code>@index</code>, <code>@id</code>, <code>@type</code>,
+            <code>@value</code>, or <code>@language</code>, then
+            set key <em>expanded property</em>'s value to
+            <em>expanded value</em> in <em>result</em>.
+          </li>
+          <li>
+            Otherwise, if <em>result</em> does not have the key
+            <em>expanded property</em>, set this key's value in <em>result</em>
+            to an empty <tref>array</tref>. Append <em>expanded value</em>
+            to the <tref>array</tref> value associated with <em>result</em>'s
+            <em>expanded property</em> key.
+          </li>
+        </ol>
+      </li>
+      <li>
+        If <em>result</em> contains the key <code>@value</code>:
+        <ol class="algorithm">
+          <li>
+            The <em>result</em> MUST NOT contain any keys other than
+            <code>@value</code>, <code>@language</code>, <code>@type</code>,
+            and <code>@index</code>. It MUST NOT contain both the
+            <code>@language</code> key and the <code>@type</code> key.
+            Otherwise, an invalid value has been detected, which is an error.
+          </li>
+          <li>
+            If the value of <em>result</em>'s <code>@value</code> key is
+            <tref>null</tref>, then set <em>result</em> to <tref>null</tref>.
+          </li>
+          <li>
+            Otherwise, if <em>result</em> contains the key
+            <code>@language</code> and the value of <em>result</em>'s
+            <code>@value</code> key is not a <tref>string</tref>, then remove
+            the <code>@language</code> key from <em>result</em>.
+          </li>
+        </ol>
+      </li>
+      <li>
+        Otherwise, if <em>result</em> contains the key <code>@type</code>
+        and its associated value is not an <tref>array</tref>, set it to
+        an <tref>array</tref> containing only the associated value.
+      </li>
+      <li>
+        Otherwise, if <em>result</em> contains the key <code>@set</code>
+        or <code>@list</code>:
+        <ol class="algorithm">
+          <li>
+            The <em>result</em> MUST contain at most one other key and that
+            key MUST be <code>@index</code>. Otherwise, an invalid
+            value has been detected, which is an error.
+          </li>
+          <li>
+            If <em>result</em> contains the key <code>@set</code>, then
+            set <em>result</em> to the key's associated value.
+          </li>
+        </ol>
+      </li>
+      <li>
+        Otherwise, if <em>result</em> contains only the key
+        <code>@language</code>, set <em>result</em> to <tref>null</tref>.
+      </li>
+      <li>
+        If <em>insideList</em> equals false and either
+        <tref>active property</tref> equals <tref>null</tref> or
+        <em>expanded active property</em> equals <code>@graph</code>, then
+        drop free-floating values as follows:
+        <ol class="algorithm">
+          <li>
+            If <em>result</em> contains no keys or contains the key
+            <code>@value</code>, setting <em>result</em> to
+            <tref>null</tref>.
+          <li>
+            Otherwise, if <em>result</em>'s keys are only keywords and none
+            of the keys are <code>@graph</code>, <code>@type</code>, or
+            <code>@list</code> then set <em>result</em> to <tref>null</tref>.
+          </li>
+        </ol>
+      </li>
+      <li>
+        Return <em>result</em>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    Otherwise, <em>element</em> must be a <tref>scalar</tref>,
+    <ol class="algorithm">
+      <li>
+        If <em>insideList</em> equals <tref>false</tref> and
+        either <tref>active property</tref> equals <tref>null</tref> or
+        the result of expanding <tref>active property</tref> using the
+        <a href="#iri-expansion">IRI Expansion</a> algorithm is
+        <code>@graph</code>, then drop the top-level
+        <tref>scalar</tref> by returning <tref>null</tref>.
+      </li>
+      <li>
+        Return the result of the
+        <a href="#value-expansion">Value Expansion</a> algorithm, passing the
+        <tref>active context</tref>, <tref>active property</tref>, and
+        <em>element</em> as <em>value</em>.
+      </li>
+    </ol>
+  </li>
+</ol>
+
+<p>
+If, after the above algorithm is run, the result is a
+<tref>JSON object</tref> that contains only an <code>@graph</code> key, set the
+result to the value of <code>@graph</code>'s value. Otherwise, if the result
+is <tref>null</tref>, set it to an empty <tref>array</tref>. Finally, if
+the result is not an <tref>array</tref>, then set the result to an
+<tref>array</tref> containing only the result.
+</p>
+
+</section>
+
+<!-- end of Expansion Algorithm -->
+</section>
+
+<section>
+<h2>IRI Expansion</h2>
+
+<p>
+In JSON-LD documents, some keys and values may represent
+<tref title="IRI">IRIs</tref>. This section defines an algorithm for
+transforming a <tref>string</tref> that represents an <tref>IRI</tref> into
+an <tref>absolute IRI</tref>. It also covers transforming <tref>keyword</tref>
+aliases into <tref title="keyword">keywords</tref>.
+</p>
+
+<p>
+<tref>IRI</tref> expansion may occur during context processing or during
+any of the other JSON-LD algorithms. If IRI expansion occurs during context
+processing, then the <tref>local context</tref> and its related
+<em>defined</em> map from the
+<a href="#context-processing">Context Processing</a> algorithm are passed
+to this algorithm. This allows for <tref>term definition</tref> dependencies
+to be processed via the context processing subalgorithm,
+<a href="#create-term-definition">Create Term Definition</a>.
+</p>
+
+<p>
+After application of this algorithm, values processed by this algorithm are
+said to be in <tdef>expanded IRI form</tdef> (Advanced note: this form
+may also include
+<tref title="blank node identifier">blank node identifiers</tref> and
+JSON-LD <tref title="keyword">keywords</tref>).
+</p>
+
+<section>
+<h3>Problem</h3>
+
+We have a value that needs to be expanded to an <tref>absolute IRI</tref>
+or a <tref>keyword</tref>, if it can be and if it is not already one. The
+given value may be <tref>null</tref>, a <tref>term</tref>, a
+<tref>keyword</tref> alias, a <tref>compact IRI</tref>,
+a <tref>relative IRI</tref>, or an <tref>absolute IRI</tref>.
+
+</section>
+
+<section>
+<h3>General Solution</h3>
+
+<p>
+In order to expand <em>value</em> to an <tref>absolute IRI</tref>, we must
+first determine if it is <tref>null</tref>, a <tref>term</tref>, a
+<tref>keyword</tref>, or some form of <tref>IRI</tref>. While inspecting
+<em>value</em> we may also find that we need to create
+<tref>term definition</tref> dependencies because we're running this
+algorithm during <a href="#context-processing">Context Processing</a>. We can
+tell whether or not we're running during
+<a href="#context-processing">Context Processing</a> by checking
+<tref>local context</tref> against <tref>null</tref>.
+We know we need to create a <tref>term definition</tref> in the
+<tref>active context</tref> when <em>value</em> is
+a key in the <tref>local context</tref> and the <em>defined</em> map
+does not have a key for <em>value</em> with an associated value of
+<tref>true</tref>. The <em>defined</em> map is used during
+<a href="#context-processing">Context Processing</a> to keep track of
+which <tref title="term">terms</tref> have already been defined or are
+in the process of being defined. We create a
+<tref>term definition</tref> by using the
+<a href="#create-term-definition">Create Term Definition</a> subalgorithm.
+</p>
+
+<p>
+To begin, we handle the simplest case, where <em>value</em> is
+<tref>null</tref>. Here all we do is return <tref>null</tref> as there is
+nothing to expand.
+</p>
+
+<p>
+Next, we create a <tref>term definition</tref> for <em>value</em> if
+we need to. This ensures that when we look in the <tref>active context</tref>,
+any information associated with <em>value</em> will be ready.
+</p>
+
+<p>
+Now we initialize our <em>result</em> to <em>value</em> and then we
+look in the <tref>active context</tref> for <em>value</em>:
+
+<ol>
+  <li>
+    If it indicates that <em>value</em> is explicitly mapped to
+    <tref>null</tref>, then we return <tref>null</tref> which has the effect
+    of dropping the <em>value</em> from our expanded output.
+  </li>
+  <li>
+    If it indicates that <em>value</em> is a <tref>keyword</tref> alias,
+    then we return the associated <tref>keyword</tref>.
+  </li>
+  <li>
+    If it has a <tref>term definition</tref> that is a
+    <tref>property generator</tref> when the <tref>local context</tref> is
+    not <tref>null</tref>, then we trigger an error because a
+    <tref>term definition</tref> cannot have a
+    <tref>property generator</tref> as a dependency.
+  </li>
+  <li>
+    Otherwise, if it has <tref>term definition</tref> that is not a
+    <tref>property generator</tref> we update <em>result</em> by setting
+    it to the associated <tref>IRI mapping</tref>. If this is the case
+    then we also know that <em>result</em> is now an
+    <tref>absolute IRI</tref> (or a <tref>blank node identifier</tref>).
+  </li>
+</ol>
+
+</p>
+
+<p>
+At this point, if we know that <em>result</em> is not an
+<tref>absolute IRI</tref> or <tref>blank node identifier</tref>, then it
+may be a <tref>compact IRI</tref>. If it has a colon (<code>:</code>) in it
+then we parse it into <tref>prefix</tref>:<em>suffix</em>. If the resulting
+<tref>prefix</tref> is <code>_</code> or the <em>suffix</em>
+is <code>//</code>, then <em>result</em> is already an
+<tref>absolute IRI</tref>. Otherwise, if the <tref>prefix</tref> is a key in
+the <tref>local context</tref>, and we need to create a
+<tref>term definition</tref>, then we do so. If the
+<tref>term definition</tref> for the <tref>prefix</tref> in the
+<tref>active context</tref> is not a <tref>property generator</tref>, then
+we replace <em>result</em> with the concatenation of the associated
+<tref>IRI mapping</tref> and <em>suffix</em>.
+</p>
+
+<p>
+Finally, if <em>result</em> is now a <tref>blank node identifier</tref>,
+we relabel it by setting it to the result of the
+<a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a>
+algorithm. Otherwise, if it is not an <tref>absolute IRI</tref>, we resolve
+it against either the <tref title="active context">active context's</tref>
+<tref>vocabulary mapping</tref> or the document base, given the
+<em>vocabRelative</em> and <em>documentRelative</em> flag values and
+the existence of a <tref>vocabulary mapping</tref>. Then we return
+<em>result</em>.
+</p>
+
+</section>
+
+<section>
+<h3>Algorithm</h3>
+
+<p>
+The algorithm takes two required and four optional input variables. The
+required inputs are an <tref>active context</tref> and a <em>value</em>
+to be expanded. The optional inputs are two flags,
+<em>documentRelative</em> and <em>vocabRelative</em>, that specifying
+whether <em>value</em> can be interpreted as a <tref>relative IRI</tref>
+against the document's base <tref>IRI</tref> or the
+<tref title="active context">active context's</tref>
+<tref>vocabulary mapping</tref>, respectively, and
+a <tref>local context</tref> and map <em>defined</em> to be used when
+this algorithm is used during
+<a href="#context-processing">Context Processing</a>. If not passed, the
+two flags are set to <code>false</code> and <tref>local context</tref> and
+<em>defined</em> are initialized to <tref>null</tref>.
+</p>
+
+<ol class="algorithm">
+  <li>
+    If <em>value</em> equals <tref>null</tref>, then return <tref>null</tref>.
+  </li>
+  <li>
+    If <tref>local context</tref> is not <tref>null</tref>, it contains
+    a key that equals <em>value</em>, and the value associated with the key
+    that equals <em>value</em> in <em>defined</em> is not <tref>true</tref>,
+    then invoke the
+    <a href="#create-term-definition">Create Term Definition</a>
+    subalgorithm, passing <tref>active context</tref>,
+    <tref>local context</tref>, <em>value</em> as <em>term</em>, and
+    <em>defined</em>. This will ensure that a <tref>term definition</tref>
+    is created for <em>value</em> in <tref>active context</tref> during
+    <a href="#context-processing">Context Processing</a>.
+  </li>
+  <li>
+    If <tref>local context</tref> is not <tref>null</tref> then
+    <tref>active context</tref> MUST NOT have a <tref>term definition</tref>
+    for <em>value</em> that is a <tref>property generator</tref>.
+    Otherwise, an invalid error has been detected, which is an error.
+  </li>
+  <li>
+    If <em>value</em> has a <tref>null</tref> mapping in
+    <tref>active context</tref>, then explicitly ignore <em>value</em>
+    by returning <tref>null</tref>.
+  </li>
+  <li>
+    If <tref>active context</tref> indicates that <em>value</em> is a
+    <tref>keyword</tref> alias then return the associated
+    <tref>keyword</tref>.
+  </li>
+  <li>
+    Initialize <em>result</em> to <em>value</em> and <em>isAbsoluteIri</em>
+    to <tref>false</tref>.
+  </li>
+  <li>
+    If <tref>active context</tref> has a <tref>term definition</tref> for
+    <em>value</em>, then set <em>result</em> to the associated
+    <tref>IRI mapping</tref> and <em>isAbsoluteIri</em> to <tref>true</tref>.
+  </li>
+  <li>
+    If <em>isAbsoluteIri</em> equals <tref>false</tref> and <em>result</em>
+    contains a colon (<code>:</code>), then it is either an
+    <tref>absolute IRI</tref> or a <tref>compact IRI</tref>:
+    <ol class="algorithm">
+      <li>
+        Split <em>result</em> into a <tref>prefix</tref> and <em>suffix</em>
+        at the first occurence of a colon (<code>:</code>).
+      </li>
+      <li>
+        If <tref>prefix</tref> does not equal underscore (<code>_</code>)
+        and <em>suffix</em> does not begin with double-forward-slash
+        (<code>//</code>), then it may be a <tref>compact IRI</tref>:
+        <ol class="algorithm">
+          <li>
+            If <tref>local context</tref> is not <tref>null</tref>, it
+            contains a key that equals <tref>prefix</tref>, and the value
+            associated with the key that equals <tref>prefix</tref> in
+            <em>defined</em> is not <tref>true</tref>, then invoke the
+            <a href="#create-term-definition">Create Term Definition</a>
+            subalgorithm, passing <tref>active context</tref>,
+            <tref>local context</tref>, <em>prefix</em> as <em>term</em>,
+            and <em>defined</em>. This will ensure that a
+            <tref>term definition</tref> is created for <tref>prefix</tref>
+            in <tref>active context</tref> during
+            <a href="#context-processing">Context Processing</a>.
+          </li>
+          <li>
+            If <tref>active context</tref> contains a
+            <tref>term definition</tref> for <tref>prefix</tref> that is
+            not a <tref>property generator</tref> then set <em>result</em>
+            to the result of concatenating the value associated with the
+            <tref>prefix</tref>'s <tref>IRI mapping</tref> and
+            <em>suffix</em>.
+          </li>
+        </ol>
+      </li>
+      <li>
+        Set <em>isAbsoluteIri</em> to <tref>true</tref>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    If <em>isAbsoluteIri</em> equals <tref>true</tref>:
+    <ol class="algorithm">
+      <li>
+        If <tref>local context</tref> equals <tref>null</tref> and
+        <em>result</em> begins with and underscore and colon
+        (<code>_:</code>) then <em>result</em> is a
+        <tref>blank node identifier</tref>. Set <em>result</em> to the
+        result of the
+        <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a>
+        algorithm, passing <tref>active context</tref> and <em>result</em>
+        for <em>identifier</em>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    Otherwise, if <em>vocabRelative</em> equals <tref>true</tref> and
+    <tref>active context</tref> has a <tref>vocabulary mapping</tref>,
+    then set <em>result</em> to the result of concatenating the
+    <tref>vocabulary mapping</tref> with <em>result</em>.
+  </li>
+  <li>
+    Otherwise, if <em>documentRelative</em> equals <tref>true</tref>,
+    set <em>result</em> to the result of resolving <em>result</em> against
+    the document base as per [RFC3986]. Only the basic algorithm in
+    section 5.2 of [RFC3986] is used; neither Syntax-Based Normalization
+    nor Scheme-Based Normalization (as described in sections 6.2.2 and
+    6.2.3 of [RFC3986]) are performed. Characters additionally allowed in
+    IRI references are treated in the same way that unreserved characters
+    are treated in URI references, per section 6.5 of [RFC3987].
+  </li>
+  <li>
+    If <tref>local context</tref> is not <tref>null</tref> then
+    <em>result</em> MUST be an <tref>absolute IRI</tref>. Otherwise,
+    an invalid context value has been detected, which is an error. Return
+    <em>result</em>.
+  </li>
+</li>
+
+</section>
+
+<!-- end of IRI Expansion -->
+</section>
+
+<section>
+<h2>Value Expansion</h2>
+
+<p>
+Some values in JSON-LD can be expressed in a <tref>compacted form</tref>.
+These values are required to be <tref title="expansion">expanded</tref> at
+times when processing JSON-LD documents. A value is said to be in
+<tdef>expanded form</tdef> after the application of this algorithm.
+</p>
+
+<section>
+<h3>Problem</h3>
+
+A <em>value</em> associated with an <tref>active property</tref> must
+be <tref title="expansion">expanded</tref> to <tref>expanded form</tref>.
+
+</section>
+
+<section>
+<h3>General Solution</h3>
+
+<p>
+Other than the simple case where <em>value</em> is <tref>null</tref>, for
+which we return <tref>null</tref>, we must primarily look at <em>value</em>'s
+associated <tref>active property</tref> to determine how to expand it.
+</p>
+
+<p>
+First we <tref title="expansion">expand</tref> the
+<tref>active property</tref> itself, so that we can resolve
+<tref>keyword</tref> aliases. Then, for certain
+<tref title="keyword">keywords</tref> like <code>@id</code> and
+<code>@type</code>, we simply expand <em>value</em>
+using the <a href="#iri-expansion">IRI Expansion</a> algorithm and return
+the result.
+</p>
+
+<p>
+Next, we check to see if <tref>active property</tref> has a
+<tref>type mapping</tref> in the <tref>active context</tref> that would alter
+what we return. If it has one that is <code>@type</code> or if the
+<em>expanded property</em> is <code>@graph</code> then we return
+a <tref>JSON object</tref> with a single key-pair of <code>@id</code>
+and the result of using the <a href="#iri-expansion">IRI Expansion</a>
+algorithm on <em>value</em>.
+</p>
+
+<p>
+If we haven't returned yet and the <em>expanded property</em> is a
+<tref>keyword</tref>, then there is no special <tref>expansion</tref> to be
+performed on the <em>value</em>, so we return it as is.
+</p>
+
+<p>
+Otherwise, we'll our result will be a <tref>JSON object</tref> containing
+the key <code>@value</code> with the value the <em>value</em>. Additionally,
+a <code>@type</code> key-value pair will be included if there is a
+<tref>type mapping</tref> associated with the <tref>active property</tref>
+or a <code>@language</code> key-value pair if <em>value</em> is a
+<tref>string</tref> and there is <tref>language mapping</tref>.
+</p>
+
+</section>
+
+<section>
+<h3>Algorithm</h3>
+
+<p>
+The algorithm takes three required inputs: an <tref>active context</tref>,
+an <tref>active property</tref>, and a <em>value</em> to expand.
+</p>
+
+<ol class="algorithm">
+  <li>
+    If <em>value</em> equals <tref>null</tref>, then return <tref>null</tref>.
+  </li>
+  <li>
+    Initialize <em>expanded property</em> to the result of using the
+    <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
+    <tref>active context</tref>, <tref>active property</tref> for
+    <em>value</em>, and <tref>true</tref> for <em>vocabRelative</em>.
+  </li>
+  <li>
+    If <em>expanded property</em> equals <code>@id</code> then return
+    the result of using the
+    <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
+    <tref>active context</tref>, <em>value</em>, and <tref>true</tref>
+    for <em>documentRelative</em>.
+  </li>
+  <li>
+    If <em>expanded property</em> equals <code>@type</code> then
+    return the result of using the
+    <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
+    <tref>active context</tref>, <em>value</em>, <tref>true</tref> for
+    <em>vocabRelative</em>, and <tref>true</tref> for
+    <em>documentRelative</em>.
+  </li>
+  <li>
+    If <tref>active property</tref> has a <tref>type mapping</tref> in
+    <tref>active context</tref> that is <code>@id</code> or if
+    <em>expanded property</em> equals <code>@graph</code>, then return
+    a new <tref>JSON object</tref> containing a single key-value pair
+    where the key is <code>@id</code> and the value is the result of
+    using the
+    <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
+    <tref>active context</tref>, <em>value</em>, and <tref>true</tref> for
+    <em>documentRelative</em>.
+  </li>
+  <li>
+    If <em>expanded property</em> is a <tref>keyword</tref> return
+    <em>value</em> as is.
+  </li>
+  <li>
+    Otherwise, initialize <em>result</em> to an empty
+    <tref>JSON object</tref>.
+  </li>
+  <li>
+    If <tref>active property</tref> has a <tref>type mapping</tref> in
+    <tref>active context</tref>:
+    <ol class="algorithm">
+      <li>
+        Initialize <em>type</em> to the value associated with the
+        <tref>type mapping</tref>.
+      </li>
+      <li>
+        If <em>type</em> is a <tref>blank node identifier</tref> (it
+        begins with <code>_:</code>), then set it to the result of the
+        <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a>
+        algorithm, passing <tref>active context</tref> and <em>type</em> for
+        <em>identifier</em>.
+      </li>
+      <li>
+        Add the key-value pair, (<code>@type</code>-<em>type</em>), to
+        <em>result</em>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    Otherwise, if <em>value</em> is a <tref>string</tref>:
+    <ol class="algorithm">
+      <li>
+        If <em>value</em> has a <tref>language mapping</tref> in
+        <tref>active context</tref> that is not <tref>null</tref>, then
+        add a key-value pair to <em>result</em> where the key is
+        <code>@language</code> and the value is the value associated with
+        the <tref>language mapping</tref>.
+      </li>
+      <li>
+        Otherwise, if <em>value</em> has no <tref>language mapping</tref> in
+        <tref>active context</tref> and <tref>active context</tref> has a
+        <tref>default language</tref>, then add a key-value pair to
+        <em>result</em> where the key is <code>@language</code> and the value
+        is the <tref>default language</tref>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    Finally, add the key-value pair, (<code>@value</code>-<em>value</em>), to
+    <em>result</em> and return <em>result</em>.
+  </li>
+</ol>
+
+</section>
+
+<!-- end of Value Expansion -->
+</section>
+
+<section>
+<h2>Label Blank Nodes Subalgorithm</h2>
+
+<p>
+During <tref>expansion</tref>, it is sometimes necessary to ensure
+all <tref title="blank node">blank nodes</tref> have been labeled. This
+occurs when a <tref>property generator</tref> is used to copy a single
+property's values across multiple properties. This step is necessary to
+ensure that these duplicated values can be later
+<tref title="compaction">recompacted</tref>. Because new labels will
+be assigned to <tref title="blank node">blank nodes</tref>, it is
+important to relabel any existing <tref title="blank node">blank nodes</tref>
+to avoid conflicting names.
+</p>
+
+<p>
+The algorithm takes two required inputs: an <tref>active context</tref>,
+and an <em>element</em> to be labeled with
+<tref title="blank node identifier">blank node identifiers</tref>.
+</p>
+
+<ol class="algorithm">
+  <li>
+    If <em>element</em> is an <tref>array</tref>, then for each
+    <em>item</em> in <em>element</em>:
+    <ol class="algorithm">
+      <li>
+        Replace <em>item</em> with the result of using this algorithm
+        recursively, passing <tref>active context</tref> and <em>item</em>
+        for <em>element</em>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    Otherwise, if <em>element</em> is a <tref>list object</tref>, then
+    replace the value of the <code>@list</code> key in <em>element</em>
+    with the result of using this algorithm recursively, passing
+    <tref>active context</tref> and the value of the <code>@list</code> key
+    for <em>element</em>.
+  </li>
+  <li>
+    Otherwise, if <em>element</em> is a <tref>JSON object</tref>:
+    <ol class="algorithm">
+      <li>
+        If <em>element</em> is a <em>blank node</em>, then set the value
+        of its <code>@id</code> key to the result of using the
+        <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a>
+        algorithm, passing the value for <em>identifier</em>, using
+        <tref>null</tref> instead if <em>element</em> has no key
+        <code>@id</code>.
+      </li>
+      <li>
+        For each <em>key</em>-<em>value</em> pair ordered lexicographically
+        by <em>key</em>:
+        <ol class="algorithm">
+          <li>
+            If <em>key</em> does not equal <code>@id</code>, then replace
+            <em>value</em> in <em>element</em> with the result of using
+            this algorithm recursively, passing <tref>active context</tref>
+            and <em>value</em> for <em>element</em>.
+          </li>
+        </ol>
+      </li>
+    </ol>
+  </li>
+  <li>
+    Otherwise, if <em>element</em> is a <tref>string</tref> and <em>isId</em>
+    equals <tref>true</tref>, and <em>element</em> is a
+    <tref>blank node identifier</tref>, then set <em>element</em> to
+    the result of using the
+    <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a>
+    algorithm, passing <em>element</em> for <em>identifier</em>.
+  </li>
+  <li>
+    Return <em>element</em>.
+  </li>
+</ol>
+
+</section>
+
+<section>
+<h2>Generate Blank Node Identifier</h2>
+
+<p>
+This algorithm is used to generate new
+<tref title="blank node identifier">blank node identifiers</tref> or to
+relabel an existing
+<tref>blank node identifier</tref> to avoid collision by the introduction
+of new ones. It needs to keep an <em>identifier map</em>, a <em>counter</em>,
+and a <em>prefix</em> between its executions to be able to generate new
+<tref title="blank node identifier">blank node identifiers</tref>. Note
+that it may be most convenient to keep this state information in the
+<tref>active context</tref>, so long as it is preserved (shared) when the
+<tref>active context</tref> is cloned during
+<a href="#context-processing">Context Processing</a>. The <em>counter</em> is
+initialized to <code>0</code> and <em>prefix</em> is set to <code>_:t</code>
+by default.
+</p>
+
+<p>
+The algorithm takes a single input variable <em>identifier</em> which may
+be <tref>null</tref>.
+</p>
+
+<ol class="algorithm">
+  <li>
+    If the <em>identifier</em> is not <tref>null</tref> and is in the
+    <em>identifier map</em>, return the mapped identifier.
+  </li>
+  <li>
+    Otherwise, generate a new <em>blankNodeIdentifier</em> by concatenating
+    <em>prefix</em> and <em>counter</em>.
+  </li>
+  <li>
+    Increment <em>counter</em> by <code>1</code>.
+  </li>
+  <li>
+    If <em>identifier</em> is not <tref>null</tref>, create a new entry in
+    <em>identifier map</em> set to <em>blankNodeIdentifer</em>.
+  </li>
+  <li>
+    Return <em>blankNodeIdentifier</em>.
+  </li>
+</ol>
+
+</section>
+
+<section>
+<h2>Compaction Algorithm</h2>
+
+<section>
+<h3>Problem</h3>
+
+<p>
+A JSON-LD document needs to be compacted, such that the given
+<tref>context</tref> is applied. This must result in shortening
+any applicable <tref title="IRI">IRIs</tref> to
+<tref title="term">terms</tref> or
+<tref title="compact IRI">compact IRIs</tref> and
+any applicable <tref title="JSON-LD value">JSON-LD values</tref>
+expressed in <tref>expanded form</tref> to simple values such as
+<tref title="string">strings</tref> or
+<tref title="number">numbers</tref>.
+</p>
+
+</section>
+
+<section>
+<h3>General Solution</h3>
+
+<p>
+Starting with its root <em>element</em>, we can process the
+JSON-LD document recursively, until we have a fully
+<tref title="compaction">compacted</tref> <em>result</em>. When
+<tref title="compaction">compacting</tref> an <em>element</em>, we can treat
+each one differently according to its type, in order to break down the
+problem:
+</p>
+
+<ol>
+  <li>
+    If the <em>element</em> is an <tref>array</tref>, then we compact
+    each of its items recursively and return them in a new
+    <tref>array</tref>.
+  </li>
+  <li>
+    If the <em>element</em> is a <tref>JSON object</tref>,
+    then we start by creating a shallow copy of it and each of its
+    key's <tref>array</tref> values. This is done so that if any key
+    is compacted to a <tref>property generator</tref> <tref>term</tref>,
+    we can remove duplicate values without modifying the original
+    <em>element</em>. Then, we compact each value in the shallow copy
+    for each key recursively. Some of the keys will be
+    compacted, using the
+    <a href="#iri-compaction">IRI Compaction</a> algorithm,
+    to <tref title="term">terms</tref> or
+    <tref title="compact IRI">compact IRIs</tref> and others will be
+    compacted from <tref title="keyword">keywords</tref> to
+    <tref>keyword</tref> aliases or simply left unchanged because
+    they do not have definitions in the <tref>context</tref>. Values will
+    be converted to <tref>compacted form</tref> via the
+    <a href="#value-compaction">Value Compaction</a> algorithm. Some data
+    will be reshaped based on
+    <tref title="container mapping">container mappings</tref> specified
+    in the context such as <code>@index</code> or <code>@language</code>
+    maps.
+  </li>
+  <li>
+    Otherwise, the <em>element</em> is a <tref>scalar</tref>, it is
+    already in <tref>compacted form</tref>, so we simply return.
+  </li>
+</ol>
+
+<p>
+The final output is a <tref>JSON object</tref> with a <code>@context</code>
+key, if a <tref>context</tref> was given, where the <tref>JSON object</tref>
+is either <em>result</em> or a wrapper for it where <em>result</em> appears
+as the value of an aliased <code>@graph</code> key because <em>result</em>
+contained two or more items in an <tref>array</tref>. If no
+<tref>context</tref> was given, the <em>result</em> is only simplified
+from an <tref>array</tref> to a <tref>JSON object</tref> if it has one or
+fewer items.
+</p>
+
+</section>
+
+<section>
+<h3>Algorithm</h3>
+
+<p>
+The algorithm takes four required input variables: an
+<tref>active context</tref>, an <tref>active property</tref>, and an
+<em>element</em> to be compacted. To begin, the <tref>active context</tref>
+is set to the result of performing
+<a href="#context-processing">Context Processing</a> on the passed
+<em>context</em>, the <tref>active property</tref> is set to
+<tref>null</tref>, and <em>element</em> is set to the result of performing
+the <a href="#expansion-algorithm">Expansion Algorithm</a> on the
+<tref>JSON-LD input</tref>.
+</p>
+
+<ol class="algorithm">
+  <li>
+    If <em>element</em> is an <tref>array</tref>:
+    <ol class="algorithm">
+      <li>
+        Initialize <em>result</em> to an empty <tref>array</tref>.
+      </li>
+      <li>
+        For each <em>item</em> in <em>element</em>:
+        <ol class="algorithm">
+          <li>
+            Initialize <em>compacted item</em> to the result of using this
+            algorithm recursively, passing <tref>active context</tref>,
+            <tref>active property</tref>, and <em>item</em> for
+            <em>element</em>.
+          </li>
+          <li>
+            If <em>compacted item</em> is not <tref>null</tref>, then append
+            it to <em>result</em>.
+          </li>
+        </ol>
+      </li>
+      <li>
+        If <em>result</em> contains only one item (it has a length of
+        <code>1</code>) and <tref>active property</tref> has no
+        <tref>container mapping</tref> in <tref>active context</tref>,
+        then set <em>result</em> to its only item.
+      </li>
+      <li>
+        Return <em>result</em>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    If <em>element</em> is an <tref>JSON object</tref>:
+    <ol class="algorithm">
+      <li>
+        If <em>element</em> contains the key <code>@value</code> or
+        if it contains only one key and that key is <code>@id</code>,
+        then return the result of using the
+        <a href="#value-compaction">Value Compaction</a> algorithm,
+        passing <tref>active context</tref>, <tref>active property</tref>,
+        and <em>element</em> as <em>value</em>.
+      </li>
+      <li>
+        Create a shallow copy of <em>element</em> and each <tref>array</tref>
+        associated with its keys so that duplicate values can be removed
+        during <tref>property generator</tref> <tref>compaction</tref>:
+        <ol class="algorithm">
+          <li>
+            Initialize <em>shallow</em> to an empty <tref>JSON object</tref>.
+          </li>
+          <li>
+            For each <em>key</em>-<em>value</em> pair in <em>element</em>:
+            <ol class="algorithm">
+              <li>
+                If <em>value</em> is an <tref>array</tref>, then add
+                a key-value pair to <em>shallow</em> where the key
+                is <em>key</em> and the value is a shallow copy of
+                <em>value</em>.
+              </li>
+              <li>
+                Otherwise, add the key-value pair, <em>key</em>-<em>value</em>
+                to <em>shallow</em>.
+              </li>
+            </ol>
+          </li>
+        </ol>
+      </li>
+      <li>
+        Initialize <em>result</em> to an empty <tref>JSON object</tref>.
+      </li>
+      <li>
+        Initialize <em>keys</em> to an <tref>array</tref> containing
+        all of the keys in <em>element</em>, ordered lexicographically.
+      </li>
+      <li>
+        For each key <em>expanded property</em> in <em>keys</em>:
+        <ol class="algorithm">
+          <li>
+            If <em>shallow</em> does not contain a key that equals
+            <em>expanded property</em>, then continue to the next
+            <em>expanded property</em>.
+          </li>
+          <li>
+            Initialize <em>expanded value</em> to the value associated
+            with the key that equals <em>expanded property</em> in
+            <em>shallow</em>.
+          </li>
+          <li>
+            If <em>expanded property</em> equals <code>@id</code> or
+            <code>@type</code>:
+              <ol class="algorithm">
+                <li>
+                  If <em>expanded value</em> is a <tref>string</tref>,
+                  then initialize <em>compacted value</em> to the result
+                  of using the
+                  <a href="#iri-compaction-algorithm">IRI Compaction</a>
+                  algorithm, passing <tref>active context</tref>,
+                  <em>expanded value</em> for <em>iri</em>,
+                  and <tref>true</tref> for <em>vocabRelative</em> if
+                  <em>expanded property</em> equals <code>@type</code>,
+                  <tref>false</tref> otherwise.
+                </li>
+                <li>
+                  Otherwise, <em>expanded value</em> must be a
+                  <code>@type</code> <tref>array</tref>:
+                  <ol class="algorithm">
+                    <li>
+                      Initialize <em>compacted value</em> to an empty
+                      <tref>array</tref>.
+                    </li>
+                    <li>
+                      For each item <em>expanded type</em> in
+                      <em>expanded value</em>, append the result of
+                      of using the
+                      <a href="#iri-compaction-algorithm">IRI Compaction</a>
+                      algorithm, passing <tref>active context</tref>,
+                      <em>expanded type</em> for <em>iri</em>, and
+                      <tref>true</tref> for <em>vocabRelative</em>,
+                      to <em>compacted value</em>.
+                    </li>
+                    <li>
+                      If <em>compacted value</em> contains only one
+                      item (it has a length of <code>1</code>), then
+                      set <em>compacted value</em> to its only item.
+                    </li>
+                  </ol>
+                </li>
+                <li>
+                  Initialize <em>alias</em> to the result of using the
+                  <a href="#iri-compaction-algorithm">IRI Compaction</a>
+                  algorithm, passing <tref>active context</tref> and
+                  <em>expanded property</em> for <em>iri</em>.
+                </li>
+                <li>
+                  Add the key-value pair,
+                  (<em>alias</em>-<em>compacted value</em>) to
+                  <em>result</em> and continue to the next
+                  <em>expanded property</em>.
+                </li>
+              </ol>
+            </li>
+          <li>
+            If <em>expanded property</em> equals <code>@index</code>:
+            <ol class="algorithm">
+              <li>
+                If <tref>active property</tref> has a
+                <tref>container mapping</tref> in <tref>active context</tref>
+                that equals <code>@index</code>, then the compacted
+                result will be inside of an <code>@index</code>
+                container, so simply drop the <code>@index</code>
+                property by continuing to the next
+                <em>expanded property</em>.
+              </li>
+              <li>
+                Otherwise, initialize <em>alias</em> to the result of using
+                the <a href="#iri-compaction-algorithm">IRI Compaction</a>
+                algorithm, passing <tref>active context</tref> and
+                <em>expanded property</em> for <em>iri</em>.
+              </li>
+              <li>
+                Add the key-value pair,
+                (<em>alias</em>-<em>expanded value</em>) to
+                <em>result</em> and continue to the next
+                <em>expanded property</em>.
+              </li>
+            </ol>
+          </li>
+          <li>
+            If <em>expanded value</em> is an empty <tref>array</tref>:
+            <ol class="algorithm">
+              <li>
+                Initialize <em>item active property</em> to the result of
+                using the
+                <a href="#iri-compaction-algorithm">IRI Compaction</a>
+                algorithm, passing <tref>active context</tref>,
+                <em>expanded property</em> for <em>iri</em>,
+                <em>expanded value</em> for <em>value</em>,
+                <tref>true</tref> for <em>vocabRelative</em>, and
+                <em>shallow</em> for <em>parent</em>.
+              </li>
+              <li>
+                If <em>result</em> does not have the key that equals
+                <em>item active property</em>, set this key's value in
+                <em>result</em> to an empty <tref>array</tref>. Otherwise, if
+                the key's value is not an <tref>array</tref>, then set it
+                equal to one containing only the value.
+              </li>
+            </ol>
+          </li>
+          <li>
+            At this point, <em>expanded value</em> must be an
+            <tref>array</tref> due to the
+            <a href="#expansion-algorithm">Expansion algorithm</a>.
+            For each item <em>expanded item</em> in <em>expanded value</em>:
+            <ol class="algorithm">
+              <li>
+                Initialize <em>item active property</em> to the result of using
+                the <a href="#iri-compaction-algorithm">IRI Compaction</a>
+                algorithm, passing <tref>active context</tref>,
+                <em>expanded property</em> for <em>iri</em>,
+                <em>expanded item</em> for <em>value</em>,
+                <tref>true</tref> for <em>vocabRelative</em>, and
+                <em>shallow</em> for <em>parent</em>.
+              </li>
+              <li>
+                Initialize <em>container</em> to <tref>null</tref>. If there
+                is a <tref>container mapping</tref> for
+                <em>item active property</em> in <tref>active context</tref>,
+                set <em>container</em> to its value.
+              </li>
+              <li>
+                If there is a <tref>term definition</tref> for
+                <em>item active property</em> in <tref>active context</tref>
+                that is a <tref>property generator</tref>, then invoke the
+                <a href="#find-property-generator-duplicates">Find Property Generator Duplicates</a>
+                algorithm, passing <tref>active context</tref>,
+                <em>shallow</em> for <em>element</em>,
+                <em>expanded property</em>, <em>expanded item</em> for
+                <em>value</em>, <em>item active property</em> for
+                <tref>active property</tref>, and
+                <tref>true</tref> for <em>remove</em>.
+              </li>
+              <li>
+                Initialize <em>compacted item</em> to the result of using
+                this algorithm recursively, passing
+                <tref>active context</tref>, <em>item active property</em>
+                for </tref>active property</tref>,
+                <em>expanded item</em> for <em>element</em> if it does
+                not contain the key <code>@list</code>, otherwise pass
+                the key's associated value for <em>element</em>.
+              </li>
+              <li>
+                If <em>expanded item</em> is a <tref>list object</tref>:
+                <ol class="algorithm">
+                  <li>
+                    If <em>compacted item</em> is not an <tref>array</tref>,
+                    then set it to an <tref>array</tref> containing only
+                    <em>compacted item</em>.
+                  </li>
+                  <li>
+                    If <em>container</em> does not equal <code>@list</code>:
+                    <ol class="algorithm">
+                      <li>
+                        Convert <em>compacted item</em> to a
+                        <tref>list object</tref> by setting it to a
+                        <tref>JSON object</tref> containing key-value pair
+                        where the key is the result of the
+                        <a href="#iri-compaction-algorithm">IRI Compaction</a>
+                        algorithm, passing <tref>active context</tref> and
+                        <code>@list</code> for <em>iri</em>, and the
+                        value is <em>compacted item</em>.
+                      </li>
+                      <li>
+                        If <em>expanded item</em> contains the key
+                        <code>@index</code>, then add a key-value pair
+                        to <em>compacted item</em> where the key is the
+                        result of the
+                        <a href="#iri-compaction-algorithm">IRI Compaction</a>
+                        algorithm, passing <tref>active context</tref> and
+                        <code>@index</code> for <em>iri</em>, and the
+                        value is the value associated with the
+                        <code>@index</code> key in
+                        <em>expanded item</em>.
+                      </li>
+                    </ol>
+                  </li>
+                  <li>
+                    Otherwise, <em>item active property</em> MUST NOT be a key
+                    in <em>result</em> because there cannot be two
+                    <tref title="list object">list objects</tref> associated
+                    with an <tref>active property</tref> that has a
+                    <tref>container mapping</tref>; this is an error.
+                  </li>
+                </ol>
+              </li>
+              <li>
+                If <em>container</em> equals <code>@language</code> or
+                <code>@index</code>:
+                <ol class="algorithm">
+                  <li>
+                    If <em>item active property</em> is a key in
+                    <em>result</em>, then initialize <em>map object</em> to
+                    its associated value, otherwise initialize it to an empty
+                    <tref>JSON object</tref>.
+                  </li>
+                  <li>
+                    If <em>container</em> is <code>@language</code> and
+                    <em>compacted item</em> contains the key
+                    <code>@value</code>, then set <em>compacted item</em>
+                    to the value associated with its <code>@value</code> key.
+                  </li>
+                  <li>
+                    Initialize <em>map key</em> to the value associated with
+                    with the key that equals <em>container</em> in
+                    <em>expanded item</em>.
+                  </li>
+                  <li>
+                    If <em>map key</em> is not a key in <em>map object</em>,
+                    then set this key's value in <em>map object</em>
+                    to <em>compacted item</em>. Otherwise, if the value
+                    is not an <tref>array</tref>, then set it equal to one
+                    containing only the value and then append
+                    <em>compacted item</em> to it.
+                  </li>
+                </ol>
+              </li>
+              <li>
+                Otherwise,
+                <ol class="algorithm">
+                  <li>
+                    Initialize <em>useArray</em> to <tref>false</tref>. If
+                    <em>container</em> equals <code>@set</code> or
+                    <code>@list</code>, or <em>compacted item</em> is
+                    an empty <tref>array</tref>, or
+                    <em>expanded property</em> equals <code>@list</code> or
+                    <code>@graph</code>, then set <em>useArray</em>
+                    to <tref>true</tref>.
+                  </li>
+                  <li>
+                    If <em>useArray</em> is <tref>true</tref> and
+                    <em>compacted item</em> is not an <tref>array</tref>,
+                    then set it equal to a new <tref>array</tref>
+                    containing only <em>compacted item</em>.
+                  </li>
+                  <li>
+                    If <em>item active property</em> is not a key in
+                    <em>result</em> then add the key-value pair,
+                    (<em>item active property</em>-<em>compacted item</em>),
+                    to <em>result</em>.
+                  </li>
+                  <li>
+                    Otherwise, if the value associated with the key that
+                    equals <em>item active property</em> in <em>result</em>
+                    is not an <tref>array</tref>, set it equal to a new
+                    <tref>array</tref> containing only the value. Then
+                    append <em>compacted item</em> to the value if
+                    <em>compacted item</em> is not an <tref>array</tref>,
+                    otherwise, concatenate it.
+                  </li>
+                </ol>
+              </li>
+            </ol>
+          </li>
+        </ol>
+      </li>
+      <li>
+        Return <em>result</em>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    At this point, <em>element</em> must a be <tref>scalar</tref>, which
+    is already compact, so simply return <em>element</em>.
+  </li>
+</ol>
+
+<p>
+If, after the algorithm outlined above is run, the result <em>result</em> is
+an <tref>array</tref> with two or more items and a <em>context</em> has
+been passed, replace it with a new <tref>JSON object</tref> with a single
+key-value pair where the key is the result of using the
+<a href="#iri-compaction-algorithm">IRI Compaction</a> algorithm, passing
+<tref>active context</tref> and <code>@graph</code> for <em>iri</em>, and
+the value is <em>result</em>. Otherwise, if <em>result</em> is an
+<tref>array</tref> with only one item, set <em>result</em> to that item.
+Otherwise, if <em>result</em> is an <tref>array</tref> with zero items,
+replace it with an empty <tref>JSON object</tref>. Finally, if a
+<em>context</em> has been passed, add an <code>@context</code> property to
+<em>result</em> and set its value to the initially passed
+<em>context</em>.
+</p>
+
+</section>
+
+<!-- end of Compaction -->
+</section>
+
+<section>
+<h2>IRI Compaction Algorithm</h2>
+
+<p>
+This section defines an algorithm for transforming an <tref>IRI</tref>
+to a <tref>term</tref> or <tref>compact IRI</tref>, or a <tref>keyword</tref>
+alias to a <tref>keyword</tref>. A value that is associated with the
+<tref>IRI</tref> may be passed in order to assist in selecting the most
+context-appropriate <tref>term</tref>.
+</p>
+
+<section>
+<h3>Problem</h3>
+
+We have an <tref>IRI</tref> (or <tref>keyword</tref>) that we may
+be able to compact to <tref>term</tref>, <tref>compact IRI</tref>, or
+<tref>keyword</tref> alias.
+
+</section>
+
+<section>
+<h3>General Solution</h3>
+
+<p>
+First, we handle the simple cases: if the value given as an <tref>IRI</tref>
+is <tref>null</tref>, we simply return <tref>null</tref> and if it is a
+<tref>keyword</tref> we return its associated alias.
+</p>
+
+<p>
+Otherwise, we first try to find a <tref>term</tref> that the
+<tref>IRI</tref> can be <tref title="compaction">compacted</tref> to. In
+order to select a <tref>term</tref>, we have to collect information about
+the <tref title="IRI">IRI's</tref> associated value. This information
+includes which <tref title="container mapping">container mappings</tref>
+would be preferred for expressing the value, and what its
+<tref>type mapping</tref> or <tref>language mapping</tref> is. For
+JSON-LD lists, the <tref>type mapping</tref> or <tref>language mapping</tref>
+will be chosen based on the most specific values that work for all items in
+the list. Once this information is gathered, it is passed to the
+<a href="#term-selection">Term Selection</a> subalgorithm, which will
+return the most appropriate <tref>term</tref> to use.</p>
+
+<p>
+If no <tref>term</tref> was found that could be used to compact the
+<tref>IRI</tref>, then an attempt is made to find a <tref>compact IRI</tref>
+to use. If there is no appropriate <tref>compact IRI</tref>, then
+the <tref title="active context">active context's</tref>
+<tref>vocabulary mapping</tref> is used. Finally, if the <tref>IRI</tref>
+still could not be compacted, we simply return it as is.
+</p>
+
+</section>
+
+<section>
+<h3>Algorithm</h3>
+
+<p>
+This algorithm takes three required inputs and three optional inputs.
+The required inputs an <tref>active context</tref> and the <em>iri</em> to
+be compacted. The optional inputs are: a <em>value</em> associated with
+the <em>iri</em>, a <em>vocabRelative</em> flag which specifies whether the
+passed <em>iri</em> should be compacted using the
+<tref title="active context">active context's</tref>
+<tref>vocabulary mapping</tref>, and the <em>parent</em> element for
+the <em>value</em>. If not passed, <em>value</em> is set to
+<tref>null</tref>, <em>vocabRelative</em> is set to <code>false</code>, and
+<em>parent</em> is set to <tref>null</tref>.
+</p>
+
+<ol class="algorithm">
+  <li>
+    If <em>iri</em> is <tref>null</tref>, return <tref>null</tref>.
+  </li>
+  <li>
+    If <em>iri</em> is a <tref>keyword</tref> and does not have a
+    <tref>keyword</tref> alias, return <em>iri</em>, otherwise return
+    its first associated <tref>keyword</tref> alias from
+    <tref>active context</tref>.
+  </li>
+  <li>
+    If <tref>active context</tref> has no associated
+    <tref>inverse context</tref>, then generate it using the
+    <a href="#inverse-context-creation">Inverse Context Creation</a>
+    algorithm. Set <em>inverse context</em> to the
+    <tref>inverse context</tref> associated with <tref>active context</tref>.
+  </li>
+  <li>
+    Initialize <em>defaultLanguage</em> to
+    <tref title="active context">active context's</tref>
+    <tref>default language</tref>, if it has one, otherwise to
+    <code>@none</code>.
+  </li>
+  <li>
+    If <em>iri</em> is a key in <em>inverse context</em>:
+    <ol class="algorithm">
+      <li>
+        Initialize <em>entry</em> to the value in <em>inverse context</em>
+        associated with the key that equals <em>iri</em>.
+      </li>
+      <li>
+        Initialize <em>containers</em> to an empty <tref>array</tref>. This
+        <tref>array</tref> will be used to keep track of an ordered list of
+        preferred <tref title="container mapping">container mappings</tref>
+        for a <tref>term</tref>, based on what is compatible with
+        <em>value</em>.
+      </li>
+      <li>
+        If <em>value</em> is a <tref>JSON object</tref> that contains the
+        key <code>@index</code>, then append the value <code>@index</code>
+        to <em>containers</em>.
+      </li>
+      <li>
+        Initialize <em>typeOrLanguage</em> to <code>@language</code>,
+        and <em>typeOrLanguageValue</em> to <code>@null</code>. These two
+        variables will keep track of the preferred
+        <tref>type mapping</tref> or <tref>language mapping</tref> for
+        a <tref>term</tref>, based on what is compatible with <em>value</em>.
+      </li>
+        If <em>value</em> is a <tref>list object</tref>, then set
+        <em>typeOrLanguage</em> and <em>typeOrLanguageValue</em>
+        to the most specific values that work for all items in
+        the list as follows:
+        <ol class="algorithm">
+          <li>
+            If <code>@index</code> is a not key in <em>value</em>, then
+            append <code>@list</code> to <em>containers</em>.
+          </li>
+          <li>
+            Initialize <em>list</em> to the <tref>array</tref> associated
+            with the key <code>@list</code> in <em>value</em>.
+          </li>
+          <li>
+            Initialize <em>commonLanguage</em> to <tref>null</tref>. If
+            <em>list</em> is empty, set <em>commonLanguage</em> to
+            <em>defaultLanguage</em>.
+          </li>
+          <li>
+            For each <em>item</em> in <em>list</em>:
+            <ol class="algorithm">
+              <li>
+                Initialize <em>itemLanguage</em> to <code>@none</code> and
+                <em>itemType</em> to <code>@none</code>.
+              </li>
+              <li>
+                If <em>item</em> contains the key <code>@value</code>:
+                <ol class="algorithm">
+                  <li>
+                    If <em>item</em> contains the key <code>@language</code>,
+                    then set <em>itemLanguage</em> to its associated
+                    value.
+                  </li>
+                  <li>
+                    Otherwise, if <em>item</em> contains the key
+                    <code>@type</code>, set <em>itemType</em> to its
+                    associated value.
+                  </li>
+                  <li>
+                    Otherwise, set <em>itemLanguage</em> to
+                    <code>@null</code>.
+                  </li>
+                </ol>
+              </li>
+              <li>
+                Otherwise, set <em>itemType</em> to <code>@id</code>.
+              </li>
+              <li>
+                If <em>commonLanguage</em> is <tref>null</tref>, set it
+                to <em>itemLanguage</em>.
+              </li>
+              <li>
+                Otherwise, if <em>itemLanguage</em> does not equal
+                <em>commonLanguage</em> and <em>item</em> contains the
+                key <code>@value</code>, then set <em>commonLanguage</em>
+                to <code>@none</code> because list items have conflicting
+                languages.
+              </li>
+              <li>
+                If <em>commonType</em> is <tref>null</tref>, set it
+                to <em>itemType</em>.
+              </li>
+              <li>
+                Otherwise, if <em>itemType</em> does not equal
+                <em>commonType</em>, then set <em>commonType</em>
+                to <code>@none</code> because list items have conflicting
+                types.
+              </li>
+              <li>
+                If <em>commonLanguage</em> equals <code>@none</code> and
+                <em>commonType</em> equals <code>@none</code>, then
+                stop processing items in the list because it has been
+                detected that there is no common language or type amongst
+                the items.
+              </li>
+            </ol>
+          </li>
+          <li>
+            If <em>commonLanguage</em> is <tref>null</tref>, set it to
+            <code>@none</code>.
+          </li>
+          <li>
+            If <em>commonType</em> is <tref>null</tref>, set it to
+            <code>@none</code>.
+          </li>
+          <li>
+            If <em>commonType</em> is not <code>@none</code> then set
+            <em>typeOrLanguage</em> to <code>@type</code> and
+            <em>typeOrLanguageValue</em> to <em>commonType</em>.
+          </li>
+          <li>
+            Otherwise, set <em>typeOrLanguageValue</em> to
+            <em>commonLanguage</em>.
+          </li>
+        </ol>
+      </li>
+      <li>
+        Otherwise:
+        <ol class="algorithm">
+          <li>
+            If <em>value</em> contains the key <code>@value</code>:
+            <ol class="algorithm">
+              <li>
+                If <em>value</em> contains the key <code>@language</code>,
+                then set <em>typeOrLanguageValue</em> to its associated
+                value and append <code>@language</code> to
+                <em>containers</em>.
+              </li>
+              <li>
+                Otherwise, if <em>value</em> contains the key
+                <code>@type</code>, then set <em>typeOrLanguageValue</em> to
+                its associated value and set <em>typeOrLanguage</em> to
+                <code>@type</code>.
+              </li>
+            </ol>
+          </li>
+          <li>
+            Otherwise, set <em>typeOrLanguage</em> to <code>@type</code>
+            and set <em>typeOrLanguageValue</em> to <code>@id</code>.
+          </li>
+          <li>
+            Append <code>@set</code> to <em>containers</em>.
+          </li>
+        </ol>
+      </li>
+      <li>
+        Initialize <em>term</em> to the result of the
+        <a href="#term-selection">Term Selection</a> subalgorithm, passing
+        <tref>active context</tref>, <em>value</em>, <em>parent</em>,
+        <em>entry</em>, <em>containers</em>, <em>typeOrLanguage</em>, and
+        <em>typeOrLangaugeValue</em>.
+      </li>
+      <li>
+        If <em>term</em> is not <tref>null</tref>, return <em>term</em>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    At this point, there is no simple <tref>term</tref> that <em>iri</em>
+    can be compacted to. Instead, try to choose a <tref>compact IRI</tref>,
+    starting by initializing <em>choice</em> to <tref>null</tref>. This
+    variable will be used to store the chosen <tref>compact IRI</tref> to
+    use, if any.
+  </li>
+  <li>
+    For each key <tref>term</tref> and value <tref>term definition</tref> in
+    the <tref>active context</tref>:
+    <ol class="algorithm">
+      <li>
+        If the <tref>term</tref> contains a colon (<code>:</code>),
+        then continue to the next <tref>term</tref> because
+        <tref title="term">terms</tref> with colons can't be
+        used as <tref title="prefix">prefixes</tref>.
+      </li>
+      <li>
+        If the <tref>term definition</tref> is <tref>null</tref>
+        or for a <tref>property generator</tref> or its
+        <tref>IRI mapping</tref> equals <em>iri</em> or is not
+        a substring at the beginning of <em>iri</em>, then the
+        <tref>term</tref> cannot be used as a <tref>prefix</tref>
+        because it is not a partial match with <em>iri</em>. So
+        continue to the next <tref>term</tref>.
+      </li>
+      <li>
+        Initialize <em>curie</em> by concatenating <tref>term</tref>,
+        a colon (<code>:</code>), and the substring of <em>iri</em>
+        that follows after the value of the
+        <tref title="term definition">term definition's</tref>
+        <tref>IRI mapping</tref>.
+      </li>
+      <li>
+        Initialize <em>isUsableCurie</em> to <tref>false</tref>. If
+        <em>curie</em> does not have a <tref>term definition</tref> in
+        <tref>active context</tref> or if the
+        <tref>term definition</tref> has an <tref>IRI mapping</tref>
+        that equals <em>iri</em> and <em>value</em> is <tref>null</tref>,
+        then set <em>isUsableCurie</em> to <tref>true</tref>.
+      </li>
+      <li>
+        If <em>isUsableCurie</em> equals <tref>true</tref> and either
+        <em>choice</em> is <tref>null</tref> or <em>curie</em> is shorter
+        or the same length but lexicographically less than
+        <em>choice</em>, set <em>choice</em> to <em>curie</em>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    If <em>choice</em> is not <tref>null</tref>, return <em>choice</em>.
+  </li>
+  <li>
+    At this point, there is no <tref>compact IRI</tref> that <em>iri</em>
+    can be compacted to, so if <em>vocabRelative</em> equals
+    <tref>true</tref> and <tref>active context</tref> has a
+    <tref>vocabulary mapping</tref>:
+    <ol class="algorithm">
+      <li>
+        If <em>iri</em> begins with the
+        <tref title="vocabulary mapping">vocabulary mapping's</tref> value
+        but is longer, then initialize <em>suffix</em> to the substring
+        of <em>iri</em> that does not match. If <em>suffix</em> does not
+        have a <tref>term definition</tref> in <tref>active context</tref>,
+        then return <em>suffix</em>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    There are no <tref>compaction</tref> options for <em>iri</em> so
+    return <em>iri</em> as is.
+  </li>
+</ol>
+
+</section>
+
+<!-- end of IRI Compaction -->
+</section>
+
+<section>
+<h2>Inverse Context Creation Subalgorithm</h2>
+
+<p>
+When there is more than one <tref>term</tref> that could be chosen
+to compact an <tref>IRI</tref>, we want to ensure that our <tref>term</tref>
+selection is both deterministic and not unexpected, representing the most
+context-appropriate choice whilst taking into consideration algorithmic
+complexity.
+</p>
+
+<p>
+In order to make <tref>term</tref> selections the concept of an
+<tref>inverse context</tref> is introduced. An <tdef>inverse context</tdef>
+is essentially a reverse lookup table that maps
+<tref title="container mapping">container mappings</tref>,
+<tref title="type mapping">type mappings</tref>, and
+<tref title="language mapping">language mappings</tref> to a simple
+<tref>term</tref> and, if applicable, an <tref>array</tref> of potential
+<tref>property generator</tref> <tref title="term">terms</tref> for
+a given <tref>active context</tref>. A <tref>inverse context</tref> only
+needs to be generated for an <tref>active context</tref> if it is being
+used for <tref>compaction</tref>.
+</p>
+
+<p>
+To make use of an <tref>inverse context</tref>, a list of preferred
+<tref title="container mapping">container mappings</tref> and the
+<tref>type mapping</tref> or <tref>language mapping</tref> are gathered
+for a particular value associated with an <tref>IRI</tref>. These parameters
+are then fed to the <a href="#term-selection">Term Selection</a>
+subalgorithm, which will find the <tref>term</tref> that most appropriately
+matches the value's mappings.
+</p>
+
+<section>
+<h3>Problem</h3>
+
+An <tref>inverse context</tref> must be created for the given
+<tref>active context</tref>.
+
+</section>
+
+<section>
+<h3>General Solution</h3>
+
+<p>
+To create an <tref>inverse context</tref> for a given
+<tref>active context</tref>, each <tref>term</tref> in the
+<tref>active context</tref> is visited, ordered by length, shortest
+first (ties are broken by choosing the lexicographically least
+<tref>term</tref>). For each <tref>term</tref>, an entry is added to
+the <tref>inverse context</tref> for each possible combination of
+<tref>container mapping</tref> and <tref>type mapping</tref>
+or <tref>language mapping</tref> that would legally match the
+<tref>term</tref>. Illegal matches include differences between a
+value's <tref>type mapping</tref> or <tref>language mapping</tref> and
+that of the <tref>term</tref>. If a <tref>term</tref> has no
+<tref>container mapping</tref>, <tref>type mapping</tref>, or
+<tref>language mapping</tref> (or some combination of these), then it
+will have an entry in the <tref>inverse context</tref> using the special
+key <code>@none</code>. This allows the
+<a href="#term-selection">Term Selection</a> subalgorithm to fall back
+to choosing more generic <tref title="term">terms</tref> when a more
+specificly-matching <tref>term</tref> is not available for a particular
+<tref>IRI</tref> and value combination.
+</p>
+
+</section>
+
+<section>
+<h3>Algorithm</h3>
+
+<p>
+The algorithm takes one required input: the <tref>active context</tref> that
+the <tref>inverse context</tref> is being created for.
+</p>
+
+<ol class="algorithm">
+  <li>
+    Initialize <em>result</em> to an empty <tref>JSON object</tref>.
+  <li>
+    Initialize <em>defaultLanguage</em> to <code>@none</code>. If the
+    <tref>active context</tref> has a <tref>default language</tref>, then
+    set <em>defaultLanguage</em> to it.
+  </li>
+  <li>
+    For each key <tref>term</tref> and value <term>term definition</tref> in
+    the <tref>active context</tref>, ordered by shortest <tref>term</tref>
+    first (breaking ties by choosing the lexicographically least
+    <tref>term</tref>):
+    <ol class="algorithm">
+      <li>
+        If the <tref>term definition</tref> is <tref>null</tref>, then
+        <tref>term</tref> cannot be selected during <tref>compaction</tref>,
+        so continue to the next <tref>term</tref>.
+      </li>
+      <li>
+        Initialize <em>container</em> to <code>@none</code>. If there
+        is a <tref>container mapping</tref> in
+        <tref>term definition</tref>, then set <em>container</em> to
+        its associated value.
+      </li>
+      <li>
+        Initialize <em>iris</em> to the value of the <tref>IRI mapping</tref>
+        for the <tref>term definition</tref>. If <em>iris</em> is not an
+        <tref>array</tref>, then set it to an <tref>array</tref> containing
+        only <em>iris</em>.
+      </li>
+      <li>
+        For each item <em>iri</em> in <em>iris</em>:
+        <ol class="algorithm">
+          <li>
+            If <em>iri</em> is not a key in <em>result</em>, then add
+            a key-value pair where the key is <em>iri</em> and the value
+            is an empty <tref>JSON object</tref> to <em>result</em>.
+          </li>
+          <li>
+            Initialize <em>container map</em> to the value associated with
+            the <em>iri</em> key in <em>result</em>.
+          </li>
+          <li>
+            If <em>container</em> is not a key in <em>container map</em>,
+            then initialize <em>typeOrLanguage map</em> to a new
+            <tref>JSON object</tref>. Add two key-value pairs to
+            <em>typeOrLanguage map</em>, where the first's key is
+            <code>@language</code> and its value is a new
+            <tref>JSON object</tref> and where the second's key is
+            <code>@type</code> and its value is a new
+            <tref>JSON object</tref>. Set the value of the key
+            <em>defaultLanguage</em> in the value associated with the
+            key <code>@language</code> in <em>typeOrLanguage map</em>
+            to a new <tref>JSON object</tref> containing a key-value pair
+            where the key is <code>term</code> and the value is
+            <tref>null</tref>.
+          </li>
+          <li>
+            Set <em>typeOrLanguage map</em> to the value associated with
+            the key <em>container</em> in <em>container map</em>.
+          </li>
+          <li>
+            If there is no <tref>type mapping</tref> in the
+            <tref>term definition</tref>:
+            <ol class="algorithm">
+              <li>
+                Initialize <em>language map</em> to the value associated
+                with the key <code>@language</code> in
+                <em>typeOrLanguage map</em>.
+              </li>
+              <li>
+                If there is a <tref>language mapping</tref> in the
+                <tref>term definition</tref>:
+                <ol class="algorithm">
+                  <li>
+                    If the value of the <tref>language mapping</tref>
+                    is <tref>null</tref> initialize <em>language</em>
+                    to <code>@null</code>, otherwise initialize it to the
+                    value.
+                  </li>
+                  <li>
+                    If <em>language</em> is not a key in
+                    <em>language map</em>, then add a key-value
+                    pair to <em>language map</em> where the key is
+                    <em>language</em> and the value is a new
+                    <tref>JSON object</tref> with two key-value
+                    pairs, where the first's key is <code>term</code>
+                    and its value is <tref>null</tref>, and the second's
+                    key is <code>propertyGenerators</code> and the
+                    value is an empty <tref>array</tref>.
+                  </li>
+                  <li>
+                    Initialize <em>entry</em> to the value associated with
+                    the key <em>language</em> in <em>language map</em>.
+                  </li>
+                  <li>
+                    If <tref>term definition</tref> is a
+                    <tref>property generator</tref>, append the
+                    <tref>term</tref> to the <tref>array</tref> associated
+                    with the <code>propertyGenerators</code> key in
+                    <em>entry</em>.
+                  </li>
+                  <li>
+                    Otherwise, if the value associated with the key
+                    <code>term</code> in <em>entry</em> is <tref>null</tref>,
+                    set it to the <tref>term</tref>.
+                  </li>
+                </ol>
+              </li>
+              <li>
+                Otherwise:
+                <ol class="algorithm">
+                  <li>
+                    If <em>defaultLanguage</em> is not a key in
+                    <em>language map</em>, then add a key-value
+                    pair to <em>language map</em> where the key is
+                    <em>defaultLanguage</em> and the value is a new
+                    <tref>JSON object</tref> with two key-value
+                    pairs, where the first's key is <code>term</code>
+                    and its value is <tref>null</tref>, and the second's
+                    key is <code>propertyGenerators</code> and the
+                    value is an empty <tref>array</tref>.
+                  </li>
+                  <li>
+                    Initialize <em>entry</em> to the value associated with
+                    the key <em>defaultLanguage</em> in <em>language map</em>.
+                  </li>
+                  <li>
+                    If <tref>term definition</tref> is a
+                    <tref>property generator</tref>, append the
+                    <tref>term</tref> to the <tref>array</tref> associated
+                    with the <code>propertyGenerators</code> key in
+                    <em>entry</em>.
+                  </li>
+                  <li>
+                    Otherwise, if the value associated with the key
+                    <code>term</code> in <em>entry</em> is <tref>null</tref>,
+                    set it to the <tref>term</tref>.
+                  </li>
+                  <li>
+                    If <code>@none</code> is not a key in
+                    <em>language map</em>, then add a key-value
+                    pair to <em>language map</em> where the key is
+                    <code>@none</code> and the value is a new
+                    <tref>JSON object</tref> with two key-value
+                    pairs, where the first's key is <code>term</code>
+                    and its value is <tref>null</tref>, and the second's
+                    key is <code>propertyGenerators</code> and the
+                    value is an empty <tref>array</tref>.
+                  </li>
+                  <li>
+                    Set <em>entry</em> to the value associated with
+                    the key <code>@none</code> in <em>language map</em>.
+                  </li>
+                  <li>
+                    If <tref>term definition</tref> is a
+                    <tref>property generator</tref>, append the
+                    <tref>term</tref> to the <tref>array</tref> associated
+                    with the <code>propertyGenerators</code> key in
+                    <em>entry</em>.
+                  </li>
+                  <li>
+                    Otherwise, if the value associated with the key
+                    <code>term</code> in <em>entry</em> is <tref>null</tref>,
+                    set it to the <tref>term</tref>.
+                  </li>
+                </ol>
+              </li>
+            </ol>
+          </li>
+          <li>
+            If there is no <tref>language mapping</tref> in the
+            <tref>term definition</tref>:
+            <ol class="algorithm">
+              <li>
+                Initialize <em>type map</em> to the value associated
+                with the key <code>@type</code> in
+                <em>typeOrLanguage map</em>.
+              </li>
+              <li>
+                If there is a <tref>type mapping</tref> in the
+                <tref>term definition</tref> then initialize <em>type</em>
+                to its value, otherwise initialize it to
+                to <code>@none</code>.
+              </li>
+              <li>
+                If <em>type</em> is not a key in <em>type map</em>, then
+                add a key-value pair to <em>type map</em> where the key is
+                <em>type</em> and the value is a new <tref>JSON object</tref>
+                with two key-value pairs, where the first's key is
+                <code>term</code> and its value is <tref>null</tref>, and the
+                second's key is <code>propertyGenerators</code> and the
+                value is an empty <tref>array</tref>.
+              </li>
+              <li>
+                Initialize <em>entry</em> to the value associated with
+                the key <em>type</em> in <em>type map</em>.
+              </li>
+              <li>
+                If <tref>term definition</tref> is a
+                <tref>property generator</tref>, append the
+                <tref>term</tref> to the <tref>array</tref> associated
+                with the <code>propertyGenerators</code> key in
+                <em>entry</em>.
+              </li>
+              <li>
+                Otherwise, if the value associated with the key
+                <code>term</code> in <em>entry</em> is <tref>null</tref>,
+                set it to the <tref>term</tref>.
+              </li>
+            </ol>
+          </li>
+        </ol>
+      </li>
+    </ol>
+  </li>
+  <li>
+    Return <em>result</em>.
+  </li>
+</ol>
+
+</section>
+
+<!-- end of Inverse Context Creation subalgorithm -->
+</section>
+
+<section>
+<h2>Term Selection Subalgorithm</h2>
+
+<p>
+This subalgorithm, invoked via the
+<a href="#iri-compaction-algorithm">IRI Compaction</a> algorithm, makes use
+of an <tref title="active context">active context's</tref>
+<tref>inverse context</tref> to find the <tref>term</tref> that is best
+used to <tref title="compaction">compact</tref> an <tref>IRI</tref>. Other
+information about a value associated with the <tref>IRI</tref> is given,
+including which <tref title="container mapping">container mappings</tref>
+and which <tref>type mapping</tref> or <tref>language mapping</tref> would
+be best used to express the value.
+</p>
+
+<section>
+<h3>Problem</h3>
+
+An <tref>IRI</tref> with an associated <em>value</em> should be compacted
+to the most appropriate <tref>term</tref> in the <tref>active context</tref>.
+
+</section>
+
+<section>
+<h3>General Solution</h3>
+
+<p>
+The <tref title="inverse context">inverse context's</tref> entry for
+the <tref>IRI</tref> will be first searched according to the preferred
+<tref title="container mapping">container mappings</tref>, in the order
+that they are given. Amongst <tref title="term">terms</tref> with a matching
+<tref>container mapping</tref>, preference will be given to those
+with a matching <tref>type mapping</tref> or <tref>language mapping</tref>,
+over those without a <tref>type mapping</tref> or
+<tref>language mapping</tref>. If there is no <tref>term</tref>
+with a matching <tref>container mapping</tref> then the <tref>term</tref>
+without a <tref>container mapping</tref> that matches the given
+<tref>type mapping</tref> or <tref>language mapping</tref> is selected. If
+there is still no selected <tref>term</tref>, then a <tref>term</tref>
+with no <tref>type mapping</tref> or <tref>language mapping</tref> will
+be selected if available. No <tref>term</tref> will be selected that
+has a conflicting <tref>type mapping</tref> or <tref>language mapping</tref>.
+Ties between <tref title="term">terms</tref> that have the same
+mappings are resolved by first choosing the shortest terms, and then by
+choosing the lexicographically least term. Note that these ties are
+resolved automatically because they were previously resolved when the
+<a href="#inverse-context-creation">Inverse Context Creation algorithm</a>
+was used to create the <tref>inverse context</tref>.
+</p>
+
+</section>
+
+<section>
+<h3>Algorithm</h3>
+
+<p>
+This subalgorithm has seven required inputs. They are:
+an <tref>active context</tref>, an <tref>IRI</tref> <em>iri</em>,
+a <em>value</em> associated with the <tref>IRI</tref>, the expanded
+<em>parent</em> element for <em>value</em> (which may be a
+<tref>JSON object</tref>, an <tref>array</tref>, or <tref>null</tref>), an
+<tref>array</tref> <em>containers</em> that represents ordered list of
+preferred <tref title="container mapping">container mappings</tref>, a
+<tref>string</tref> <em>typeOrLanguage</em> that indicates whether
+to look for a <tref>term</tref> with a matching <tref>type mapping</tref>
+or <tref>language mapping</tref>, and a <tref>string</tref>
+<em>typeOrLanguageValue</em> with the associated value for the
+<tref>type mapping</tref> or <tref>language mapping</tref> to look for.
+</p>
+
+<ol class="algorithm">
+  <li>
+    Append <code>@none</code> to <em>containers</em>. This represents
+    the non-existence of a <tref>container mapping</tref>, and it will
+    be the last <tref>container mapping</tref> value to be checked as it
+    is the most generic.
+  </li>
+  <li>
+    Initialize <em>container map</em> to the value associated with
+    <em>iri</em> in the <tref>inverse context</tref>.
+  </li>
+  <li>
+    If <em>typeOrLanguageValue</em> is <tref>null</tref>, set it to
+    <code>@null</code>. This is the key under which <tref>null</tref> values
+    are stored in the <tref>inverse context</tref> <em>entry</em>.
+  </li>
+  <li>
+    Initialize <em>preferred values</em> to an <tref>array</tref> containing
+    <em>typeOrLangageValue</em> and <code>@none</code>, in that order. This
+    <tref>array</tref> indicates, in order, the preferred values for
+    a <tref title="term">term's</tref> <tref>type mapping</tref> or
+    <tref>language mapping</tref>.
+  </li>
+  <li>
+    Initialize <em>selected term</em> to <tref>null</tref>.
+  </li>
+  <li>
+    For each item <em>container</em> in <em>containers</em> while
+    <em>selected term</em> is <tref>null</tref>:
+    <ol class="algorithm">
+      <li>
+        If <em>container</em> is not a key in <em>container map</em>, then
+        there is no <tref>term</tref> with a matching
+        <tref>container mapping</tref> for it, so continue to the next
+        <em>container</em>.
+      </li>
+      <li>
+        Initialize <em>typeOrLanguage map</em> to the value associated
+        with <em>container</em> in <em>container map</em>.
+      </li>
+      <li>
+        Initialize <em>typeOrLanguageValue map</em> to the value associated
+        with <em>typeOrLanguage</em> in <em>typeOrLanguage map</em>.
+      </li>
+      <li>
+        For each <em>item</em> in <em>preferred values</em> while
+        <em>selected term</em> is <tref>null</tref>:
+        <ol class="algorithm">
+          <li>
+            If <em>item</em> is not a key in <em>typeOrLanguageValue map</em>,
+            then there is no <tref>term</tref> with a matching
+            <tref>type mapping</tref> or <tref>language mapping</tref>,
+            so continue to the next <em>item</em>.
+          </li>
+          <li>
+            Initialize <em>termInfo</em> to the value associated with
+            <em>item</em> in <em>typeOrLanguageValue map</em>.
+          </li>
+          <li>
+            If <em>parent</em> is a <tref>JSON object</tref>,
+            then for each <tref>property generator</tref> <tref>term</tref>
+            <em>propertyGeneratorTerm</em> in <em>termInfo</em> while
+            <em>selected term</em> is <tref>null</tref>:
+            <ol class="algorithm">
+              <li>
+                Initialize <em>match</em> to the result of using the
+                <a href="#find-property-generator-duplicates">Find Property Generator Duplicates</a>
+                algorithm, passing <tref>active context</tref>,
+                <em>parent</em> for <em>element</em>, <em>iri</em> for
+                <em>expanded property</em>, <em>value</em>,
+                <em>propertyGeneratorTerm</em> for <em>activeProperty</em>,
+                and <tref>false</tref> for <em>remove</em>.
+              </li>
+              <li>
+                If <em>match</em> equals <tref>true</tref>, then set
+                <em>selected term</em> to <em>propertyGeneratorTerm</em>.
+              </li>
+            </ol>
+          </li>
+          <li>
+            If <em>selected term</em> is <tref>null</tref>, then no
+            <tref>property generator</tref> match was found, so set
+            <em>selected term</em> to the non-<tref>property generator</tref>
+            <tref>term</tref> in <em>termInfo</em>, which may be
+            <tref>null</tref>.
+          </li>
+        </ol>
+      </li>
+    </ol>
+  </li>
+  <li>
+    Return <em>selected term</em>.
+  </li>
+</ol>
+
+</section>
+
+<!-- end of Term Selection subalgorithm -->
+</section>
+
+<section>
+<h2>Value Compaction</h2>
+
+<p>
+<tref>Expansion</tref> transforms all values into <tref>expanded form</tref>
+in JSON-LD. This algorithm performs the opposite operation, transforming
+a value into <tdef>compacted form</tdef>. This algorithm compacts a
+value according to the <tref>term definition</tref> in the given
+<tref>active context</tref> that is associated with the value's associated
+<tref>active property</tref>.
+</p>
+
+<section>
+<h3>Problem</h3>
+
+A <em>value</em> associated with an <tref>active property</tref> must
+be <tref title="compaction">compacted</tref> to <tref>compacted form</tref>.
+
+</section>
+
+<section>
+<h3>General Solution</h3>
+
+<p>
+The <em>value</em> to compact either contains the key <code>@value</code>
+or the key <code>@id</code>.
+</p>
+
+<p>
+We start with the former case, first trying to compact the
+<em>value</em> into just the value associated with its
+<code>@value</code> key. This can be done if the <em>value</em> is not
+going to be contained by an <code>@index</code> container and if the
+<tref>active property</tref> has a matching <tref>type mapping</tref> or
+<tref>language mapping</tref>. It can also be done if <code>@value</code>
+is the only key in <em>value</em> and either its associated value is
+not a <tref>string</tref>, there's no <tref>default language</tref>, or
+there's an explicit <tref>null</tref> <tref>language mapping</tref> for
+the <tref>active property</tref>.
+</p>
+
+<p>
+If we couldn't do the above optimal compaction, then we simply replace
+<tref title="keyword">keywords</tref> with aliases and compact any
+<tref title="IRI">IRIs</tref>.
+</p>
+
+<p>
+For the latter case, where the key <code>@id</code> appears in <em>value</em>,
+we compact the associated value using the
+<a href="#iri-compaction-algorithm">IRI Compaction</a> algorithm, and
+use its value if the <tref>type mapping</tref> associated with the
+<tref>active property</tref> is <code>@id</code> or the expanded value for
+the <tref>active property</tref> is <code>@graph</code>. Otherwise, we
+replace the <code>@id</code> key with its alias and its associated value
+with its compacted version.
+</p>
+
+</section>
+
+<section>
+<h3>Algorithm</h3>
+
+<p>
+This algorithm has three required inputs: an <tref>active context</tref>, an
+an <tref>active property</tref>, and a <em>value</em> to be compacted.
+</p>
+
+<ol class="algorithm">
+  <li>
+    If <em>value</em> contains the key <code>@value</code>:
+    <ol class="algorithm">
+      <li>
+        Initialize <em>preserveIndex</em> to <tref>false</tref>. If
+        <code>@index</code> is a key in <em>value</em> and
+        <tref>active property</tref> does not have a
+        <tref>container mapping</tref> in <tref>active context</tref> that
+        equals <code>@index</code>, set <em>preserveIndex</em> to
+        <tref>true</tref>.
+      </li>
+      <li>
+        If <em>preserveIndex</em> equals <tref>false</tref> and either
+        <em>value</em> has a <code>@type</code> key with a value that
+        matches <tref title="active property">active property's</tref>
+        <tref>type mapping</tref> in <tref>active context</tref> or
+        <em>value</em> has a <code>@language</code> key with a value that
+        matches <tref title="active property">active property's</tref>
+        <tref>language mapping</tref> in <tref>active context</tref>, then
+        return the value associated with the <code>@value</code> key in
+        <em>value</em>.
+      </li>
+      <li>
+        If <code>@value</code> is the only key in <em>value</em> or
+        <em>preserveIndex</em> equals <tref>false</tref> and either
+        there is no <tref>default language</tref> in
+        <tref>active context</tref>, the value associated with the
+        <code>@value</code> key in <em>value</em> is not a
+        <tref>string</tref>, or <tref>active property</tref>
+        has a <tref>null</tref> <tref>language mapping</tref> in
+        <tref>active context</tref>, then return the value
+        associated with the <code>@value</code> key in <em>value</em>.
+      </li>
+      <li>
+        Initialize <em>result</em> to an empty <tref>JSON object</tref>.
+      </li>
+      <li>
+        If <em>preserveIndex</em> equals <tref>true</tref>, then add
+        a key-value pair to <em>result</em> where the key is the result
+        using the <a href="#iri-compaction-algorithm">IRI compaction</a>
+        algorithm, passing <tref>active context</tref> and
+        <code>@index</code> for <em>iri</em>, and the value is
+        the value associated with the <code>@index</code> key in
+        <em>value</em>.
+      </li>
+      <li>
+        If <em>value</em> contains the key <code>@type</code>, then add
+        a key-value pair to <em>result</em> where the key is the result
+        using the <a href="#iri-compaction-algorithm">IRI compaction</a>
+        algorithm, passing <tref>active context</tref> and
+        <code>@type</code> for <em>iri</em>, and the value is the result
+        of using the <a href="#iri-compaction-algorithm">IRI compaction</a>
+        algorithm, passing <tref>active context</tref>, the value associated
+        with the <code>@type</code> key in <em>value</em> for <em>iri</em>,
+        <tref>true</tref> for <em>vocabRelative</em>, and
+        <tref>true</tref> for <em>documentRelative</em>.
+      </li>
+      <li>
+        Otherwise, if <em>value</em> contains the key <code>@language</code>,
+        then add a key-value pair to <em>result</em> where the key is the
+        result using the
+        <a href="#iri-compaction-algorithm">IRI compaction</a>
+        algorithm, passing <tref>active context</tref> and
+        <code>@language</code> for <em>iri</em>, and the value is the
+        value associated with the <code>@language</code> key in
+        <em>value</em>.
+      </li>
+      <li>
+        Add a key-value pair to <em>result</em> where the key is the result
+        using the <a href="#iri-compaction-algorithm">IRI compaction</a>
+        algorithm, passing <tref>active context</tref> and
+        <code>@value</code> for <em>iri</em>, and the value is the value
+        associated with the <code>@value</code> key in <em>value</em>.
+      </li>
+      <li>
+        Return <em>result</em>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    Otherwise, <em>value</em> must contain the single key <code>@id</code>.
+    Initialize <em>expanded property</em> to the result of using the
+    <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
+    <tref>active context</tref> and <em>value</em>.
+  </li>
+  <li>
+    Initialize <em>term</em> to the result of using the
+    <a href="#iri-compaction-algorithm">IRI compaction</a> algorithm,
+    passing <tref>active context</tref>, the value associated with
+    the key <code>@id</code> in <em>value</em> for <em>iri</em>,
+    and <tref>true</tref> for <em>documentRelative</em>.
+  </li>
+  <li>
+    If <tref>active property</tref> has a <tref>type mapping</tref> in
+    the <tref>active context</tref> that is equal to <code>@id</code> or
+    <em>expanded property</em> equals <code>@graph</code>, then return
+    <em>term</em>.
+  </li>
+  <li>
+    Initialize <em>result</em> to an empty <tref>JSON object</tref>. Add
+    a key-value pair to <em>result</em> where the key is the result of
+    using the <a href="#iri-compaction-algorithm">IRI compaction</a>
+    algorithm, passing <tref>active context</tref>, and <code>@id</code> for
+    <em>iri</em>, and the value is <em>term</em>.
+  </li>
+  <li>
+    Return <em>result</em>.
+  </li>
+</ol>
+
+</section>
+
+<!-- end of Value Compaction algorithm -->
+</section>
+
+<section>
+<h2>Find Property Generator Duplicates Subalgorithm</h2>
+
+<p>
+This algorithm checks if a specific value exists for all
+<tref title="IRI">IRIs</tref> associated with a
+<tref>property generator</tref> and, if specified, it removes them.
+The algorithm takes six required inputs: an <tref>active context</tref>,
+<em>element</em>, <em>expanded property</em>, <em>value</em>,
+<tref>active property</tref>, and a flag <em>remove</em>, that indicates
+whether or not to remove the duplicate values. It returns <tref>true</tref>
+if the required duplicate values were found and <tref>false</tref> if not.
+</p>
+
+<ol class="algorithm">
+  <li>
+    Initialize <em>result</em> to <tref>true</tref>.
+  </li>
+  <li>
+    Initialize <em>iris</em> to the <tref>array</tref> associated with the
+    <tref>IRI mapping</tref> for <tref>active property</tref> in
+    <tref>active context</tref>.
+  </li>
+  <li>
+    For each <em>iri</em> in <em>iris</em>:
+    <ol class="algorithm">
+      <li>
+        If <em>iri</em> equals <em>expanded property</em>, then this
+        is the <em>iri</em> that is to be preserved, so continue to the next
+        <em>iri</em>.
+      </li>
+      <li>
+        Set <em>result</em> to <tref>false</tref>.
+      </li>
+      <li>
+        If <em>element</em> contains a key that equals <em>iri</em>:
+        <ol class="algorithm">
+          <li>
+            Initialize <em>prospects</em> to the value associated with the
+            key that equals <em>iri</em> in <em>element</em>. This
+            <tref>array</tref> will be checked for a value that matches
+            the <tref>property generator</tref> <em>value</em>.
+          </li>
+          <li>
+            If <em>value</em> is an empty <tref>array</tref>:
+            <ol class="algorithm">
+              <li>
+                Set <em>result</em> to <tref>true</tref>.
+              </li>
+              <li>
+                If <em>remove</em> is <tref>true</tref>, remove <em>iri</em>
+                from <em>element</em>.
+              </li>
+              <li>
+                Continue to the next <em>iri</em>.
+              </li>
+            </ol>
+          </li>
+          <li>
+            For each item <em>prospect</em> in <em>prospects</em>, until
+            a <tref>property generator</tref> duplicate is found for
+            <em>value</em>:
+            <ol class="algorithm">
+              <li>
+                Check to see if <em>prospect</em> and <em>value</em> are
+                <tref>property generator</tref> duplicates:
+                <ol class="algorithm">
+                  <li>
+                    If their types and values are equal, then they are
+                    duplicates.
+                  </li>
+                  <li>
+                    Otherwise, if they are both
+                    <tref title="JSON object">JSON objects</tref> that contain
+                    the key <code>@value</code> and they both have the same
+                    key-value pairs for the keys <code>@value</code>,
+                    <code>@type</code>, <code>@language</code>, and
+                    <code>@index</code>, then they are duplicates.
+                  </li>
+                  <li>
+                    Otherwise, if they are both
+                    <tref title="list object">list objects</tref> with the same
+                    key-value pairs for the key <code>@index</code>, and the
+                    <tref title="array">arrays</tref> associated with their
+                    <code>@list</code> keys have the same length and their
+                    corresponding items, by index, are duplicates, then they
+                    are duplicates.
+                  </li>
+                  <li>
+                    Otherwise, if they are both
+                    <tref title="JSON object">JSON objects</tref> that contain
+                    the key <code>@id</code> and the values associated with
+                    those keys are equal, then they are duplicates.
+                  </li>
+                  <li>
+                    Otherwise, they are not duplicates.
+                  </li>
+                </ol>
+              </li>
+              <li>
+                If <em>prospect</em> and <em>value</em> are
+                <tref>property generator</tref> duplicates:
+                <ol class="algorithm">
+                  <li>
+                    Set <em>result</em> to <tref>true</tref>.
+                  </li>
+                  <li>
+                    If <em>remove</em> is <tref>true</tref>, then remove
+                    <em>prospect</em> from <em>prospects</em> and, if
+                    <em>prospects</em> is now empty, remove <em>iri</em>
+                    from <em>element</em>.
+                  </li>
+                </ol>
+              </li>
+            </ol>
+          </li>
+        </ol>
+      </li>
+    </ol>
+  </li>
+  <li>
+    Return <em>result</em>.
+  </li>
+</ol>
+
+</section>
+
+<!-- FIXME -->
 <section>
   <h2>Flattening Algorithm</h2>
 
@@ -1875,6 +3977,7 @@
   </ol>
 </section>
 
+<!-- FIXME -->
 <section>
   <h2>Node Map Generation</h2>
 
@@ -1979,176 +4082,258 @@
   </ol>
 </section>
 
-  <section>
-    <h2>RDF Conversion Algorithms</h2>
-
-    <p>This section describes an algorithms to transform JSON-LD documents to an array of
-      RDF <tref title="quad">quads</tref> and vice-versa. Note that many uses of JSON-LD
-      may not require generation of RDF.</p>
-
-    <p>The processing algorithms described in this section are provided in order to demonstrate
-      how one might implement a JSON-LD to RDF processor. Conformant implementations are only
-      required to produce the same type and number of <tref title="quad">quads</tref> but are
-      not required to implement the algorithm exactly as described.</p>
-
-    <p class="issue">This algorithm hasn't been updated yet.</p>
-
-    <section>
-      <h3>Convert to RDF Algorithm</h3>
-      <p>
-        The algorithm below is designed for in-memory implementations with random access to <tref>JSON object</tref> elements.
-      </p>
-      <p>
-        A conforming JSON-LD processor implementing RDF conversion MUST implement a
-        processing algorithm that results in the same set of RDF <tref title="quad">quads</tref> that the following
-        algorithm generates.
-      </p>
-
-      <p>The algorithm takes four input variables: a <em>element</em> to be converted, an
-        <tref>active subject</tref>, <tref>active property</tref> and <tref>graph name</tref>.
-        To begin, the <tref>active subject</tref>, <tref>active property</tref> and <tref>graph name</tref>
-        are set to <tref>null</tref>, and <em>element</em> is
-        set to the result of performing the <a href="#expansion-algorithm">Expansion Algorithm</a> on
-        the <tref>JSON-LD input</tref> which is expected to be a a well-formed JSON-LD document as defined in [[!JSON-LD]].
-        This removes any existing context to allow the given context to be cleanly applied.</p>
-
-      <ol class="algorithm">
-        <li id="processing-step-associative">
-          If <em>element</em> is a <tref>JSON object</tref>, perform the following steps:
-          <ol class="algorithm">
-            <li>Set <tref>active object</tref> to <tref>null</tref>.</li>
-            <li>
-              If <em>element</em> has a <code>@value</code> property:
-              <ol class="algorithm">
-                <li>If the value of <code>@value</code> is a <tref>number</tref>, set the
-                  <tref>active object</tref> to a <tref>typed value</tref> using a <tref>canonical lexical form</tref>
-                  of the value as defined in the section <a href="#data-round-tripping">Data Round Tripping</a>.
-                  Set datatype to the value of the <code>@type</code> property if it exists, otherwise
-                  either <code>xsd:integer</code> or <code>xsd:double</code>, depending
-                  on if the value contains a fractional and/or an exponential component.</li>
-                <li>Otherwise, if the value of <code>@value</code> is <strong>true</strong> or <strong>false</strong>,
-                  set the <tref>active object</tref> to a <tref>typed value</tref> created from the
-                  <tref>canonical lexical form</tref> of the value. Set datatype to the value of the <code>@type</code>
-                  property if it exists, otherwise <code>xsd:boolean</code>.</li>
-                <li>
-                  Otherwise, if <em>element</em> contains a <code>@type</code> property, set the
-                  <tref>active object</tref> to a <tref>typed value</tref>.
-                </li>
-                <li>
-                  Otherwise, if <em>element</em> contains a <code>@language</code> property, set the
-                  <tref>active object</tref> to a <tref>language-tagged string</tref>.
-                </li>
-                <li>
-                  Otherwise, set the <tref>active object</tref> to a <tref>typed value</tref>
-                  using <code>xsd:string</code> as the datatype.
-                </li>
-              </ol>
-            </li>
-            <li>
-              If <em>element</em> has a <code>@list</code> property the value MUST be an <tref>array</tref>.
-              Process its value as a list as described in <a href="#list-conversion">List Conversion</a> using
-              the return value as the <tref>active object</tref>
-            </li>
-            <li>If <tref>active object</tref> is not <tref>null</tref>:
-              <ol class="algorithm">
-                <li>If neither <tref>active subject</tref> nor <tref>active property</tref> are <tref>null</tref>,
-                  generate a <tref>Quad</tref>
-                  representing <tref>active subject</tref>, <tref>active property</tref>,
-                  <tref>active object</tref>, and <tref>graph name</tref>.</li>
-                <li>Return <tref>active object</tref>.</li>
-              </ol>
-            </li>
-            <li id="processing-step-subject">If <em>element</em> has a <code>@id</code> property,
-              the value MUST be a <tref>string</tref>, set the <tref>active subject</tref> to the previously
-              expanded value (either a <tref>blank node</tref> or an <tref>IRI</tref>).</li>
-            <li>
-              Otherwise, if <em>element</em> does not have a <code>@id</code> property, set the <tref>active
-              subject</tref> to newly generated <tref>blank node</tref>.</li>
-            <li>
-              Process each <em>property</em> and <em>value</em> in <em>element</em>, ordered by
-              <em>property</em>, as follows:
-              <ol class="algorithm">
-                <li>
-                  If <em>property</em> is <code>@type</code>, set the <tref>active property</tref>
-                  to <code>rdf:type</code>.
-                </li>
-                <li>Otherwise, if <em>property</em> is <code>@graph</code>,
-                  process <em>value</em> algorithm recursively, using <tref>active subject</tref> as <tref>graph name</tref>
-                  and null values for <tref>active subject</tref> and <tref>active property</tref> and then
-                  proceed to next property.</li>
-                <li>Otherwise, if <em>property</em> is a <tref>keyword</tref>, skip this step.</li>
-                <li>Otherwise, set <tref>active property</tref> to the <tref>expanded IRI form</tref> of <em>property</em>.</li>
-                <li>Process <em>value</em> recursively using this algorithm, passing copies of
-                  <tref>active subject</tref>, <tref>active property</tref> and <tref>graph name</tref>.
-                </li>
-              </ol>
-            </li>
-            <li>
-              Set <tref>active object</tref> to <tref>active subject</tref>.
-            </li>
-          </ol>
-        </li>
-
-        <li>Otherwise, if <em>element</em> is an <tref>array</tref>, process each value in the <tref>array</tref>
-          as follows, process <em>element</em> recursively using this algorithm, using copies of
-          <tref>active subject</tref>, <tref>active property</tref>, and <tref>graph name</tref>.</li>
-
-        <li>Otherwise, if <em>element</em> is a <tref>string</tref>, then the <tref>active property</tref>
-          must be <code>rdf:type</code> so set the <tref>active object</tref> to an <tref>IRI</tref>.</li>
-
-        <li>If any of these steps created an <tref>active object</tref> and neither <tref>active subject</tref>
-          nor <tref>active property</tref> are <tref>null</tref>, generate a <tref>Quad</tref> using
-          <tref>active subject</tref>,<tref>active property</tref>, <tref>active object</tref> and
-          <tref>graph name</tref>.
-        </li>
-        <li>Return <tref>active object</tref>.</li>
-      </ol>
+<!-- FIXME -->
+<section>
+<h2>RDF Conversion Algorithms</h2>
+
+<p>
+This section describes algorithms to transform JSON-LD documents to an array
+of RDF <tref title="quad">quads</tref> and vice-versa. Note that many uses of
+JSON-LD may not require generation of RDF.
+</p>
+
+<p>
+The processing algorithms described in this section are provided in order to
+demonstrate how one might implement a JSON-LD to RDF processor. Conformant
+implementations are only required to produce the same type and number of
+<tref title="quad">quads</tref> but are not required to implement the
+algorithm exactly as described.
+</p>
+
+<section>
+<h3>Convert to RDF Algorithm</h3>
+
+<p>
+The algorithm below is designed for in-memory implementations with random
+access to <tref>JSON object</tref> elements.
+</p>
+
+<p>
+A conforming JSON-LD processor implementing RDF conversion MUST implement a
+processing algorithm that results in the same set of RDF
+<tref title="quad">quads</tref> that the following algorithm generates.
+</p>
+
+<p>
+The algorithm takes five input variables: an <em>element</em> to be converted,
+an <tref>active subject</tref>, an <tref>active property</tref>, a
+<tref>graph name</tref>, and an <tref>array</tref> <em>quads</em> of
+<tref title="quad">Quads</tref>. To begin, the <tref>active subject</tref>,
+<tref>active property</tref>, and <tref>graph name</tref>
+are set to <tref>null</tref>, <em>quads</em> is set to an empty
+<tref>array</tref>, and <em>element</em> is set to the result of
+performing the <a href="#expansion-algorithm">Expansion Algorithm</a> on the
+<tref>JSON-LD input</tref> which is expected to be a a well-formed JSON-LD
+document as defined in [[!JSON-LD]].
+</p>
+
+<p class="issue">This algorithm hasn't been updated to use [[!RDF-CONCEPTS]]
+yet.</p>
+<p class="issue">This algorithm needs some clarification on its details.</p>
+
+<ol class="algorithm">
+  <li>
+    If <em>element</em> is an <tref>array</tref>, then for each <em>item</em>
+    in <em>element</em> invoke this algorithm recursively, passing
+    <em>item</em> for <em>element</em>, <tref>active subject</tref>,
+    <tref>active property</tref>, <tref>graph name</tref>, and <em>quads</em>.
+  </li>
+  <li>
+    Otherwise, if <em>element</em> is a <tref>string</tref>, then
+    generate a <tref>quad</tref> using <tref>active subject</tref>,
+    <tref>active property</tref>, an <tref>IRI</tref> with the value
+    of <em>element</em> for <tref>RDF object</tref>, and
+    <tref>graph name</tref>. Append the <tref>quad</tref> to
+    <em>quads</em>.
+  </li>
+  <li>
+    Otherwise, if <em>element</em> is a <tref>list object</tref>:
+    <ol class="algorithm">
+      <li>
+        Initialize <em>list</em> to the result of the
+        <a href="#list-conversion">List Conversion</a> algorithm, passing
+        the value associated with the <code>@list</code> key.
+      </li>
+      <li>
+        Invoke this algorithm recursively, passing <em>list</em> for
+        <em>element</em>, <tref>active subject</tref>,
+        <tref>active property</tref>, <tref>graph name</tref>, and
+        <em>quads</em>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    Otherwise, if <em>element</em> is a <tref>JSON object</tref> that
+    contains the key <code>@value</code>:
+    <ol class="algorithm">
+      <li>
+        Initialize <em>value</em> to the value associated with the
+        <code>@value</code> key in <em>element</em>. Initialize
+        <em>datatype</em> to the value associated with the <code>@type</code>
+        key in <em>element</em>, or <tref>null</tref> if <em>element</em>
+        does not contain that key.
+      </li>
+      <li>
+        Otherwise, if <em>value</em> equals <tref>true</tref> or
+        <tref>false</tref>, then set <em>value</em> its
+        <tref>canonical lexical form</tref> as defined
+        in the section <a href="#data-round-tripping">Data Round Tripping</a>.
+        If <em>datatype</em> is <tref>null</tref>, set it to
+        <code>xsd:boolean</code>.
+      </li>
+      <li>
+        Otherwise, if <em>value</em> is a <tref>number</tref>, then set
+        <em>value</em> to its <tref>canonical lexical form</tref> as defined
+        in the section <a href="#data-round-tripping">Data Round Tripping</a>.
+        If <em>datatype</em> is <tref>null</tref>, set it to either
+        <code>xsd:integer</code> or <code>xsd:double</code>, depending
+        on if the value contains a fractional and/or an exponential
+        component.
+      </li>
+      <li>
+        Otherwise, if <em>datatype</em> is <tref>null</tref>, set it to
+        <code>xsd:string</code>.
+      </li>
+      <li>
+        Initialize <tref>active object</tref> using <em>value</em> and
+        <em>datatype</em>. If <em>element</em> has the key
+        <code>@language</code> and <em>datatype</em> equals
+        <code>xsd:string</code>, then add the value associated with the
+        <code>@language</code> key as the language of the
+        <tref>active object</tref>.
+      </li>
+      <li>
+        Generate a <tref>quad</tref> using <tref>active subject</tref>,
+        <tref>active property</tref>, <tref>active object</tref>, and
+        <tref>graph name</tref>. Append the <tref>quad</tref> to
+        <em>quads</em>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    Otherwise, <em>element</em> must represent the next
+    <tref>RDF subject</tref> to be processed:
+    <ol class="algorithm">
+      <li>
+        If <em>element</em> contains the key <code>@id</code>, then
+        initialize <em>id</em> to its associated value, otherwise initialize
+        it to <tref>null</tref>. If <em>element</em> is a
+        <tref>blank node</tref>, then set <em>id</em> to the result of
+        using the
+        <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a>
+        algorithm, passing <em>id</em> for <em>identifier</em>.
+      </li>
+      <li>
+        Initialize <tref>active object</tref> to an <tref>IRI</tref> or
+        <tref>blank node</tref>, as appropriate, with the value of
+        <em>element</em>.
+      </li>
+      <li>
+        If <tref>active subject</tref> is not <tref>null</tref>, then
+        generate a <tref>quad</tref> using <tref>active subject</tref>,
+        <tref>active property</tref>, <tref>active object</tref>, and
+        <tref>graph name</tref>. Append the <tref>quad</tref> to
+        <em>quads</em>.
+      </li>
+      <li>
+        Set <tref>active subject</tref> to <tref>active object</tref>.
+      </li>
+      <li>
+        For each <em>key</em>-<em>value</em> pair in <em>element</em>,
+        sorted lexicographically by <em>key</em>:
+        <ol class="algorithm">
+          <li>
+            Set <tref>active property</tref> to <em>value</em>.
+          </li>
+          <li>
+            If <tref>active property</tref> equals <code>@graph</code>, then
+            use this algorithm recursively, passing <em>value</em> for
+            <em>element</em>, <tref>null</tref> for
+            <tref>active subject</tref> and <tref>active property</tref>,
+            <tref>active subject</tref> for <tref>graph name</tref>,
+            and <em>quads</em>. Then continue to the next <em>key</em>.
+          </li>
+          <li>
+            If <em>key</em> equals <code>@type</code>, then set
+            <tref>active property</tref> to <code>rdf:type</code>.
+          </li>
+          <li>
+            If <tref>active property</tref> is a <tref>keyword</tref>,
+            then continue to the next <em>key</em>.
+          </li>
+          <li>
+            Use this algorithm recursively, passing <em>value</em> for
+            <em>element</em>, <tref>active subject</tref>,
+            <tref>active property</tref>, <tref>graph name</tref>,
+            and <em>quads</em>.
+          </li>
+        </ol>
+      </li>
+    </ol>
+  </li>
+</ol>
+
+</section>
+
+<section id="list-conversion">
+<h3>List Conversion</h3>
+
+<p>
+List Conversion is the process of taking an <tref>array</tref> of values and
+converting it to a JSON-LD linked list of
+<tref title="JSON object">JSON objects</tref>. Each element of the list is
+linked by using <code>rdf:first</code> and <code>rdf:rest</code>, terminating
+the list with <code>rdf:nil</code>.
+</p>
+
+<p>
+The algorithm takes a single input: an <tref>array</tref> <em>list</em>.
+</p>
+
+<div class="note">This algorithm does not support lists containing lists.</div>
+
+<ol class="algorithm">
+  <li>
+    Initialize <em>length</em> to the length of <em>list</em>.
+  </li>
+  <li>
+    Initialize <em>tail</em> to a <tref>JSON object</tref> containing
+    one key-value pair, (<code>@id</code>-<code>rdf:nil</code>).
+  </li>
+  <li>
+    Starting <em>itr</em> at <em>length</em> minus <code>1</code>, loop
+    until <em>itr</em> is <code>0</code> (inclusive):
+    <ol class="algorithm">
+      <li>
+        Initialize <em>element</em> to an empty <tref>JSON object</tref>.
+      </li>
+      <li>
+        Add a key-value pair to <em>element</em> where the key is
+        <code>rdf:first</code> and the value is an <tref>array</tref>
+        containing the value associated with the index <em>itr</em>
+        in <em>list</em>.
+      </li>
+      <li>
+        Add a key-value pair to <em>element</em> where the key is
+        <code>rdf:rest</code> and the value is an <tref>array</tref>
+        containing <em>tail</em>.
+      </li>
+      <li>
+        Set <em>tail</em> to <em>element</em>.
+      </li>
+      <li>
+        Decrement <em>itr</em> by <code>1</code>.
+      </li>
+    </ol>
+  </li>
+  <li>
+    Return <em>tail</em>.
+  </li>
+</ol>
+
     </section>
 
-    <section id="list-conversion">
-      <h3>List Conversion</h3>
-
-      <p>List Conversion is the process of taking an <tref>array</tref> of values and adding them to a newly
-        created <cite><a href="http://www.w3.org/TR/rdf-schema/#ch_collectionvocab">RDF Collection</a></cite> (see
-        [[!RDF-SCHEMA]]) by linking each element of the list using <code>rdf:first</code> and <code>rdf:next</code>,
-        terminating the list with <code>rdf:nil</code> using the following sequence:</p>
-      <p>The algorithm is invoked with an <tref>array</tref> <em>array</em>, the <tref>active property</tref>
-        and returns a value to be used as an <tref>active object</tref> in the calling location.</p>
-      <div class="note">This algorithm does not support lists containing lists.</div>
-
-      <p class="issue">This algorithm hasn't been updated yet.</p>
-
-      <ol class="algorithm">
-        <li>
-          If <em>array</em> is empty return <code>rdf:nil</code>.
-        </li>
-        <li>
-          Otherwise, generate a <tref>Quad</tref> using using the <tref>active subject</tref>, <tref>active property</tref>
-          and a newly generated <tref>blank node</tref> identified as <em>first <tref>blank node</tref></em>.
-        </li>
-        <li>
-          For each element in <em>array</em> other than the last element:
-          <ol class="algorithm">
-            <li>Create a processor state using
-              <em>first blank node</em> as the <tref>active subject</tref>, and
-              <code>rdf:first</code> as the <tref>active property</tref>.
-              <ol class="algorithm">
-                <li>Process the value starting at <a href="#processing-step-associative">Step 1</a>.</li>
-                <li>Proceed using the previous <tref>processor state</tref>.</li>
-              </ol>
-            </li>
-            <li>Unless this is the last element in <em>array</em>, generate a new <tref>blank node</tref> identified as
-              <em>rest blank node</em>, otherwise use <code>rdf:nil</code>.</li>
-            <li>Generate a new <tref>Quad</tref> using <em>first blank node</em>,
-              <code>rdf:rest</code> and <em>rest blank node</em>.</li>
-            <li>Set <em>first blank node</em> to
-              <em>rest blank node</em>.</li>
-            <li>Return <em>first blank node</em>.</li>
-          </ol>
-        </li>
-      </ol>
-    </section>
-
+<!-- FIXME -->
     <section>
       <h2>Convert from RDF Algorithm</h2>
       <p>In some cases, data exists natively in the form of triples or or <tref title="quad">quads</tref>;
@@ -2162,7 +4347,7 @@
       <p>The conversion algorithm takes a single parameter <em>input</em> in the form of an
         array of <tref>Quad</tref> representations.</p>
 
-      <p class="issue">This algorithm hasn't been updated yet.</p>
+      <p class="issue">This algorithm hasn't been updated to use [[!RDF-CONCEPTS]] yet.</p>
 
       <ol class="algorithm">
         <li id="new_graph">Construct <em>defaultGraph</em> as a <tref>JSON object</tref>
@@ -2290,6 +4475,7 @@
       </ol>
     </section>
 
+<!-- FIXME -->
     <section>
       <h3>Data Round Tripping</h3>
 
@@ -2358,7 +4544,11 @@
         There is no need to backslash-escape forward slashes in JSON-LD. To aid interoperability
         between JSON-LD processors, a JSON-LD serializer MUST NOT backslash-escape forward slashes.</p>
     </section>
-  </section>
+
+<!-- end of RDF algorithms -->
+</section>
+
+<!-- end of Algorithms -->
 </section>
 
 <section>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/latest/json-ld-api/markus.html	Tue Feb 12 19:50:01 2013 +0100
@@ -0,0 +1,2670 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>JSON-LD 1.0 Processing Algorithms and API</title>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
+<script type="text/javascript" src="../respec-w3c-common.js" class="remove"></script>
+<script type="text/javascript" src="../respec-w3c-extensions.js" class="remove"></script>
+<script type="text/javascript" class="remove">
+//<![CDATA[
+  var respecConfig = {
+      // extend the bibliography entries
+      "localBiblio": localBibliography,
+
+      doRDFa: "1.1",
+      // specification status (e.g. WD, LCWD, NOTE, etc.). If in doubt use ED.
+      specStatus:           "ED",
+      // if you wish the publication date to be other than today, set this
+      //publishDate:          "2012-12-25",
+      copyrightStart:       "2010",
+
+      // the specification's short name, as in http://www.w3.org/TR/short-name/
+      shortName:            "json-ld-api",
+
+      // if there is a previously published draft, uncomment this and set its YYYY-MM-DD date
+      // and its maturity status
+      previousPublishDate:  "2012-09-30",
+      previousMaturity:     "ED",
+      previousURI:          "http://dvcs.w3.org/hg/json-ld/raw-file/66d980964784/spec/ED/json-ld-api/20120930/index.html",
+
+      // if there a publicly available Editor's Draft, this is the link
+      edDraftURI:           "http://json-ld.org/spec/latest/json-ld-api/index.html",
+
+      testSuiteURI:         "http://json-ld.org/test-suite/",
+
+      // if this is a LCWD, uncomment and set the end of its review period
+      // lcEnd: "2009-08-05",
+
+      // if you want to have extra CSS, append them to this list
+      // it is recommended that the respec.css stylesheet be kept
+      // extraCSS: [],
+
+      issueBase: "https://github.com/json-ld/json-ld.org/issues/",
+
+      // editors, add as many as you like
+      // only "name" is required
+      editors:  [
+          { name: "Markus Lanthaler", url: "http://www.markus-lanthaler.com/",
+            company: "Graz University of Technology", companyURL: "http://www.tugraz.at/" },
+          { name: "Gregg Kellogg", url: "http://greggkellogg.net/",
+            company: "Kellogg Associates", companyURL: "http://kellogg-assoc.com/" },
+          { name: "Manu Sporny", url: "http://manu.sporny.org/",
+            company: "Digital Bazaar", companyURL: "http://digitalbazaar.com/" }
+      ],
+
+      // authors, add as many as you like.
+      // This is optional, uncomment if you have authors as well as editors.
+      // only "name" is required. Same format as editors.
+
+      authors:  [
+          { name: "Dave Longley", url: "http://digitalbazaar.com/",
+            company: "Digital Bazaar", companyURL: "http://digitalbazaar.com/"},
+          { name: "Gregg Kellogg", url: "http://greggkellogg.net/",
+            company: "Kellogg Associates", companyURL: "http://kellogg-assoc.com/" },
+          { name: "Markus Lanthaler", url: "http://www.markus-lanthaler.com/",
+            company: "Graz University of Technology", companyURL: "http://www.tugraz.at/" },
+          { name: "Manu Sporny", url: "http://digitalbazaar.com/",
+            company: "Digital Bazaar", companyURL: "http://digitalbazaar.com/" }
+      ],
+
+      // name of the WG
+      wg:           "RDF Working Group",
+
+      // URI of the public WG page
+      wgURI:        "http://www.w3.org/2011/rdf-wg/",
+
+      // name (with the @w3c.org) of the public mailing to which comments are due
+      wgPublicList: "public-rdf-comments",
+
+      // URI of the patent status for this WG, for Rec-track documents
+      // !!!! IMPORTANT !!!!
+      // This is important for Rec-track documents, do not copy a patent URI from a random
+      // document unless you know what you're doing. If in doubt ask your friendly neighbourhood
+      // Team Contact.
+      wgPatentURI:  "http://www.w3.org/2004/01/pp-impl/46168/status",
+      maxTocLevel: 3,
+      preProcess: [ preProc ],
+      alternateFormats: [ {uri: "diff-20120930.html", label: "diff to previous version"} ],
+  };
+//]]>
+</script>
+<style type="text/css">
+  .diff { font-weight:bold; color:#0a3; }
+</style>
+</head>
+
+<body>
+<section id="abstract">
+<p>
+JSON [[!RFC4627]] has proven to be a highly useful object serialization and
+messaging format. JSON-LD [[!JSON-LD]] harmonizes the representation of
+Linked Data in JSON by outlining a common JSON representation format for
+expressing directed graphs, mixing both Linked Data and non-Linked Data in
+a single document. This document outlines an Application Programming
+Interface and a set of algorithms for programmatically transforming
+JSON-LD documents to make them easier to work with in programming
+environments like those that use JavaScript, Python, and Ruby.
+</p>
+</section>
+
+<section id="sotd">
+<p>This document has been under development for over 18 months in the
+JSON for Linking Data Community Group. The document has recently been
+transferred to the RDF Working Group for review, improvement, and publication
+along the Recommendation track. The specification has undergone significant
+development, review, and changes during the course of the last 18 months.
+</p>
+<p>There are several independent
+<a href="http://json-ld.org/#impl">interoperable implementations</a> of
+this specification. There is
+a <a href="https://github.com/json-ld/json-ld.org/tree/master/test-suite">fairly complete test suite</a>
+and a <a href="http://json-ld.org/playground/">live JSON-LD editor</a>
+that is capable of demonstrating the features described in
+this document. While development on implementations, the test suite
+and the live editor will continue, they are believed to be mature enough
+to be integrated into a non-production system at this point in time with
+the expectation that they could be used in a production system within the
+next year.
+</p>
+<p class="issue">
+It is important for readers to understand that the scope of this document is
+currently under debate and new features may be added to the specification.
+Existing features may be modified heavily or removed entirely from the
+specification upon further review and feedback from the broader community.
+This is a work in progress and publication as a Working Draft
+does not require that all Working Group members agree on the content of the
+document.
+</p>
+
+<p>There are a number of ways that one may participate in the development of
+  this specification:</p>
+
+<ul>
+  <li>If you want to make sure that your feedback is formally addressed by
+    the RDF Working Group, you should send it to public-rdf-comments:
+    <a href="http://lists.w3.org/Archives/Public/public-rdf-comments/">public-rdf-comments@w3.org</a></li>
+
+  <li>Ad-hoc technical discussion primarily occurs on the public community mailing list:
+    <a href="http://lists.w3.org/Archives/Public/public-linked-json/">public-linked-json@w3.org</a></li>
+
+  <li><a href="http://json-ld.org/minutes/">Public JSON-LD Community Group teleconferences</a>
+    are held on Tuesdays at 1500UTC every week. Participation is open to the
+    public.</li>
+
+  <li>RDF Working Group teleconferences are held on Wednesdays at 1500UTC
+    every week. Participation is limited to RDF Working Group members.</li>
+
+  <li>Specification bugs and issues should be reported in the
+    <a href="https://github.com/json-ld/json-ld.org/issues">issue tracker</a>
+    if you do not want to send an e-mail to the public-rdf-comments mailing
+    list.</li>
+
+  <li><a href="https://github.com/json-ld/json-ld.org/tree/master/spec">Source code</a>
+    for the specification can be found on Github.</li>
+
+  <li>The <a href="http://webchat.freenode.net/?channels=json-ld">#json-ld</a>
+    IRC channel is available for real-time discussion on irc.freenode.net.</li>
+</ul>
+
+</section>
+
+<section class="informative">
+<h2>Introduction</h2>
+
+<p>
+This document is a detailed specification for an Application Programming
+Interface for the JSON-LD Syntax. The document is primarily intended for
+the following audiences:
+</p>
+
+<ul>
+  <li>Web authors and developers that want a very detailed view of how
+    a JSON-LD processor and the API operates.</li>
+  <li>Software developers that want to implement processors and APIs for
+    JSON-LD documents.</li>
+</ul>
+
+<p>
+To understand the basics in this specification you must first be familiar with
+JSON, which is detailed in [[!RFC4627]]. You must also understand the
+JSON-LD Syntax [[!JSON-LD]], which is the base syntax used by all of the
+algorithms in this document. To understand the API and how it is
+intended to operate in a programming environment, it is useful to have working
+knowledge of the JavaScript programming language [[ECMA-262]] and
+WebIDL [[!WEBIDL]]. To understand how JSON-LD maps to RDF, it is helpful to be
+familiar with the basic RDF concepts [[!RDF-CONCEPTS]].</p>
+
+</section>
+
+<section class="informative">
+<h1>Features</h1>
+
+<p>The JSON-LD Syntax specification [[!JSON-LD]] outlines a language that may be
+  used to express Linked Data in JSON. Often, it is useful to be able to transform
+  JSON-LD documents so that they may be easily processed in various programming
+  environments.</p>
+
+<p>There are four major types of transformation that are discussed in this document:
+  expansion, compaction, flattening, and RDF conversion.</p>
+
+<section class="informative">
+  <h2>Expansion</h2>
+  <p>Software algorithms are easiest to write when the data that they are processing
+    have a regular form. Since information can be represented by JSON-LD in a
+    variety of different ways, transforming all of these methods into a uniform
+    structure allows the developer to simplify their processing code. For example,
+    note that the following input uses only <tref>term</tref>s and is fairly
+    compact:</p>
+
+  <pre class="example" data-transform="updateExample"
+       title="Sample JSON-LD document">
+  <!--
+  {
+    "@context": {
+      "name": "http://xmlns.com/foaf/0.1/name",
+      "homepage": {
+        "@id": "http://xmlns.com/foaf/0.1/homepage",
+        "@type": "@id"
+      }
+    },
+    "@id": "http://me.markus-lanthaler.com/",
+    "name": "Markus Lanthaler",
+    "homepage": "http://www.markus-lanthaler.com/"
+  }
+  -->
+  </pre>
+
+  <p>The next input example uses one <tref>IRI</tref> to express a property, but leaves
+    the rest of the information untouched.</p>
+
+  <pre class="example" data-transform="updateExample"
+       title="Sample JSON-LD document using a IRI instead of a term to express a property">
+  <!--
+  {
+    "@context": {
+      "homepage": {
+        "@id": "http://xmlns.com/foaf/0.1/homepage",
+        "@type": "@id"
+      }
+    },
+    "@id": "http://me.markus-lanthaler.com/",
+    "****http://xmlns.com/foaf/0.1/name****": "Markus Lanthaler",
+    "homepage": "http://www.markus-lanthaler.com/"
+  }
+  -->
+  </pre>
+
+  <p>While both inputs are valid JSON-LD, writing a program to handle every
+    permutation of possible inputs can be difficult, especially when the incoming
+    context could change as well. To ensure that the data can be given a more
+    uniform structure, JSON-LD introduces the notion of expansion. <tdef>Expansion</tdef>
+    performs two important operations. The first is to expand all values that represent
+    <tref title="IRI">IRIs</tref> to <tref title="absolute IRI">absolute IRIs</tref>.
+    The second is to express all values in <tref>expanded form</tref>. Running the
+    <a href="#expansion-algorithm">Expansion algorithm</a> against the examples provided
+    above results in the following output:</p>
+
+  <pre class="example" data-transform="updateExample"
+       title="Expanded sample document">
+  <!--
+  [
+    {
+      "@id": "http://me.markus-lanthaler.com/",
+      "http://xmlns.com/foaf/0.1/name": [
+        { "@value": "Markus Lanthaler" }
+      ],
+      "http://xmlns.com/foaf/0.1/homepage": [
+        { "@id": "http://www.markus-lanthaler.com/" }
+      ]
+    }
+  ]
+  -->
+  </pre>
+
+  <p>Note that in the output above all <tref>context</tref> definitions have
+    been removed, all <tref title="term">terms</tref> and <tref title="prefix">prefixes</tref>
+    have been expanded to absolute <tref title="IRI">IRIs</tref>, and all
+    <tref title="JSON-LD value">JSON-LD values</tref> are expressed in <tref>expanded form</tref>.
+    While the output is more difficult for a human to read, it is easier for a
+    software program to process because of its very regular structure.</p>
+</section>
+
+<section class="informative">
+  <h2>Compaction</h2>
+  <p>While expansion expands a given input as much as possible, compaction performs
+    the opposite operation: it expresses a given input as succinctly as possible. In contrast
+    to expansion which is meant to produce something that is easy to process by software
+    programs, compaction is meant to produce something that is easy to read by software
+    developers. Compaction uses a developer-supplied <tref>context</tref> to compress
+    <tref title="IRI">IRIs</tref> to <tref title="term">terms</tref> or
+    <tref title="compact IRI">compact IRIs</tref> and <tref title="JSON-LD value">JSON-LD values</tref>
+    expressed in <tref>expanded form</tref> to simple values such as
+    <tref title="string">strings</tref> or <tref title="number">numbers</tref>.</p>
+
+  <p>For example, assume the following expanded JSON-LD input document:</p>
+
+  <pre class="example" data-transform="updateExample"
+       title="Expanded sample document">
+  <!--
+  [
+    {
+      "@id": "http://me.markus-lanthaler.com/",
+      "http://xmlns.com/foaf/0.1/name": [
+        { "@value": "Markus Lanthaler" }
+      ],
+      "http://xmlns.com/foaf/0.1/homepage": [
+        { "@id": "http://www.markus-lanthaler.com/" }
+      ]
+    }
+  ]
+  -->
+  </pre>
+
+  <p>Additionally, assume the following developer-supplied JSON-LD <tref>context</tref>:</p>
+
+  <pre class="example" data-transform="updateExample"
+       title="JSON-LD context">
+  <!--
+  {
+    "@context": {
+      "name": "http://xmlns.com/foaf/0.1/name",
+      "homepage": {
+        "@id": "http://xmlns.com/foaf/0.1/homepage",
+        "@type": "@id"
+      }
+    }
+  }
+  -->
+  </pre>
+
+  <p>Running the <a href="#compaction-algorithm">Compaction Algorithm</a> given the context
+    supplied above against the JSON-LD input document provided above would result in the
+    following output:</p>
+
+  <pre class="example" data-transform="updateExample"
+       title="Compacted sample document">
+  <!--
+  {
+    "@context": {
+      "name": "http://xmlns.com/foaf/0.1/name",
+      "homepage": {
+        "@id": "http://xmlns.com/foaf/0.1/homepage",
+        "@type": "@id"
+      }
+    },
+    "@id": "http://me.markus-lanthaler.com/",
+    "name": "Markus Lanthaler",
+    "homepage": "http://www.markus-lanthaler.com/"
+  }
+  -->
+  </pre>
+
+  <p>Note that all <tref title="IRI">IRIs</tref> have been compacted to
+    <tref title="term">terms</tref> as specified in the <tref>context</tref>
+    which consequently has been injected into the output. While compacted
+    output is most useful to humans, it can often also be used to generate
+    structures that are easy to program against. Compaction enables developers
+    to map any expanded document into an application-specific compacted document.
+    While the context provided above mapped <code>http://xmlns.com/foaf/0.1/name</code>
+    to <code>name</code>, it could have also have been mapped to any other term
+    provided by the developer.</p>
+
+</section>
+
+<section class="informative">
+  <h2>Flattening</h2>
+  <p>While expansion ensures that a document is in a uniform structure, flattening
+    goes a step further and ensures that also the shape of the data is deterministic.
+    In expanded documents properties of a single <tref>node</tref> may still be
+    spread across a number of different <tref title="JSON object">JSON objects</tref>.
+    By flattening a document, all properties of a <tref>node</tref> are collected in a
+    single <tref>JSON object</tref> and all <tref title="blank node">blank nodes</tref>
+    are labeled with a <tref>blank node identifier</tref>. Often this drastically
+    simplifies the code to process JSON-LD data.</p>
+
+  <p>For example, assume the following JSON-LD input document:</p>
+
+  <pre class="example" data-transform="updateExample"
+       title="Sample JSON-LD document">
+  <!--
+  {
+    "@context": {
+      "name": "http://xmlns.com/foaf/0.1/name",
+      "knows": "http://xmlns.com/foaf/0.1/knows"
+    },
+    "@id": "http://me.markus-lanthaler.com/",
+    "name": "Markus Lanthaler",
+    "knows": [
+      {
+        "name": "Manu Sporny",
+        "knows": {
+          "@id": "http://greggkellogg.net/foaf#me"
+        }
+      },
+      {
+        "@id": "http://greggkellogg.net/foaf#me",
+        "name": "Gregg Kellogg"
+      }
+    ]
+  }
+  -->
+  </pre>
+
+  <p>Running the <a href="#flattening-algorithm">Flattening Algorithm</a>
+    with a context set to <tref>null</tref> to prevent compaction returns
+    the following document:</p>
+
+  <pre class="example" data-transform="updateExample"
+       title="Flattened sample document in expanded form">
+  <!--
+  [
+    {
+      "@id": "http://me.markus-lanthaler.com/",
+      "http://xmlns.com/foaf/0.1/name": [
+        { "@value": "Markus Lanthaler" }
+      ],
+      "http://xmlns.com/foaf/0.1/knows": [
+        { "@id": "_:t0" },
+        { "@id": "http://greggkellogg.net/foaf#me" }
+      ]
+    },
+    {
+      "@id": "_:t0",
+      "http://xmlns.com/foaf/0.1/name": [
+        { "@value": "Manu Sporny" }
+      ],
+      "http://xmlns.com/foaf/0.1/knows": [
+        { "@id": "http://greggkellogg.net/foaf#me" }
+      ]
+    },
+    {
+      "@id": "http://greggkellogg.net/foaf#me",
+      "http://xmlns.com/foaf/0.1/name": [
+        { "@value": "Gregg Kellogg" }
+      ]
+    }
+  ]
+  -->
+  </pre>
+
+  <p>Note how in the output above all properties of a <tref>node</tref> are collected in a
+    single <tref>JSON object</tref> and how the <tref>blank node</tref> representing
+    &quot;Manu Sporny&quot; has been assigned the <tref>blank node identifier</tref>
+    <code>_:t0</code>.</p>
+
+  <p>To make it easier for humans to read such a flattened document can be compacted by
+    passing a context. Using the same context as the input document, the flattened
+    and compacted document looks as follows:</p>
+
+  <pre class="example" data-transform="updateExample"
+       title="Flattened and compacted sample document">
+  <!--
+  {
+    "@context": {
+      "name": "http://xmlns.com/foaf/0.1/name",
+      "knows": "http://xmlns.com/foaf/0.1/knows"
+    },
+    "@graph": [
+      {
+        "@id": "http://me.markus-lanthaler.com/",
+        "name": "Markus Lanthaler",
+        "knows": [
+          { "@id": "_:t0" },
+          { "@id": "http://greggkellogg.net/foaf#me" }
+        ]
+      },
+      {
+        "@id": "_:t0",
+        "name": "Manu Sporny",
+        "knows": {
+          "@id": "http://greggkellogg.net/foaf#me"
+        }
+      },
+      {
+        "@id": "http://greggkellogg.net/foaf#me",
+        "name": "Gregg Kellogg"
+      }
+    ]
+  }
+  -->
+  </pre>
+
+  <p>Please note that the flattened and compacted result will explicitly
+    designate the default graph by the <code>@graph</code> member in the top-level
+    <tref>JSON object</tref>, except if its value contains just one item.</p>
+
+</section>
+
+<section class="informative">
+  <h2>RDF Conversion</h2>
+  <p>JSON-LD can be used to serialize data expressed in RDF as described in
+    [[RDF-CONCEPTS]]. This ensures that data can be round-tripped to and from
+    any RDF syntax without any loss in fidelity.</p>
+
+  <p>For example, assume the following RDF input serialized in Turtle [[TURTLE-TR]]:</p>
+
+  <pre class="example" data-transform="updateExample"
+       title="Sample Turtle document">
+  <!--
+  <http://me.markus-lanthaler.com/> <http://xmlns.com/foaf/0.1/name> "Markus Lanthaler" .
+  <http://me.markus-lanthaler.com/> <http://xmlns.com/foaf/0.1/homepage> <http://www.markus-lanthaler.com/> .
+  -->
+  </pre>
+
+  <p>Using the <a href="#convert-from-rdf-algorithm">Convert from RDF Algorithm</a> a
+    developer could transform this document into expanded JSON-LD:</p>
+
+  <pre class="example" data-transform="updateExample"
+       title="Sample Turtle document converted to JSON-LD">
+  <!--
+  [
+    {
+      "@id": "http://me.markus-lanthaler.com/",
+      "http://xmlns.com/foaf/0.1/name": [
+        {
+          "@value": "Markus Lanthaler"
+        }
+      ],
+      "http://xmlns.com/foaf/0.1/homepage": [
+        {
+          "@id": "http://www.markus-lanthaler.com/"
+        }
+      ]
+    }
+  ]
+  -->
+  </pre>
+
+  <p>Note that the output above could easily be compacted using the technique outlined
+    in the previous section. It is also possible to transform the JSON-LD document back
+    to RDF using the <a href="#convert-to-rdf-algorithm">Convert to RDF Algorithm</a>.</p>
+  </section>
+
+</section>
+
+<section>
+  <h1>Conformance</h1>
+
+  <p>All examples and notes as well as sections marked as non-normative in this
+    specification are non-normative. Everything else in this specification is
+    normative.</p>
+
+  <p>The keywords MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, RECOMMENDED,
+    MAY, and OPTIONAL in this specification are to be interpreted as described
+    in [[!RFC2119]].</p>
+
+  <p>There are two classes of products that can claim conformance to this
+    specification: <tref title="JSON-LD Implementation">JSON-LD Implementations</tref>
+    and <tref title="JSON-LD Processor">JSON-LD Processors</tref>.</p>
+
+  <p>A conforming <tdef>JSON-LD Implementation</tdef> is a system capable of transforming
+    JSON-LD documents according the algorithms defined in this specification.</p>
+
+  <p>A conforming <tdef>JSON-LD Processor</tdef> is a conforming <tref>JSON-LD Implementation</tref>
+    that exposes the Application Programming Interface (API) defined in this specification.</p>
+
+  <p>The algorithms in this specification are generally written with more concern for clarity than
+    efficiency. Thus, JSON-LD Implementations and Processors may implement the algorithms
+    given in this specification in any way desired, so long as the end result is indistinguishable
+    from the result that would be obtained by the specification's algorithms.</p>
+
+  <p>This specification does not define how JSON-LD Implementations or Processors handle
+    non-conforming input documents. This implies that JSON-LD Implementations or Processors
+    MUST NOT attempt to correct malformed <tref title="IRI">IRIs</tref> or language tags;
+    however, they MAY issue validation warnings. IRIs are not modified other than converted
+    between <tref title="relative IRI">relative</tref> and
+    <tref title="absolute IRI">absolute IRIs</tref>.</p>
+
+  <p class="note">Implementers can partially check their level of conformance to
+    this specification by successfully passing the test cases of the JSON-LD test
+    suite [[JSON-LD-TESTS]]. Note, however, that passing all the tests in the test
+    suite does not imply complete conformance to this specification. It only implies
+    that the implementation conforms to aspects tested by the test suite.</p>
+</section>
+
+<section>
+  <h1>General Terminology</h1>
+
+  <p>This document uses the following terms as defined in JSON [[!RFC4627]]. Refer
+    to the <em>JSON Grammar</em> section in [[!RFC4627]] for formal definitions.</p>
+
+  <dl>
+    <dt><tdef>JSON object</tdef></dt>
+    <dd>An object structure is represented as a pair of curly brackets
+      surrounding zero or more key-value pairs. A key is a
+      <tref>string</tref>. A single colon comes after each key, separating the
+      key from the value. A single comma separates a value from a following
+      key.</dd>
+    <dt><tdef>array</tdef></dt>
+    <dd>An array structure is represented as square brackets surrounding zero
+      or more values (or elements). Elements are separated by commas.
+      In JSON, an array is an <em>ordered</em> sequence of zero or more values.
+      While JSON-LD uses the same array representation as JSON,
+      the collection is <em>unordered</em> by default. While order is
+      preserved in regular JSON arrays, it is not in regular JSON-LD arrays
+      unless specific markup is provided (see <a href="#sets-and-lists"></a>).</dd>
+    <dt><tdef>string</tdef></dt>
+    <dd>A string is a sequence of zero or more Unicode characters,
+      wrapped in double quotes, using backslash escapes (if necessary). A
+      character is represented as a single character string.</dd>
+    <dt><tdef>number</tdef></dt>
+    <dd>A number is similar to that used in most programming languages, except
+      that the octal and hexadecimal formats are not used and that leading
+      zeros are not allowed.</dd>
+    <dt><tdef>true</tdef> and <tdef>false</tdef></dt>
+    <dd>Values that are used to express one of two possible boolean states.</dd>
+    <dt><tdef>null</tdef></dt>
+    <dd>The <tref>null</tref> value. A key-value pair in the
+      <code>@context</code> where the value, or the <code>@id</code> of the
+      value, is <tref>null</tref> explicitly decouples a term's association
+      with an IRI. A key-value pair in the body of a JSON-LD document whose
+      value is <tref>null</tref> has the same meaning as if the key-value pair
+      was not defined. If <code>@value</code>, <code>@list</code>, or
+      <code>@set</code> is set to <tref>null</tref> in expanded form, then
+      the entire <tref>JSON object</tref> is ignored.</dd>
+  </dl>
+
+  <p>Furthermore, the following terminology is used throughout this document:</p>
+
+  <dl>
+    <dt><tdef>keyword</tdef></dt>
+    <dd>A JSON key that is specific to JSON-LD, specified in the JSON-LD Syntax specification [[!JSON-LD]]
+      in the section titled <cite><a href="../json-ld-syntax/#syntax-tokens-and-keywords">Syntax Tokens and Keywords</a></cite>.</dd>
+    <dt><tdef>context</tdef></dt>
+    <dd>A a set of rules for interpreting a JSON-LD document as specified in
+      <cite><a href="../json-ld-syntax/#the-context">The Context</a></cite> of the [[JSON-LD]] specification.</dd>
+    <dt><tdef>JSON-LD document</tdef></dt>
+    <dd>A <tref>JSON-LD document</tref> is a serialization of a collection of
+      <tref title="JSON-LD graph">JSON-LD graphs</tref> and comprises exactly one
+      <tref>default graph</tref> and zero or more <tref title="named graph">named graphs</tref>.</dd>
+    <dt><tdef>named graph</tdef></dt>
+    <dd>A named graph is a pair consisting of an <tref>IRI</tref> or <tref>blank node</tref>
+      (the <tdef>graph name</tdef>) and a <tref>JSON-LD graph</tref>.</dd>
+    <dt><tdef>default graph</tdef></dt>
+    <dd>The default graph is the only graph in a JSON-LD document which has no <tref>graph name</tref>.</dd>
+    <dt><tdef>JSON-LD graph</tdef></dt>
+    <dd>A labeled directed graph, i.e., a set of <tref title="node">nodes</tref> connected by <tref title="edge">edges</tref>,
+      as specified in the <cite><a href="../json-ld-syntax/#data-model">Data Model</a></cite> section of the JSON-LD syntax
+      specification [[!JSON-LD]].</dd>
+    <dt><tdef>edge</tdef></dt>
+    <dd>Every <tref>edge</tref> has a direction associated with it and is labeled with
+      an <tref>IRI</tref> or a <tref>blank node identifier</tref>. Within the JSON-LD syntax
+      these edge labels are called <tdef title="property">properties</tdef>. Whenever possible, an
+      <tref>edge</tref> SHOULD be labeled with an <tref>IRI</tref>.</dd>
+    <dt><tdef>node</tdef></dt>
+    <dd>Every <tref>node</tref> is an <tref>IRI</tref>, a <tref>blank node</tref>,
+      a <tref>JSON-LD value</tref>, or a <tref>list</tref>.</dd>
+    <dt><tdef><abbr title="Internationalized Resource Identifier">IRI</abbr></tdef></dt>
+    <dd>An <tref>IRI</tref> (Internationalized Resource Identifier) is a string that conforms to the syntax
+      defined in [[RFC3987]].</dd>
+    <dt><tdef>absolute IRI</tdef></dt>
+    <dd>An absolute IRI is defined in [[!RFC3987]] containing a <em>scheme</em> along with a <em>path</em> and
+      optional <em>query</em> and fragment segments.</dd>
+    <dt><tdef>relative IRI</tdef></dt>
+    <dd>A relative IRI is an IRI that is relative some other <tref>absolute IRI</tref>;
+      in the case of JSON-LD this is the base location of the document.</dd>
+    <dt><tdef>blank node</tdef></dt>
+    <dd>A <tref>node</tref> in a <tref>JSON-LD graph</tref> that does not contain a de-referenceable
+      identifier because it is either ephemeral in nature or does not contain information that needs to be
+      linked to from outside of the JSON-LD graph.</dd>
+    <dt><tdef>blank node identifier</tdef></dt>
+    <dd>A blank node identifier is a string that can be used as an identifier for a <tref>blank node</tref> within
+      the scope of a JSON-LD document. Blank node identifiers begin with <code>_:</code>.</dd>
+    <dt><tdef>JSON-LD value</tdef></dt>
+    <dd>A <tref>JSON-LD value</tref> is a <tref>string</tref>, a <tref>number</tref>,
+      <tref>true</tref> or <tref>false</tref>, a <tref>typed value</tref>, or a
+      <tref>language-tagged string</tref>.</dd>
+    <dt><tdef>typed value</tdef></dt>
+    <dd>A <tref>typed value</tref> consists of a value, which is a string, and a type, which is an <tref>IRI</tref>.</dd>
+    <dt><tdef>language-tagged string</tdef></dt>
+    <dd>A <tref>language-tagged string</tref> consists of a string and a non-empty language
+      tag as defined by [[BCP47]]. The language tag must be well-formed according to section
+      <a href="http://tools.ietf.org/html/bcp47#section-2.2.9">2.2.9</a> of [[BCP47]], and MUST
+      be normalized to lowercase.</dd>
+    <dt><tdef>list</tdef></dt>
+    <dd>A <tref>list</tref> is an ordered sequence of <tref title="IRI">IRIs</tref>,
+      <tref title="blank node">blank nodes</tref>, and
+      <tref title="JSON-LD value">JSON-LD values</tref>.</dd>
+  </dl>
+
+</section>
+
+<section>
+<h1>Algorithms</h1>
+
+<p>All algorithms described in this section are intended to operate on
+  language-native data structures. That is, the serialization to a text-based
+  JSON document isn't required as input or output to any of these algorithms and
+  language-native data structures MUST be used where applicable.</p>
+
+<section>
+  <h2>Algorithm Terms</h2>
+
+  <dl>
+    <dt><tdef>active graph</tdef></dt>
+    <dd>The name of the currently active graph that the processor should use when
+      processing.</dd>
+    <dt><tdef>active subject</tdef></dt>
+    <dd>The currently active subject that the processor should use when
+      processing.</dd>
+    <dt><tdef>active property</tdef></dt>
+    <dd>The currently active property that the processor should use when
+      processing. The active property is represented in the original lexical form, which
+      is used for finding type mappings in the <tref>active context</tref>.</dd>
+    <dt><tdef>active object</tdef></dt>
+    <dd>The currently active object that the processor should use when
+      processing.</dd>
+    <dt><tdef>active context</tdef></dt>
+    <dd>A context that is used to resolve <tref title="term">terms</tref> while
+      the processing algorithm is running.</dd>
+    <dt><tdef>local context</tdef></dt>
+    <dd>A context that is specified within a <tref>JSON object</tref>,
+      specified via the <code>@context</code> <tref>keyword</tref>.</dd>
+    <dt><tdef>processor state</tdef></dt>
+    <dd>The <tref>processor state</tref>, which includes the <tref>active
+      context</tref>, <tref>active subject</tref>, and
+      <tref>active property</tref>. The <tref>processor state</tref> is managed
+      as a stack with elements from the previous <tref>processor state</tref>
+      copied into a new <tref>processor state</tref> when entering a new
+      <tref>JSON object</tref>.</dd>
+    <dt><tdef>JSON-LD input</tdef></dt>
+    <dd>The JSON-LD data structure that is provided as input to the algorithm.</dd>
+    <dt><tdef>JSON-LD output</tdef></dt>
+    <dd>The JSON-LD data structure that is produced as output by the algorithm.</dd>
+    <dt><tdef>term</tdef></dt>
+    <dd>A <tref>term</tref> is a short word defined in a context that MAY be expanded to an <tref>IRI</tref></dd>
+    <dt><tdef>compact IRI</tdef></dt>
+    <dd>A compact IRI is has the form of <tdef>prefix</tdef>:<em>suffix</em> and is used as a way
+      of expressing an IRI without needing to define separate <tref>term</tref> definitions for
+      each IRI contained within a common vocabulary identified by <tref>prefix</tref>.</dd>
+    <dt><tdef>node object</tdef></dt>
+    <dd>A <tref>node object</tref> represents zero or more properties of a
+      <tref>node</tref> in the <tref>JSON-LD graph</tref> serialized by the
+      JSON-LD document. A <tref>JSON object</tref> is a <tref>node object</tref>
+      if it exists outside of the JSON-LD <tref>context</tref> and:
+      <ul>
+        <li>it does not contain the <code>@value</code>, <code>@list</code>,
+          or <code>@set</code> keywords, or</li>
+        <li>it is not the top-level <tref>JSON object</tref> in the JSON-LD document containing
+          the <code>@graph</code> keyword.</li>
+      </ul>
+    </dd>
+    <dt><tdef>list object</tdef></dt>
+    <dd>A <tref>list object</tref> is a <tref>JSON object</tref> that has an <code>@list</code>
+      member.</dd>
+    <dt><tdef>scalar</tdef></dt>
+    <dd>A scalar is either a JSON <tref>string</tref>, <tref>number</tref>, <tref>true</tref>,
+      or <tref>false</tref>.</dd>
+    <dt><tdef>quad</tdef></dt>
+    <dd>An <em>RDF triple</em> as specified by [[RDF-CONCEPTS]] augmented with
+      a fourth component, a <tref>graph name</tref>.</dd>
+  </dl>
+</section>
+
+<section>
+  <h2>Expansion Algorithm</h2>
+
+  <p>The algorithm takes three input variables: an <tref>active context</tref>,
+    an <tref>active property</tref>, and an <em>element</em> to be expanded. To
+    begin, the <tref>active context</tref> is set to the result of performing, <a
+    href="#context-processing">Context Processing</a> on the passed
+    <code class="idlMemberName"><a href="#widl-JsonLdOptions-expandContext">expandContext</a></code>,
+    or empty if <code class="idlMemberName"><a href="#widl-JsonLdOptions-expandContext">expandContext</a></code>
+    is <tref>null</tref>, <tref>active property</tref> is set to <tref>null</tref>, and
+    <em>element</em> is set to the <tref>JSON-LD input</tref>. This algorithm expects the
+    <tref>JSON-LD input</tref> to be a well-formed JSON-LD document as defined in [[!JSON-LD]].</p>
+
+  <ol class="algorithm">
+    <li>If <em>element</em> is a <tref>scalar</tref>, expand it according to the
+      <a href="#value-expansion">Value Expansion</a> algorithm, passing copies of the
+      <tref>active context</tref> and <tref>active property</tref> and return. If the
+      <tref>active property</tref> equals <tref>null</tref> or <code>@graph</code>
+      set <em>element</em> to <tref>null</tref> instead and return.</li>
+    <li>If <em>element</em> is <tref>null</tref>, return.</li>
+    <li>If <em>element</em> is an <tref>array</tref>,
+      <ol class="algorithm">
+        <li>initialize an empty array <em>result</em>.</li>
+        <li>Expand each <em>item</em> by recursively using this algorithm, passing copies of
+          the <tref>active context</tref> and <tref>active property</tref>.</li>
+        <li>If the <tref title="active property">active property's</tref>
+          <tref>container mapping</tref> is set to <code>@list</code> and the expanded
+          <em>item</em> is an <tref>array</tref> or a <tref>list object</tref> trigger
+          a <code class="error">list of lists detected</code> error.</li>
+        <li>If the expanded <em>item</em> is <tref>null</tref>, drop it.</li>
+        <li>Otherwise, if the expanded <em>item</em> is an <tref>array</tref>, merge its
+          entries with <em>result's</em> entries.</li>
+        <li>Otherwise, append <em>item</em> to <em>result</em>.</li>
+        <li>Finally, set <em>element</em> to <em>result</em> and return.</li>
+      </ol>
+    </li>
+    <li>Otherwise, <em>element</em> must be an object.
+      <ol class="algorithm">
+        <li>If <em>element</em> has a <code>@context</code> member, update the
+          <tref>active context</tref> according to the steps outlined in
+          <a href="#context-processing">Context Processing</a> and remove the
+          <code>@context</code> member.</li>
+        <li>Initialize an empty <tref>JSON object</tref> <em>result</em> and</li>
+        <li>then process each <em>property</em> and <em>value</em> in <em>element</em>
+          ordered by <em>property</em> as follows:
+          <ol class="algorithm">
+            <li>If the <tref>active context</tref> contains a <tref>property generator</tref> for
+               <em>property</em> set <em>expanded property</em> to its <tref title="IRI">IRIs</tref>,
+               otherwise set it to the result of expanding <em>property</em> according to the steps
+               outlined in <a href="#iri-expansion">IRI Expansion</a> (passing <code>true</code> for
+               the <em>vocabRelative</em> flag).</li>
+            <li>If <em>expanded property</em> is a <tref>keyword</tref>, process it as
+              follows:
+              <ol class="algorithm">
+                <li>If <em>expanded property</em> equals <code>@id</code>, set the <code>@id</code>
+                  member of <em>result</em> to the result of expanding <em>value</em>
+                  according the <a href="#iri-expansion">IRI Expansion algorithm</a> (passing <code>true</code>
+                  for the <em>documentRelative</em> flag). If <em>value</em> is not a <tref>string</tref>
+                  trigger an <code class="error">invalid @id value</code> error.</li>
+                <li>If <em>expanded property</em> equals <code>@type</code>, set the <code>@type</code>
+                  member of <em>result</em> to the result of expanding <em>value</em>
+                  according the <a href="#iri-expansion">IRI Expansion algorithm</a> (passing <code>true</code>
+                  for both the <em>documentRelative</em> and the <em>vocabRelative</em> flag). If <em>value</em>
+                  is neither a <tref>string</tref> nor an <tref>array</tref> of
+                  <tref title="string">strings</tref> trigger an <code class="error">invalid type value</code>
+                  error. Empty <tref title="array">arrays</tref> are ignored.</li>
+                <li>If <em>expanded property</em> equals <code>@value</code>, set the <code>@value</code>
+                  member of <em>result</em> to <em>value</em>. If <em>value</em> is neither a <tref>scalar</tref>
+                  nor <tref>null</tref> trigger an <code class="error">invalid value object value</code> error.</li>
+                <li>If <em>expanded property</em> equals <code>@language</code>, set the <code>@language</code>
+                  member of <em>result</em> to the lowercased <em>value</em>. If <em>value</em> is not
+                  a <tref>string</tref>, trigger an <code class="error">invalid language value</code> error.</li>
+                <li>If <em>expanded property</em> equals <code>@index</code>, set the <code>@index</code>
+                  member of <em>result</em> to <em>value</em>. If <em>value</em> is not a <tref>string</tref>
+                  trigger an <code class="error">invalid @index value</code> error.</li>
+                <li>If <em>expanded property</em> equals <code>@set</code> set the <em>expanded property</em>
+                  member of <em>result</em> to the result of expanding <em>value</em> by
+                  recursively using this algorithm, passing copies of the <tref>active context</tref> and
+                  <tref>active property</tref>.</li>
+                <li>If <em>expanded property</em> equals <code>@list</code>, set the <em>expanded property</em>
+                  member of <em>result</em> to the result of expanding <em>value</em> by
+                  recursively using this algorithm, passing copies of the <tref>active context</tref> and
+                  <tref>active property</tref>; if <tref>active property</tref> equals <tref>null</tref> or
+                  <code>@graph</code>, pass <code>@list</code> as <tref>active property</tref> instead.</li>
+                <li>If <em>expanded property</em> equals <code>@graph</code>, set the <code>@graph</code>
+                  member of <em>result</em> to the result of expanding <em>value</em> by
+                  recursively using this algorithm, passing copies of the <tref>active context</tref> and
+                  <code>@graph</code> as <tref>active property</tref>.</li>
+                <li>Continue with the next <em>property</em>-<em>value</em> pair from <em>element</em>.</li>
+              </ol>
+            </li>
+            <li>If <em>expanded property</em> is neither a <tref>blank node identifier</tref> nor an
+              <tref>absolute IRI</tref>,i.e., it is <tref>null</tref> or does not contain a colon
+              (<code>:</code>), continue with the next member from <em>element</em>.</li>
+            <li>Otherwise, if <em>property's</em> <tref>container mapping</tref> is set to
+              <code>@language</code>
+              <ol class="algorithm">
+                <li>Initialize a new empty <tref>array</tref> <em>language map values</em>.</li>
+                <li>Process each <em>key</em>-<em>val</em> pair of <em>value</em> ordered by
+                  <em>key</em> as follows:
+                  <ol class="algorithm">
+                    <li>If <em>val</em> is not an array, transform it to one.</li>
+                    <li>For each item of <em>val</em>, construct a new <tref>JSON object</tref>
+                      consisting of two members: <code>@value</code> set to the currently
+                      processed item and <code>@language</code> set to the lowercased <em>key</em>.
+                      If <em>val</em> is not a <tref>string</tref>, trigger a
+                      <code class="error">language map invalid value</code> error. Otherwise append
+                      the object to <em>language map values</em>.</li>
+                  </ol>
+                </li>
+                <li>Set <em>value</em> to <em>language map values</em>.</li>
+              </ol>
+            </li>
+            <li>Otherwise, if <em>property's</em> <tref>container mapping</tref> is set to
+              <code>@index</code>
+              <ol class="algorithm">
+                <li>Initialize a new empty <tref>array</tref> <em>index map values</em>.</li>
+                <li>Process each <em>key</em>-<em>val</em> pair of <em>value</em> ordered by
+                  <em>key</em> as follows:
+                  <ol class="algorithm">
+                    <li>If <em>val</em> is not an array, transform it to one.</li>
+                    <li>Expand <em>val</em> by recursively using this algorithm, passing copies of
+                      the <tref>active context</tref> and <em>property</em> as
+                      <tref>active property</tref>.</li>
+                    <li>Add to each item of <em>val</em> a member <code>@index</code> set to
+                      <em>key</em> if no such member exists yet and append the resulting
+                      <tref>JSON object</tref> to <em>index map values</em>.</li>
+                  </ol>
+                </li>
+                <li>Set <em>value</em> to <em>index map values</em>.</li>
+              </ol>
+            </li>
+            <li>Otherwise, expand <em>value</em> by recursively using this algorithm, passing
+              copies of the <tref>active context</tref> and <em>property</em> as
+              <tref>active property</tref>.</li>
+            <li>If the expanded <em>value</em> equals <tref>null</tref>, continue with the next
+              <em>property</em>-<em>value</em> pair from <em>element</em>.</li>
+            <li>If <em>property's</em> <tref>container mapping</tref> is set to <code>@list</code> and
+              <em>value</em> is either not an <tref>JSON object</tref> or a <tref>JSON object</tref>
+              without an <code>@list</code> member, replace <em>value</em> with a
+              <tref>JSON object</tref> with an <code>@list</code> member whose value is set to
+              <em>value</em> (wrapped in an <tref>array</tref> if it is not already one).</li>
+            <li>If <em>expanded property</em> is an <tref>array</tref>,
+              <ol class="algorithm">
+                <li>label all <tref title="blank node">blank nodes</tref> in <em>value</em> with
+                  <tref title="blank node identifier">blank node identifiers</tref> by using the
+                  <a href="#label-blank-nodes-algorithm">Label Blank Nodes Algorithm</a>.</li>
+                <li>Then, for each <em>iri</em> of <em>expanded property</em> merge a copy
+                  of <em>value</em> into the <em>iri</em> member of the <em>result</em>
+                  <tref>JSON object</tref>.</li>
+              </ol>
+            </li>
+            <li>Otherwise, merge <em>value</em> into the <em>iri</em> member of the <em>result</em>
+              <tref>JSON object</tref>.</li>
+          </ol>
+        </li>
+        <li>Set <em>element</em> to <em>result</em> and <em>numProperties</em> to the number of members
+          of <em>result</em>.</li>
+        <li>If <em>element</em> has an <code>@index</code> member, decrease <em>numProperties</em>
+          by 1.</li>
+        <li>If the <tref>active property</tref> equals <tref>null</tref> or <code>@graph</code> and
+          <em>element</em> has an <code>@value</code> member, <em>numProperties</em> equals <code>0</code>,
+          or <em>element</em> consists of only an <code>@id</code> member, set <em>element</em> to
+          <tref>null</tref> and return.</li>
+        <li>If <em>element</em> has an <code>@value</code> member,
+          <ol class="algorithm">
+            <li>decrease <em>numProperties</em> by 1.</li>
+            <li>If <em>element</em> has an <code>@language</code> member, decrease <em>numProperties</em>
+              by 1 and check that the value of the <code>@value</code> member is a string. If not,
+              trigger an <code class="error">invalid language tagged string</code> error.</li>
+            <li>Otherwise, if <em>element</em> has an <code>@type</code> member, decrease
+              <em>numProperties</em> by 1 and check that the value of the <code>@type</code> member is a
+              string. If not, trigger an <code class="error">invalid typed value</code> error.</li>
+            <li>If <em>numProperties</em> is greater than 0, trigger an
+              <code class="error">invalid value object</code> error.</li>
+            <li>If the value of the <code>@value</code> member equals <tref>null</tref>, set
+              <em>element</em> to <tref>null</tref>.</li>
+            <li>Return.</li>
+          </ol>
+        </li>
+        <li>If <em>element</em> has an <code>@type</code> member whose value is not an <tref>array</tref>,
+          transform it to an <tref>array</tref>.</li>
+        <li>If <em>element</em> has an <code>@list</code> or <code>@set</code> member and
+          <em>numProperties</em> is greater than 1, trigger an
+          <code class="error">invalid set or list object</code> error.</li>
+        <li>Otherwise, if <em>element</em> has an <code>@set</code> member, set <em>element</em> to
+          the value of that member.</li>
+        <li>Otherwise, if <em>element</em> has just an <code>@language</code> member, set <em>element</em>
+          to null.</li>
+      </ol>
+    </li>
+  </ol>
+
+  <p>If, after the algorithm outlined above is run, the resulting <em>element</em> is an
+    <tref>JSON object</tref> with just a <code>@graph</code> member, <em>element</em> is set to
+    the value of <code>@graph</code>'s value. Finally, if <em>element</em> is a <tref>JSON object</tref>,
+    it is wrapped into an <tref>array</tref>, if <em>element</em> equals <tref>null</tref>, an empty
+    <tref>array</tref> is returned.</p>
+</section>
+
+<section>
+  <h2 id="context">Context Processing</h2>
+
+  <p>Processing of JSON-LD data structure is managed recursively. During processing, each
+    rule is applied using information provided by the <tref>active context</tref>.</p>
+
+  <p>The <tref>active context</tref> contains the active <tdef title="term definition">term definitions</tdef>
+    which specify how properties and values have to be interpreted as well as the current
+    <tdef>vocabulary mapping</tdef> and the <tdef>default language</tdef>. Each <tref>term definition</tref> consists
+    of an <tdef>IRI mapping</tdef> and optionally a <tdef>type mapping</tdef> from terms to datatypes or
+    <tdef>language mapping</tdef> from terms to language codes, and a <tdef>container mapping</tdef>. If an
+    <tref>IRI mapping</tref> maps a term to multiple <tref="IRI">IRIs</tref> it is said to be a
+    <tdef>property generator</tdef>.</p>
+
+  <p>If a <tref>local context</tref> is encountered, information from the <tref>local context</tref>
+    is merged into the <tref>active context</tref>. A <tref>local context</tref> is identified within
+    a <tref>JSON object</tref> having a <code>@context</code> member with a <tref>string</tref>,
+    <tref>array</tref> or a <tref>JSON object</tref> value.</p>
+
+  <p>This algorithm specifies how the <tref>active context</tref> is updated with a
+    <tref>local context</tref>. The algorithm takes three input variables: an <tref>active context</tref>,
+    a <tref>local context</tref>, and an array of already included remote contexts <em>remoteContexts</em>. To
+    begin, <em>remoteContexts</em> is initialized to an empty array.</p>
+
+  <p>All calls of the <a href="#iri-expansion">IRI Expansion algorithm</a> pass the value specified in the
+    algorithm along with the <tref>active context</tref>, the currently being processed <tref>local context</tref>,
+    and <code>true</code> for the <em>vocabRelative</em> flag.</p>
+
+  <ol class="algorithm">
+    <li>If the <tref>local context</tref> is not an array, transform it to one.</li>
+    <li>Process each item <em>context</em> of the <tref>local context</tref> as follows:
+      <ol class="algorithm">
+        <li>If <em>context</em> equals <tref>null</tref>, reset the <tref>active context</tref>
+          and continue with the next item.</li>
+        <li>If <em>context</em> is a <tref>string</tref>:
+          <ol class="algorithm">
+            <li>Expand <em>context</em> according to <a href="#iri-expansion">IRI Expansion</a>.</li>
+            <li>If <em>context</em> is in the <em>remoteContexts</em> array, raise an
+              <code class="error">recursive context inclusion</code> error. Otherwise, add
+              <em>context</em> to <em>remoteContexts</em>.</li>
+            <li>Dereference <em>context</em>.</li>
+            <li>If the resulting document is a JSON document consisting of a top-level
+              <tref>JSON object</tref> that has a <code>@context</code> member recursively invoke
+              this algorithm passing a copy of <tref>active context</tref>, the value of the
+              <code>@context</code> member as <tref>local context</tref>, and a copy of
+                the <em>remoteContexts</em> array. <tref title="relative IRI">Relative IRIs</tref>
+                are expanded using the remote context's IRI. Otherwise raise an
+                <code class="error">invalid remote context</code> error.</li>
+            <li>Continue with the next item from <em>context</em>.</li>
+          </ol>
+        </li>
+        <li>If <em>context</em> is not a <tref>JSON object</tref>, raise an
+          <code class="error">invalid local context</code> error.</li>
+        <li>Otherwise, if <em>context</em> is an <tref>JSON object</tref>, perform the following steps:
+          <ol class="algorithm">
+            <li>If <em>context</em> has a <code>@vocab</code> member: if its value is neither
+              an <tref>absolute IRI</tref>, i.e., it does not contain a colon (<code>:</code>),
+              nor <tref>null</tref>, trigger an <code class="error">invalid vocab mapping</code>
+              error; otherwise set the <tref title="active context">active context's</tref>
+              <tref>vocabulary mapping</tref> to its value and remove the <code>@vocab</code>
+              member from <em>context</em>.</li>
+            <li>If <em>context</em> has a <code>@language</code> member: if its value is neither
+              a <tref>string</tref> nor <tref>null</tref>, trigger an
+              <code class="error">invalid default language</code> error; otherwise set the
+              <tref title="active context">active context's</tref> <tref>default language</tref> to
+              its value and remove the <code>@language</code> member from <em>context</em>.</li>
+            <li>For each other <em>key</em>-<em>value</em> pair in <em>context</em> perform the
+              following steps:
+              <ol class="algorithm">
+                <li>Remove the <em>key</em>-<em>value</em> pair from <em>context</em>.</li>
+                <li>If <em>key</em> is a JSON-LD <tref>keyword</tref>, raise a
+                  <code class="error">keyword redefinition</code> error.</li>
+                <li>If <em>value</em> equals <tref>null</tref>, replace the <tref>term definition</tref>
+                  for <em>key</em> in the <tref>active context</tref> with an <tref>IRI mapping</tref>
+                  set to <tref>null</tref> and continue with the next <em>key</em>-<em>value</em> pair.</li>
+                <li>If <em>value</em> is a <tref>string</tref>, expand it according to the
+                  <a href="#iri-expansion">IRI Expansion algorithm</a> and replace the
+                  <tref>term definition</tref> for <em>key</em> in the <tref>active context</tref> with
+                  an <tref>IRI mapping</tref> set to the expanded <em>value</em>. Continue with
+                  the next <em>key</em>-<em>value</em> pair.</li>
+                <li>If <em>value</em> is not a <tref>JSON object</tref>, trigger an
+                  <code class="error">invalid term definition</code> error</li>
+                <li>If <tref>term definition</tref> for <em>key</em> exists in the
+                  <tref>active context</tref>, remove it.</li>
+                <li>Initialize a new, empty <tref>term definition</tref> <em>definition</em>.</li>
+                <li>If <em>value</em> has an <code>@id</code> member with a value <em>val</em>:
+                  <ol class="algorithm">
+                    <li>if <em>val</em> is an <tref>array</tref>,:
+                      <ol class="algorithm">
+                        <li>expand each <em>item</em> in the array according the
+                          <a href="#iri-expansion">IRI Expansion algorithm</a> if it is a
+                          <tref>string</tref>. If am <em>item</em> is not a <tref>string</tref>,
+                          raise an <code class="error">invalid property generator</code> error; if
+                          <em>item</em> does not expand to an <tref>absolute IRI</tref> or
+                          <tref>blank node identifier</tref>, i.e., it does not contain a colon
+                          (<code>:</code>) after expansion, raise an
+                          <code class="error">invalid property generator IRI mapping</code> error.</li>
+                        <li>Lexicographically sort <em>val</em> and set the <tref>IRI mapping</tref>
+                          of <em>definition</em> to <em>val</em>.</li>
+                      </ol>
+                    <li>Otherwise, expand <em>val</em> according the
+                      <a href="#iri-expansion">IRI Expansion algorithm</a> and set the
+                      <tref>IRI mapping</tref> of <em>definition</em> to <em>val</em>.</li>
+                  </ol>
+                </li>
+                <li>Otherwise, set the <tref>IRI mapping</tref> of <em>definition</em> to the result of
+                  expanding <em>key</em> according the <a href="#iri-expansion">IRI Expansion algorithm</a>.</li>
+                <li>If the <tref>IRI mapping</tref> of <em>definition</em> is set to <tref>null</tref> or a
+                  <tref>keyword</tref>, store <em>definition</em> as the <tref>term definition</tref>
+                  for <em>key</em> in the <tref>active context</tref> and continue with the next
+                  <em>key</em>-<em>value</em> pair from <em>context</em>.</li>
+                <li>Otherwise, if the <tref>IRI mapping</tref> of <em>definition</em> is set to
+                  a <tref>string</tref> which does not contain a colon (<code>:</code>), i.e., it is
+                  neither an <tref>absolute IRI</tref> nor a <tref>blank node identifier</tref>,
+                  raise an <code class="error">invalid term IRI mapping</code> error.</li>
+                <li>If <em>value</em> has an <code>@type</code> member with a value <em>val</em> and <em>val</em>
+                  is not a <tref>string</tref> or does not expand to an <tref>absolute IRI</tref> using the
+                  <a href="#iri-expansion">IRI Expansion algorithm</a>, raise an
+                  <code class="error">invalid type mapping</code> error. Otherwise set the
+                  <tref>IRI mapping</tref> of <em>definition</em> to the expanded <em>val</em>.</li>
+                <li>Otherwise, if <em>value</em> has an <code>@language</code> member with a value <em>val</em>
+                  that is a <tref>string</tref> or <tref>null</tref>, set the <tref>language mapping</tref> of
+                  <em>definition</em> to the lowercased <em>val</em>. If <em>val</em> is neither a
+                  <tref>string</tref> nor <tref>null</tref>, raise an
+                  <code class="error">invalid language mapping</code> error.</li>
+                <li>If <em>value</em> has an <code>@container</code> member with a value <em>val</em> that
+                  equals <code>@list</code>, <code>@set</code>, <code>@language</code>, or <code>@index</code>,
+                  set the <tref>container mapping</tref> of <em>definition</em> to <em>val</em>.
+                  If <em>val</em> is not one of those values, raise an
+                  <code class="error">invalid container mapping</code> error.</li>
+              </ol>
+            </li>
+          </ol>
+        </li>
+      </ol>
+    </li>
+  </ol>
+</section>
+
+<section>
+  <h2>IRI Expansion</h2>
+
+  <p>In JSON-LD documents keys and some values are evaluated to produce an <tref>IRI</tref>.
+    This section defines an algorithm for transforming strings representing an IRI into an
+    <tref>absolute IRI</tref>. If IRI expansion occurs during context processing, the
+    <tref>local context</tref> that is being processed is passed to this algorithm.
+    After application of this algorithm, values processed by this algorithm are said to be
+    in <tdef>expanded IRI form</tdef>, although this may also include
+    <tref title="blank node identifier">blank node identifiers</tref> and
+    JSON-LD <tref title="keyword">keywords</tref>.</p>
+
+  <p>The algorithm takes two mandatory and four optional input variables: a <em>value</em>
+    to be expanded, an <tref>active context</tref>, two flags <em>documentRelative</em> and
+    <em>vocabRelative</em> specifying whether <em>value</em> should be interpreted as
+    <tref>relative IRI</tref> against the document's base IRI or the
+    <tref title="active context">active context's</tref> <tref>vocabulary mapping</tref>,
+    along with an <tref>local context</tref> passed when this algorithm is used in
+    <a href="#context-processing">Context Processing</a>, and finally an array
+    <em>path</em> which is used to detect cyclic <tref title="IRI mapping">IRI mappings</tref>.
+    If not passed, the two flags are set to <code>false</code> and <em>path</em> is
+    initialized to an empty <tref>array</tref> by default.</p>
+
+  <p>The algorithm for generating an IRI is:</p>
+
+  <ol class="algorithm">
+    <li>If <em>value</em> is <tref>null</tref> or a JSON-LD <tref>keyword</tref>, return
+      <em>value</em> as is.</li>
+    <li>If a <tref>local context</tref> has been passed
+      <ol class="algorithm">
+        <li>and <em>value</em> is in the <em>path</em> array, raise a
+          <code class="error">cyclic IRI mapping</code> error. Otherwise append <em>value</em>
+          to <em>path</em>.</li>
+        <li>If <tref>local context</tref> contains an <tref>IRI mapping</tref> for <em>value</em>
+          that is not a <tref>property generator</tref> return the result of recursively calling
+          this algorithm passing the <tref>IRI</tref> of the <tref>IRI mapping</tref> as new
+          <em>value</em>, the <tref>active context</tref> and <tref>local context</tref>,
+          <em>path</em>, and <code>true</code> for the <em>vocabRelative</em> flag. If the result
+          is a <tref>property generator</tref>, raise an
+          <code class="error">property generator in term definition</code> error.</li>
+      </ol>
+    </li>
+    <li>If the <em>vocabRelative</em> flag is set to <code>true</code> and an <tref>IRI mapping</tref>
+      exists for <em>value</em> in the <tref>active context</tref> that is not a
+      <tref>property generator</tref>, return the value of the <tref>IRI mapping</tref>.</li>
+    <li>If <em>value</em> contains a colon (<code>:</code>), perform the following steps:
+      <ol class="algorithm">
+        <li>Split <em>value</em> into a <em>prefix</em> and <em>suffix</em> at the first occurrence of
+          a colon (<code>:</code>).</li>
+        <li>If <em>suffix</em> begins with <code>//</code> or <em>prefix</em> equals <code>_</code>,
+          return <em>value</em> as is.</li>
+        <li>If a <tref>local context</tref> has been passed, expand <em>prefix</em> by recursively
+          invoking this algorithm passing <em>prefix</em> as <em>value</em>, the <tref>active context</tref>
+          and <tref>local context</tref>, <em>path</em>, and <code>true</code> for the
+          <em>vocabRelative</em> flag. If the expanded <em>prefix</em> contains a colon (<code>:</code>)
+          generate and return an <tref>IRI</tref> by prepending the expanded <em>prefix</em> to the
+          (possibly empty) <em>suffix</em> using textual concatenation.</li>
+        <li>Otherwise, if the <tref>active context</tref> contains an <tref>IRI mapping</tref> for
+          <em>prefix</em> that is not a <tref>property generator</tref>, generate and return an
+          <tref>IRI</tref> by prepending the <tref>IRI</tref> mapped to <em>prefix</em> to the
+          (possibly empty) <em>suffix</em> using textual concatenation.</li>
+      </ol>
+    </li>
+    <li>Otherwise, if the <em>vocabRelative</em> flag is set to <code>true</code> and the
+      <tref>active context</tref> contains a <tref>vocabulary mapping</tref>, generate and return an
+      <tref>IRI</tref> by prepending the <tref>IRI</tref> of the <tref>vocabulary mapping</tref>
+      to the <em>value</em> using textual concatenation.</li>
+    <li>Otherwise, if the <em>documentRelative</em> flag is set to <code>true</code>, resolve <em>value</em>
+      against the base IRI as per [[!RFC3986]] and return the resulting <tref>IRI</tref>. Only the basic
+      algorithm in section&nbsp;5.2 of [[!RFC3986]] is used; neither <em>Syntax-Based Normalization</em>
+      nor <em>Scheme-Based Normalization</em> (as described in sections&nbsp;6.2.2 and&nbsp;6.2.3 of [[!RFC3986]])
+      are performed. Characters additionally allowed in IRI references are treated in the same way that
+      unreserved characters are treated in URI references, per section&nbsp;6.5 of [[!RFC3987]]</li>
+    <li>Otherwise return <em>value</em> as is.</li>
+  </ol>
+
+  <p>If the result of the algorithm above is a <tref>blank node identifier</tref>, i.e., a string that begins with
+    <code>_:</code>, and no <tref>local context</tref> has been passed,
+    <a href="#generate-blank-node-identifier">generated a new blank node identifier</a> before returning the
+    final result.</p>
+</section>
+
+<section>
+  <h2>Value Expansion</h2>
+
+  <p>Some values in JSON-LD can be expressed in a <tref>compacted form</tref>. These values
+    are required to be expanded at times when processing JSON-LD documents.
+    A value is said to be in <tdef>expanded form</tdef> after
+    the application of this algorithm.</p>
+
+  <p>The algorithm for expanding a <em>value</em> takes an <tref>active property</tref>
+    and <tref>active context</tref>. It is implemented as follows:</p>
+
+  <ol class="algorithm">
+    <li>If <em>value</em> is <tref>null</tref>, return <tref>null</tref>.</li>
+    <li>Initialize an empty object <em>result</em>.</li>
+    <li>If <tref>active property</tref> is <code>@graph</code> or the
+      <tref title="active property">active property's</tref> <tref>type mapping</tref> is set to
+      <code>@id</code>, add a key-value pair to <em>result</em> where the key is <code>@id</code>
+      and the value is the result of expanding <em>value</em> according to the
+      <a href="#iri-expansion">IRI Expansion algorithm</a> passing <code>true</code> for the
+      <em>documentRelative</em> flag. Then return <em>result</em>.</li>
+    <li>Add a key-value pair to <em>result</em> where the key is <code>@value</code>
+      and the value is <em>value</em>.</li>
+    <li>If the <tref>active property</tref> has a <tref>type mapping</tref>, add a key-value
+      pair to <em>result</em> where the key is <code>@type</code> and the value is the
+      <tref>IRI</tref> associated with the <tref>type mapping</tref> or a newly
+      <a href="#generate-blank-node-identifier">generated blank node identifier</a> if the
+      <tref>type mapping</tref> is set to a <tref>blank node identifier</tref>.</li>
+    <li>Otherwise, if <em>value</em> is a <tref>string</tref> and the <tref>active property</tref> has a
+      <tref>language mapping</tref> or an <tref>default language</tref> is set in the <tref>active context</tref>,
+      add a key-value pair to <em>result</em> where the key is <code>@language</code> and the value is the
+      language tag associated with the <tref>language mapping</tref> or the <tref>active property</tref> or the
+      <tref>default language</tref>.</li>
+    <li>Return <em>result</em>.</li>
+  </ol>
+</section>
+
+<section>
+  <h2>Label Blank Nodes Algorithm</h2>
+
+  <p>The algorithm takes a single input variable: an <em>element</em> to be labeled with
+    <tref title="blank node identifier">blank node identifiers</tref>.</p>
+
+  <ol class="algorithm">
+    <li>If <em>element</em> is an <tref>array</tref>, recursively apply this
+      algorithm to all its items.</li>
+    <li>Otherwise, if <em>element</em> is a <tref>JSON object</tref> with a
+      <code>@list</code> member, recursively apply this algorithm to all items
+      of the <code>@list</code> member's value.</li>
+    <li>Otherwise, if <em>element</em> is a <tref>JSON object</tref>
+      <ol class="algorithm">
+        <li>For each <em>key</em>-<em>value</em> pair ordered by <em>key</em>
+          recursively apply this algorithm to <em>value</em>.</li>
+        <li>If <em>element</em> is a <tref>node object</tref> without an <code>@id</code> member,
+          create a new <code>@id</code> member and assign it a new
+          <tref>blank node identifier</tref> according the
+          <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a> algorithm.</li>
+      </ol>
+    </li>
+  </ol>
+</section>
+
+<section>
+  <h2>Generate Blank Node Identifier</h2>
+
+  <p>This algorithm is used to generate new
+    <tref title="blank node identifier">blank node identifiers</tref> or to relabel existing
+    <tref title="blank node identifier">blank node identifiers</tref> with a new one to avoid
+    collision by the introduction of new ones. It needs to keep an <em>identifier map</em>,
+    a <em>counter</em>, and a <em>prefix</em> between its executions to be able to generate new
+    <tref title="blank node identifier">blank node identifiers</tref>. The <em>counter</em>
+    is initialized to <code>0</code> and <em>prefix</em> is set to <code>_:t</code> by default.</p>
+
+  <p>The algorithm takes a single input variable <em>identifier</em> which might be
+    <tref>null</tref>.</p>
+
+  <ol class="algorithm">
+    <li>If the <em>identifier</em> is not <tref>null</tref> and is in the <em>identifier map</em>,
+      return the mapped identifier.</li>
+    <li>Otherwise, generate a new <em>blankNodeIdentifier</em> by concatenating <em>prefix</em>
+      and <em>counter</em>.</li>
+    <li>Increment <em>counter</em> by <code>1</code>.</li>
+    <li>If <em>identifier</em> is not <tref>null</tref>, create a new entry in
+      <em>identifier map</em> set to <em>blankNodeIdentifer</em>.</li>
+    <li>Return <em>blankNodeIdentifier</em>.</li>
+  </ol>
+</section>
+
+<section>
+  <h2>Compaction Algorithm</h2>
+
+  <p>The algorithm takes four input variables: an <tref>active context</tref>,
+    an <tref>inverse context</tref>, an <tref>active property</tref>, and an <em>element</em>
+    to be compacted. To begin, the <tref>active context</tref> is set to the result of performing
+    <a href="#context-processing">Context Processing</a> on the passed <em>context</em>,
+    <tref>inverse context</tref> is set to the result of
+    <a href="#context-processing">creating an inverse context</a> from the <tref>active context</tref>,
+    <tref>active property</tref> is set to <tref>null</tref>, and <em>element</em> is set to
+    the result of performing the <a href="#expansion-algorithm">Expansion Algorithm</a>
+    on the <tref>JSON-LD input</tref>.</p>
+
+  <ol class="algorithm">
+    <li>If <em>element</em> is an <tref>array</tref>,
+      <ol class="algorithm">
+        <li>Initialize a new empty array <em>result</em>.</li>
+        <li>Process each item in <em>element</em> recursively using this algorithm,
+          passing a copy of the <tref>active context</tref>, <tref>inverse context</tref>,
+          and the <tref>active property</tref>. Add each compacted item to <em>result</em>
+          unless it is <tref>null</tref>.</li>
+        <li>If <em>result</em> has a single item and the
+          <code class="idlMemberName"><a href="#widl-JsonLdOptions-compactArrays">compactArrays</a></code>
+          option is set to <code>true</code>, return that item; otherwise return
+          <em>result</em>.</li>
+      </ol>
+    </li>
+    <li>If <em>element</em> is not a <tref>JSON object</tref> it is already in
+      compact form, return it as is.</li>
+    <li>If <em>element</em> has an <code>@value</code> or <code>@id</code> member,
+      replace <em>element</em> with the result of the
+      <a href="#value-compaction">Value Compaction algorithm</a>. If the updated
+      <em>element</em> is a <tref>scalar</tref>, return it as it cannot be further
+      compacted.</li>
+    <li>Initialize a new empty <tref>JSON object</tref> result.</li>
+    <li>Process each <em>property</em> and <em>value</em> in <em>element</em> ordered
+      by <em>property</em> as follows:
+      <ol class="algorithm">
+        <li>If <em>property</em> is a JSON-LD <tref>keyword</tref>
+          <ol class="algorithm">
+            <li>and <em>property</em> equals <code>@id</code>, compact <em>value</em>
+              according the rules of the <a href="#iri-compaction-algorithm">IRI Compaction algorithm</a>.</li>
+            <li>Otherwise, if <em>property</em> equals <code>@type</code>, compact <em>value</em>
+              (or each item of <em>value</em> if it is an <tref>array</tref>) according the rules of the
+              <a href="#iri-compaction-algorithm">IRI Compaction algorithm</a> with the
+              <em>vocabRelative</em> flag set to <code>true</code>. If <em>value</em> is an
+              <tref>array</tref> consisting of just one item, replace <em>value</em> with that item.</li>
+            <li>Otherwise, if <em>property</em> equals <code>@graph</code> or <code>@list</code>, compact <em>value</em>
+              by recursively invoking this algorithm, passing a copy of the <tref>active context</tref>,
+              <tref>inverse context</tref>, and <em>property</em> as <tref>active property</tref>
+              ensuring that the result is an <tref>array</tref>.</li>
+            <li>Set <tref>active property</tref> to the result of performing
+              <a href="#iri-compaction-algorithm">IRI Compaction</a> on <em>property</em>.</li>
+            <li>Set the <tref>active property</tref> member of <em>result</em> to <em>value</em>.</li>
+            <li>Continue with the next <em>property</em>-<em>value</em> pair from <em>element</em>.</li>
+        </li>
+      </ol>
+    </li>
+    <li>If <em>value</em> is an empty <tref>array</tref>,
+      <ol class="algorithm">
+        <li>set <tref>active property</tref> to the result of performing
+          <a href="#iri-compaction-algorithm">IRI Compaction</a> on <em>property</em> with the
+          <em>vocabRelative</em> flag set to <code>true</code>.</li>
+        <li>If <tref>active property</tref> is a <tref>JSON object</tref>, i.e., it is a
+          <tref>property generator</tref>, set <tref>active property</tref> to the result of performing the
+          <a href="#find-and-remove-property-generator-duplicates">Find and Remove Property Generator Duplicates</a>
+          algorithm passing <em>element</em>, <em>property</em>, <tref>null</tref> for value, the
+          <tref>active context</tref>, and <tref>active property</tref>.</li>
+        <li>Ensure that <em>result</em> has an <tref>active property</tref> member; if not create it
+          and set its value to an empty <tref>array</tref>.</li>
+        <li>Continue with the next <em>property</em>-<em>value</em> pair from <em>element</em>.</li>
+      </ol>
+    </li>
+    <li>Otherwise perform the following steps for each <em>item</em> of <em>value</em>:
+      <ol class="algorithm">
+        <li>Set <tref>active property</tref> to the result of performing
+          <a href="#iri-compaction-algorithm">IRI Compaction</a> on <em>property</em> with the
+              <em>vocabRelative</em> flag set to <code>true</code>.</li>
+        <li>If <tref>active property</tref> is a <tref>JSON object</tref>, i.e., it is a
+          <tref>property generator</tref>, set <tref>active property</tref> to the result of performing the
+          <a href="#find-and-remove-property-generator-duplicates">Find and Remove Property Generator Duplicates</a>
+          algorithm passing <em>element</em>, <em>property</em>, <em>item</em>, the
+          <tref>active context</tref>, and <tref>active property</tref>.</li>
+        </li>
+        <li>If the <tref title="active property">active property's</tref> <tref>container mapping</tref>
+          is set to <code>@language</code> or <code>@index</code>
+          <ol class="algorithm">
+            <li>Unless <em>result</em> has already an <tref>active property</tref> member, create one and
+              initialize its value to an empty <tref>JSON object</tref>. This object is called <em>mapObject</em>.</li>
+            <li>Set <em>index</em> to the value of the <code>@language</code> or
+              <code>@index</code> member of <em>item</em> (depending on the value of the
+              <tref title="active property">active property's</tref> <tref>container mapping</tref>).</li>
+            <li>First compact <em>item</em> using the <a href="#value-compaction">Value Compaction algorithm</a>
+              passing <em>index</em> as <em>containerValue</em>, then compact it by recursively invoking this
+              algorithm passing a copy of the <tref>active context</tref>, <tref>inverse context</tref>, and the
+              <tref>active property</tref>.</li>
+            <li>If no <em>index</em> member exists in the <em>mapObject</em> create one and set its value
+              to <em>item</em>; otherwise append <em>item</em> to the <em>index</em> member (converting it to
+              an array if it is not one already).</li>
+            <li>Continue with the next <em>property</em>-<em>value</em> pair from <em>element</em>.</li>
+          </ol>
+        </li>
+        <li>If <em>item</em> is a <tref>JSON object</tref> having a <code>@list</code> member,
+          <ol class="algorithm">
+            <li>compact the value of that member by recursively invoking this algorithm passing
+              a copy of the <tref>active context</tref>, <tref>inverse context</tref>, and the
+              <tref>active property</tref> ensuring that the result is an <tref>array</tref>.</li>
+            <li>If the <tref title="active property">active property's</tref> <tref>container mapping</tref>
+              is set to <code>@list</code>, set the <tref>active property</tref> member of <em>result</em>
+              to the value of <em>item's</em> <code>@list</code> member. If such an member already exists
+              in result, raise an <code class="error">compaction to list of lists</code> error; otherwise
+              continue with the next <em>property</em>-<em>value</em> pair from <em>element</em>.</li>
+          </ol>
+        </li>
+        <li>If <em>item</em> is a <tref>JSON object</tref>, compact it by recursively
+          invoking this algorithm passing a copy of the <tref>active context</tref>,
+          <tref>inverse context</tref>, and the <tref>active property</tref>.</li>
+        <li>If no <tref>active property</tref> member exists in <em>result</em> create one and set its value
+          to <em>item</em>; otherwise append <em>item</em> to the <tref>active property</tref> member
+          (converting it to an <tref>array</tref> if it is not one already).</li>
+        <li>If the <code class="idlMemberName"><a href="#widl-JsonLdOptions-compactArrays">compactArrays</a></code>
+          option is set to <code>false</code> or the <tref title="active property">active property's</tref>
+          <tref>container mapping</tref> is set to <code>@list</code> or <code>@set</code>, convert the
+          value of the <tref>active property</tref> member of <em>result</em> to an <tref>array</tref> if
+          it is not one already.</li>
+      </ol>
+    </li>
+  </ol>
+
+  <p>If, after the algorithm outlined above is run, the resulting <em>element</em> is an <tref>array</tref>
+    with one or more items, replace it with a new <tref>JSON object</tref> with a single member whose name
+    is the result of compacting the value <code>@graph</code> with the
+    <a href="#iri-compaction-algorithm">IRI Compaction algorithm</a> and whose value is <em>element</em>. If
+    the resulting <em>element</em> is an <tref>array</tref> with zero items, replace it with an empty
+    <tref>JSON object</tref>. Finally, if a <em>context</em> has been passed, add a <code>@context</code>
+    property to <em>element</em> and set its value to the initially passed <em>context</em>.</p>
+</section>
+
+<section>
+  <h2>IRI Compaction Algorithm</h2>
+
+  <p>This section defines an algorithm for transforming an <tref>IRI</tref> to a
+    <tref>term</tref> or <tref>compact IRI</tref>. If a <em>value</em> is passed
+    it is used to choose the best matching <tref>term</tref>.</p>
+
+  <p>This algorithm takes three mandatory and three optional parameters. The mandatory
+    parameters are the <em>iri</em> to be compacted, an <tref>active context</tref>,
+    and an <tref>inverse context</tref>. Optionally it is possible to pass a <em>value</em>,
+    and a <em>vocabRelative</em> flag which specifies whether the passed <em>iri</em>
+    should be compacted using the <tref title="active context">active context's</tref>
+    <tref>vocabulary mapping</tref>, and a base <tref>IRI</tref> which, when passed, is used
+    to transform the passed <em>iri</em> to a <tref title="relative IRI">relative IRIs</tref>
+    if the <em>vocabRelative</em> flag is set to false (which is its default value).</p>
+
+  <p>The algorithm for generating a <tref>compact IRI</tref> is:</p>
+
+  <ol class="algorithm">
+    <li>Initialize a variable <em>result</em> to <tref>null</tref>.</li>
+    <li>If the <em>vocabRelative</em> flag is set to <code>true</code> and an entry for
+      <em>iri</em> exists in the <tref>inverse context</tref>, perform the following steps:
+      <ol class="algorithm">
+        <li>If a <em>value</em> has been passed, perform the following steps:
+          <ol class="algorithm">
+            <li>Initialize <em>queryPath</em>, which will be used to query the
+              <tref>inverse context</tref>, to an empty <tref>array</tref></li>
+            <li id="calculate-value-profile-algorithm">Initialize <em>container</em>
+              to <code>@set</code>, <em>typeOrLanguage</em>, and <em>typeLanguageValue</em>
+              to <tref>null</tref>.</li>
+            <li>If <em>value</em> is a <tref>JSON object</tref>
+              <ol class="algorithm">
+                <li>and it has an <code>@index</code> member, set <em>container</em> to
+                  <code>@index</code>.</li>
+                <li>If <em>value</em> has an <code>@id</code> member, set
+                  <em>typeOrLanguage</em> to <code>@type</code> and <em>typeLanguageValue</em>
+                  to <code>@id</code>.</li>
+                <li>Otherwise, if <em>value</em> has an <code>@value</code> member,
+                  <ol class="algorithm">
+                    <li>and an <code>@type</code> member, set <em>typeOrLanguage</em> to
+                      <code>@type</code> and <em>typeLanguageValue</em> to the value of the
+                      <code>@type</code> member of <em>value</em>.</li>
+                    <li>Otherwise, if it has an <code>@language</code> member, set
+                      <em>typeOrLanguage</em> to <code>@language</code> and
+                      <em>typeLanguageValue</em> to the value of the <code>@language</code>
+                      member of <em>value</em>. If <em>value</em> has no <code>@index</code>
+                      member, set <em>container</em> to <code>@language</code></li>
+                    <li>Otherwise, set <em>typeOrLanguage</em> to <code>@language</code> and
+                      <em>typeLanguageValue</em> to <code>@null</code>.</li>
+                  </ol>
+                </li>
+                <li>Otherwise, if <em>value</em> has an <code>@list</code> member,
+                  <ol class="algorithm">
+                    <li>If the <code>@list</code> member has at least one item, update
+                      <em>container</em>, <em>typeOrLanguage</em>, and
+                      <em>typeLanguageValue</em> by recursively running the steps
+                      <a href="#calculate-value-profile-algorithm">2.1.2</a> to
+                      2.1.3.4 (which will never be true since list of lists are not
+                      allowed) of this algorithm passing the first item of <em>value's</em>
+                      <code>@list</code> member as new <em>value</em>.</li>
+                    <li>If <em>value</em> has no <code>@index</code> member, set
+                      <em>container</em> to <code>@list</code>.</li>
+                    <li>Starting from the second item of <em>value's</em> <code>@list</code>
+                      member, recursively run the steps
+                      <a href="#calculate-value-profile-algorithm">2.1.2</a> to
+                      2.1.3.4 (which will never be true since list of lists are not
+                      allowed) of this algorithm passing the item as new <em>value</em>. If
+                      the resulting <em>typeOrLanguage</em> or <em>typeLanguageValue</em>
+                      differ from the current value of <em>typeOrLanguage</em> or
+                      <em>typeLanguageValue</em>, set both to <tref>null</tref> and stop
+                      processing the <code>@list</code> items.</li>
+                  </ol>
+                </li>
+              </ol>
+            </li>
+            <li>If the <em>container</em> equals <code>@list</code>, set the first item of
+              <em>queryPath</em> to an <tref>array</tref> consisting of the two elements
+              <code>@list</code> and <code>null</code>; otherwise set it to an array
+              consisting of three elements where the first element is the value of <em>container</em>
+               and the other two elements are <code>@set</code> and <code>@null</code>.</li>
+            <li>If <em>typeOrLanguage</em> is <tref>null</tref>, set the second and the the
+              third item of <em>queryPath</em> to an <tref>array</tref> consisting of a
+              single element <code>@null</code>.</li>
+            <li>Otherwise, set the second item of <em>queryPath</em> to an <tref>array</tref>
+              consisting of two elements where the first element is the value of
+              <em>typeOrLanguage</em> and the second element is <code>@null</code>. Set the
+              third item of <em>queryPath</em> to an <tref>array</tref> whose first element
+              <em>typeLanguageValue</em> and whose second element is <code>@null</code>.</li>
+            <li><a href="#inverse-context-query-algorithm">Query the inverse context</a> and
+              store the result in <em>result</em>.</li>
+            <li>If <em>result</em> is a a <tref>string</tref> or a <tref>JSON object</tref> with a
+              <code>term</code> member, return <em>result</em>.</li>
+          </ol>
+        </li>
+        <li>Otherwise, if the entry for <em>iri</em> in the <tref>inverse context</tref>
+          has a <code>term</code> member, return its value.</li>
+      </ol>
+    </li>
+    <li>For each <em>termIri</em>-<em>termDefinition</em> pair in <tref>inverse context</tref>
+      sorted in reverse order by <em>termIri</em> the (longest <em>termIri</em> comes first),
+      perform the following steps:
+      <ol class="algorithm">
+        <li>If <em>termDefinition</em> does not have a <code>term</code> member, i.e., it is
+          a property generator, continue with the next <em>termIri</em>-<em>termDefinition</em>
+          pair from <tref>inverse context</tref>.</li>
+        <li>Otherwise, if <em>iri</em> begins with <em>termIri</em> and is longer than
+          <em>termIri</em>, generate a <tref>compact IRI</tref> by concatenating the value
+          of the <code>term</code> member of <em>termDefinition</em> with a colon
+          (<code>:</code>) character and the unmatched part of <em>iri</em>.</li>
+        <li>If the resulting <tref>compact IRI</tref> has an entry in the <tref>active context</tref>
+          and the <em>vocabRelative</em> flag is set to <code>true</code> or the <tref>IRI mapping</tref>
+          does not correspond to <em>iri</em>, continue with the next <em>termIri</em>-<em>termDefinition</em>
+          pair from <tref>inverse context</tref> as the <tref>compact IRI</tref> cannot be used.</li>
+        <li>Otherwise, if result is <tref>null</tref>, return the <tref>compact IRI</tref>; if it is
+          not null, set the <code>term</code> member of <em>result</em> to the <tref>compact IRI</tref>
+          and return <em>result</em>.</li>
+      </ol>
+    </li>
+    <li>If the <em>vocabRelative</em> flag is set to <code>false</code> and a base <tref>IRI</tref> has
+       been passed, transform <em>iri</em> to a <tref>relative IRI</tref>.</li>
+    <li>Otherwise, if the <em>vocabRelative</em> flag is set to <code>true</code>, the
+      <tref>active context</tref> has a <tref>vocabulary mapping</tref>, and <em>iri</em>
+      begins with the IRI of the <tref>vocabulary mapping</tref> but is longer
+      <ol class="algorithm">
+        <li>Set <em>vocabIri</em> to the unmatched part of <em>iri</em>.</li>
+        <li>If there does not exist an entry for <em>vocabIri</em> in the <tref>active context</tref>,
+          return <em>vocabIri</em> if <em>result</em> is <tref>null</tref>; if it is not
+          <tref>null</tref> set the <code>term</code> member of <em>result</em> to
+          <em>vocabIri</em> and return <em>result</em>.</li>
+      </ol>
+    </li>
+    <li>If <em>result</em> is <tref>null</tref>, return <em>iri</em> as is.</li>
+    <li>Otherwise set the <code>term</code> member of <em>result</em> to <em>iri</em> and
+      return <em>result</em>.</li>
+  </ol>
+</section>
+
+<section>
+  <h2>Inverse Context Creation</h2>
+
+  <p>An <tref>active context</tref> as produced by the
+    <a href="#context-processing">Context Processing</a> algorithm is very
+    efficient for <a href="#iri-expansion">expanding</a>
+    <tref title="term">terms</tref> and <tref title="compact IRI">compact IRIs</tref>
+    to <tref title="IRI">IRIs</tref> but is of limited use for the opposite
+    operation: <a href="#iri-compaction-algorithm">IRI compaction</a>. Hence,
+    this algorithm introduces the notion of an <tref>inverse context</tref>
+    which brings the same efficiency to <a href="#iri-compaction-algorithm">IRI compaction</a>.
+    An <tdef>inverse context</tdef> is a tree of <tref title="JSON object">JSON objects</tref>
+    which allow to efficiently select a <tref>term</tref> for a <tref>IRI</tref>-value
+    pair. Consider the following <tref>context</tref>:</p>
+
+  <pre class="example" data-transform="updateExample"
+       title="A context containing of two terms and a property generator">
+  <!--
+  {
+    "@context": {
+      ****"name"****: "http://xmlns.com/foaf/0.1/name",
+      ****"homepage"****: {
+        "@id": "http://xmlns.com/foaf/0.1/homepage",
+        "@type": "@id"
+      },
+      ****"gender"****: {
+        "@id": [ "http://xmlns.com/foaf/0.1/gender", "http://schema.org/gender" ],
+        "@language": "en"
+      }
+    }
+  }
+  -->
+  </pre>
+
+  <p>The corresponding <tref>inverse context</tref> looks as shown below. All entries of
+    the <tref>context</tref> above are first indexed by <tref>IRI</tref>, followed by
+    their <tref>container mapping</tref>, and finally by their
+    <tref title="language mapping">language</tref> or <tref>type mapping</tref>. If a
+    specific mapping is not set or <tref>null</tref>, the entry is indexed under the
+     respective <code>@null</code> member instead.</p>
+
+  <pre class="example" data-transform="updateExample"
+       title="The inverse context corresponding to the context above">
+  <!--
+  {
+    "http://xmlns.com/foaf/0.1/homepage": {
+      "term": "homepage",
+      "@null": {
+        "@type": {
+          "@id": {
+            "term": ****"homepage"****
+          }
+        }
+      }
+    },
+    "http://xmlns.com/foaf/0.1/gender": {
+      "@null": {
+        "@language": {
+          "en": {
+            "propertyGenerators": [ ****"gender"**** ]
+          }
+        }
+      }
+    },
+    "http://xmlns.com/foaf/0.1/name": {
+      "term": "name",
+      "@null": {
+        "@language": {
+          "@null": {
+            "term": ****"name"****
+          }
+        },
+        "@null": {
+          "@null": {
+            "term": ****"name"****
+          }
+        }
+      }
+    },
+    "http://schema.org/gender": {
+      "@null": {
+        "@language": {
+          "en": {
+            "propertyGenerators": [ ****"gender"**** ]
+          }
+        }
+      }
+    }
+  }
+  -->
+  </pre>
+
+  <p>Please note that the <tref>property generator</tref> <code>gender</code> and the <tref>term</tref>
+    <code>name</code> are included twice in <tref>inverse context</tref>. While <code>gender</code>
+    is included once for each <tref>IRI</tref> it is mapped to, <code>name</code> is included
+    twice since it has neither a <tref>type mapping</tref> nor a <tref>language mapping</tref>.
+    It can thus be used for <tref title="string">strings</tref> without an associated language
+    (the first entry), or all other (untyped) <tref title="JSON-LD value">values</tref>.</p>
+
+  <p>The following algorithm takes an <tref>active context</tref> and returns the corresponding
+    <tref>inverse context</tref>.</p>
+
+  <ol class="algorithm">
+    <li>Set <em>defaultLanguage</em> to <tref title="active context">active context's</tref>
+      <tref>default language</tref> if there is one; otherwise set it to <code>@null</code>.</li>
+    <li>For each <tref>term definition</tref> in the <tref>active context</tref>
+      perform the following steps:
+      <ol class="algorithm">
+        <li>If the <tref title="term">term's</tref> <tref>IRI mapping</tref> is set to
+          <tref>null</tref> continue with the next <tref>term definition</tref>.</li>
+        <li>Set <em>container</em> to the value of the <tref title="term">term's</tref>
+          <tref>container mapping</tref> or <code>@null</code> if no such mapping exists.</li>
+        <li>If the <tref>term</tref> is a <tref>property generator</tref>, set <em>termType</em>
+          to <code>propertyGenerators</code>.</li>
+        <li>Otherwise set  set <em>termType</em> to <code>term</code> and append the
+          <tref>term</tref> to the <code>term</code> member of the <tref>JSON object</tref> for
+          the <tref title="term">term's</tref> IRI in <tref>inverse context</tref>
+          (append <em>term</em> to <code>inverseContext[iri]['term']</code>).</li>
+        <li>For each <em>iri</em> mapped to the <tref>term</tref>, perform the following steps:
+          <ol class="algorithm">
+            <li>If the <tref>term</tref> has a <tref>type mapping</tref> to <em>type</em>,
+              append the <tref>term</tref> to
+              <code>inverseContext[iri][container]['@type'][type][termType]</code> (e.g.,
+              <code>inverseContext['http://...']['@list']['@type']['http://...']['term']</code>).</li>
+            <li>Otherwise, if the <tref>term</tref> has a <tref>language mapping</tref> store the
+              associated language in <em>language</em>, replacing <tref>null</tref> with
+              <code>@null</code>. Then append the <tref>term</tref> to
+              <code>inverseContext[iri][container]['@language'][language][termType]</code> (e.g.,
+              <code>inverseContext['http://...']['@list']['@language']['de']['term']</code>).</li>
+            <li>Otherwise append the <tref>term</tref> to
+              <code>inverseContext[iri][container]['@null']['@null'][termType]</code> as well as
+              <code>inverseContext[iri][container]['@language'][defaultLanguage][termType]</code>
+              to take the <tref>default language</tref> into consideration for terms without
+              explicit <tref>language mapping</tref>.</li>
+          </ol>
+        </li>
+      </ol>
+    </li>
+    <li>Remove all but the shortest and lexicographically least <tref>term</tref> in each
+      <code>term</code> member in <tref>inverse context</tref>. The result is thus a single
+      <tref>string</tref> value.</li>
+    <li>Finally, sort the <tref>array</tref> associated with every <code>propertyGenerators</code> member in
+      <tref>inverse context</tref> lexicographically (shortest <tref title="term">terms</tref> come
+      first).</li>
+  </ol>
+</section>
+
+<section>
+  <h2>Inverse Context Query Algorithm</h2>
+
+  <p>It is possible that multiple <tref title="term">terms</tref> that differ
+    in their <tref title="container mapping">container</tref>,
+    <tref title="type mapping">type</tref>, or <tref>language mapping</tref> are
+    mapped to the same <tref>IRI</tref>. The purpose of this algorithm is to query
+    the <tref>inverse context</tref> to return either the best matching <tref>term</tref>,
+    or a list of potential <tref title="property generator">property generators</tref>
+    along with a <tref>term</tref> to fall back to if none of the
+    <tref title="property generator">property generators</tref> can be applied.</p>
+
+  <p>This algorithm takes an <em>inverseContextSubtree</em>, a <em>queryPath</em>
+    as generated by the <a href="#iri-compaction-algorithm">IRI Compaction algorithm</a>
+    and a <em>level</em> parameter which is initialized to <code>0</code> if nothing else
+    is passed. The algorithm returns either a <tref>string</tref> representing the best matching
+    <tref>term</tref> or a <tref>JSON object</tref> consisting of a
+    <code>propertyGenerators</code> member, containing a sorted <tref>array</tref> of
+    potential <tref title="property generator">property generators</tref>,
+    and an optional <code>term</code> member containing a <tref>term</tref> to fall back
+    to if none of the <tref title="property generator">property generators</tref>
+    can be applied.</p>
+
+  <ol class="algorithm">
+    <li>Initialize <em>result</em> to <tref>null</tref>.</li>
+    <li>If <em>level</em> equals <code>3</code>, i.e., the deepest nested
+      <tref>JSON object</tref> in the <tref>inverse context</tref> has been reached,
+      perform the following steps:
+      <ol class="algorithm">
+        <li>If <em>inverseContextSubtree</em> has a <code>propertyGenerators</code> member,
+          copy that member into a new <tref>JSON object</tref> and store that object in
+          <em>result</em>.</li>
+        <li>If <em>inverseContextSubtree</em> has a <code>term</code> member and
+          <em>result</em> is <tref>null</tref>, return the value of that member;
+          otherwise <em>result</em> is a <tref>JSON object</tref>, copy the <code>term</code>
+          member into <em>result</em> and return <em>result</em>.</li>
+      </ol>
+    </li>
+    <li>Otherwise, for each <em>entry</em> of the <tref>array</tref> in <em>queryPath's</em>
+      <em>level'd</em> position (<code>queryPath[level]</code>), perform the following steps:
+      <ol class="algorithm">
+        <li>If <em>inverseContextSubtree</em> has no <em>entry</em> member, continue with
+          the next <em>entry</em>.</li>
+        <li>Otherwise set <em>tmpResult</em> to the result of recursively invoking this
+          algorithm passing the <em>entry</em> member of <em>inverseContextSubtree</em> as
+          new <em>inverseContextSubtree</em>, <em>queryPath</em>, and <em>level</em> + <code>1</code>
+          as new <em>level</em>.</li>
+        <li>If <em>tmpResult</em> is a <tref>string</tref> and <em>result</em> is
+          <tref>null</tref>, return <em>tmpResult</em>; otherwise, if <em>result</em> is
+          not <tref>null</tref>, transform <em>tmpResult</em> to a <tref>JSON object</tref>
+          whose <code>propertyGenerators</code> member is set to an empty <tref>array</tref>
+          and whose <code>term</code> member is set to <em>tmpResult</em>.</li>
+        <li>If <em>result</em> is <tref>null</tref>, replace it with <em>tmpResult</em>.</li>
+        <li>Otherwise, append each item of the <code>propertyGenerator</code> member of
+          <em>tmpResult</em> to the <code>propertyGenerator</code> member of <em>result</em>
+          unless it is already in <em>result's</em> member. If <em>result</em> has no
+          <code>term</code> member but <em>tmpResult</em> does, copy <em>tmpResult's</em>
+          <code>term</code> member into <em>result</em>.</li>
+      </ol>
+    </li>
+    <li>Return <em>result</em>.</li>
+  </ol>
+</section>
+
+<section>
+  <h2>Value Compaction</h2>
+
+  <p>Expansion transforms all values into <tref>expanded form</tref>in JSON-LD. This algorithm
+    does the opposite, it compacts an algorithm according the <tref>term definition</tref>
+    of the passed <tref>active property</tref>. After the application of this algorithm a value
+    is said to be in <tdef>compacted form</tdef>.</p>
+
+  <p>This algorithm takes a <em>value</em>, an <tref>active context</tref>, an
+    <tref>inverse context</tref>, an <tref>active property</tref>, and an optional
+    <em>containerValue</em>.</p>
+
+  <ol class="algorithm">
+    <li>If a <em>containerValue</em> has been passed, the <tref>active property</tref> has a
+      <tref>container mapping</tref> set to <code>@index</code> and <em>value</em>
+      has an <code>@index</code> member which equals <em>containerValue</em>, remove that member.</li>
+    <li>If <em>value</em> is a <tref>JSON object</tref> having a single member <code>@id</code>,
+      return the result of performing <a href="#iri-compaction-algorithm">IRI Compaction</a> on that
+      member's value.</li>
+    <li>Otherwise, if <em>value</em> is a <tref>JSON object</tref> having a <code>@value</code>
+      member, perform the following steps:
+      <ol class="algorithm">
+        <li>If the <tref>active property</tref> has a <tref>type mapping</tref> and <em>value</em>
+          has a corresponding <code>@type</code> member, remove the <code>@type</code> member
+          from <em>value</em>.</li>
+        <li>Otherwise, if the <tref>active property</tref> has a <tref>language mapping</tref> and
+          <em>value</em> has a corresponding <code>@language</code> member, remove the
+          <code>@language</code> member from <em>value</em>.</li>
+        <li>Otherwise, if a <em>containerValue</em> has been passed, the <tref>active property</tref>
+          has a <tref>container mapping</tref> set to <code>@language</code>, and <em>value</em> has
+          a <code>@language</code> member which equals <em>containerValue</em>, remove the
+          <code>@language</code> member from <em>value</em>.</li>
+        <li>Otherwise, if the <tref>active context</tref> has a <tref>default language</tref>
+          <ol class="algorithm">
+            <li>and the <em>value</em> has a corresponding <code>@language</code> member, remove the
+              <code>@language</code> member from <em>value</em>.</li>
+            <li>Otherwise, or if the value of <em>value's</em> <code>@value</code> member is a
+              <tref>string</tref>, return <em>value</em>.</li>
+          </ol>
+        </li>
+        <li>If <em>value</em> has just a <code>@value</code> member, return the value of that
+          member.</li>
+      </ol>
+    </li>
+    <li>Return <em>value</em> as is.</li>
+  </ol>
+</section>
+
+<section>
+  <h2>Find and Remove Property Generator Duplicates</h2>
+
+  <p>This algorithm checks if a specific value exists for all <tref title="IRI">IRIs</tref>
+    associated with a <tref>property generator</tref> and if so, it removes them. The
+    algorithm takes five parameters: <em>element</em>, <em>property</em>, <em>value</em>,
+    <tref>active context</tref>, <tref>active property</tref>.</p>
+
+  <ol class="algorithm">
+    <li>For each item <em>propertyGenerator</em> of the <tref>array</tref> which is the
+      value of the <code>propertyGenerators</code> member of <tref>active property</tref> perform
+      the following steps:
+      <ol class="algorithm">
+        <li>Check that a member exists for each <tref>IRI</tref> associated with the
+          <em>propertyGenerator</em>. If <em>value</em> is not <tref>null</tref> also check
+          whether each of those members contains <em>value</em>. Values are considered to be equal
+          if they are of the same type and have the same value(s); <tref title="node object">node objects</tref>
+          are considered to be equal if all members match, except if no <code>@id</code> member exists (i.e., it is
+          an unlabeled <tref>blank node</tref>, in that case <tref title="node object">node objects</tref> are never
+          considered to be equal.
+          </li>
+        <li>If that's not the case, continue with the next <em>propertyGenerator</em>.</li>
+        <li>Otherwise, remove <em>value</em> from every member. If the resulting value
+          of a member is an empty <tref>array</tref>, remove the member altogether
+          from <em>element</em>.</li>
+        <li>Return <em>propertyGenerator</em>.</li>
+      </ol>
+    </li>
+    <li>Return the value of the <code>term</code> member of <tref>active property</tref>
+      since no matching <tref>property generator</tref> has been found.</li>
+  </ol>
+</section>
+
+<section>
+  <h2>Flattening Algorithm</h2>
+
+  <p>The algorithm takes two input variables, an <em>element</em> to flatten and a
+    <em>context</em> used to compact the flattened document.</p>
+
+  <ol class="algorithm">
+    <li>Expand <em>element</em> according the
+      <a href="#expansion-algorithm">Expansion algorithm</a>.</li>
+    <li>Generate a <em>nodeMap</em> according the
+      <a href="#node-map-generation">Node Map Generation algorithm</a>.</li>
+    <li>Let <em>defaultGraph</em> be the value of the <code>@default</code> member of
+      <em>nodeMap</em>; a <tref>JSON object</tref> representing the <tref>default graph</tref>.</li>
+    <li>For each other <em>graphName</em>-<em>graph</em> pair in <em>nodeMap</em>
+      perform the following steps:
+      <ol class="algorithm">
+        <li>If <em>defaultGraph</em> does not have a <em>graphName</em> member, create
+          one and initialize its value to a <tref>JSON object</tref> consisting of an
+          <code>@id</code> member whose value is set to <em>graphName</em>.</li>
+        <li>Add an <code>@graph</code> member set to an empty <tref>array</tref>
+          (referred to as <em>nodes</em>) to the <tref>JSON object</tref> which is the
+          value of the <em>graphName</em> member of <em>nodeMap</em>.</li>
+        <li>For each <em>id</em>-<em>node</em> pair in <em>graph</em> ordered by <em>id</em>,
+          add <em>node</em> to the <em>nodes</em> <tref>array</tref>.</li>
+      </ol>
+    </li>
+    <li>Initialize an empty <tref>array</tref> flattened.</li>
+    <li>For each <em>id</em>-<em>node</em> pair in <em>defaultGraph</em> ordered by <em>id</em>,
+      add <em>node</em> to <em>flattened</em>.</li>
+    <li>If <em>context</em> equals <tref>null</tref>, return <em>flattened</em>.</li>
+    <li>Otherwise, return the result of compacting <em>flattened</em> according the
+      <a href="#compaction-algorithm">Compaction algorithm</a> passing <em>context</em>
+      ensuring that the compaction result uses the <code>@graph</code> keyword (or its alias)
+      at the top-level, even if the context is empty or if there is only one element to
+      put in the <code>@graph</code> <tref>array</tref>. This ensures that the returned
+      document has a deterministic structure.</li>
+  </ol>
+</section>
+
+<section>
+  <h2>Node Map Generation</h2>
+
+  <p>This algorithm creates a <tref>JSON object</tref> <em>nodeMap</em> holding an indexed
+    representation of the <tref title="JSON-LD graph">graphs</tref> and <tref title="node">nodes</tref>
+    represented in the passed, expanded document. All <tref title="node">nodes</tref> that are not
+    uniquely identified by an IRI get assigned a (new) <tref>blank node identifier</tref>.
+    The resulting <em>nodeMap</em> will have a member for every graph in the document whose
+    value is another object with a member for every <tref>node</tref> represented in the document.
+    The default graph is stored under the <code>@default</code> member, all other graphs are
+    stored under their graph name</tref>.</p>
+
+  <p>The algorithm takes as input an expanded JSON-LD document <em>element</em> and a reference to
+    a <tref>JSON object</tref> <em>nodeMap</em>. Furthermore it has the optional parameters
+    <tref>active graph</tref> (which defaults to <code>@default</code>), an <tref>active subject</tref>,
+    <tref>active property</tref>, and a reference to a <tref>JSON object</tref> <em>list</em>. The
+    <em>nodeMap</em> must be initialized to a <tref>JSON object</tref> consisting of a single member
+    whose name corresponds with <tref>active graph</tref> and whose value is an empty <tref>JSON object</tref>.</p>
+
+  <ol class="algorithm">
+    <li>If <em>element</em> is an array, process each entry in <em>element</em> recursively, using this algorithm
+      and return.</li>
+    <li>Otherwise <em>element</em> is a <tref>JSON object</tref>. Let <em>activeGraph</em> be the
+      <tref>JSON object</tref> which is the value of the <tref>active graph</tref> member of
+      <em>nodeMap</em>.</li>
+    <li>If it has an <code>@type</code> member, perform for each <em>item</em> the following
+      steps:
+      <ol class="algorithm">
+        <li>If <em>item</em> is a <tref>blank node identifier</tref>, replace it with a
+          <a href="#generate-blank-node-identifier">new blank node identifier</a>.</li>
+        <li>If <em>activeGraph</em> has no member <em>item</em>, create it and initialize its
+          value to a <tref>JSON object</tref> consisting of a single member <code>@id</code>
+          with the value <em>item</em>.</li>
+      </ol>
+    </li>
+    <li>If <em>element</em> has an <code>@value</code> member, perform the following steps:
+      <ol class="algorithm">
+        <li>If no <em>list</em> has been passed, merge <em>element</em> into the
+          <tref>active property</tref> member of the <tref>active subject</tref> in
+          <em>activeGraph</em>.</li>
+        <li>Otherwise, append <em>element</em> to the <code>@list</code> member of <em>list</em>.</li>
+      </ol>
+    </li>
+    <li>Otherwise, if <em>element</em> has an <code>@list</code> member, perform
+      the following steps:
+      <ol class="algorithm">
+        <li>Initialize a new <tref>JSON object</tref> <em>result</em> having a single member
+          <code>@list</code> whose value is initialized to an empty <tref>array</tref>.</li>
+        <li>Recursively call this algorithm passing the value of <em>element's</em>
+          <code>@list</code> member as new <em>element</em> and <em>result</em> as <em>list</em>.</li>
+        <li>If <tref>active property</tref> equals <tref>null</tref> or <code>@graph</code>,
+          <a href="#generate-blank-node-identifier">generate a blank node identifier</a> <em>id</em>
+          and store <em>result</em> as value of the member <em>id</em> in <em>activeGraph</em>.</li>
+        <li>Otherwise, add <em>result</em> to the the value of the <tref>active property</tref> member
+          of the <tref>active subject</tref> in <em>activeGraph</em>.</li>
+      </ol>
+    </li>
+    <li>Otherwise <em>element</em> is a <tref>node object</tref>, perform the following
+      steps:
+      <ol class="algorithm">
+        <li>If <em>element</em> has an <code>@id</code> member, store its value in <em>id</em> and remove
+          the member from <em>element</em>. If <em>id</em> is a <tref>blank node identifier</tref>, replace it with
+          <a href="#generate-blank-node-identifier">a new blank node identifier</a>.</li>
+        <li>Otherwise <a href="#generate-blank-node-identifier">generate a new blank node identifier</a>
+          and store it as <em>id</em>.</li>
+        <li>If <em>activeGraph</em> does not contain a member <em>id</em>, create one and initialize
+          it to a <tref>JSON object</tref> consisting of a single member <code>@id</code> whose
+          value is set to <em>id</em>.</li>
+        <li>If <tref>active property</tref> is not <tref>null</tref>, perform the following steps:
+          <ol class="algorithm">
+            <li>Create a new <tref>JSON object</tref> <em>reference</em> consisting of a single member
+              <code>@id</code> whose value is <em>id</em>.</li>
+            <li>If no <em>list</em> has been passed, merge <em>element</em> into the
+              <tref>active property</tref> member of the <tref>active subject</tref> in
+              <em>activeGraph</em>.</li>
+            <li>Otherwise, append <em>element</em> to the <code>@list</code> member of <em>list</em>.</li>
+          </ol>
+        </li>
+        <li>If <em>element</em> has an <code>@type</code> member, merge each value into the <code>@type</code>
+          of <tref>active subject</tref> in <em>activeGraph</em>. Then remove the <code>@type</code> member
+          from <em>element</em>.</li>
+        <li>If <em>element</em> has an <code>@index</code> member, set the <code>@index</code>
+          of <tref>active subject</tref> in <em>activeGraph</em> to its value. If such a member already
+          exists in <tref>active subject</tref> and has a different value, raise a
+          <code class="error">conflicting indexes</code> error. Otherwise continue and remove the
+          <code>@index</code> from <em>element</em>.</li>
+        <li>If <em>element</em> has an <code>@graph</code> member, recursively invoke this algorithm passing
+          the value of the <code>@graph</code> member as new <em>element</em> and <em>id</em> as new
+          <tref>active subject</tref>. Then remove the <code>@graph</code> member from <em>element</em>.</li>
+        <li>Finally for each <em>property</em>-<em>value</em> pair in <em>element</em> ordered by
+          <em>property</em> perform the following steps:
+          <ol class="algorithm">
+            <li>If no <em>property</em> member exists in the <tref>JSON object</tref> which is the
+              value of the <em>id</em> member of <em>activeGraph</em> create the member and initialize
+              its value to an empty <tref>array</tref>.</li>
+            <li>Recursively invoke this algorithm passing <em>value</em> as new <em>element</em>, <em>id</em>
+              as new <tref>active subject</tref>, and <em>property</em> as new <tref>active property</tref>.</li>
+          </ol>
+        </li>
+      </ol>
+    </li>
+  </ol>
+</section>
+
+  <section>
+    <h2>RDF Conversion Algorithms</h2>
+
+    <p>This section describes an algorithms to transform JSON-LD documents to an array of
+      RDF <tref title="quad">quads</tref> and vice-versa. Note that many uses of JSON-LD
+      may not require generation of RDF.</p>
+
+    <p>The processing algorithms described in this section are provided in order to demonstrate
+      how one might implement a JSON-LD to RDF processor. Conformant implementations are only
+      required to produce the same type and number of <tref title="quad">quads</tref> but are
+      not required to implement the algorithm exactly as described.</p>
+
+    <p class="issue">This algorithm hasn't been updated yet.</p>
+
+    <section>
+      <h3>Convert to RDF Algorithm</h3>
+      <p>
+        The algorithm below is designed for in-memory implementations with random access to <tref>JSON object</tref> elements.
+      </p>
+      <p>
+        A conforming JSON-LD processor implementing RDF conversion MUST implement a
+        processing algorithm that results in the same set of RDF <tref title="quad">quads</tref> that the following
+        algorithm generates.
+      </p>
+
+      <p>The algorithm takes four input variables: a <em>element</em> to be converted, an
+        <tref>active subject</tref>, <tref>active property</tref> and <tref>graph name</tref>.
+        To begin, the <tref>active subject</tref>, <tref>active property</tref> and <tref>graph name</tref>
+        are set to <tref>null</tref>, and <em>element</em> is
+        set to the result of performing the <a href="#expansion-algorithm">Expansion Algorithm</a> on
+        the <tref>JSON-LD input</tref> which is expected to be a a well-formed JSON-LD document as defined in [[!JSON-LD]].
+        This removes any existing context to allow the given context to be cleanly applied.</p>
+
+      <ol class="algorithm">
+        <li id="processing-step-associative">
+          If <em>element</em> is a <tref>JSON object</tref>, perform the following steps:
+          <ol class="algorithm">
+            <li>Set <tref>active object</tref> to <tref>null</tref>.</li>
+            <li>
+              If <em>element</em> has a <code>@value</code> property:
+              <ol class="algorithm">
+                <li>If the value of <code>@value</code> is a <tref>number</tref>, set the
+                  <tref>active object</tref> to a <tref>typed value</tref> using a <tref>canonical lexical form</tref>
+                  of the value as defined in the section <a href="#data-round-tripping">Data Round Tripping</a>.
+                  Set datatype to the value of the <code>@type</code> property if it exists, otherwise
+                  either <code>xsd:integer</code> or <code>xsd:double</code>, depending
+                  on if the value contains a fractional and/or an exponential component.</li>
+                <li>Otherwise, if the value of <code>@value</code> is <strong>true</strong> or <strong>false</strong>,
+                  set the <tref>active object</tref> to a <tref>typed value</tref> created from the
+                  <tref>canonical lexical form</tref> of the value. Set datatype to the value of the <code>@type</code>
+                  property if it exists, otherwise <code>xsd:boolean</code>.</li>
+                <li>
+                  Otherwise, if <em>element</em> contains a <code>@type</code> property, set the
+                  <tref>active object</tref> to a <tref>typed value</tref>.
+                </li>
+                <li>
+                  Otherwise, if <em>element</em> contains a <code>@language</code> property, set the
+                  <tref>active object</tref> to a <tref>language-tagged string</tref>.
+                </li>
+                <li>
+                  Otherwise, set the <tref>active object</tref> to a <tref>typed value</tref>
+                  using <code>xsd:string</code> as the datatype.
+                </li>
+              </ol>
+            </li>
+            <li>
+              If <em>element</em> has a <code>@list</code> property the value MUST be an <tref>array</tref>.
+              Process its value as a list as described in <a href="#list-conversion">List Conversion</a> using
+              the return value as the <tref>active object</tref>
+            </li>
+            <li>If <tref>active object</tref> is not <tref>null</tref>:
+              <ol class="algorithm">
+                <li>If neither <tref>active subject</tref> nor <tref>active property</tref> are <tref>null</tref>,
+                  generate a <tref>Quad</tref>
+                  representing <tref>active subject</tref>, <tref>active property</tref>,
+                  <tref>active object</tref>, and <tref>graph name</tref>.</li>
+                <li>Return <tref>active object</tref>.</li>
+              </ol>
+            </li>
+            <li id="processing-step-subject">If <em>element</em> has a <code>@id</code> property,
+              the value MUST be a <tref>string</tref>, set the <tref>active subject</tref> to the previously
+              expanded value (either a <tref>blank node</tref> or an <tref>IRI</tref>).</li>
+            <li>
+              Otherwise, if <em>element</em> does not have a <code>@id</code> property, set the <tref>active
+              subject</tref> to newly generated <tref>blank node</tref>.</li>
+            <li>
+              Process each <em>property</em> and <em>value</em> in <em>element</em>, ordered by
+              <em>property</em>, as follows:
+              <ol class="algorithm">
+                <li>
+                  If <em>property</em> is <code>@type</code>, set the <tref>active property</tref>
+                  to <code>rdf:type</code>.
+                </li>
+                <li>Otherwise, if <em>property</em> is <code>@graph</code>,
+                  process <em>value</em> algorithm recursively, using <tref>active subject</tref> as <tref>graph name</tref>
+                  and null values for <tref>active subject</tref> and <tref>active property</tref> and then
+                  proceed to next property.</li>
+                <li>Otherwise, if <em>property</em> is a <tref>keyword</tref>, skip this step.</li>
+                <li>Otherwise, set <tref>active property</tref> to the <tref>expanded IRI form</tref> of <em>property</em>.</li>
+                <li>Process <em>value</em> recursively using this algorithm, passing copies of
+                  <tref>active subject</tref>, <tref>active property</tref> and <tref>graph name</tref>.
+                </li>
+              </ol>
+            </li>
+            <li>
+              Set <tref>active object</tref> to <tref>active subject</tref>.
+            </li>
+          </ol>
+        </li>
+
+        <li>Otherwise, if <em>element</em> is an <tref>array</tref>, process each value in the <tref>array</tref>
+          as follows, process <em>element</em> recursively using this algorithm, using copies of
+          <tref>active subject</tref>, <tref>active property</tref>, and <tref>graph name</tref>.</li>
+
+        <li>Otherwise, if <em>element</em> is a <tref>string</tref>, then the <tref>active property</tref>
+          must be <code>rdf:type</code> so set the <tref>active object</tref> to an <tref>IRI</tref>.</li>
+
+        <li>If any of these steps created an <tref>active object</tref> and neither <tref>active subject</tref>
+          nor <tref>active property</tref> are <tref>null</tref>, generate a <tref>Quad</tref> using
+          <tref>active subject</tref>,<tref>active property</tref>, <tref>active object</tref> and
+          <tref>graph name</tref>.
+        </li>
+        <li>Return <tref>active object</tref>.</li>
+      </ol>
+    </section>
+
+    <section id="list-conversion">
+      <h3>List Conversion</h3>
+
+      <p>List Conversion is the process of taking an <tref>array</tref> of values and adding them to a newly
+        created <cite><a href="http://www.w3.org/TR/rdf-schema/#ch_collectionvocab">RDF Collection</a></cite> (see
+        [[!RDF-SCHEMA]]) by linking each element of the list using <code>rdf:first</code> and <code>rdf:next</code>,
+        terminating the list with <code>rdf:nil</code> using the following sequence:</p>
+      <p>The algorithm is invoked with an <tref>array</tref> <em>array</em>, the <tref>active property</tref>
+        and returns a value to be used as an <tref>active object</tref> in the calling location.</p>
+      <div class="note">This algorithm does not support lists containing lists.</div>
+
+      <p class="issue">This algorithm hasn't been updated yet.</p>
+
+      <ol class="algorithm">
+        <li>
+          If <em>array</em> is empty return <code>rdf:nil</code>.
+        </li>
+        <li>
+          Otherwise, generate a <tref>Quad</tref> using using the <tref>active subject</tref>, <tref>active property</tref>
+          and a newly generated <tref>blank node</tref> identified as <em>first <tref>blank node</tref></em>.
+        </li>
+        <li>
+          For each element in <em>array</em> other than the last element:
+          <ol class="algorithm">
+            <li>Create a processor state using
+              <em>first blank node</em> as the <tref>active subject</tref>, and
+              <code>rdf:first</code> as the <tref>active property</tref>.
+              <ol class="algorithm">
+                <li>Process the value starting at <a href="#processing-step-associative">Step 1</a>.</li>
+                <li>Proceed using the previous <tref>processor state</tref>.</li>
+              </ol>
+            </li>
+            <li>Unless this is the last element in <em>array</em>, generate a new <tref>blank node</tref> identified as
+              <em>rest blank node</em>, otherwise use <code>rdf:nil</code>.</li>
+            <li>Generate a new <tref>Quad</tref> using <em>first blank node</em>,
+              <code>rdf:rest</code> and <em>rest blank node</em>.</li>
+            <li>Set <em>first blank node</em> to
+              <em>rest blank node</em>.</li>
+            <li>Return <em>first blank node</em>.</li>
+          </ol>
+        </li>
+      </ol>
+    </section>
+
+    <section>
+      <h2>Convert from RDF Algorithm</h2>
+      <p>In some cases, data exists natively in the form of triples or or <tref title="quad">quads</tref>;
+        for example, if the data was originally represented in an RDF graph or triple/quad store. This
+        algorithm is designed to simply translate an array of <tref title="quad">quads</tref> into a
+        JSON-LD document.</p>
+      <p>When expanding <tref title="typed value">typed values</tref> having a datatype of <code>xsd:string</code>,
+        the <code>@type</code> MUST NOT be set to <code>xsd:string</code> and the resulting value
+        MUST have only an <code>@value</code> property.</p>
+
+      <p>The conversion algorithm takes a single parameter <em>input</em> in the form of an
+        array of <tref>Quad</tref> representations.</p>
+
+      <p class="issue">This algorithm hasn't been updated yet.</p>
+
+      <ol class="algorithm">
+        <li id="new_graph">Construct <em>defaultGraph</em> as a <tref>JSON object</tref>
+          containing <em>nodes</em> and <em>listMap</em>, each an empty <tref>JSON object</tref>.</li>
+        <li>Construct <em>graphs</em> as a <tref>JSON object</tref> containing <em>defaultGraph</em>
+          identified by
+          an empty <tref>string</tref>.</li>
+        <li>For each <tref>quad</tref> in <em>input</em>:
+          <ol class="algorithm">
+            <li>Set <em>graph</em> to the entry in <em>graphs</em> identified
+              by <em>name</em>, initializing it to a new entry using the mechanism
+              described in <a href="#new_graph">Step 1</a>.</li>
+            <li>If <em>property</em> is <code>rdf:first</code>,
+              use the entry in <em>graph.listMap</em> indexed by <em>subject</em>,
+              initializing it to a new <tref>JSON object</tref> if nesessary. Represent
+              <em>object</em> in <tref>expanded form</tref>, as described in
+              <a href="#value-expansion">Value Expansion</a>. Add the
+              resulting <em>object representation</em> to the entry indexed by
+              <em>first</em>, and skip to the next <tref>quad</tref>.</li>
+            <li>If <em>property</em> is <code>rdf:rest</code>:
+              <ol class="algorithm">
+                <li>If <em>object</em> is a <tref>blank node</tref>, use the entry in
+                  <em>graph.listMap</em> indexed by <em>subject</em>, initializing it
+                  to a new <tref>JSON object</tref> if necessary. Add the <em>nominalValue</em> of
+                  <em>object</em> to the entry indexed by <em>rest</em>.
+                </li>
+                <li>Skip to the next <tref>quad</tref>.</li>
+              </ol>
+            </li>
+            <li>If <em>name</em> is not <tref>null</tref>, and <em>defaultGraph.nodes</em>
+              does not contain an entry for <em>name</em>,
+              create a new entry for <em>name</em> from a new
+              <tref>JSON object</tref> with key/value pair of <code>@id</code> and
+              <em>name</em> represented in <tref>expanded IRI form</tref>.</li>
+            <li>Set <em>value</em> as the entry from <em>graph.nodes</em> for
+              <em>subject</em>, initializing it to a new
+              <tref>JSON object</tref> with key/value pair of <code>@id</code> and
+              <em>subject</em> represented in <tref>expanded IRI form</tref> if necessary.</li>
+            <li>If <em>property</em> is <code>rdf:type</code>, <em>object</em> is not a <tref>JSON-LD value</tref>, and the
+              <code class="idlMemberName"><a href="#widl-JsonLdOptions-useRdfType">useRdfType</a></code>
+              option is not present or <tref>false</tref>:
+              <ol class="algorithm">
+                <li>Append <em>object</em> represented in <tref>expanded IRI form</tref> to the array value for the
+                  key <code>@type</code>, creating an entry in <em>value</em> if necessary.</li>
+              </ol>
+            </li>
+
+            <li>Otherwise, if <em>object</em> is a <tref>typed value</tref> and the
+              <code class="idlMemberName"><a href="#widl-JsonLdOptions-useNativeTypes">useNativeTypes</a></code>
+              option is set to <tref>true</tref>:
+              <ol class="algorithm">
+                <li>Generate a <em>converted value</em>:
+                  <ol class="algorithm">
+                    <li>If the literal's type is <code>xsd:boolean</code>, the
+                      <em>converted value</em> is <tref>true</tref> if the literal
+                      matches the value <code>true</code> or <code>false</code> if
+                      the literal matches the value <code>false</code>.</li>
+                    <li>If the literal's type is <code>xsd:integer</code> or
+                      <code>xsd:double</code>, try to convert the literal to a
+                      JSON <tref>number</tref>. If the conversion is successful,
+                      store the result in <em>converted value</em>, otherwise
+                      set <em>converted value</em> to <em>value</em>.</li>
+                    <li>Otherwise, do not perform a conversion. Set
+                      the <em>converted value</em> to the <em>value</em>.</li>
+                  </ol>
+                </li>
+                <li>Append the <em>converted value</em> to the array value for the
+                  key, creating an entry in <em>value</em> if necessary.</li>
+              </ol>
+            </li>
+
+            <li>Otherwise, if <em>object</em> is <code>rdf:nil</code>:
+              <ol class="algorithm">
+                <li>Let <em>key</em> be <em>property</em> expressed in <tref>expanded IRI form</tref>.</li>
+                <li>Append an empty <code>@list</code> representation to the array value for
+                  <em>key</em>, creating an entry in <em>value</em> if necessary.</li>
+              </ol>
+            </li>
+            <li>Otherwise,
+              <ol class="algorithm">
+                <li>Let <em>key</em> be <em>property</em> expressed in <tref>expanded IRI form</tref> and let
+                  <em>object representation</em>
+                  be <em>object</em> represented in <tref>expanded form</tref> as described in
+                  <a href="#value-expansion">Value Expansion</a>.</li>
+                <li>If <em>object</em> is a <tref>blank node</tref>,
+                  use the entry in <em>graph.listMap</em> indexed by <em>object</em>,
+                  initializing it to a new <tref>JSON object</tref> if nesessary.
+                  Add an entry for <em>head</em> with <em>object representation</em>.</li>
+                <li>Append <em>object representation</em> to the array value for
+                  <em>key</em>, creating an entry in <em>value</em> if necessary.</li>
+              </ol>
+            </li>
+          </ol>
+        </li>
+        <li>For each <em>name</em> and <em>graph</em> in <em>graphs</em>:
+          <ol class="algorithm">
+            <li>For each <em>subject</em> and <em>entry</em> in <em>graph</em>
+              where <em>entry</em> has both <em>head</em> and <em>first</em> keys:
+              <ol class="algorithm">
+                <li>Set <em>value</em> to the value of <em>head</em> in <em>entry</em>.</li>
+                <li>Remove the entry for <code>@id</code> in <em>value</em>.</li>
+                <li>Add an entry to <em>value</em> for <code>@list</code> initialized to a new array
+                  containing the value of <em>first</em> from <em>entry</em>.</li>
+                <li>While <em>entry</em> has a key for <em>rest</em>:
+                  <ol class="algorithm">
+                    <li>Set <em>entry</em> to the value of <em>graph.listMap</em> for <em>entry.rest</em>.</li>
+                    <li>Add the value for <em>entry.first</em> to the list array.</li>
+                  </ol>
+                </li>
+              </ol>
+            </li>
+          </ol>
+        </li>
+        <li>Create <em>array</em> as an empty <tref>array</tref>.</li>
+        <li>For each <em>subject</em> and <em>entry</em> in <em>defaultGraph.nodes</em>
+          ordered by <em>subject</em>:
+          <ol class="algorithm">
+            <li>Add <em>entry</em> to <em>array</em>.</li>
+            <li>If <em>graphs</em> has an entry for <em>subject</em>, add a property
+              <code>@graph</code> in <em>entry</em> containing the ordered entries
+              from <em>graphs[subject].nodes</em>.</li>
+          </ol>
+        </li>
+        <li>Return <em>array</em> as the result.</li>
+      </ol>
+    </section>
+
+    <section>
+      <h3>Data Round Tripping</h3>
+
+      <p>When <a href="#rdf-conversion">converting JSON-LD to RDF</a> JSON-native types such as
+        <em>numbers</em> and <em>booleans</em> are automatically coerced to <strong>xsd:integer</strong>,
+        <strong>xsd:double</strong>, or <strong>xsd:boolean</strong>. Implementers MUST ensure that the
+        result is in <tref>canonical lexical form</tref>. A
+        <tdef>canonical lexical form</tdef> is a set of literals from among the valid set of literals for
+        a datatype such that there is a one-to-one mapping between the <tref>canonical lexical form</tref> and a value
+        in the value space as defined in [[!XMLSCHEMA11-2]]. In other words, every value MUST be converted
+        to a deterministic <tref>string</tref> representation.</p>
+
+      <p>The canonical lexical form of an <em>integer</em>, i.e., a number without fractions
+        or a number coerced to <strong>xsd:integer</strong>, is a finite-length sequence of decimal
+        digits (<code>0-9</code>) with an optional leading minus sign; leading zeroes are prohibited.
+        To convert the number in JavaScript, implementers can use the following snippet of code:</p>
+
+      <pre class="example" data-transform="updateExample"
+           title="Sample integer serialization implementation in JavaScript">
+      <!--
+      (value).toFixed(0).toString()
+      -->
+      </pre>
+
+      <p>The canonical lexical form of a <em>double</em>, i.e., a number with fractions
+        or a number coerced to <strong>xsd:double</strong>, consists of a mantissa followed by the
+        character "E", followed by an exponent. The mantissa MUST be a decimal number. The exponent
+        MUST be an integer. Leading zeroes and a preceding plus sign (<code>+</code>) are prohibited
+        in the exponent. If the exponent is zero, it must be indicated by <code>E0</code>.
+        For the mantissa, the preceding optional plus sign is prohibited and the decimal point is
+        required. Leading and trailing zeroes are prohibited subject to the following: number
+        representations must be normalized such that there is a single digit which is non-zero to the
+        left of the decimal point and at least a single digit to the right of the decimal point unless
+        the value being represented is zero. The canonical representation for zero is <code>0.0E0</code>.
+        <strong>xsd:double</strong>'s value space is defined by the IEEE double-precision 64-bit
+        floating point type [[!IEEE-754-1985]]; in JSON-LD the mantissa is rounded to 15 digits after the
+        decimal point.</p>
+
+      <p>To convert the number in JavaScript, implementers can use the following snippet of code:</p>
+
+      <pre class="example" data-transform="updateExample"
+           title="Sample floating point number serialization implementation in JavaScript">
+      <!--
+      (value).toExponential(15).replace(/(\d)0*e\+?/,'$1E')
+      -->
+      </pre>
+
+      <p class="note">When data such as decimals need to be normalized, JSON-LD authors should
+        not use values that are going to undergo automatic conversion. This is due to the lossy nature
+        of <strong>xsd:double</strong> values. Authors should instead use the expanded object form to
+        set the canonical lexical form directly.</p>
+
+      <p>The canonical lexical form of the <em>boolean</em> values <code>true</code> and <code>false</code>
+        are the strings <strong>true</strong> and <strong>false</strong>.</p>
+
+      <p>When JSON-native <tref>number</tref>s, are type coerced, lossless data round-tripping can not
+        be guaranted as rounding errors might occur. Additionally, only literals typed as
+        <strong>xsd:integer</strong>, <strong>xsd:double</strong>, and  <strong>xsd:boolean</strong> are
+        automatically converted back to their JSON-native counterparts in when
+        <a href="#rdf-conversion">converting from RDF</a>.</p>
+
+      <p>Some JSON serializers, such as PHP's native implementation in some versions,
+        backslash-escape the forward slash character. For example, the value
+        <code>http://example.com/</code> would be serialized as <code>http:\/\/example.com\/</code>.
+        This is problematic as other JSON parsers might not understand those escaping characters.
+        There is no need to backslash-escape forward slashes in JSON-LD. To aid interoperability
+        between JSON-LD processors, a JSON-LD serializer MUST NOT backslash-escape forward slashes.</p>
+    </section>
+  </section>
+</section>
+
+<section>
+  <h2>The Application Programming Interface</h2>
+
+  <p>This API provides a clean mechanism that enables developers to convert
+  JSON-LD data into a a variety of output formats that are easier to work
+  with in JavaScript. If a JavaScript JSON-LD API is provided, the entirety
+  of the following API MUST be implemented.</p>
+
+  <section>
+    <h3>JsonLdProcessor</h3>
+
+    <p>The JSON-LD Processor interface is the high-level programming structure
+      that developers use to access the JSON-LD transformation methods.</p>
+
+    <p>It is important to highlight that conformant <tref title="JSON-LD Processor">JSON-LD processors</tref>
+      MUST NOT modify the input parameters.</p>
+
+    <dl title="[Constructor] interface JsonLdProcessor" class="idl">
+
+      <dt>void expand()</dt>
+      <dd>
+        <a href="#expansion">Expands</a> the given <code>input</code> according to
+        the steps in the <a href="#expansion-algorithm">Expansion Algorithm</a>.
+
+        <dl class="parameters">
+          <dt>(object or object[] or DOMString) input</dt>
+          <dd>The JSON-LD object or array of JSON-LD objects to perform the expansion upon or an
+            <tref>IRI</tref> referencing the JSON-LD document to expand.</dd>
+          <dt>JsonLdCallback callback</dt>
+          <dd>A callback that is called when processing completed successfully
+            on the given <code>input</code>, or a fatal error prevented
+            processing from completing.</dd>
+          <dt>optional JsonLdOptions? options</dt>
+          <dd>A set of options to configure the used algorithms such. This allows, e.g.,
+            to set the input document's base <tref>IRI</tref>.</dd>
+        </dl>
+      </dd>
+
+      <dt>void compact()</dt>
+      <dd>
+        <a href="#compaction">Compacts</a> the given <code>input</code> using the
+        <code>context</code> according to the steps in the
+        <a href="#compaction-algorithm">Compaction Algorithm</a>.
+
+        <dl class="parameters">
+          <dt>(object or object[] or DOMString) input</dt>
+           <dd>The JSON-LD object or array of JSON-LD objects to perform the compaction upon or an
+            <tref>IRI</tref> referencing the JSON-LD document to compact.</dd>
+          <dt>(object or DOMString) context</dt>
+          <dd>The context to use when compacting the <code>input</code>; either in the
+            form of an <tref>JSON object</tref> or as <tref>IRI</tref>.</dd>
+          <dt>JsonLdCallback callback</dt>
+          <dd>A callback that is called when processing completed successfully
+            on the given <code>input</code>, or a fatal error prevented
+            processing from completing.</dd>
+          <dt>optional JsonLdOptions? options</dt>
+          <dd>A set of options to configure the used algorithms such. This allows, e.g.,
+            to set the input document's base <tref>IRI</tref>. This also includes
+            the <code>optimize</code> flag, which, if set, will allow processor-specific
+            optimization.</dd>
+        </dl>
+      </dd>
+
+      <dt>void flatten()</dt>
+      <dd>
+        <a href="#flattening">Flattens</a> the given <code>input</code> and
+        <a href="#compaction">compacts</a> it using the passed <code>context</code>
+          according to the steps in the <a href="#flattening-algorithm">Flattening Algorithm</a>.
+
+        <dl class="parameters">
+          <dt>(object or object[] or DOMString) input</dt>
+           <dd>The JSON-LD object or array of JSON-LD objects or an <tref>IRI</tref>
+            referencing the JSON-LD document to flatten.</dd>
+          <dt>(object or DOMString)? context</dt>
+          <dd>The context to use when compacting the flattened <code>input</code>; either
+            in the form of an <tref>JSON object</tref> or as <tref>IRI</tref>. If
+            <tref>null</tref> is passed, the result will not be compacted but keept
+            in expanded form.</dd>
+          <dt>JsonLdCallback callback</dt>
+          <dd>A callback that is called when processing completed successfully
+            on the given <code>input</code>, or a fatal error prevented
+            processing from completing.</dd>
+          <dt>optional JsonLdOptions? options</dt>
+          <dd>A set of options to configure the used algorithms such. This allows, e.g.,
+            to set the input document's base <tref>IRI</tref>.</dd>
+        </dl>
+      </dd>
+    </dl>
+
+  </section>
+
+  <section>
+    <h3>Callbacks</h3>
+
+    <p>JSON-LD processors utilize callbacks in order to return information in an
+      asynchronous manner to calling applications. This section details the
+      parameters sent to those callbacks.</p>
+
+    <section>
+      <h3>JsonLdCallback</h3>
+      <p>The <a>JsonLdCallback</a> is called when an API method of
+        <a>JsonLdProcessor</a> has been completed, either successfully or
+        by a fatal error.</p>
+
+      <dl title="callback JsonLdCallback = void" class="idl">
+        <dt>JsonLdError error</dt>
+        <dd>If the value is <tref>null</tref>, then no issue was detected
+          during processing. Otherwise, a processing issue was detected and
+          the details are contained within the <em>error</em> object.</dd>
+        <dt>object or object[] document</dt>
+        <dd>The processed JSON-LD document.</dd>
+      </dl>
+    </section>
+  </section>
+
+  <section>
+    <h3>Data Structures</h3>
+    <p>This section describes datatype definitions used within the JSON-LD API.</p>
+
+    <section>
+      <h3>JsonLdOptions</h3>
+      <p>The <a>JsonLdOptions</a> type is used to pass various options to the <a>JsonLdProcessor</a> methods.</p>
+      <dl title="dictionary JsonLdOptions" class="idl">
+        <dt>DOMString base</dt>
+        <dd>The Base IRI to use when expanding the document. This overrides the value of
+          <em>input</em> if it is a <a>IRI</a>. If not specified and <em>input</em> is not
+          an <a>IRI</a>, the base IRI defaults to the current document IRI if in a browser context,
+          or the empty string if there is no document context.
+          <p class="issue atrisk" title="Feature at risk">The default value of this option
+            implies that all IRIs that cannot be compacted otherwise are transformed to relative IRIs
+            during compaction. To avoid that data is being lost, developers thus have to store the
+            base IRI along with the compacted document. This might be problematic in practice and
+            thus the default behavior might be changed in future.</p>
+        </dd>
+        <dt>object or DOMString expandContext = null</dt>
+        <dd>A context that is used to initialize the active context when expanding a document.</dd>
+        <dt>boolean compactArrays = true</dt>
+        <dd>If set to <code>true</code>, the JSON-LD processor replaces arrays with just
+          one element with that element during compaction. If set to <code>false</code>,
+          all arrays will remain arrays even if they have just one element.
+        </dd>
+        <dt>boolean optimize = false</dt>
+        <dd>If set to <code>true</code>, the JSON-LD processor is allowed to
+          optimize the output of the <a href="#compaction-algorithm">Compaction Algorithm</a>
+          to produce even compacter representations. The algorithm for compaction
+          optimization is beyond the scope of this specification and thus
+          not defined. Consequently, different implementations MAY implement
+          different optimization algorithms.
+        </dd>
+        <dt>boolean useRdfType = false</dt>
+        <dd>If set to <code>true</code>, the JSON-LD processor will use the
+          expanded <code>rdf:type</code> IRI as the property instead of
+          <code>@type</code> when <a href="#convert-from-rdf-algorithm">converting from RDF</a>.
+        </dd>
+        <dt>boolean useNativeTypes = true</dt>
+        <dd>If set to <code>true</code>, the JSON-LD processor will try to convert
+          <tref title="typed value">typed values</tref> to JSON native types instead of using the
+          expanded object form when <a href="#convert-from-rdf-algorithm">converting from RDF</a>.
+          <code>xsd:boolean</code> values will be converted to <tref>true</tref> or <tref>false</tref>.
+          <code>xsd:integer</code> and <code>xsd:double</code> values will be
+          converted to
+          <tref title="number">JSON numbers</tref>.
+        </dd>
+      </dl>
+    </section>
+
+    <section>
+      <h3>JsonLdError</h3>
+
+      <p>The <a>JsonLdError</a> type is used to report processing errors
+        to a <a>JsonLdCallback</a>.</p>
+
+      <dl title="dictionary JsonLdError" class="idl">
+        <dt>JsonLdErrorCode code</dt>
+        <dd>a string representing the particular error type, as described in
+          the various algorithms in this document.</dd>
+        <dt>DOMString? message</dt>
+        <dd>an optional error message containing additional debugging information.
+          The specific contents of error messages are outside the scope of this
+          specification.</dd>
+      </dl>
+    </section>
+
+    <section>
+      <h3>JsonLdErrorCode</h3>
+      <p>The <a>JsonLdErrorCode</a> represents the collection of valid JSON-LD error
+        codes.</p>
+
+      <dl title="enum JsonLdErrorCode" class="idl">
+        <dt>invalid syntax</dt>
+        <dd>The document could not be parsed as JSON.</dd>
+        <dt>list of lists detected</dt>
+        <dd>A list of lists was detected. List of lists are not supported in
+          this version of JSON-LD due to the algorithmic complexity associated
+          with conversion to RDF.</dd>
+        <dt>invalid @index value</dt>
+        <dd>An <code>@index</code> member was encountered whose value was
+          not a <tref>string</tref>.</dd>
+        <dt>conflicting indexes</dt>
+        <dd>Multiple conflicting indexes have been found for the same node.</dd>
+        <dt>invalid @id value</dt>
+        <dd>An <code>@id</code> member was encountered whose value was not a
+          <tref>string</tref>.</dd>
+        <dt>invalid local context</dt>
+        <dd>In invalid <tref>local context</tref> was detected.</dd>
+        <dt>loading remote context failed</dt>
+        <dd>There was a problem encountered loading a remote context.</dd>
+        <dt>invalid remote context</dt>
+        <dd>No valid context document has been found for a referenced,
+         remote context.</dd>
+        <dt>recursive context inclusion</dt>
+        <dd>A cycle in remote context inclusions has been detected.</dd>
+        <dt>invalid default language</dt>
+        <dd>The value of the <tref>default language</tref> is not a <tref>string</tref>
+          or <tref>null</tref> and thus invalid.</dd>
+        <dt>invalid vocab mapping</dt>
+        <dd>An invalid <tref>vocabulary mapping</tref> has been detected, i.e.,
+          it is neither an <tref>absolute IRI</tref> nor <tref>null</tref>.</dd>
+        <dt>keyword redefinition</dt>
+        <dd>A <tref>keyword</tref> redefinition has been detected.</dd>
+        <dt>invalid term definition</dt>
+        <dd>An invalid <tref>term definition</tref> has been detected.</dd>
+        <dt>invalid term IRI mapping</dt>
+        <dd>A <tref>local context</tref> contains a <tref>term</tref> that
+          has not been mapped to an <tref>absolute IRI</tref>.</dd>
+        <dt>cyclic IRI mapping</dt>
+        <dd>A cycle in <tref title="IRI mapping">IRI mappings</tref> has been detected.</dd>
+        <dt>invalid type mapping</dt>
+        <dd>An <code>@type</code> member in a <tref>term definition</tref>
+          was encountered whose value could not be expanded to an
+          <tref>absolute IRI</tref>.</dd>
+        <dt>invalid language mapping</dt>
+        <dd>An <code>@language</code> member in a <tref>term definition</tref>
+          was encountered whose value was neither a <tref>string</tref> nor
+          <tref>null</tref> and thus invalid.</dd>
+        <dt>invalid container mapping</dt>
+        <dd>An <code>@container</code> member was encountered whose value was
+          not one of the following <tref title="string">strings</tref>:
+          <code>@list</code>, <code>@set</code>, or <code>@index</code>.</dd>
+        <dt>invalid property generator</dt>
+        <dd>A non-<tref>string</tref> value has been detected in a
+          <tref title="property generator">property generator's</tref>
+          <tref>IRI mapping</tref>.</dd>
+        <dt>invalid property generator IRI mapping</dt>
+        <dd>Expanding all values of a
+          <tref title="property generator">property generator's</tref>
+          <tref>IRI mapping</tref> to <tref>absolute IRI</tref> failed.</dd>
+        <dt>property generator in term definition</dt>
+        <dd>A <tref>property generator</tref> was used in the
+          <tref>IRI mapping</tref> of another <tref>term</tref> or
+          <tref>property generator</tref>.</dd>
+        <dt>invalid type value</dt>
+        <dd>An invalid value for an <code>@type</code> member has been detected,
+          i.e., the value was neither a <tref>string</tref> nor an <tref>array</tref>
+          of <tref title="string">strings</tref>.</dd>
+        <dt>invalid value object</dt>
+        <dd>A <tdef>value object</tdef> with disallowed members has been
+          detected.</dd>
+        <dt>invalid value object value</dt>
+        <dd>An invalid value for the <code>@value</code> member of a
+          <tref>value object</tref> has been detected, i.e., it is neither
+          a <tref>scalar</tref> nor <tref>null</tref>.</dd>
+        <dt>invalid language tagged string</dt>
+        <dd>A <tref>language-tagged string</tref> with disallowed members has
+          been detected.</dd>
+        <dt>invalid language value</dt>
+        <dd>A <tref>language-tagged string</tref> with an invalid language
+          value was detected.</dd>
+        <dt>invalid typed value</dt>
+        <dd>A <tref>typed value</tref> with disallowed members has been
+          detected.</dd>
+        <dt>invalid set or list object</dt>
+        <dd>A <tdef>set object</tref> or <tref>list object</tref> with
+          disallowed members has been detected.</dd>
+        <dt>language map invalid value</dt>
+        <dd>An invalid value in a <tdef>language map</tdef> was detected. It has
+          to be a <tref>string</tref> or an <tref>array</tref> of
+          <tref title="string">strings</tref>.</dd>
+        <dt>compaction to list of lists</dt>
+        <dd>The compacted document contains a list of lists as multiple
+          lists have been compacted to the same term.</dd>
+      </dl>
+    </section>
+
+  </section>
+</section>
+
+<section class="appendix">
+  <h1>Acknowledgements</h1>
+
+  <p>A large amount of thanks goes out to the JSON-LD Community Group
+    participants who worked through many of the technical issues on the mailing
+    list and the weekly telecons - of special mention are Niklas Lindström,
+    François Daoust, Lin Clark, and Zdenko 'Denny' Vrandečić.
+    The editors would like to thank Mark Birbeck, who provided a great deal of
+    the initial push behind the JSON-LD work via his work on RDFj.
+    The work of Dave Lehn and Mike Johnson are appreciated for reviewing,
+    and performing several implementations of the specification. Ian Davis is
+    thanked for his work on RDF/JSON. Thanks also to Nathan Rixham,
+    Bradley P. Allen, Kingsley Idehen, Glenn McDonald, Alexandre Passant,
+    Danny Ayers, Ted Thibodeau Jr., Olivier Grisel, Josh Mandel, Eric Prud'hommeaux,
+    David Wood, Guus Schreiber, Pat Hayes, Sandro Hawke, and Richard Cyganiak
+    or their input on the specification.</p>
+</section>
+
+</body>
+</html>
--- a/spec/latest/json-ld-api/merge-index-alternate2.html	Tue Feb 12 19:04:34 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4795 +0,0 @@
-<html>
-<head>
-<title>JSON-LD 1.0 Processing Algorithms and API</title>
-<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
-<script type="text/javascript" src="../respec-w3c-common.js" class="remove"></script>
-<script type="text/javascript" src="../respec-w3c-extensions.js" class="remove"></script>
-<script type="text/javascript" class="remove">
-//<![CDATA[
-  var respecConfig = {
-      // extend the bibliography entries
-      "localBiblio": localBibliography,
-
-      doRDFa: "1.1",
-      // specification status (e.g. WD, LCWD, NOTE, etc.). If in doubt use ED.
-      specStatus:           "ED",
-      // if you wish the publication date to be other than today, set this
-      //publishDate:          "2012-12-25",
-      copyrightStart:       "2010",
-
-      // the specification's short name, as in http://www.w3.org/TR/short-name/
-      shortName:            "json-ld-api",
-
-      // if there is a previously published draft, uncomment this and set its YYYY-MM-DD date
-      // and its maturity status
-      previousPublishDate:  "2012-09-30",
-      previousMaturity:     "ED",
-      previousURI:          "http://dvcs.w3.org/hg/json-ld/raw-file/66d980964784/spec/ED/json-ld-api/20120930/index.html",
-
-      // if there a publicly available Editor's Draft, this is the link
-      edDraftURI:           "http://json-ld.org/spec/latest/json-ld-api/index.html",
-
-      testSuiteURI:         "http://json-ld.org/test-suite/",
-
-      // if this is a LCWD, uncomment and set the end of its review period
-      // lcEnd: "2009-08-05",
-
-      // if you want to have extra CSS, append them to this list
-      // it is recommended that the respec.css stylesheet be kept
-      // extraCSS: [],
-
-      issueBase: "https://github.com/json-ld/json-ld.org/issues/",
-
-      // editors, add as many as you like
-      // only "name" is required
-      editors:  [
-          { name: "Markus Lanthaler", url: "http://www.markus-lanthaler.com/",
-            company: "Graz University of Technology", companyURL: "http://www.tugraz.at/" },
-          { name: "Gregg Kellogg", url: "http://greggkellogg.net/",
-            company: "Kellogg Associates", companyURL: "http://kellogg-assoc.com/" },
-          { name: "Manu Sporny", url: "http://manu.sporny.org/",
-            company: "Digital Bazaar", companyURL: "http://digitalbazaar.com/" },
-          { name: "Dave Longley", url: "http://digitalbazaar.com/",
-            company: "Digital Bazaar", companyURL: "http://digitalbazaar.com/"}
-      ],
-
-      // authors, add as many as you like.
-      // This is optional, uncomment if you have authors as well as editors.
-      // only "name" is required. Same format as editors.
-
-      authors:  [
-          { name: "Dave Longley", url: "http://digitalbazaar.com/",
-            company: "Digital Bazaar", companyURL: "http://digitalbazaar.com/"},
-          { name: "Gregg Kellogg", url: "http://greggkellogg.net/",
-            company: "Kellogg Associates", companyURL: "http://kellogg-assoc.com/" },
-          { name: "Markus Lanthaler", url: "http://www.markus-lanthaler.com/",
-            company: "Graz University of Technology", companyURL: "http://www.tugraz.at/" },
-          { name: "Manu Sporny", url: "http://manu.sporny.org/",
-            company: "Digital Bazaar", companyURL: "http://digitalbazaar.com/" }
-      ],
-
-      // name of the WG
-      wg:           "RDF Working Group",
-
-      // URI of the public WG page
-      wgURI:        "http://www.w3.org/2011/rdf-wg/",
-
-      // name (with the @w3c.org) of the public mailing to which comments are due
-      wgPublicList: "public-rdf-comments",
-
-      // URI of the patent status for this WG, for Rec-track documents
-      // !!!! IMPORTANT !!!!
-      // This is important for Rec-track documents, do not copy a patent URI from a random
-      // document unless you know what you're doing. If in doubt ask your friendly neighbourhood
-      // Team Contact.
-      wgPatentURI:  "http://www.w3.org/2004/01/pp-impl/46168/status",
-      maxTocLevel: 3,
-      preProcess: [ preProc ],
-      alternateFormats: [ {uri: "diff-20120930.html", label: "diff to previous version"} ],
-  };
-//]]>
-</script>
-<style type="text/css">
-  .diff { font-weight:bold; color:#0a3; }
-</style>
-</head>
-
-<body>
-<section id="abstract">
-
-<p>
-JSON [[!RFC4627]] has proven to be a highly useful object serialization and
-messaging format. JSON-LD [[!JSON-LD]] harmonizes the representation of
-Linked Data in JSON by outlining a common JSON representation format for
-expressing directed graphs, mixing both Linked Data and non-Linked Data in
-a single document. This document outlines an Application Programming
-Interface and a set of algorithms for programmatically transforming
-JSON-LD documents to make them easier to work with in programming
-environments like those that use JavaScript, Python, and Ruby.
-</p>
-
-</section>
-
-<section id="sotd">
-<p>This document has been under development for over 18 months in the
-JSON for Linking Data Community Group. The document has recently been
-transferred to the RDF Working Group for review, improvement, and publication
-along the Recommendation track. The specification has undergone significant
-development, review, and changes during the course of the last 18 months.
-</p>
-<p>There are several independent
-<a href="http://json-ld.org/#impl">interoperable implementations</a> of
-this specification. There is
-a <a href="https://github.com/json-ld/json-ld.org/tree/master/test-suite">fairly complete test suite</a>
-and a <a href="http://json-ld.org/playground/">live JSON-LD editor</a>
-that is capable of demonstrating the features described in
-this document. While there will be continuous development on implementations,
-the test suite, and the live editor, they are believed to be mature enough
-to be integrated into a non-production system at this point in time. There
-is an expectation that they could be used in a production system within the
-year.
-</p>
-<p class="issue">
-It is important for readers to understand that the scope of this document is
-currently under debate and new features may be added to the specification.
-Existing features may be modified heavily or removed entirely from the
-specification upon further review and feedback from the broader community.
-This is a work in progress and publication as a Working Draft
-does not require that all Working Group members agree on the content of the
-document.
-</p>
-
-<p>There are a number of ways that one may participate in the development of
-  this specification:</p>
-
-<ul>
-  <li>If you want to make sure that your feedback is formally addressed by
-    the RDF Working Group, you should send it to public-rdf-comments:
-    <a href="http://lists.w3.org/Archives/Public/public-rdf-comments/">public-rdf-comments@w3.org</a></li>
-
-  <li>Ad-hoc technical discussion primarily occurs on the public community mailing list:
-    <a href="http://lists.w3.org/Archives/Public/public-linked-json/">public-linked-json@w3.org</a></li>
-
-  <li><a href="http://json-ld.org/minutes/">Public JSON-LD Community Group teleconferences</a>
-    are held on Tuesdays at 1500UTC every week. Participation is open to the
-    public.</li>
-
-  <li>RDF Working Group teleconferences are held on Wednesdays at 1500UTC
-    every week. Participation is limited to RDF Working Group members.</li>
-
-  <li>Specification bugs and issues should be reported in the
-    <a href="https://github.com/json-ld/json-ld.org/issues">issue tracker</a>
-    if you do not want to send an email to the public-rdf-comments mailing
-    list.</li>
-
-  <li><a href="https://github.com/json-ld/json-ld.org/tree/master/spec">Source code</a>
-    for the specification can be found on Github.</li>
-
-  <li>The <a href="http://webchat.freenode.net/?channels=json-ld">#json-ld</a>
-    IRC channel is available for real-time discussion on irc.freenode.net.</li>
-</ul>
-
-</section>
-
-<section class="informative">
-<h2>Introduction</h2>
-
-<p>
-This document is a detailed specification for an Application Programming
-Interface for the JSON-LD Syntax. The document is primarily intended for
-the following audiences:
-</p>
-
-<ul>
-  <li>Web authors and developers that want a very detailed view of how
-    a JSON-LD processor and the API operates.</li>
-  <li>Software developers that want to implement processors and APIs for
-    JSON-LD documents.</li>
-</ul>
-
-<p>
-To understand the basics in this specification you must first be familiar with
-JSON, which is detailed in [[!RFC4627]]. You must also understand the
-JSON-LD Syntax [[!JSON-LD]], which is the base syntax used by all of the
-algorithms in this document. To understand the API and how it is
-intended to operate in a programming environment, it is useful to have working
-knowledge of the JavaScript programming language [[ECMA-262]] and
-WebIDL [[!WEBIDL]]. To understand how JSON-LD maps to RDF, it is helpful to be
-familiar with the basic RDF concepts [[!RDF-CONCEPTS]].</p>
-
-</section>
-
-<section class="informative">
-<h1>Features</h1>
-
-<p>The JSON-LD Syntax specification [[!JSON-LD]] outlines a syntax that may be
-  used to express Linked Data in JSON. Because there is more than one way to
-  express Linked Data using this syntax, it is often useful to be able to
-  transform JSON-LD documents so that they may be more easily consumed by
-  specific applications.</p>
-
-<p>There are four major types of transformation that are discussed in this document:
-  expansion, compaction, flattening, and RDF conversion.</p>
-
-<section class="informative">
-  <h2>Expansion</h2>
-
-  <p>JSON-LD allows <tref>context</tref> to be applied to JSON data. Applying
-    <tref>context</tref> to JSON data allows it to be expressed in a way that
-    is specifically tailored to a particular person or application. A common
-    use case occurs when an application or person wants to use data that was
-    created using a different <tref>context</tref> than they would prefer.
-    Therefore, a JSON-LD processor must be able to transform the data from
-    one <tref>context</tref> to another. Instead of requiring JSON-LD processors
-    to write specific code for every imaginable <tref>context</tref> switching
-    scenario, it is much easier to specify a single algorithm that can remove
-    any <tref>context</tref> (and another that can subsequently apply any
-    <tref>context</tref>). The algorithm that removes <tref>context</tref> is
-    called <tdef>expansion</tdef>.</p>
-
-  <p>To get an idea of how context and data structuring affects the same data,
-    here is an example of JSON-LD that uses only <tref title="term">terms</tref>
-    and is fairly compact:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Sample JSON-LD document">
-  <!--
-  {
-    "@context": {
-      "name": "http://schema.org/name",
-      "homepage": {
-        "@id": "http://schema.org/url",
-        "@type": "@id"
-      }
-    },
-    "@id": "http://me.markus-lanthaler.com/",
-    "name": "Markus Lanthaler",
-    "homepage": "http://www.markus-lanthaler.com/"
-  }
-  -->
-  </pre>
-
-  <p>The next input example uses one <tref>IRI</tref> to express a property
-    and <tref title="array">array</tref> to encapsulate another, but
-    leaves the rest of the information untouched.</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Sample JSON-LD document using a IRI instead of a term to express a property">
-  <!--
-  {
-    "@context": {
-      "homepage": {
-        "@id": "http://schema.org/url",
-        "@type": "@id"
-      }
-    },
-    "@id": "http://me.markus-lanthaler.com/",
-    "****http://schema.org/name****": "Markus Lanthaler",
-    "homepage": ****[****"http://www.markus-lanthaler.com/"****]****
-  }
-  -->
-  </pre>
-
-  <p>Note that both inputs are valid JSON-LD and both represent the same
-    information. The difference is in their <tref>context</tref> information
-    and in the data structures used. A JSON-LD processor can remove
-    <tref>context</tref> and ensure that the data is more regular by employing
-    <tref>expansion</tref>.</p>
-
-  <p><tref>Expansion</tref> has two important goals: ensuring all values
-    are represented in a regular form, and removing any contextual information
-    from the document. These goals are accomplished by expanding all properties
-    to <tref title="absolute IRI">absolute IRIs</tref> and by expressing all
-    values in <tref title="array">arrays</tref> in
-    <tref>expanded form</tref>. <tref>Expanded form</tref> is the most verbose
-    and regular way of expressing of values in JSON-LD; all contextual
-    information from the document is instead stored locally with each value.
-    Running the <a href="#expansion-algorithm">Expansion algorithm</a> against
-    the examples provided above results in the following output:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Expanded sample document">
-  <!--
-  [
-    {
-      "@id": "http://me.markus-lanthaler.com/",
-      "http://schema.org/name": [
-        { "@value": "Markus Lanthaler" }
-      ],
-      "http://schema.org/url": [
-        { "@id": "http://www.markus-lanthaler.com/" }
-      ]
-    }
-  ]
-  -->
-  </pre>
-
-  <p>Note that in the output above all <tref>context</tref> definitions have
-    been removed, all <tref title="term">terms</tref> and <tref title="compact IRI">compact IRIs</tref>
-    have been expanded to absolute <tref title="IRI">IRIs</tref>, and all
-    <tref title="JSON-LD value">JSON-LD values</tref> are expressed in <tref title="array">arrays</tref> in <tref>expanded form</tref>.
-    While the output is more verbose and difficult for a human to read, it establishes a
-    baseline that makes JSON-LD processing easier because of its very regular
-    structure.</p>
-
-</section>
-
-<section class="informative">
-  <h2>Compaction</h2>
-
-  <p>While <tref>expansion</tref> removes <tref>context</tref> from a given
-    input, <tref title="compaction">compaction's</tref> primary function is to
-    perform the opposite operation: to express a given input according to
-    a particular <tref>context</tref>. <tdef>Compaction</tdef> applies a
-    <tref>context</tref> that specifically tailors the way information is
-    expressed for a particular person or application. This simplifies applications
-    that consume JSON or JSON-LD by expressing the data in application-specific
-    terms, and it makes the data easier to read by humans.
-
-  <p><tref>Compaction</tref> uses a developer-supplied <tref>context</tref> to shorten
-    <tref title="IRI">IRIs</tref> to <tref title="term">terms</tref> or
-    <tref title="compact IRI">compact IRIs</tref> and <tref title="JSON-LD value">JSON-LD values</tref>
-    expressed in <tref>expanded form</tref> to simple values such as
-    <tref title="string">strings</tref> or <tref title="number">numbers</tref>.</p>
-
-  <p>For example, assume the following expanded JSON-LD input document:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Expanded sample document">
-  <!--
-  [
-    {
-      "@id": "http://me.markus-lanthaler.com/",
-      "http://schema.org/name": [
-        { "@value": "Markus Lanthaler" }
-      ],
-      "http://schema.org/url": [
-        { "@id": "http://www.markus-lanthaler.com/" }
-      ]
-    }
-  ]
-  -->
-  </pre>
-
-  <p>Additionally, assume the following developer-supplied JSON-LD <tref>context</tref>:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="JSON-LD context">
-  <!--
-  {
-    "@context": {
-      "name": "http://schema.org/name",
-      "homepage": {
-        "@id": "http://schema.org/url",
-        "@type": "@id"
-      }
-    }
-  }
-  -->
-  </pre>
-
-  <p>Running the <a href="#compaction-algorithm">Compaction Algorithm</a> given the context
-    supplied above against the JSON-LD input document provided above would result in the
-    following output:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Compacted sample document">
-  <!--
-  {
-    "@context": {
-      "name": "http://schema.org/name",
-      "homepage": {
-        "@id": "http://schema.org/url",
-        "@type": "@id"
-      }
-    },
-    "@id": "http://me.markus-lanthaler.com/",
-    "name": "Markus Lanthaler",
-    "homepage": "http://www.markus-lanthaler.com/"
-  }
-  -->
-  </pre>
-
-  <p>Note that all <tref title="IRI">IRIs</tref> have been compacted to
-    <tref title="term">terms</tref> as specified in the <tref>context</tref>,
-    which has been injected into the output. While compacted output is
-    useful to humans, it is also used to generate
-    structures that are easy to program against. Compaction enables developers to
-    map any expanded document into an application-specific compacted document.
-    While the context provided above mapped <code>http://schema.org/name</code>
-    to <code>name</code>, it could also have been mapped to any other term
-    provided by the developer.</p>
-
-</section>
-
-<section class="informative">
-  <h2>Flattening</h2>
-
-  <p>While expansion ensures that a document is in a uniform structure, flattening
-    goes a step further to ensure that the shape of the data is deterministic.
-    In expanded documents, the properties of a single properties <tref>node</tref>
-    may be spread across a number of different <tref title="JSON object">JSON objects</tref>.
-    By flattening a document, all properties of a <tref>node</tref> are collected in a
-    single <tref>JSON object</tref>. This may drastically simplify the code required
-    to process JSON-LD data in certain applications.</p>
-
-  <p>For example, assume the following JSON-LD input document:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Sample JSON-LD document">
-  <!--
-  {
-    "@context": {
-      "name": "http://schema.org/name",
-      "knows": "http://schema.org/knows"
-    },
-    "@id": "http://digitalbazaar.com/people/dlongley",
-    ****"knows"****: {
-      "@id": "http://digitalbazaar.com/people/msporny",
-      "name": "Manu Sporny",
-      "knows": {
-        "@id": "http://digitalbazaar.com/people/dlongley",
-        ****"name"****: "Dave Longley"
-      }
-    }
-  }
-  -->
-  </pre>
-
-  <p>Running the <a href="#flattening-algorithm">Flattening Algorithm</a>
-    with a context set to <tref>null</tref> to prevent compaction returns
-    the following document:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Flattened sample document in expanded form">
-  <!--
-  [
-    ****{****
-      "@id": "http://digitalbazaar.com/people/dlongley",
-      ****"http://schema.org/name"****: [
-        { "@value": "Dave Longley" }
-      ],
-      ****"http://schema.org/knows"****: [
-        { "@id": "http://digitalbazaar.com/people/msporny" }
-      ]
-    ****}****,
-    {
-      "@id": "http://digitalbazaar.com/people/msporny",
-      "http://schema.org/name": [
-        { "@value": "Manu Sporny" }
-      ],
-      "http://schema.org/knows": [
-        { "@id": "http://digitalbazaar.com/people/dlongley" }
-      ]
-    }
-  ]
-  -->
-  </pre>
-
-  <p>Note how in the output above all properties of a <tref>node</tref> are collected in a
-    single <tref>JSON object</tref>.</p>
-
-  <p>To make it easier for humans to read or for certain applications to
-    process it, a flattened document can be compacted by passing a context. Using
-    the same context as the input document, the flattened and compacted document
-    looks as follows:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Flattened and compacted sample document">
-  <!--
-  {
-    "@context": {
-      "name": "http://schema.org/name",
-      "knows": "http://schema.org/knows"
-    },
-    "@graph": [
-      ****{****
-        "@id": "http://digitalbazaar.com/people/dlongley",
-        ****"name"****: "Dave Longley",
-        ****"knows"****: [
-          { "@id": "http://digitalbazaar.com/people/msporny" }
-        ]
-      ****}****,
-      {
-        "@id": "http://digitalbazaar.com/people/msporny",
-        "name": "Manu Sporny",
-        "knows": {
-          "@id": "http://digitalbazaar.com/people/dlongley"
-        }
-      }
-    ]
-  }
-  -->
-  </pre>
-
-  <p>Please note that the flattened and compacted result will explicitly
-    designate the default graph by the <code>@graph</code> member in the top-level
-    <tref>JSON object</tref>, except if its value contains just one item.</p>
-
-</section>
-
-<section class="informative">
-  <h2>RDF Conversion</h2>
-
-  <p>JSON-LD can be used to serialize data expressed in RDF as described in
-    [[RDF-CONCEPTS]]. This ensures that data can be round-tripped to and from
-    any RDF syntax without any loss in fidelity.</p>
-
-  <p>For example, assume the following RDF input serialized in Turtle [[TURTLE-TR]]:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Sample Turtle document">
-  <!--
-  <http://me.markus-lanthaler.com/> <http://schema.org/name> "Markus Lanthaler" .
-  <http://me.markus-lanthaler.com/> <http://schema.org/url> <http://www.markus-lanthaler.com/> .
-  -->
-  </pre>
-
-  <p>Using the <a href="#convert-from-rdf-algorithm">Convert from RDF Algorithm</a> a
-    developer could transform this document into expanded JSON-LD:</p>
-
-  <pre class="example" data-transform="updateExample"
-       title="Sample Turtle document converted to JSON-LD">
-  <!--
-  [
-    {
-      "@id": "http://me.markus-lanthaler.com/",
-      "http://schema.org/name": [
-        {
-          "@value": "Markus Lanthaler"
-        }
-      ],
-      "http://schema.org/url": [
-        {
-          "@id": "http://www.markus-lanthaler.com/"
-        }
-      ]
-    }
-  ]
-  -->
-  </pre>
-
-  <p>Note that the output above could easily be compacted using the technique outlined
-    in the previous section. It is also possible to transform the JSON-LD document back
-    to RDF using the <a href="#convert-to-rdf-algorithm">Convert to RDF Algorithm</a>.</p>
-
-</section>
-
-<!-- end of Features -->
-</section>
-
-<section>
-  <h1>Conformance</h1>
-
-  <p>All examples and notes as well as sections marked as non-normative in this
-    specification are non-normative. Everything else in this specification is
-    normative.</p>
-
-  <p>The keywords MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, RECOMMENDED,
-    MAY, and OPTIONAL in this specification are to be interpreted as described
-    in [[!RFC2119]].</p>
-
-  <p>There are two classes of products that can claim conformance to this
-    specification: <tref title="JSON-LD Implementation">JSON-LD Implementations</tref>
-    and <tref title="JSON-LD Processor">JSON-LD Processors</tref>.</p>
-
-  <p>A conforming <tdef>JSON-LD Implementation</tdef> is a system capable of transforming
-    JSON-LD documents according the algorithms defined in this specification.</p>
-
-  <p>A conforming <tdef>JSON-LD Processor</tdef> is a conforming <tref>JSON-LD Implementation</tref>
-    that exposes the Application Programming Interface (API) defined in this specification.</p>
-
-  <p>The algorithms in this specification are generally written with more concern for clarity than
-    efficiency. Thus, JSON-LD Implementations and Processors may implement the algorithms
-    given in this specification in any way desired, so long as the end result is indistinguishable
-    from the result that would be obtained by the specification's algorithms.</p>
-
-  <p>This specification does not define how JSON-LD Implementations or Processors handle
-    non-conforming input documents. This implies that JSON-LD Implementations or Processors
-    MUST NOT attempt to correct malformed <tref title="IRI">IRIs</tref> or language tags;
-    however, they MAY issue validation warnings. IRIs are not modified other than converted
-    between <tref title="relative IRI">relative</tref> and
-    <tref title="absolute IRI">absolute IRIs</tref>.</p>
-
-  <p class="note">Implementers can partially check their level of conformance to
-    this specification by successfully passing the test cases of the JSON-LD test
-    suite [[JSON-LD-TESTS]]. Note, however, that passing all the tests in the test
-    suite does not imply complete conformance to this specification. It only implies
-    that the implementation conforms to aspects tested by the test suite.</p>
-
-</section>
-
-<section>
-  <h1>General Terminology</h1>
-
-  <p>This document uses the following terms as defined in JSON [[!RFC4627]]. Refer
-    to the <em>JSON Grammar</em> section in [[!RFC4627]] for formal definitions.</p>
-
-  <dl>
-    <dt><tdef>JSON object</tdef></dt>
-    <dd>An object structure is represented as a pair of curly brackets
-      surrounding zero or more key-value pairs. A key is a
-      <tref>string</tref>. A single colon comes after each key, separating the
-      key from the value. A single comma separates a value from a following
-      key.</dd>
-    <dt><tdef>array</tdef></dt>
-    <dd>An array structure is represented as square brackets surrounding zero
-      or more values (or elements). Elements are separated by commas.
-      In JSON, an array is an <em>ordered</em> sequence of zero or more values.
-      While JSON-LD uses the same array representation as JSON,
-      the collection is <em>unordered</em> by default. While order is
-      preserved in regular JSON arrays, it is not in regular JSON-LD arrays
-      unless specific markup is provided (see <a href="#sets-and-lists"></a>).</dd>
-    <dt><tdef>string</tdef></dt>
-    <dd>A string is a sequence of zero or more Unicode characters,
-      wrapped in double quotes, using backslash escapes (if necessary). A
-      character is represented as a single character string.</dd>
-    <dt><tdef>number</tdef></dt>
-    <dd>A number is similar to that used in most programming languages, except
-      that the octal and hexadecimal formats are not used and that leading
-      zeros are not allowed.</dd>
-    <dt><tdef>true</tdef> and <tdef>false</tdef></dt>
-    <dd>Values that are used to express one of two possible boolean states.</dd>
-    <dt><tdef>null</tdef></dt>
-    <dd>The <tref>null</tref> value. A key-value pair in the
-      <code>@context</code> where the value, or the <code>@id</code> of the
-      value, is <tref>null</tref> explicitly decouples a term's association
-      with an IRI. A key-value pair in the body of a JSON-LD document whose
-      value is <tref>null</tref> has the same meaning as if the key-value pair
-      was not defined. If <code>@value</code>, <code>@list</code>, or
-      <code>@set</code> is set to <tref>null</tref> in expanded form, then
-      the entire <tref>JSON object</tref> is ignored.</dd>
-  </dl>
-
-  <p>Furthermore, the following terminology is used throughout this document:</p>
-
-  <dl>
-    <dt><tdef>keyword</tdef></dt>
-    <dd>A JSON key that is specific to JSON-LD, specified in the JSON-LD Syntax specification [[!JSON-LD]]
-      in the section titled <cite><a href="../json-ld-syntax/#syntax-tokens-and-keywords">Syntax Tokens and Keywords</a></cite>.</dd>
-    <dt><tdef>context</tdef></dt>
-    <dd>A a set of rules for interpreting a JSON-LD document as specified in
-      <cite><a href="../json-ld-syntax/#the-context">The Context</a></cite> of the [[JSON-LD]] specification.</dd>
-    <dt><tdef>JSON-LD document</tdef></dt>
-    <dd>A <tref>JSON-LD document</tref> is a serialization of a collection of
-      <tref title="JSON-LD graph">JSON-LD graphs</tref> and comprises exactly one
-      <tref>default graph</tref> and zero or more <tref title="named graph">named graphs</tref>.</dd>
-    <dt><tdef>named graph</tdef></dt>
-    <dd>A named graph is a pair consisting of an <tref>IRI</tref> or <tref>blank node</tref>
-      (the <tdef>graph name</tdef>) and a <tref>JSON-LD graph</tref>.</dd>
-    <dt><tdef>default graph</tdef></dt>
-    <dd>The default graph is the only graph in a JSON-LD document which has no <tref>graph name</tref>.</dd>
-    <dt><tdef>JSON-LD graph</tdef></dt>
-    <dd>A labeled directed graph, i.e., a set of <tref title="node">nodes</tref> connected by <tref title="edge">edges</tref>,
-      as specified in the <cite><a href="../json-ld-syntax/#data-model">Data Model</a></cite> section of the JSON-LD syntax
-      specification [[!JSON-LD]].</dd>
-    <dt><tdef>edge</tdef></dt>
-    <dd>Every <tref>edge</tref> has a direction associated with it and is labeled with
-      an <tref>IRI</tref> or a <tref>blank node identifier</tref>. Within the JSON-LD syntax
-      these edge labels are called <tdef title="property">properties</tdef>. Whenever possible, an
-      <tref>edge</tref> SHOULD be labeled with an <tref>IRI</tref>.</dd>
-    <dt><tdef>node</tdef></dt>
-    <dd>Every <tref>node</tref> is an <tref>IRI</tref>, a <tref>blank node</tref>,
-      a <tref>JSON-LD value</tref>, or a <tref>list</tref>.</dd>
-    <dt><tdef><abbr title="Internationalized Resource Identifier">IRI</abbr></tdef></dt>
-    <dd>An <tref>IRI</tref> (Internationalized Resource Identifier) is a string that conforms to the syntax
-      defined in [[RFC3987]].</dd>
-    <dt><tdef>absolute IRI</tdef></dt>
-    <dd>An absolute IRI is defined in [[!RFC3987]] containing a <em>scheme</em> along with a <em>path</em> and
-      optional <em>query</em> and fragment segments.</dd>
-    <dt><tdef>relative IRI</tdef></dt>
-    <dd>A relative IRI is an IRI that is relative some other <tref>absolute IRI</tref>;
-      in the case of JSON-LD this is the base location of the document.</dd>
-    <dt><tdef>blank node</tdef></dt>
-    <dd>A <tref>node</tref> in a <tref>JSON-LD graph</tref> that does not contain a de-referenceable
-      identifier because it is either ephemeral in nature or does not contain information that needs to be
-      linked to from outside of the JSON-LD graph.</dd>
-    <dt><tdef>blank node identifier</tdef></dt>
-    <dd>A blank node identifier is a string that can be used as an identifier for a <tref>blank node</tref> within
-      the scope of a JSON-LD document. Blank node identifiers begin with <code>_:</code>.</dd>
-    <dt><tdef>JSON-LD value</tdef></dt>
-    <dd>A <tref>JSON-LD value</tref> is a <tref>string</tref>, a <tref>number</tref>,
-      <tref>true</tref> or <tref>false</tref>, a <tref>typed value</tref>, or a
-      <tref>language-tagged string</tref>.</dd>
-    <dt><tdef>typed value</tdef></dt>
-    <dd>A <tref>typed value</tref> consists of a value, which is a string, and a type, which is an <tref>IRI</tref>.</dd>
-    <dt><tdef>language-tagged string</tdef></dt>
-    <dd>A <tref>language-tagged string</tref> consists of a string and a non-empty language
-      tag as defined by [[BCP47]]. The language tag must be well-formed according to section
-      <a href="http://tools.ietf.org/html/bcp47#section-2.2.9">2.2.9</a> of [[BCP47]], and MUST
-      be normalized to lowercase.</dd>
-    <dt><tdef>list</tdef></dt>
-    <dd>A <tref>list</tref> is an ordered sequence of <tref title="IRI">IRIs</tref>,
-      <tref title="blank node">blank nodes</tref>, and
-      <tref title="JSON-LD value">JSON-LD values</tref>.</dd>
-  </dl>
-
-</section>
-
-<section>
-<h1>Algorithms</h1>
-
-<p>All algorithms described in this section are intended to operate on
-  language-native data structures. That is, the serialization to a text-based
-  JSON document isn't required as input or output to any of these algorithms and
-  language-native data structures MUST be used where applicable.</p>
-
-<section>
-  <h2>Algorithm Terms</h2>
-
-  <dl>
-    <dt><tdef>active graph</tdef></dt>
-    <dd>The name of the currently active graph that the processor should use when
-      processing.</dd>
-    <dt><tdef>active subject</tdef></dt>
-    <dd>The currently active subject that the processor should use when
-      processing.</dd>
-    <dt><tdef>active property</tdef></dt>
-    <dd>The currently active property that the processor should use when
-      processing. The active property is represented in the original lexical form, which
-      is used for finding type mappings in the <tref>active context</tref>.</dd>
-    <dt><tdef>active object</tdef></dt>
-    <dd>The currently active object that the processor should use when
-      processing.</dd>
-    <dt><tdef>active context</tdef></dt>
-    <dd>A context that is used to resolve <tref title="term">terms</tref> while
-      the processing algorithm is running.</dd>
-    <dt><tdef>local context</tdef></dt>
-    <dd>A context that is specified within a <tref>JSON object</tref>,
-      specified via the <code>@context</code> <tref>keyword</tref>.</dd>
-    <dt><tdef>JSON-LD input</tdef></dt>
-    <dd>The JSON-LD data structure that is provided as input to the algorithm.</dd>
-    <dt><tdef>JSON-LD output</tdef></dt>
-    <dd>The JSON-LD data structure that is produced as output by the algorithm.</dd>
-    <dt><tdef>term</tdef></dt>
-    <dd>A <tref>term</tref> is a short word defined in a context that MAY be expanded to an <tref>IRI</tref></dd>
-    <dt><tdef>compact IRI</tdef></dt>
-    <dd>A compact IRI is has the form of <tdef>prefix</tdef>:<em>suffix</em> and is used as a way
-      of expressing an IRI without needing to define separate <tref>term</tref> definitions for
-      each IRI contained within a common vocabulary identified by <tref>prefix</tref>.</dd>
-    <dt><tdef>node object</tdef></dt>
-    <dd>A <tref>node object</tref> represents zero or more properties of a
-      <tref>node</tref> in the <tref>JSON-LD graph</tref> serialized by the
-      JSON-LD document. A <tref>JSON object</tref> is a <tref>node object</tref>
-      if it exists outside of the JSON-LD <tref>context</tref> and:
-      <ul>
-        <li>it does not contain the <code>@value</code>, <code>@list</code>,
-          or <code>@set</code> keywords, or</li>
-        <li>it is not the top-level <tref>JSON object</tref> in the JSON-LD document containing
-          the <code>@graph</code> keyword.</li>
-      </ul>
-    </dd>
-    <dt><tdef>list object</tdef></dt>
-    <dd>A <tref>list object</tref> is a <tref>JSON object</tref> that has an <code>@list</code>
-      member.</dd>
-    <dt><tdef>scalar</tdef></dt>
-    <dd>A scalar is either a JSON <tref>string</tref>, <tref>number</tref>, <tref>true</tref>,
-      or <tref>false</tref>.</dd>
-    <dt><tdef>quad</tdef></dt>
-    <dd>An <em>RDF triple</em> as specified by [[RDF-CONCEPTS]] augmented with
-      a fourth component, a <tref>graph name</tref>.</dd>
-    <dt><tdef>RDF subject</tdef></dt>
-    <dd>A <em>subject</em> as specified by [[RDF-CONCEPTS]].</dd>
-    <dt><tdef>RDF predicate</tdef></dt>
-    <dd>A <em>predicate</em> as specified by [[RDF-CONCEPTS]].</dd>
-    <dt><tdef>RDF object</tdef></dt>
-    <dd>An <em>object</em> as specified by [[RDF-CONCEPTS]].</dd>
-  </dl>
-
-</section>
-
-<section>
-<h2 id="remote-context">Remote Context Resolution</h2>
-
-<section>
-<h3>Problem</h3>
-
-<p>
-A JSON-LD document may contain remote <tref title="context">contexts</tref>.
-These <tref title="context">contexts</tref> must be dereferenced before they
-can be processed.
-</p>
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-Dereferencing remote <tref title="context">contexts</tref> can be performed
-either inline with the other JSON-LD algorithms or as a separate, prior step.
-This solution opts to dereference them first, in a prior step, to both
-separate concerns and to better enable <tref>active context</tref> caching.
-By separating concerns, the other JSON-LD algorithms can be described more
-simply. Implementations may also be either simplified or made more efficient
-because there is no need to block or respond to events when remote
-<tref title="context">contexts</tref> are dereferenced over the network. This
-is particularly important for simplifying implementations in asynchronous
-programming environments. Of course, choosing this approach is not a
-requirement.
-</p>
-
-<p>
-The JSON-LD document is searched for remote <tref title="context">contexts</tref>
-recursively, starting with its root <em>element</em>. If the <em>element</em>
-contains an <code>@context</code> key, its value is searched for
-<tref title="string">strings</tref>. The result represents a remote
-<tref>context</tref>, which we add to a map that will ensure we don't
-dereference an already dereferenced remote
-<tref>context</tref> for a given <tref>IRI</tref>.
-</p>
-
-<p>
-When we have finished searching, we dereference each remote
-<tref>context</tref> (or get its already-dereferenced value from our map).
-Each time we dereference a remote <tref>context</tref>, we store its result
-in our map and then recursively search it for more remote
-<tref title="IRI">contexts</tref> as above, checking to ensure there is no
-cyclical reference, which is an error.
-</p>
-
-<p>
-Once all of the remote <tref title="IRI">contexts</tref> have been
-dereferenced, we replace all of their associated <tref>context</tref>
-<tref title="IRI">IRIs</tref> in the JSON-LD document with the
-results from our map.
-</p>
-
-</section>
-
-<!-- end of Remote Context Resolution -->
-</section>
-
-<section>
-  <h2 id="context-processing">Context Processing</h2>
-
-  <p>When processing a JSON-LD data structure, each processing rule is applied
-    using information provided by the <tref>active context</tref>. This
-    section describes how to produce an <tref>active context</tref>.</p>
-
-  <p>The <tref>active context</tref> contains the active <tdef title="term definition">term definitions</tdef>
-    which specify how properties and values have to be interpreted as well as the current
-    <tdef>vocabulary mapping</tdef> and the <tdef>default language</tdef>. Each <tref>term definition</tref> consists
-    of an <tdef>IRI mapping</tdef> and optionally a <tdef>type mapping</tdef> from terms to datatypes or
-    <tdef>language mapping</tdef> from terms to language codes, and a <tdef>container mapping</tdef>. If an
-    <tref>IRI mapping</tref> maps a term to multiple <tref="IRI">IRIs</tref> it is said to be a
-    <tdef>property generator</tdef>. The <tref>active context</tref> also
-    keeps track of <tref>keyword</tref> aliases.</p>
-
-  <p>When processing, the <tref>active context</tref> is initialized
-    without any <tref title="term definition">term definitions</tref>,
-    <tref>vocabulary mapping</tref>, or <tref>default language</tref>.
-    If a <tref>local context</tref> is encountered during processing, a new
-    <tref>active context</tref> is created by cloning the existing
-    <tref>active context</tref>. Then the information from the
-    <tref>local context</tref>
-
-    is merged into the new <tref>active context</tref>. A <tref>local context</tref> is identified within
-    a <tref>JSON object</tref> by the value of the <code>@context</code> key, which MUST be a <tref>string</tref>, an
-    <tref>array</tref>, or a <tref>JSON object</tref>.</p>
-
-<section>
-<h3>Problem</h3>
-
-<p>
-A <tref>local context</tref> needs to be transformed into an
-<tref>active context</tref> so that the <tref>active context</tref> can be
-used when executing other JSON-LD algorithms such as
-<a href="#expansion-algorithm">Expansion</a> or
-<a href="#compaction-algorithm">Compaction</a>. Any remote
-<tref title="context">contexts</tref> in the <tref>local context</tref>
-have already been dereferenced.
-</p>
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-First we prepare a new <tref>active context</tref> <em>result</em> by cloning
-the current <tref>active context</tref>. Next we update the
-<tref>vocabulary mapping</tref> and <tref>default language</tref> by
-processing two specific keywords: <code>@vocab</code> and <code>@language</code>.
-These are handled before any other keys in the <tref>local context</tref> because
-they affect how the other keys are processed.
-</p>
-
-<p>
-Then, for every other key in <tref>local context</tref>, we update
-the <tref>term definition</tref> in <em>result</em>.
-</p>
-
-<p>
-Since <tref title="context">context</tref> values in a
-<tref>local context</tref> may themselves contain
-<tref title="compact IRI">compact IRIs</tref>, we may need to recurse to
-define a <tref>prefix</tref>. When doing so, we must ensure that there is
-no cyclical dependency, which is an error. After we have processed any
-<tref title="term definition">term definition</tref> dependencies, we update
-the current <tref title="term definition">term definition</tref>, which may be
-a keyword alias or consist of <code>@id</code>, <code>@language</code>,
-<code>@type</code>, or <code>@container</code> mappings.
-</p>
-
-<p>
-Finally, we return <em>result</em> as the new <tref>active context</tref>.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-This algorithm specifies how a new <tref>active context</tref> is updated
-with a <tref>local context</tref>. The algorithm takes two input variables:
-an <tref>active context</tref> and a <tref>local context</tref>.
-
-<ol class="algorithm">
-  <li>
-    Initialize <em>result</em> to the result of cloning
-    <tref>active context</tref>.
-  </li>
-  <li>
-    If <tref>local context</tref> is not an <tref>array</tref>, then
-    set it equal to an <tref>array</tref> containing only
-    <tref>local context</tref>.
-  </li>
-  <li>
-    For each item <em>context</em> in <tref>local context</tref>:
-    <ol class="algorithm">
-      <li>
-        If <em>context</em> equals <tref>null</tref>, then set <em>result</em>
-        to a newly-initialized <tref>active context</tref> and continue to the
-        next <em>context</em>.
-      </li>
-      <li>
-        At this point, <em>context</em> MUST be a <tref>JSON object</tref>
-        because all remote <tref title="context">contexts</tref> have already
-        been dereferenced. Otherwise, an invalid value has been detected,
-        which is an error.
-      </li>
-      <li>
-        Create a <tref>JSON object</tref> <em>defined</em> to use to keep
-        track of whether or not a <tref>term</tref> has already been defined
-        or currently being defined during recursion.
-      </li>
-      <li>
-        If <em>context</em> has an <code>@vocab</code> key:
-        <ol class="algorithm">
-          <li>
-            Initialize <em>value</em> to the value associated with the
-            <code>@vocab</code> key.
-          </li>
-          <li>
-            If <em>value</em> equals <tref>null</tref>, then remove
-            any <tref>vocabulary mapping</tref> from <em>result</em>.
-          </li>
-          <li>
-            Otherwise, <em>value</em> MUST be an <tref>absolute IRI</tref>.
-            Otherwise, an invalid value has been detected, which is an error.
-            Set <em>result</em>'s <tref>vocabulary mapping</tref> to
-            <em>value</em>.
-          </li>
-          <li>
-            Set <em>defined</em>'s <code>@vocab</code> key to
-            <tref>true</tref>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        If <em>context</em> has an <code>@language</code> key:
-        <ol class="algorithm">
-          <li>
-            Initialize <em>value</em> to the value associated with the
-            <code>@language</code> key.
-          </li>
-          <li>
-            If <em>value</em> equals <tref>null</tref>, then remove
-            any <tref>default language</tref> from <em>result</em>.
-          </li>
-          <li>
-            Otherwise, <em>value</em> MUST be a <tref>string</tref>.
-            Otherwise, an invalid value has been detected, which is an error.
-            Set <em>result</em>'s <tref>default language</tref> to
-            lowercased <em>value</em>.
-          </li>
-          <li>
-            Set <em>defined</em>'s <code>@language</code> key to
-            <tref>true</tref>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        For each <em>key</em>-<em>value</em> pair in <em>context</em> invoke
-        the <a href="#create-term-definition">Create Term Definition</a>
-        subalgorithm, passing <em>result</em> for <tref>active context</tref>,
-        <em>context</em> for <tref>local context</tref>, <em>key</em>,
-        and <em>defined</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Return <em>result</em>.
-  </li>
-</ol>
-
-</section>
-
-<!-- end of Context Processing algorithm -->
-</section>
-
-<section>
-<h2 id="create-term-definition">Create Term Definition Subalgorithm</h2>
-
-<p>
-This algorithm is called from the
-<a href="#context-processing">Context Processing</a> algorithm to create
-<tref title="term definition">term definitions</tref> in a new
-<tref>active context</tref>.
-</p>
-
-<section>
-<h3>Problem</h3>
-
-A <tref>term definition</tref> must be created for the given
-<tref>term</tref>.
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-<tref title="term definition">Term definitions</tref> are created by
-parsing the information in the given <tref>local context</tref> for the
-given <tref>term</tref>. If the given <tref>term</tref> is a
-<tref>compact IRI</tref> with a <tref>prefix</tref> that is a key in the
-<tref>local context</tref>, then that <tref>prefix</tref> is considered
-a dependency with its own <tref>term definition</tref> that must first
-be created, through recursion, before continuing. Because a
-<tref>term definition</tref> can depend on other
-<tref title="term definition">term definitions</tref>, a mechanism must
-be used to detect cyclical dependencies. The solution employed here
-uses a map, <em>defined</em>, that keeps track of whether or not a
-<tref>term</tref> has been defined or is currently in the process of
-being defined. This map is checked before any recursion is attempted.
-</p>
-
-<p>
-After all dependencies have been defined, the rest of the information
-in the <tref>local context</tref> for the given <tref>term</tref> is
-taken into account, creating the appropriate <tref>IRI mapping</tref>,
-<tref>container mapping</tref>, and <tref>type mapping</tref> or
-<tref>language mapping</tref> for the <tref>term</tref>.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-The algorithm has four required inputs which are:
-an <tref>active context</tref>, a <tref>local context</tref>,
-a <em>term</em>, and a map <em>defined</em>.
-</p>
-
-<ol class="algorithm">
-  <li>
-    If <em>defined</em> contains the key <em>term</em>, then the associated
-    value MUST be <tref>true</tref>, indicating that the
-    <tref>term definition</tref> has already been created, so return.
-    Otherwise, a cyclical <tref>term definition</tref> has been detected,
-    which is an error.
-  </li>
-  <li>
-    Set the value associated with <em>defined</em>'s <em>term</em> key to
-    <tref>false</tref>. This indicates that the <tref>term definition</tref>
-    is now being created but is not yet complete.
-  </li>
-  <li>
-    If <em>term</em> is a <tref>compact IRI</tref> with a <tref>prefix</tref>
-    that is a key in <tref>local context</tref> then a dependency has been
-    found. Use this algorithm recursively passing <tref>active context</tref>,
-    <tref>local context</tref>, the <tref>prefix</tref> as <em>term</em>,
-    and <em>defined</em>.
-  </li>
-  <li>
-    Since <tref title="keyword">keywords</tref> cannot be overridden,
-    <em>term</em> MUST NOT be a <tref>keyword</tref>. Otherwise, an
-    invalid value has been detected, which is an error.
-  </li>
-  <li>
-    If <em>term</em> is a <tref>keyword</tref> alias in
-    <tref>active context</tref>, remove it.
-  </li>
-  <li>
-    Initialize <em>value</em> to the value associated with the key
-    <em>term</em> in <tref>local context</tref>.
-  </li>
-  <li>
-    If <em>value</em> equals <tref>null</tref> or <em>value</em>
-    is a <tref>JSON object</tref> containing the key-value pair
-    (<code>@id</code>-<tref>null</tref>), then set the
-    <tref>term definition</tref> in <tref>active context</tref> to
-    <tref>null</tref>, set the value associated with <em>defined</em>'s
-    key <em>term</em> to <tref>true</tref>, and return.
-  </li>
-  <li>
-    Otherwise, if <em>value</em> is a <tref>string</tref>:
-    <ol class="algorithm">
-      <li>
-        If <em>value</em> is a <tref>keyword</tref>, then <em>value</em>
-        MUST NOT be equal to <code>@context</code> or <code>@preserve</code>.
-        Otherwise an invalid keyword alias has been detected, which is an
-        error. Add <em>term</em> to <tref>active context</tref> as a
-        <tref>keyword</tref> alias for <em>value</em>. If there is more
-        than one <tref>keyword</tref> alias for <em>value</em>, then
-        store its aliases as an <tref>array</tref>, sorted by length,
-        breaking ties lexicographically.
-      </li>
-      <li>
-        Otherwise, expand <em>value</em> by setting it to the result of
-        using the <a href="#iri-expansion">IRI Expansion</a> algorithm,
-        passing <tref>active context</tref>, <em>value</em>,
-        <tref>true</tref> for <em>documentRelative</em>,
-        <tref>local context</tref>, and <em>defined</em>.
-      </li>
-      <li>
-        Set the <tref>IRI mapping</tref> for the <tref>term definition</tref>
-        for <em>term</em> in <tref>active context</tref> to <em>value</em>,
-        set the value associated with <em>defined</em>'s key <em>term</em> to
-        <tref>true</tref>, and return.
-      <li>
-    </ol>
-  </li>
-  <li>
-    Otherwise, <em>value</em> MUST be a <tref>JSON object</tref>, otherwise
-    an invalid value has been detected, which is an error.
-  </li>
-  <li>
-    Create a new <tref>JSON object</tref>, <em>definition</em>.
-  </li>
-  <li>
-   If <em>term</em> is a <tref>compact IRI</tref> and its
-   <tref>prefix</tref> has a <tref>term definition</tref> in
-   <tref>active context</tref>, set <em>definition</em> to a copy of it.
-  </li>
-  <li>
-    If <em>value</em> contains the key <code>@id</code>:
-    <ol class="algorithm">
-      <li>
-        Initialize <em>id</em> to the value associated with the
-        <code>@id</code> key.
-      </li>
-      <li>
-        If <em>id</em> is an <tref>array</tref>, then the
-        <tref>term definition</tref> is for a <tref>property generator</tref>:
-        <ol class="algorithm">
-          <li>
-            Create an empty <tref>array</tref> <em>property generator</em>.
-          <li>
-            For each item <em>iri</em> in <em>id</em>:
-            <ol class="algorithm">
-              <li>
-                <em>iri</em> MUST be a <tref>string</tref>, otherwise an
-                invalid value has been detected, which is an error.
-              </li>
-              <li>
-                If <em>iri</em> does not equal <code>@type</code> then
-                set it equal to the result of using the
-                <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-                <tref>active context</tref>, <em>iri</em> for <em>value</em>,
-                <tref>true</tref> for <em>documentRelative</em>,
-                <tref>local context</tref>, and <em>defined</em>.
-              </li>
-              <li>
-                Append <em>iri</em> to <em>property generator</em>.
-              </li>
-            </ol>
-          </li>
-          <li>
-            Set the <tref>property generator</tref> <tref>IRI mapping</tref>
-            for <em>definition</em> to the result of sorting
-            <em>property generator</em> lexicographically.
-          </li>
-        </ol>
-      </li>
-      <li>
-        Otherwise <em>id</em> MUST be a <tref>string</tref>, otherwise
-        an invalid value has been detected, which is an error. If <em>id</em>
-        does not equal <code>@type</code> then set it equal to the result of using the
-        <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-        <tref>active context</tref>, <em>id</em> for <em>value</em>,
-        <tref>true</tref> for <em>documentRelative</em>,
-        <tref>local context</tref>, and <em>defined</em>. Set the
-        <tref>IRI mapping</tref> for <em>definition</em> to <em>id</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Otherwise, if <em>term</em> is not a <tref>compact IRI</tref>,
-    then <tref>active context</tref> MUST have a
-    <tref>vocabulary mapping</tref>, otherwise an invalid value has
-    been detected, which is an error. Set the <tref>IRI mapping</tref>
-    for <em>definition</em> to the result of concatenating the value
-    associated with the <tref>vocabulary mapping</tref> and <em>term</em>.
-  </li>
-  <li>
-    Otherwise, if <em>term</em>'s <tref>prefix</tref> has a
-    <tref>term definition</tref> in <tref>active context</tref>, set
-    the <tref>IRI mapping</tref> for <em>definition</em> to the result of
-    concatenating the value associated with the <tref>prefix</tref>'s
-    <tref>IRI mapping</tref> and the <em>term</em>'s <em>suffix</em>.
-  </li>
-  <li>
-    Otherwise, <em>term</em> is an <tref>absolute IRI</tref>. Set the
-    <tref>IRI mapping</tref> for <em>definition</em> to <em>term</em>.
-  </li>
-  <li>
-    If <em>value</em> contains the key <code>@type</code>:
-    <ol class="algorithm">
-      <li>
-        Initialize <em>type</em> equal to the value associated with the
-        <code>@type</code> key, which MUST be a <tref>string</tref>.
-        Otherwise, an invalid value has been detected, which is an error.
-      </li>
-      <li>
-        If <em>type</em> does not equal <code>@id</code> then set it to
-        the result of using the
-        <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-        <tref>active context</tref>, <em>type</em> for <em>value</em>,
-        <tref>true</tref> for <em>vocabRelative</em>,
-        <tref>true</tref> for <em>documentRelative</em>,
-        <tref>local context</tref>, and <em>defined</em>. Set the
-        <tref>type mapping</tref> for <em>definition</em> to <em>type</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    If <em>value</em> contains the key <code>@container</code>:
-    <ol class="algorithm">
-      <li>
-        Initialize <em>container</em> equal to the value associated with the
-        <code>@container</code> key, which MUST be either:
-        <code>@list</code>, <code>@set</code>, <code>@index</code>,
-        or <code>@language</code>. Otherwise, an invalid value has been
-        detected, which is an error.
-      </li>
-      <li>
-        Set the <tref>container mapping</tref> for <em>definition</em> to
-        <em>container</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    If <em>value</em> contains the key <code>@language</code> and
-    does not contain the key <code>@type</code>:
-    <ol class="algorithm">
-      <li>
-        Initialize <em>language</em> equal to the value associated with the
-        <code>@language</code> key, which MUST be either <tref>null</tref>
-        or a <tref>string</tref>. Otherwise, an invalid value has been
-        detected, which is an error.
-      </li>
-      <li>
-        If <em>language</em> is a <tref>string</tref> set it to
-        lowercased <em>language</em>. Set the <tref>language mapping</tref>
-        for <em>definition</em> to <em>language</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Set the <tref>term definition</tref> for <em>term</em> in
-    <tref>active context</tref> to <em>definition</em> and set the value
-    associated with <em>defined</em>'s key <em>term</em> to
-    <tref>true</tref>.
-  </li>
-</ol>
-
-</section>
-
-<!-- end of Term Creation subalgorithm -->
-</section>
-
-<section>
-<h2>Expansion Algorithm</h2>
-
-<section>
-<h3>Problem</h3>
-
-<p>
-A JSON-LD document needs to be expanded, such that all <tref>context</tref>
-definitions have been removed, all <tref title="term">terms</tref> and
-<tref title="compact IRI">compact IRIs</tref> have been expanded to absolute
-<tref title="IRI">IRIs</tref>, and all
-<tref title="JSON-LD value">JSON-LD values</tref> are expressed in
-<tref title="array">arrays</tref> in <tref>expanded form</tref>.
-</p>
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-Starting with its root <em>element</em>, we can process the
-JSON-LD document recursively, until we have a fully
-<tref title="expansion">expanded</tref> <em>result</em>. When
-<tref title="expansion">expanding</tref> an <em>element</em>, we can treat
-each one differently according to its type, in order to break down the
-problem:
-</p>
-
-<ol>
-  <li>
-    If the <em>element</em> is <tref>null</tref>, there is nothing
-    to expand.
-  </li>
-  <li>
-    If the <em>element</em> is an <tref>array</tref>, then we expand
-    each of its items recursively and return them in a new
-    <tref>array</tref>.
-  </li>
-  <li>
-    If the <em>element</em> is a <tref>JSON object</tref>,
-    then we expand each of its keys, adding them to our <em>result</em>,
-    and then we expand each value for each key recursively. Some of the keys
-    will be
-    <tref title="term">terms</tref> or
-    <tref title="compact IRI">compact IRIs</tref> and others will be
-    <tref title="keyword">keywords</tref> or simply ignored because
-    they do not have definitions in the <tref>context</tref>. Any
-    <tref title="IRI">IRIs</tref> will be expanded using the
-    <a href="#iri-expansion">IRI Expansion</a> algorithm.
-  </li>
-  <li>
-    Otherwise, the <em>element</em> is a <tref>scalar</tref>, which
-    we expand according to the <a href="#value-expansion">Value Expansion</a>
-    subalgorithm.
-  </li>
-</ol>
-
-<p>
-Finally, after ensuring <em>result</em> is in an <tref>array</tref>,
-we return <em>result</em>.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-The algorithm takes four input variables: an <tref>active context</tref>,
-an <tref>active property</tref>, an <em>element</em> to be expanded, and
-an <em>insideList</em> flag. To begin, the <tref>active context</tref> is set
-to the result of performing, <a
-href="#context-processing">Context Processing</a> on the passed
-<code class="idlMemberName"><a href="#widl-JsonLdOptions-expandContext">expandContext</a></code>,
-or empty if <code class="idlMemberName"><a href="#widl-JsonLdOptions-expandContext">expandContext</a></code>
-is <tref>null</tref>, <tref>active property</tref> is set to <tref>null</tref>,
-<em>element</em> is set to the <tref>JSON-LD input</tref>, and <em>insideList</em>
-is set to <tref>false</tref>. This algorithm expects the
-<tref>JSON-LD input</tref> to be a well-formed JSON-LD document as defined in
-[[!JSON-LD]].
-
-The algorithm outputs the result of expanding <em>element</em>.
-</p>
-
-<ol class="algorithm">
-  <li>
-    If <em>element</em> is <tref>null</tref>, return <tref>null</tref>.
-  </li>
-  <li>If <em>element</em> is an <tref>array</tref>,
-    <ol class="algorithm">
-      <li>
-        Initialize an empty array, <em>result</em>.
-      </li>
-      <li>For each <em>item</em> in <em>element</em>:
-        <ol class="algorithm">
-          <li>
-            Initialize <em>expanded item</em> to the result of using this
-            algorithm recursively, passing <tref>active context</tref>,
-            <tref>active property</tref>, <em>item</em> as <em>element</em>,
-            and <em>insideList</em>.
-          </li>
-          <li>
-            If <em>insideList</em> equals <tref>true</tref> then
-            <em>expanded item</em> MUST NOT be an <tref>array</tref> or a
-            <tref>list object</tref>, otherwise a list of lists has been
-            detected, which is an error.
-          </li>
-          <li>
-            If <em>expanded item</em> is an <tref>array</tref>, append each
-            of its items to <em>result</em>. Otherwise, if
-            <em>expanded item</em> is not null, append it to <em>result</em>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        Return <em>result</em>.
-      </li>
-    </ol>
-  </li>
-  <li>If <em>element</em> is a <tref>JSON object</tref>,
-    <ol class="algorithm">
-      <li>
-        If <em>element</em> contains the key <code>@context</code>, set
-        <tref>active context</tref> equal to the result of the
-        <a href="#context-processing">Context Processing</a> algorithm,
-        passing <tref>active context</tref> and the value of the
-        <code>@context</code> key as <tref>local context</tref>.
-      </li>
-      <li>
-        Initialize <em>expanded active property</em> to the result of the
-        <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-        <tref>active context</tref> and <tref>active property</tref> for
-        <em>value</em>.
-      <li>
-        Initialize an empty <tref>JSON object</tref>, <em>result</em>.
-      </li>
-      <li>
-        For each <em>key</em> and <em>value</em> in <em>element</em>,
-        ordered lexicographically by <em>key</em>:
-        <ol class="algorithm">
-          <li>
-            If <em>key</em> is mapped to a <tref>property generator</tref>
-            in <tref>active context</tref>, set <em>expanded property</em>
-            to an array containing its <tref title="IRI">IRIs</tref>.
-            Otherwise, set <em>expanded property</em> to the result of
-            using the <a href="#iri-expansion">IRI Expansion</a> algorithm,
-            passing <tref>active context</tref>, <em>key</em> for
-            <em>value</em>, and <tref>true</tref> for <em>vocabRelative</em>.
-          </li>
-          <li>
-            If <em>expanded property</em> is either <tref>null</tref> or
-            is: not an <tref>array</tref>, an <tref>absolute IRI</tref> or
-            a <tref>keyword</tref>, then drop <em>key</em> by
-            continuing to the next <em>key</em>.
-          </li>
-          <li>
-            Validate <em>expanded property</em> against <em>value</em>
-            as follows:
-            <ol class="algorithm">
-              <li>
-                If <em>expanded property</em> is <code>@id</code> then
-                <em>value</em> MUST be a <tref>string</tref>, otherwise
-                an invalid value has been detected, which is an error.
-              </li>
-              <li>
-                If <em>expanded property</em> is <code>@type</code> then
-                <em>value</em> MUST be a <tref>string</tref> or an <tref>array</tref>
-                of strings, otherwise an invalid value has been detected, which
-                is an error.
-              </li>
-              <li>
-                If <em>expanded property</em> is <code>@graph</code> then
-                <em>value</em> MUST be a <tref>JSON object</tref> or an
-                <tref>array</tref>, otherwise an invalid value has been
-                detected, which is an error.
-              </li>
-              <li>
-                If <em>expanded property</em> is <code>@value</code> then
-                <em>value</em> MUST NOT be a <tref>JSON object</tref> or
-                an <tref>array</tref>, otherwise an invalid value has been
-                detected, which is an error.
-              </li>
-              <li>
-                If <em>expanded property</em> is <code>@language</code> then
-                <em>value</em> MUST be a <tref>string</tref>, otherwise an
-                invalid value has been detected, which is an error. Set
-                <em>expanded value</em> to lowercased <em>value</em>.
-              </li>
-              <li>
-                If <em>expanded property</em> is <code>@index</code>
-                then <em>value</em> MUST be a <tref>string</tref>, otherwise an
-                invalid value has been detected, which is an error.
-              </li>
-            </ol>
-          </li>
-          <li>
-            If <em>key</em>'s <tref>container mapping</tref> in
-            <tref>active context</tref> is <code>@language</code> and
-            <em>value</em> is a <tref>JSON object</tref> then <em>value</em>
-            is expanded from a <tref>language map</tref> as follows:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>expanded value</em> to an empty
-                <tref>array</tref>.
-              </li>
-              <li>
-                For each key <em>language</em> and value <em>language value</em>
-                in <em>value</em>, ordered lexicographically by
-                <em>language</em>:
-                <ol class="algorithm">
-                  <li>
-                    If <em>language value</em> is not an <tref>array</tref>
-                    set it to an <tref>array</tref> containing only
-                    <em>language value</em>.
-                  </li>
-                  <li>
-                    For each <em>item</em> in <em>language value</em>:
-                    <ol class="algorithm">
-                      <li>
-                        <em>item</em> MUST be a <tref>string</tref>,
-                        otherwise an invalid value has been detected,
-                        which is an error.
-                      </li>
-                      <li>
-                        Append a <tref>JSON object</tref> to
-                        <em>expanded value</em> that consists of two
-                        key-value pairs: (<code>@value</code>-<em>item</em>)
-                        and (<code>@language</code>-lowercased
-                        <em>language</em>).
-                      </li>
-                    </ol>
-                  </li>
-                </ol>
-              </li>
-            </ol>
-          </li>
-          <li>
-            If <em>key</em>'s <tref>container mapping</tref> in
-            <tref>active context</tref> is <code>@index</code> and
-            <em>value</em> is a <tref>JSON object</tref> then <em>value</em>
-            is expanded from an index map as follows:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>expanded value</em> to an empty
-                <tref>array</tref>.
-              </li>
-              <li>
-                For each key <em>index</em> and value
-                <em>index value</em> in <em>value</em>, ordered
-                lexicographically by <em>index</em>:
-                <ol class="algorithm">
-                  <li>
-                    If <em>index value</em> is not an <tref>array</tref>
-                    set it to an <tref>array</tref> containing only
-                    <em>index value</em>.
-                  </li>
-                  <li>
-                    Initialize <em>index value</em> to the result of
-                    using this algorithm recursively, passing
-                    <tref>active context</tref>, <tref>active property</tref>,
-                    <em>index value</em> as <em>element</em>, and
-                    <tref>false</tref> for <em>insideList</em>.
-                  <li>
-                    For each <em>item</em> in <em>index value</em>:
-                    <ol class="algorithm">
-                      <li>
-                        If <em>item</em> does not have the key
-                        <code>@index</code>, add the key-value pair
-                        (<code>@index</code>-<em>index</em>) to
-                        <em>item</em>.
-                      </li>
-                      <li>
-                        Append <em>item</em> to <em>expanded value</em>.
-                      </li>
-                    </ol>
-                  </li>
-                </ol>
-              </li>
-            </ol>
-          </li>
-          <li>
-            Otherwise, if <em>expanded property</em> equals <code>@list</code>
-            or <code>@set</code>, initialize <em>expanded value</em> to the
-            result of using this algorithm recursively passing
-            <tref>active context</tref>, <tref>null</tref> for
-            <tref>active property</tref> if <em>expanded property</em> equals
-            <code>@list</code> and <em>expanded active property</em> equals
-            <code>@graph</code> otherwise <tref>active property</tref>,
-            <em>value</em> for <em>element</em>, and <tref>true</tref>
-            for <em>insideList</em> if <em>expanded property</em> equals
-            <code>@list</code> otherwise <tref>false</tref>.
-            If <em>expanded property</em> equals <code>@list</code>
-            then <em>expanded value</em> MUST NOT be a
-            <tref>list object</tref>, otherwise a list of lists has been
-            detected, which is an error.
-          </li>
-          <li>
-            Otherwise, initialize <em>expanded value</em> to the result of
-            using this algorithm recursively, passing
-            <tref>active context</tref>, <em>key</em> for
-            <tref>active property</tref>, <em>value</em>
-            for <em>element</em>, and <tref>false</tref> for
-            <em>insideList</em>.
-          </li>
-          <li>
-            If <em>expanded value</em> equals <tref>null</tref> and
-            <em>expanded property</em> is not <code>@value</code> then
-            drop <em>key</em> by continuing to the next key.
-          </li>
-          <li>
-            If <em>expanded property</em> is not <code>@list</code> and
-            <em>expanded value</em> is not a <tref>list object</tref> and
-            <em>key</em>'s <tref>container mapping</tref> in
-            <tref>active context</tref> is <code>@list</code> then convert
-            <em>expanded value</em> to a <tref>list object</tref> by first
-            setting it to an <tref>array</tref> containing only
-            <em>expanded value</em> if it is not already an
-            <tref>array</tref>, and then by setting it to a
-            <tref>JSON object</tref> containing the key-value pair
-            (<code>@list</code>-<em>expanded value</em>).
-          </li>
-          <li>
-            If <em>expanded property</em> is an <tref>array</tref>:
-            <ol class="algorithm">
-              <li>
-                Invoke the
-                <a href="#label-blank-nodes-algorithm">Label Blank Nodes</a>
-                subalgorithm, passing <tref>active context</tref> and
-                <em>expanded value</em> as <em>element</em>.
-              </li>
-              <li>
-                For each item <em>iri</em> in <em>expanded property</em>:
-                <ol class="algorithm">
-                  <li>
-                    If <em>result</em> does not have the key <em>iri</em>,
-                    set this key's value in <em>result</em> to an empty
-                    <tref>array</tref>. Append a copy of
-                    <em>expanded value</em> to the <tref>array</tref> value
-                    associated with <em>result</em>'s <em>iri</em> key.
-                  </li>
-                </ol>
-              </li>
-            </ol>
-          </li>
-          <li>
-            Otherwise, if <em>expanded property</em> is
-            <code>@index</code>, <code>@id</code>, <code>@type</code>,
-            <code>@value</code>, or <code>@language</code>, then
-            set key <em>expanded property</em>'s value to
-            <em>expanded value</em> in <em>result</em>.
-          </li>
-          <li>
-            Otherwise, if <em>result</em> does not have the key
-            <em>expanded property</em>, set this key's value in <em>result</em>
-            to an empty <tref>array</tref>. Append <em>expanded value</em>
-            to the <tref>array</tref> value associated with <em>result</em>'s
-            <em>expanded property</em> key.
-          </li>
-        </ol>
-      </li>
-      <li>
-        If <em>result</em> contains the key <code>@value</code>:
-        <ol class="algorithm">
-          <li>
-            The <em>result</em> MUST NOT contain any keys other than
-            <code>@value</code>, <code>@language</code>, <code>@type</code>,
-            and <code>@index</code>. It MUST NOT contain both the
-            <code>@language</code> key and the <code>@type</code> key.
-            Otherwise, an invalid value has been detected, which is an error.
-          </li>
-          <li>
-            If the value of <em>result</em>'s <code>@value</code> key is
-            <tref>null</tref>, then set <em>result</em> to <tref>null</tref>.
-          </li>
-          <li>
-            Otherwise, if <em>result</em> contains the key
-            <code>@language</code> and the value of <em>result</em>'s
-            <code>@value</code> key is not a <tref>string</tref>, then remove
-            the <code>@language</code> key from <em>result</em>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        Otherwise, if <em>result</em> contains the key <code>@type</code>
-        and its associated value is not an <tref>array</tref>, set it to
-        an <tref>array</tref> containing only the associated value.
-      </li>
-      <li>
-        Otherwise, if <em>result</em> contains the key <code>@set</code>
-        or <code>@list</code>:
-        <ol class="algorithm">
-          <li>
-            The <em>result</em> MUST contain at most one other key and that
-            key MUST be <code>@index</code>. Otherwise, an invalid
-            value has been detected, which is an error.
-          </li>
-          <li>
-            If <em>result</em> contains the key <code>@set</code>, then
-            set <em>result</em> to the key's associated value.
-          </li>
-        </ol>
-      </li>
-      <li>
-        Otherwise, if <em>result</em> contains only the key
-        <code>@language</code>, set <em>result</em> to <tref>null</tref>.
-      </li>
-      <li>
-        If <em>insideList</em> equals false and either
-        <tref>active property</tref> equals <tref>null</tref> or
-        <em>expanded active property</em> equals <code>@graph</code>, then
-        drop free-floating values as follows:
-        <ol class="algorithm">
-          <li>
-            If <em>result</em> contains no keys or contains the key
-            <code>@value</code>, setting <em>result</em> to
-            <tref>null</tref>.
-          <li>
-            Otherwise, if <em>result</em>'s keys are only keywords and none
-            of the keys are <code>@graph</code>, <code>@type</code>, or
-            <code>@list</code> then set <em>result</em> to <tref>null</tref>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        Return <em>result</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Otherwise, <em>element</em> must be a <tref>scalar</tref>,
-    <ol class="algorithm">
-      <li>
-        If <em>insideList</em> equals <tref>false</tref> and
-        either <tref>active property</tref> equals <tref>null</tref> or
-        the result of expanding <tref>active property</tref> using the
-        <a href="#iri-expansion">IRI Expansion</a> algorithm is
-        <code>@graph</code>, then drop the top-level
-        <tref>scalar</tref> by returning <tref>null</tref>.
-      </li>
-      <li>
-        Return the result of the
-        <a href="#value-expansion">Value Expansion</a> algorithm, passing the
-        <tref>active context</tref>, <tref>active property</tref>, and
-        <em>element</em> as <em>value</em>.
-      </li>
-    </ol>
-  </li>
-</ol>
-
-<p>
-If, after the above algorithm is run, the result is a
-<tref>JSON object</tref> that contains only an <code>@graph</code> key, set the
-result to the value of <code>@graph</code>'s value. Otherwise, if the result
-is <tref>null</tref>, set it to an empty <tref>array</tref>. Finally, if
-the result is not an <tref>array</tref>, then set the result to an
-<tref>array</tref> containing only the result.
-</p>
-
-</section>
-
-<!-- end of Expansion Algorithm -->
-</section>
-
-<section>
-<h2>IRI Expansion</h2>
-
-<p>
-In JSON-LD documents, some keys and values may represent <tref title="IRI">IRIs</tref>.
-This section defines an algorithm for transforming a <tref>string</tref> that represents an <tref>IRI</tref> into an
-<tref>absolute IRI</tref>. It also covers transforming <tref>keyword</tref>
-aliases into <tref title="keyword">keywords</tref>.
-</p>
-
-<p>
-<tref>IRI</tref> expansion may occur during context processing or during
-any of the other JSON-LD algorithms. If IRI expansion occurs during context
-processing, then the <tref>local context</tref> and its related
-<em>defined</em> map from the
-<a href="#context-processing">Context Processing</a> algorithm are passed
-to this algorithm. This allows for <tref>term definition</tref> dependencies
-to be processed via the context processing subalgorithm,
-<a href="#create-term-definition">Create Term Definition</a>.
-</p>
-
-<p>
-After application of this algorithm, values processed by this algorithm are
-said to be in <tdef>expanded IRI form</tdef> (Advanced note: this form
-may also include
-<tref title="blank node identifier">blank node identifiers</tref> and
-JSON-LD <tref title="keyword">keywords</tref>).
-</p>
-
-<section>
-<h3>Problem</h3>
-
-We have a value that needs to be expanded to an <tref>absolute IRI</tref>
-or a <tref>keyword</tref>, if it can be and if it is not already one. The
-given value may be <tref>null</tref>, a <tref>term</tref>, a
-<tref>keyword</tref> alias, a <tref>compact IRI</tref>,
-a <tref>relative IRI</tref>, or an <tref>absolute IRI</tref>.
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-In order to expand <em>value</em> to an <tref>absolute IRI</tref>, we must
-first determine if it is <tref>null</tref>, a <tref>term</tref>, a
-<tref>keyword</tref>, or some form of <tref>IRI</tref>. While inspecting
-<em>value</em> we may also find that we need to create
-<tref>term definition</tref> dependencies because we're running this
-algorithm during <a href="#context-processing">Context Processing</a>. We can
-tell whether or not we're running during
-<a href="#context-processing">Context Processing</a> by checking
-<tref>local context</tref> against <tref>null</tref>.
-We know we need to create a <tref>term definition</tref> in the
-<tref>active context</tref> when <em>value</em> is
-a key in the <tref>local context</tref> and the <em>defined</em> map
-does not have a key for <em>value</em> with an associated value of
-<tref>true</tref>. The <em>defined</em> map is used during
-<a href="#context-processing">Context Processing</a> to keep track of
-which <tref title="term">terms</tref> have already been defined or are
-in the process of being defined. We create a
-<tref>term definition</tref> by using the
-<a href="#create-term-definition">Create Term Definition</a> subalgorithm.
-</p>
-
-<p>
-To begin, we handle the simplest case, where <em>value</em> is
-<tref>null</tref>. Here all we do is return <tref>null</tref> as there is
-nothing to expand.
-</p>
-
-<p>
-Next, we create a <tref>term definition</tref> for <em>value</em> if
-we need to. This ensures that when we look in the <tref>active context</tref>,
-any information associated with <em>value</em> will be ready.
-</p>
-
-<p>
-Now we initialize our <em>result</em> to <em>value</em> and then we
-look in the <tref>active context</tref> for <em>value</em>:
-
-<ol>
-  <li>
-    If it indicates that <em>value</em> is explicitly mapped to
-    <tref>null</tref>, then we return <tref>null</tref> which has the effect
-    of dropping the <em>value</em> from our expanded output.
-  </li>
-  <li>
-    If it indicates that <em>value</em> is a <tref>keyword</tref> alias,
-    then we return the associated <tref>keyword</tref>.
-  </li>
-  <li>
-    If it has a <tref>term definition</tref> that is a
-    <tref>property generator</tref> when the <tref>local context</tref> is
-    not <tref>null</tref>, then we trigger an error because a
-    <tref>term definition</tref> cannot have a
-    <tref>property generator</tref> as a dependency.
-  </li>
-  <li>
-    Otherwise, if it has <tref>term definition</tref> that is not a
-    <tref>property generator</tref> we update <em>result</em> by setting
-    it to the associated <tref>IRI mapping</tref>. If this is the case
-    then we also know that <em>result</em> is now an
-    <tref>absolute IRI</tref> (or a <tref>blank node identifier</tref>).
-  </li>
-</ol>
-
-</p>
-
-<p>
-At this point, if we know that <em>result</em> is not an
-<tref>absolute IRI</tref> or <tref>blank node identifier</tref>, then it
-may be a <tref>compact IRI</tref>. If it has a colon (<code>:</code>) in it
-then we parse it into <tref>prefix</tref>:<em>suffix</em>. If the resulting
-<tref>prefix</tref> is <code>_</code> or the <em>suffix</em>
-is <code>//</code>, then <em>result</em> is already an
-<tref>absolute IRI</tref>. Otherwise, if the <tref>prefix</tref> is a key in
-the <tref>local context</tref>, and we need to create a
-<tref>term definition</tref>, then we do so. If the
-<tref>term definition</tref> for the <tref>prefix</tref> in the
-<tref>active context</tref> is not a <tref>property generator</tref>, then
-we replace <em>result</em> with the concatenation of the associated
-<tref>IRI mapping</tref> and <em>suffix</em>.
-</p>
-
-<p>
-Finally, if <em>result</em> is now a <tref>blank node identifier</tref>,
-we relabel it by setting it to the result of the
-<a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a>
-algorithm. Otherwise, if it is not an <tref>absolute IRI</tref>, we resolve
-it against either the <tref title="active context">active context's</tref>
-<tref>vocabulary mapping</tref> or the document base, given the
-<em>vocabRelative</em> and <em>documentRelative</em> flag values and
-the existence of a <tref>vocabulary mapping</tref>. Then we return
-<em>result</em>.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-The algorithm takes two required and four optional input variables. The
-required inputs are an <tref>active context</tref> and a <em>value</em>
-to be expanded. The optional inputs are two flags,
-<em>documentRelative</em> and <em>vocabRelative</em>, that specifying
-whether <em>value</em> can be interpreted as a <tref>relative IRI</tref>
-against the document's base <tref>IRI</tref> or the
-<tref title="active context">active context's</tref>
-<tref>vocabulary mapping</tref>, respectively, and
-a <tref>local context</tref> and map <em>defined</em> to be used when
-this algorithm is used during
-<a href="#context-processing">Context Processing</a>. If not passed, the
-two flags are set to <code>false</code> and <tref>local context</tref> and
-<em>defined</em> are initialized to <tref>null</tref>.
-</p>
-
-<ol class="algorithm">
-  <li>
-    If <em>value</em> equals <tref>null</tref>, then return <tref>null</tref>.
-  </li>
-  <li>
-    If <tref>local context</tref> is not <tref>null</tref>, it contains
-    a key that equals <em>value</em>, and the value associated with the key
-    that equals <em>value</em> in <em>defined</em> is not <tref>true</tref>,
-    then invoke the
-    <a href="#create-term-definition">Create Term Definition</a>
-    subalgorithm, passing <tref>active context</tref>,
-    <tref>local context</tref>, <em>value</em> as <em>term</em>, and
-    <em>defined</em>. This will ensure that a <tref>term definition</tref>
-    is created for <em>value</em> in <tref>active context</tref> during
-    <a href="#context-processing">Context Processing</a>.
-  </li>
-  <li>
-    If <tref>local context</tref> is not <tref>null</tref> then
-    <tref>active context</tref> MUST NOT have a <tref>term definition</tref>
-    for <em>value</em> that is a <tref>property generator</tref>.
-    Otherwise, an invalid error has been detected, which is an error.
-  </li>
-  <li>
-    If <em>value</em> has a <tref>null</tref> mapping in
-    <tref>active context</tref>, then explicitly ignore <em>value</em>
-    by returning <tref>null</tref>.
-  </li>
-  <li>
-    If <tref>active context</tref> indicates that <em>value</em> is a
-    <tref>keyword</tref> alias then return the associated
-    <tref>keyword</tref>.
-  </li>
-  <li>
-    Initialize <em>result</em> to <em>value</em> and <em>isAbsoluteIri</em>
-    to <tref>false</tref>.
-  </li>
-  <li>
-    If <tref>active context</tref> has a <tref>term definition</tref> for
-    <em>value</em>, then set <em>result</em> to the associated
-    <tref>IRI mapping</tref> and <em>isAbsoluteIri</em> to <tref>true</tref>.
-  </li>
-  <li>
-    If <em>isAbsoluteIri</em> equals <tref>false</tref> and <em>result</em>
-    contains a colon (<code>:</code>), then it is either an
-    <tref>absolute IRI</tref> or a <tref>compact IRI</tref>:
-    <ol class="algorithm">
-      <li>
-        Split <em>result</em> into a <tref>prefix</tref> and <em>suffix</em>
-        at the first occurence of a colon (<code>:</code>).
-      </li>
-      <li>
-        If <tref>prefix</tref> does not equal underscore (<code>_</code>)
-        and <em>suffix</em> does not begin with double-forward-slash
-        (<code>//</code>), then it may be a <tref>compact IRI</tref>:
-        <ol class="algorithm">
-          <li>
-            If <tref>local context</tref> is not <tref>null</tref>, it
-            contains a key that equals <tref>prefix</tref>, and the value
-            associated with the key that equals <tref>prefix</tref> in
-            <em>defined</em> is not <tref>true</tref>, then invoke the
-            <a href="#create-term-definition">Create Term Definition</a>
-            subalgorithm, passing <tref>active context</tref>,
-            <tref>local context</tref>, <em>prefix</em> as <em>term</em>,
-            and <em>defined</em>. This will ensure that a
-            <tref>term definition</tref> is created for <tref>prefix</tref>
-            in <tref>active context</tref> during
-            <a href="#context-processing">Context Processing</a>.
-          </li>
-          <li>
-            If <tref>active context</tref> contains a
-            <tref>term definition</tref> for <tref>prefix</tref> that is
-            not a <tref>property generator</tref> then set <em>result</em>
-            to the result of concatenating the value associated with the
-            <tref>prefix</tref>'s <tref>IRI mapping</tref> and
-            <em>suffix</em>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        Set <em>isAbsoluteIri</em> to <tref>true</tref>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    If <em>isAbsoluteIri</em> equals <tref>true</tref>:
-    <ol class="algorithm">
-      <li>
-        If <tref>local context</tref> equals <tref>null</tref> and
-        <em>result</em> begins with and underscore and colon
-        (<code>_:</code>) then <em>result</em> is a
-        <tref>blank node identifier</tref>. Set <em>result</em> to the
-        result of the
-        <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a>
-        algorithm, passing <tref>active context</tref> and <em>result</em>
-        for <em>identifier</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Otherwise, if <em>vocabRelative</em> equals <tref>true</tref> and
-    <tref>active context</tref> has a <tref>vocabulary mapping</tref>,
-    then set <em>result</em> to the result of concatenating the
-    <tref>vocabulary mapping</tref> with <em>result</em>.
-  </li>
-  <li>
-    Otherwise, if <em>documentRelative</em> equals <tref>true</tref>,
-    set <em>result</em> to the result of resolving <em>result</em> against
-    the document base as per [RFC3986]. Only the basic algorithm in
-    section 5.2 of [RFC3986] is used; neither Syntax-Based Normalization
-    nor Scheme-Based Normalization (as described in sections 6.2.2 and
-    6.2.3 of [RFC3986]) are performed. Characters additionally allowed in
-    IRI references are treated in the same way that unreserved characters
-    are treated in URI references, per section 6.5 of [RFC3987].
-  </li>
-  <li>
-    If <tref>local context</tref> is not <tref>null</tref> then
-    <em>result</em> MUST be an <tref>absolute IRI</tref>. Otherwise,
-    an invalid context value has been detected, which is an error. Return
-    <em>result</em>.
-  </li>
-</li>
-
-</section>
-
-<!-- end of IRI Expansion -->
-</section>
-
-<section>
-<h2>Value Expansion</h2>
-
-<p>
-Some values in JSON-LD can be expressed in a <tref>compacted form</tref>.
-These values are required to be <tref title="expansion">expanded</tref> at
-times when processing JSON-LD documents. A value is said to be in
-<tdef>expanded form</tdef> after the application of this algorithm.
-</p>
-
-<section>
-<h3>Problem</h3>
-
-A <em>value</em> associated with an <tref>active property</tref> must
-be <tref title="expansion">expanded</tref> to <tref>expanded form</tref>.
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-Other than the simple case where <em>value</em> is <tref>null</tref>, for
-which we return <tref>null</tref>, we must primarily look at <em>value</em>'s
-associated <tref>active property</tref> to determine how to expand it.
-</p>
-
-<p>
-First we <tref title="expansion">expand</tref> the
-<tref>active property</tref> itself, so that we can resolve
-<tref>keyword</tref> aliases. Then, for certain
-<tref title="keyword">keywords</tref> like <code>@id</code> and
-<code>@type</code>, we simply expand <em>value</em>
-using the <a href="#iri-expansion">IRI Expansion</a> algorithm and return
-the result.
-</p>
-
-<p>
-Next, we check to see if <tref>active property</tref> has a
-<tref>type mapping</tref> in the <tref>active context</tref> that would alter
-what we return. If it has one that is <code>@type</code> or if the
-<em>expanded property</em> is <code>@graph</code> then we return
-a <tref>JSON object</tref> with a single key-pair of <code>@id</code>
-and the result of using the <a href="#iri-expansion">IRI Expansion</a>
-algorithm on <em>value</em>.
-</p>
-
-<p>
-If we haven't returned yet and the <em>expanded property</em> is a
-<tref>keyword</tref>, then there is no special <tref>expansion</tref> to be
-performed on the <em>value</em>, so we return it as is.
-</p>
-
-<p>
-Otherwise, we'll our result will be a <tref>JSON object</tref> containing
-the key <code>@value</code> with the value the <em>value</em>. Additionally,
-a <code>@type</code> key-value pair will be included if there is a
-<tref>type mapping</tref> associated with the <tref>active property</tref>
-or a <code>@language</code> key-value pair if <em>value</em> is a
-<tref>string</tref> and there is <tref>language mapping</tref>.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-The algorithm takes three required inputs: an <tref>active context</tref>,
-an <tref>active property</tref>, and a <em>value</em> to expand.
-</p>
-
-<ol class="algorithm">
-  <li>
-    If <em>value</em> equals <tref>null</tref>, then return <tref>null</tref>.
-  </li>
-  <li>
-    Initialize <em>expanded property</em> to the result of using the
-    <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-    <tref>active context</tref>, <tref>active property</tref> for
-    <em>value</em>, and <tref>true</tref> for <em>vocabRelative</em>.
-  </li>
-  <li>
-    If <em>expanded property</em> equals <code>@id</code> then return
-    the result of using the
-    <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-    <tref>active context</tref>, <em>value</em>, and <tref>true</tref>
-    for <em>documentRelative</em>.
-  </li>
-  <li>
-    If <em>expanded property</em> equals <code>@type</code> then
-    return the result of using the
-    <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-    <tref>active context</tref>, <em>value</em>, <tref>true</tref> for
-    <em>vocabRelative</em>, and <tref>true</tref> for
-    <em>documentRelative</em>.
-  </li>
-  <li>
-    Initialize <em>type</em> to <tref>null</tref>.
-  </li>
-  <li>
-    If <tref>active property</tref> has a <tref>type mapping</tref> in
-    <tref>active context</tref> that is <code>@id</code> or if
-    <em>expanded property</em> equals <code>@graph</code>, then return
-    a new <tref>JSON object</tref> containing a single key-value pair
-    where the key is <code>@id</code> and the value is the result of
-    using the
-    <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-    <tref>active context</tref>, <em>value</em>, and <tref>true</tref> for
-    <em>documentRelative</em>.
-  </li>
-  <li>
-    If <em>expanded property</em> is a <tref>keyword</tref> return
-    <em>value</em> as is.
-  </li>
-  <li>
-    Otherwise, initialize <em>result</em> to an empty
-    <tref>JSON object</tref>.
-  </li>
-  <li>
-    If <tref>active property</tref> has a <tref>type mapping</tref> in
-    <tref>active context</tref>:
-    <ol class="algorithm">
-      <li>
-        Initialize <em>type</em> to the value associated with the
-        <tref>type mapping</tref>.
-      </li>
-      <li>
-        If <em>type</em> is a <tref>blank node identifier</tref> (it
-        begins with <code>_:</code>), then set it to the result of the
-        <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a>
-        algorithm, passing <tref>active context</tref> and <em>type</em> for
-        <em>identifier</em>.
-      </li>
-      <li>
-        Add the key-value pair, (<code>@type</code>-<em>type</em>), to
-        <em>result</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Otherwise, if <em>value</em> is a <tref>string</tref> and
-    <tref>active property</tref> has a <tref>language mapping</tref> in
-    <tref>active context</tref> that is not <tref>null</tref>, then
-    add a key-value pair to <em>result</em> where the key is
-    <code>@language</code> and the value is the value associated with
-    the <tref>language mapping</tref>.
-  </li>
-  <li>
-    Finally, add the key-value pair, (<code>@value</code>-<em>value</em>), to
-    <em>result</em> and return <em>result</em>.
-  </li>
-</ol>
-
-</section>
-
-<!-- end of Value Expansion -->
-</section>
-
-<section>
-<h2>Label Blank Nodes Subalgorithm</h2>
-
-<p>
-During <tref>expansion</tref>, it is sometimes necessary to ensure
-all <tref title="blank node">blank nodes</tref> have been labeled. This
-occurs when a <tref>property generator</tref> is used to copy a single
-property's values across multiple properties. This step is necessary to
-ensure that these duplicated values can be later
-<tref title="compaction">recompacted</tref>. Because new labels will
-be assigned to <tref title="blank node">blank nodes</tref>, it is
-important to relabel any existing <tref title="blank node">blank nodes</tref>
-to avoid conflicting names.
-</p>
-
-<p>
-The algorithm takes two required inputs and one optional input. The
-required inputs are: an <tref>active context</tref>,
-and an <em>element</em> to be labeled with
-<tref title="blank node identifier">blank node identifiers</tref>. The
-optional input is a flag <em>isId</em> that indicates whether or not
-<em>element</em> represents a value that is either an <tref>IRI</tref> or
-a <tref>blank node identifier</tref>. The <em>isId</em> flag defaults to
-<tref>false</tref>.
-</p>
-
-<ol class="algorithm">
-  <li>
-    If <em>element</em> is an <tref>array</tref>, then for each
-    <em>item</em> in <em>element</em>:
-    <ol class="algorithm">
-      <li>
-        Replace <em>item</em> with the result of using this algorithm
-        recursively, passing <tref>active context</tref>, <em>item</em>
-        for <em>element</em>, and <em>isId</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Otherwise, if <em>element</em> is a <tref>list object</tref>, then
-    replace the value of the <code>@list</code> key in <em>element</em>
-    with the result of using this algorithm recursively, passing
-    <tref>active context</tref>, the value of the <code>@list</code> key
-    for <em>element</em>, and <em>isId</em>.
-  </li>
-  <li>
-    Otherwise, if <em>element</em> is a <tref>JSON object</tref>:
-    <ol class="algorithm">
-      <li>
-        If <em>element</em> is a <em>blank node</em>, then set the value
-        of its <code>@id</code> key to the result of using the
-        <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a>
-        algorithm, passing the value for <em>identifier</em>, using
-        <tref>null</tref> instead if <em>element</em> has no key
-        <code>@id</code>.
-      </li>
-      <li>
-        For each <em>key</em>-<em>value</em> pair ordered lexicographically
-        by <em>key</em>:
-        <ol class="algorithm">
-          <li>
-            If <em>key</em> does not equal <code>@id</code>, then replace
-            <em>value</em> in <em>element</em> with the result of using
-            this algorithm recursively, passing <tref>active context</tref>,
-            <em>value</em> for <em>element</em>, and <tref>true</tref>
-            for <em>isId</em> if <em>key</em> equals <code>@type</code>,
-            otherwise <tref>false</tref> for <em>isId</em>.
-          </li>
-        </ol>
-      </li>
-    </ol>
-  </li>
-  <li>
-    Otherwise, if <em>element</em> is a <tref>string</tref> and <em>isId</em>
-    equals <tref>true</tref>, and <em>element</em> is a
-    <tref>blank node identifier</tref>, then set <em>element</em> to
-    the result of using the
-    <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a>
-    algorithm, passing <em>element</em> for <em>identifier</em>.
-  </li>
-  <li>
-    Return <em>element</em>.
-  </li>
-</ol>
-
-</section>
-
-<section>
-<h2>Generate Blank Node Identifier</h2>
-
-<p>
-This algorithm is used to generate new
-<tref title="blank node identifier">blank node identifiers</tref> or to
-relabel an existing
-<tref>blank node identifier</tref> to avoid collision by the introduction
-of new ones. It needs to keep an <em>identifier map</em>, a <em>counter</em>,
-and a <em>prefix</em> between its executions to be able to generate new
-<tref title="blank node identifier">blank node identifiers</tref>. Note
-that it may be most convenient to keep this state information in the
-<tref>active context</tref>, so long as it is preserved (shared) when the
-<tref>active context</tref> is cloned during
-<a href="#context-processing">Context Processing</a>. The <em>counter</em> is
-initialized to <code>0</code> and <em>prefix</em> is set to <code>_:t</code>
-by default.
-</p>
-
-<p>
-The algorithm takes a single input variable <em>identifier</em> which may
-be <tref>null</tref>.
-</p>
-
-<ol class="algorithm">
-  <li>
-    If the <em>identifier</em> is not <tref>null</tref> and is in the
-    <em>identifier map</em>, return the mapped identifier.
-  </li>
-  <li>
-    Otherwise, generate a new <em>blankNodeIdentifier</em> by concatenating
-    <em>prefix</em> and <em>counter</em>.
-  </li>
-  <li>
-    Increment <em>counter</em> by <code>1</code>.
-  </li>
-  <li>
-    If <em>identifier</em> is not <tref>null</tref>, create a new entry in
-    <em>identifier map</em> set to <em>blankNodeIdentifer</em>.
-  </li>
-  <li>
-    Return <em>blankNodeIdentifier</em>.
-  </li>
-</ol>
-
-</section>
-
-<section>
-<h2>Compaction Algorithm</h2>
-
-<section>
-<h3>Problem</h3>
-
-<p>
-A JSON-LD document needs to be compacted, such that the given
-<tref>context</tref> is applied. This must result in shortening
-any applicable <tref title="IRI">IRIs</tref> to
-<tref title="term">terms</tref> or
-<tref title="compact IRI">compact IRIs</tref> and
-any applicable <tref title="JSON-LD value">JSON-LD values</tref>
-expressed in <tref>expanded form</tref> to simple values such as
-<tref title="string">strings</tref> or
-<tref title="number">numbers</tref>.
-</p>
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-Starting with its root <em>element</em>, we can process the
-JSON-LD document recursively, until we have a fully
-<tref title="compaction">compacted</tref> <em>result</em>. When
-<tref title="compaction">compacting</tref> an <em>element</em>, we can treat
-each one differently according to its type, in order to break down the
-problem:
-</p>
-
-<ol>
-  <li>
-    If the <em>element</em> is an <tref>array</tref>, then we compact
-    each of its items recursively and return them in a new
-    <tref>array</tref>.
-  </li>
-  <li>
-    If the <em>element</em> is a <tref>JSON object</tref>,
-    then we start by creating a shallow copy of it and each of its
-    key's <tref>array</tref> values. This is done so that if any key
-    is compacted to a <tref>property generator</tref> <tref>term</tref>,
-    we can remove duplicate values without modifying the original
-    <em>element</em>. Then, we compact each value in the shallow copy
-    for each key recursively. Some of the keys will be
-    compacted, using the
-    <a href="#iri-compaction">IRI Compaction</a> algorithm,
-    to <tref title="term">terms</tref> or
-    <tref title="compact IRI">compact IRIs</tref> and others will be
-    compacted from <tref title="keyword">keywords</tref> to
-    <tref>keyword</tref> aliases or simply left unchanged because
-    they do not have definitions in the <tref>context</tref>. Values will
-    be converted to <tref>compacted form</tref> via the
-    <a href="#value-compaction">Value Compaction</a> algorithm. Some data
-    will be reshaped based on
-    <tref title="container mapping">container mappings</tref> specified
-    in the context such as <code>@index</code> or <code>@language</code>
-    maps.
-  </li>
-  <li>
-    Otherwise, the <em>element</em> is a <tref>scalar</tref>, it is
-    already in <tref>compacted form</tref>, so we simply return.
-  </li>
-</ol>
-
-<p>
-The final output is a <tref>JSON object</tref> with a <code>@context</code>
-key, if a <tref>context</tref> was given, where the <tref>JSON object</tref>
-is either <em>result</em> or a wrapper for it where <em>result</em> appears
-as the value of an aliased <code>@graph</code> key because <em>result</em>
-contained two or more items in an <tref>array</tref>. If no
-<tref>context</tref> was given, the <em>result</em> is only simplified
-from an <tref>array</tref> to a <tref>JSON object</tref> if it has one or
-fewer items.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-The algorithm takes four required input variables: an
-<tref>active context</tref>, an <tref>active property</tref>, and an
-<em>element</em> to be compacted. To begin, the <tref>active context</tref>
-is set to the result of performing
-<a href="#context-processing">Context Processing</a> on the passed
-<em>context</em>, the <tref>active property</tref> is set to
-<tref>null</tref>, and <em>element</em> is set to the result of performing
-the <a href="#expansion-algorithm">Expansion Algorithm</a> on the
-<tref>JSON-LD input</tref>.
-</p>
-
-<ol class="algorithm">
-  <li>
-    If <em>element</em> is an <tref>array</tref>:
-    <ol class="algorithm">
-      <li>
-        Initialize <em>result</em> to an empty <tref>array</tref>.
-      </li>
-      <li>
-        For each <em>item</em> in <em>element</em>:
-        <ol class="algorithm">
-          <li>
-            Initialize <em>compacted item</em> to the result of using this
-            algorithm recursively, passing <tref>active context</tref>,
-            <tref>active property</tref>, and <em>item</em> for
-            <em>element</em>.
-          </li>
-          <li>
-            If <em>compacted item</em> is not <tref>null</tref>, then append
-            it to <em>result</em>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        If <em>result</em> contains only one item (it has a length of
-        <code>1</code>) and <tref>active property</tref> has no
-        <tref>container mapping</tref> in <tref>active context</tref>,
-        then set <em>result</em> to its only item.
-      </li>
-      <li>
-        Return <em>result</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    If <em>element</em> is an <tref>JSON object</tref>:
-    <ol class="algorithm">
-      <li>
-        If <em>element</em> contains the key <code>@value</code> or
-        if it contains only one key and that key is <code>@id</code>,
-        then return the result of using the
-        <a href="#value-compaction">Value Compaction</a> algorithm,
-        passing <tref>active context</tref>, <tref>active property</tref>,
-        and <em>element</em> as <em>value</em>.
-      </li>
-      <li>
-        Create a shallow copy of <em>element</em> and each <tref>array</tref>
-        associated with its keys so that duplicate values can be removed
-        during <tref>property generator</tref> <tref>compaction</tref>:
-        <ol class="algorithm">
-          <li>
-            Initialize <em>shallow</em> to an empty <tref>JSON object</tref>.
-          </li>
-          <li>
-            For each <em>key</em>-<em>value</em> pair in <em>element</em>:
-            <ol class="algorithm">
-              <li>
-                If <em>value</em> is an <tref>array</tref>, then add
-                a key-value pair to <em>shallow</em> where the key
-                is <em>key</em> and the value is a shallow copy of
-                <em>value</em>.
-              </li>
-              <li>
-                Otherwise, add the key-value pair, <em>key</em>-<em>value</em>
-                to <em>shallow</em>.
-              </li>
-            </ol>
-          </li>
-        </ol>
-      </li>
-      <li>
-        Initialize <em>result</em> to an empty <tref>JSON object</tref>.
-      </li>
-      <li>
-        Initialize <em>keys</em> to an <tref>array</tref> containing
-        all of the keys in <em>element</em>, ordered lexicographically.
-      </li>
-      <li>
-        For each key <em>expanded property</em> in <em>keys</em>:
-        <ol class="algorithm">
-          <li>
-            If <em>shallow</em> does not contain a key that equals
-            <em>expanded property</em>, then continue to the next
-            <em>expanded property</em>.
-          </li>
-          <li>
-            Initialize <em>expanded value</em> to the value associated
-            with the key that equals <em>expanded property</em> in
-            <em>shallow</em>.
-          </li>
-          <li>
-            If <em>expanded property</em> equals <code>@id</code> or
-            <code>@type</code>:
-              <ol class="algorithm">
-                <li>
-                  If <em>expanded value</em> is a <tref>string</tref>,
-                  then initialize <em>compacted value</em> to the result
-                  of using the
-                  <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                  algorithm, passing <tref>active context</tref>,
-                  <em>expanded value</em> for <em>iri</em>,
-                  <tref>true</tref> for <em>vocabRelative</em> if
-                  <em>expanded property</em> equals <code>@type</code>,
-                  <tref>false</tref> otherwise, and <tref>true</tref>
-                  for <em>documentRelative</em>.
-                </li>
-                <li>
-                  Otherwise, <em>expanded value</em> must be a
-                  <code>@type</code> <tref>array</tref>:
-                  <ol class="algorithm">
-                    <li>
-                      Initialize <em>compacted value</em> to an empty
-                      <tref>array</tref>.
-                    </li>
-                    <li>
-                      For each item <em>expanded type</em> in
-                      <em>expanded value</em>, append the result of
-                      of using the
-                      <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                      algorithm, passing <tref>active context</tref>,
-                      <em>expanded type</em> for <em>iri</em>,
-                      <tref>true</tref> for <em>vocabRelative</em>,
-                      and <tref>true</tref> for <em>documentRelative</em>,
-                      to <em>compacted value</em>.
-                    </li>
-                    <li>
-                      If <em>compacted value</em> contains only one
-                      item (it has a length of <code>1</code>), then
-                      set <em>compacted value</em> to its only item.
-                    </li>
-                  </ol>
-                </li>
-                <li>
-                  Initialize <em>alias</em> to the result of using the
-                  <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                  algorithm, passing <tref>active context</tref> and
-                  <em>expanded property</em> for <em>iri</em>.
-                </li>
-                <li>
-                  Add the key-value pair,
-                  (<em>alias</em>-<em>compacted value</em>) to
-                  <em>result</em> and continue to the next
-                  <em>expanded property</em>.
-                </li>
-              </ol>
-            </li>
-          <li>
-            If <em>expanded property</em> equals <code>@index</code>:
-            <ol class="algorithm">
-              <li>
-                If <tref>active property</tref> has a
-                <tref>container mapping</tref> in <tref>active context</tref>
-                that equals <code>@index</code>, then the compacted
-                result will be inside of an <code>@index</code>
-                container, so simply drop the <code>@index</code>
-                property by continuing to the next
-                <em>expanded property</em>.
-              </li>
-              <li>
-                Otherwise, initialize <em>alias</em> to the result of using
-                the <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                algorithm, passing <tref>active context</tref> and
-                <em>expanded property</em> for <em>iri</em>.
-              </li>
-              <li>
-                Add the key-value pair,
-                (<em>alias</em>-<em>expanded value</em>) to
-                <em>result</em> and continue to the next
-                <em>expanded property</em>.
-              </li>
-            </ol>
-          </li>
-          <li>
-            If <em>expanded value</em> is an empty <tref>array</tref>:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>activeProperty</em> to the result of using
-                the <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                algorithm, passing <tref>active context</tref>,
-                <em>expanded property</em> for <em>iri</em>,
-                <tref>true</tref> for <em>vocabRelative</em>, and
-                <em>shallow</em> for <em>parent</em>.
-              </li>
-              <li>
-                If <em>result</em> does not have the key that equals
-                <em>activeProperty</em>, set this key's value in <em>result</em>
-                to an empty <tref>array</tref>. Otherwise, if the key's value
-                is not an <tref>array</tref>, then set it equal to one
-                containing only the value.
-              </li>
-            </ol>
-          </li>
-          <li>
-            At this point, <em>expanded value</em> must be an
-            <tref>array</tref> due to the
-            <a href="#expansion-algorithm">Expansion algorithm</a>.
-            For each item <em>expanded item</em> in <em>expanded value</em>:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>activeProperty</em> to the result of using
-                the <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                algorithm, passing <tref>active context</tref>,
-                <em>expanded property</em> for <em>iri</em>,
-                <em>expanded item</em> for <em>value</em>,
-                <tref>true</tref> for <em>vocabRelative</em>, and
-                <em>shallow</em> for <em>parent</em>.
-              </li>
-              <li>
-                Initialize <em>container</em> to <tref>null</tref>. If there
-                is a <tref>container mapping</tref> for
-                <em>activeProperty</em> in <tref>active context</tref>,
-                set <em>container</em> to its value.
-              </li>
-              <li>
-                If there is a <tref>term definition</tref> for
-                <em>activeProperty</em> in <tref>active context</tref> that
-                is a <tref>property generator</tref>, then invoke the
-                <a href="#find-and-remove-property-generator-duplicates">Find and Remove Property Generator Duplicates</a>
-                algorithm, passing <tref>active context</tref>,
-                <em>shallow</em> for <em>element</em>,
-                <em>expanded property</em>, <em>expanded item</em> for
-                <em>value</em>, and <em>activeProperty</em>.
-              </li>
-              <li>
-                Initialize <em>compacted item</em> to the result of using
-                this algorithm recursively, passing
-                <tref>active context</tref>, <em>activeProperty</em>,
-                <em>expanded item</em> for <em>element</em> if it does
-                not contain the key <code>@list</code>, otherwise pass
-                the key's associated value for <em>element</em>.
-              </li>
-              <li>
-                If <em>expanded item</em> is a <tref>list object</tref>:
-                <ol class="algorithm">
-                  <li>
-                    If <em>compacted item</em> is not an <tref>array</tref>,
-                    then set it to an <tref>array</tref> containing only
-                    <em>compacted item</em>.
-                  </li>
-                  <li>
-                    If <em>container</em> does not equal <code>@list</code>:
-                    <ol class="algorithm">
-                      <li>
-                        Convert <em>compacted item</em> to a
-                        <tref>list object</tref> by setting it to a
-                        <tref>JSON object</tref> containing key-value pair
-                        where the key is the result of the
-                        <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                        algorithm, passing <tref>active context</tref> and
-                        <code>@list</code> for <em>iri</em>, and the
-                        value is <em>compacted item</em>.
-                      </li>
-                      <li>
-                        If <em>expanded item</em> contains the key
-                        <code>@index</code>, then add a key-value pair
-                        to <em>compacted item</em> where the key is the
-                        result of the
-                        <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                        algorithm, passing <tref>active context</tref> and
-                        <code>@index</code> for <em>iri</em>, and the
-                        value is the value associated with the
-                        <code>@index</code> key in
-                        <em>expanded item</em>.
-                      </li>
-                    </ol>
-                  </li>
-                  <li>
-                    Otherwise, <tref>active property</tref> MUST NOT be a key
-                    in <em>result</em> because there cannot be two
-                    <tref title="list object">list objects</tref> associated
-                    with an <tref>active property</tref> that has a
-                    <tref>container mapping</tref>; this is an error.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                If <em>container</em> equals <code>@language</code> or
-                <code>@index</code>:
-                <ol class="algorithm">
-                  <li>
-                    If <em>active property</em> is a key in <em>result</em>,
-                    then initialize <em>map object</em> to its associated
-                    value, otherwise initialize it to an empty
-                    <tref>JSON object</tref>.
-                  </li>
-                  <li>
-                    If <em>container</em> is <code>@language</code> and
-                    <em>compacted item</em> contains the key
-                    <code>@value</code>, then set <em>compacted item</em>
-                    to the value associated with its <code>@value</code> key.
-                  </li>
-                  <li>
-                    Initialize <em>map key</em> to the value associated with
-                    with the key that equals <em>container</em> in
-                    <em>expanded item</em>.
-                  </li>
-                  <li>
-                    If <em>map key</em> is not a key in <em>map object</em>,
-                    then set this key's value in <em>map object</em>
-                    to <em>compacted item</em>. Otherwise, if the value
-                    is not an <tref>array</tref>, then set it equal to one
-                    containing only the value and then append
-                    <em>compacted item</em> to it.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                Otherwise,
-                <ol class="algorithm">
-                  <li>
-                    Initialize <em>useArray</em> to <tref>false</tref>. If
-                    <em>container</em> equals <code>@set</code> or
-                    <code>@list</code>, or <em>compacted item</em> is
-                    an empty <tref>array</tref>, or <em>expanded property</em>
-                    equals <code>@graph</code>, then set <em>useArray</em>
-                    to <tref>true</tref>.
-                  </li>
-                  <li>
-                    If <em>useArray</em> is <tref>true</tref> and
-                    <em>compacted item</em> is not an <tref>array</tref>,
-                    then set it equal to a new <tref>array</tref>
-                    containing only <em>compacted item</em>.
-                  </li>
-                    If <tref>active property</tref> is not a key in
-                    <em>result</em> then add the key-value pair,
-                    (<tref>active property</tref>-<em>compacted item</em>),
-                    to <em>result</em>.
-                  </li>
-                  <li>
-                    Otherwise, if the value associated with the key that
-                    equals <tref>active property</tref> in <em>result</em>
-                    is not an <tref>array</tref>, set it equal to a new
-                    <tref>array</tref> containing only the value. Then
-                    append <em>compacted item</em> to the value if
-                    <em>compacted item</em> is not an <tref>array</tref>,
-                    otherwise, concatenate it.
-                  </li>
-                </ol>
-              </li>
-            </ol>
-          </li>
-        </ol>
-      </li>
-      <li>
-        Return <em>result</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    At this point, <em>element</em> must a be <tref>scalar</tref>, which
-    is already compact, so simply return <em>element</em>.
-  </li>
-</ol>
-
-<p>
-If, after the algorithm outlined above is run, the result <em>result</em> is
-an <tref>array</tref> with two or more items and a <em>context</em> has
-been passed, replace it with a new <tref>JSON object</tref> with a single
-key-value pair where the key is the result of using the
-<a href="#iri-compaction-algorithm">IRI Compaction</a> algorithm, passing
-<tref>active context</tref> and <code>@graph</code> for <em>iri</em>, and
-the value is <em>result</em>. Otherwise, if <em>result</em> is an
-<tref>array</tref> with only one item, set <em>result</em> to that item.
-Otherwise, if <em>result</em> is an <tref>array</tref> with zero items,
-replace it with an empty <tref>JSON object</tref>. Finally, if a
-<em>context</em> has been passed, add an <code>@context</code> property to
-<em>result</em> and set its value to the initially passed
-<em>context</em>.
-</p>
-
-</section>
-
-<!-- end of Compaction -->
-</section>
-
-<section>
-<h2>IRI Compaction Algorithm</h2>
-
-<p>
-This section defines an algorithm for transforming an <tref>IRI</tref>
-to a <tref>term</tref> or <tref>compact IRI</tref>, or a <tref>keyword</tref>
-alias to a <tref>keyword</tref>. A value that is associated with the
-<tref>IRI</tref> may be passed in order to assist in selecting the most
-context-appropriate <tref>term</tref>.
-</p>
-
-<section>
-<h3>Problem</h3>
-
-We have an <tref>IRI</tref> (or <tref>keyword</tref>) that we may
-be able to compact to <tref>term</tref>, <tref>compact IRI</tref>, or
-<tref>keyword</tref> alias.
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-First, we handle the simple cases: if the value given as an <tref>IRI</tref>
-is <tref>null</tref>, we simply return <tref>null</tref> and if it is a
-<tref>keyword</tref> we return its associated alias.
-</p>
-
-<p>
-Otherwise, we first try to find a <tref>term</tref> that the
-<tref>IRI</tref> can be <tref title="compaction">compacted</tref> to. In
-order to select a <tref>term</tref>, we have to collect information about
-the <tref title="IRI">IRI's</tref> associated value. This information
-includes which <tref title="container mapping">container mappings</tref>
-would be preferred for expressing the value, and what its
-<tref>type mapping</tref> or <tref>language mapping</tref> is. For
-JSON-LD lists, the <tref>type mapping</tref> or <tref>language mapping</tref>
-will be chosen based on the most specific values that work for all items in
-the list. Once this information is gathered, it is passed to the
-<a href="#term-selection">Term Selection</a> subalgorithm, which will
-return the most appropriate <tref>term</tref> to use.</p>
-
-<p>
-If no <tref>term</tref> was found that could be used to compact the
-<tref>IRI</tref>, then an attempt is made to find a <tref>compact IRI</tref>
-to use. If there is no appropriate <tref>compact IRI</tref>, then
-the <tref title="active context">active context's</tref>
-<tref>vocabulary mapping</tref> is used. Finally, if the <tref>IRI</tref>
-still could not be compacted, we simply return it as is.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-This algorithm takes three required inputs and three optional inputs.
-The required inputs an <tref>active context</tref> and the <em>iri</em> to
-be compacted. The optional inputs are: a <em>value</em> associated with
-the <em>iri</em>, a <em>vocabRelative</em> flag which specifies whether the
-passed <em>iri</em> should be compacted using the
-<tref title="active context">active context's</tref>
-<tref>vocabulary mapping</tref>, and the <em>parent</em> element for
-the <em>value</em>. If not passed, <em>value</em> is set to
-<tref>null</tref>, <em>vocabRelative</em> is set to <code>false</code>, and
-<em>parent</em> is set to <tref>null</tref>.
-</p>
-
-<ol class="algorithm">
-  <li>
-    If <em>iri</em> is <tref>null</tref>, return <tref>null</tref>.
-  </li>
-  <li>
-    If <em>iri</em> is a <tref>keyword</tref> and does not have a
-    <tref>keyword</tref> alias, return <em>iri</em>, otherwise return
-    its first associated <tref>keyword</tref> alias from
-    <tref>active context</tref>.
-  </li>
-  <li>
-    If <tref>active context</tref> has no associated
-    <tref>inverse context</tref>, then generate it using the
-    <a href="#inverse-context-creation">Inverse Context Creation</a>
-    algorithm. Set <em>inverse context</em> to the
-    <tref>inverse context</tref> associated with <tref>active context</tref>.
-  </li>
-  <li>
-    Initialize <em>defaultLanguage</em> to
-    <tref title="active context">active context's</tref>
-    <tref>default language</tref>, if it has one, otherwise to
-    <code>@none</code>.
-  </li>
-  <li>
-    If <em>iri</em> is a key in <em>inverse context</em>:
-    <ol class="algorithm">
-      <li>
-        Initialize <em>entry</em> to the value in <em>inverse context</em>
-        associated with the key that equals <em>iri</em>.
-      </li>
-      <li>
-        Initialize <em>containers</em> to an empty <tref>array</tref>. This
-        <tref>array</tref> will be used to keep track of an ordered list of
-        preferred <tref title="container mapping">container mappings</tref>
-        for a <tref>term</tref>, based on what is compatible with
-        <em>value</em>.
-      </li>
-      <li>
-        If <em>value</em> is a <tref>JSON object</tref> that contains the
-        key <code>@index</code>, then append the value <code>@index</code>
-        to <em>containers</em>.
-      </li>
-      <li>
-        Initialize <em>typeOrLanguage</em> to <code>@language</code>,
-        and <em>typeOrLanguageValue</em> to <code>@null</code>. These two
-        variables will keep track of the preferred
-        <tref>type mapping</tref> or <tref>language mapping</tref> for
-        a <tref>term</tref>, based on what is compatible with <em>value</em>.
-      </li>
-        If <em>value</em> is a <tref>list object</tref>, then set
-        <em>typeOrLanguage</em> and <em>typeOrLanguageValue</em>
-        to the most specific values that work for all items in
-        the list as follows:
-        <ol class="algorithm">
-          <li>
-            If <code>@index</code> is a not key in <em>value</em>, then
-            append <code>@list</code> to <em>containers</em>.
-          </li>
-          <li>
-            Initialize <em>list</em> to the <tref>array</tref> associated
-            with the key <code>@list</code> in <em>value</em>.
-          </li>
-          <li>
-            Initialize <em>commonLanguage</em> to <tref>null</tref>. If
-            <em>list</em> is empty, set <em>commonLanguage</em> to
-            <em>defaultLanguage</em>.
-          </li>
-          <li>
-            For each <em>item</em> in <em>list</em>:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>itemLanguage</em> to <code>@none</code> and
-                <em>itemType</em> to <code>@none</code>.
-              </li>
-              <li>
-                If <em>item</em> contains the key <code>@value</code>:
-                <ol class="algorithm">
-                  <li>
-                    If <em>item</em> contains the key <code>@language</code>,
-                    then set <em>itemLanguage</em> to its associated
-                    value.
-                  </li>
-                  <li>
-                    Otherwise, if <em>item</em> contains the key
-                    <code>@type</code>, set <em>itemType</em> to its
-                    associated value.
-                  </li>
-                  <li>
-                    Otherwise, set <em>itemLanguage</em> to
-                    <code>@null</code>.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                If <em>commonLanguage</em> is <tref>null</tref>, set it
-                to <em>itemLanguage</em>.
-              </li>
-              <li>
-                Otherwise, if <em>itemLanguage</em> does not equal
-                <em>commonLanguage</em> and <em>item</em> contains the
-                key <code>@value</code>, then set <em>commonLanguage</em>
-                to <code>@none</code> because list items have conflicting
-                languages.
-              </li>
-              <li>
-                If <em>commonType</em> is <tref>null</tref>, set it
-                to <em>itemType</em>.
-              </li>
-              <li>
-                Otherwise, if <em>itemType</em> does not equal
-                <em>commonType</em>, then set <em>commonType</em>
-                to <code>@none</code> because list items have conflicting
-                types.
-              </li>
-              <li>
-                If <em>commonLanguage</em> equals <code>@none</code> and
-                <em>commonType</em> equals <code>@none</code>, then
-                stop processing items in the list because it has been
-                detected that there is no common language or type amongst
-                the items.
-              </li>
-            </ol>
-          </li>
-          <li>
-            If <em>commonLanguage</em> is <tref>null</tref>, set it to
-            <code>@none</code>.
-          </li>
-          <li>
-            If <em>commonType</em> is <tref>null</tref>, set it to
-            <code>@none</code>.
-          </li>
-          <li>
-            If <em>commonType</em> is not <code>@none</code> then set
-            <em>typeOrLanguage</em> to <code>@type</code> and
-            <em>typeOrLanguageValue</em> to <em>commonType</em>.
-          </li>
-          <li>
-            Otherwise, set <em>typeOrLanguageValue</em> to
-            <em>commonLanguage</em>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        Otherwise:
-        <ol class="algorithm">
-          <li>
-            If <em>value</em> contains the key <code>@value</code>:
-            <ol class="algorithm">
-              <li>
-                If <em>value</em> contains the key <code>@language</code>,
-                then set <em>typeOrLanguageValue</em> to its associated
-                value and append <code>@language</code> to
-                <em>containers</em>.
-              </li>
-              <li>
-                Otherwise, if <em>value</em> contains the key
-                <code>@type</code>, then set <em>typeOrLanguageValue</em> to
-                its associated value and set <em>typeOrLanguage</em> to
-                <code>@type</code>.
-              </li>
-            </ol>
-          </li>
-          <li>
-            Otherwise, set <em>typeOrLanguage</em> to <code>@type</code>
-            and set <em>typeOrLanguageValue</em> to <code>@id</code>.
-          </li>
-          <li>
-            Append <code>@set</code> to <em>containers</em>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        Initialize <em>term</em> to the result of the
-        <a href="#term-selection">Term Selection</a> subalgorithm, passing
-        <tref>active context</tref>, <em>value</em>, <em>parent</em>,
-        <em>entry</em>, <em>containers</em>, <em>typeOrLanguage</em>, and
-        <em>typeOrLangaugeValue</em>.
-      </li>
-      <li>
-        If <em>term</em> is not <tref>null</tref>, return <em>term</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    At this point, there is no simple <tref>term</tref> that <em>iri</em>
-    can be compacted to. Instead, try to choose a <tref>compact IRI</tref>,
-    starting by initializing <em>choice</em> to <tref>null</tref>. This
-    variable will be used to store the chosen <tref>compact IRI</tref> to
-    use, if any.
-  </li>
-  <li>
-    For each key <tref>term</tref> and value <tref>term definition</tref> in
-    the <tref>active context</tref>:
-    <ol class="algorithm">
-      <li>
-        If the <tref>term</tref> contains a colon (<code>:</code>),
-        then continue to the next <tref>term</tref> because
-        <tref title="term">terms</tref> with colons can't be
-        used as <tref title="prefix">prefixes</tref>.
-      </li>
-      <li>
-        If the <tref>term definition</tref> is <tref>null</tref>
-        or for a <tref>property generator</tref> or its
-        <tref>IRI mapping</tref> equals <em>iri</em> or is not
-        a substring at the beginning of <em>iri</em>, then the
-        <tref>term</tref> cannot be used as a <tref>prefix</tref>
-        because it is not a partial match with <em>iri</em>. So
-        continue to the next <tref>term</tref>.
-      </li>
-      <li>
-        Initialize <em>curie</em> by concatenating <tref>term</tref>,
-        a colon (<code>:</code>), and the substring of <em>iri</em>
-        that follows after the value of the
-        <tref title="term definition">term definition's</tref>
-        <tref>IRI mapping</tref>.
-      </li>
-      <li>
-        Initialize <em>isUsableCurie</em> to <tref>false</tref>. If
-        <em>curie</em> does not have a <tref>term definition</tref> in
-        <tref>active context</tref> or if the
-        <tref>term definition</tref> has an <tref>IRI mapping</tref>
-        that equals <em>iri</em> and <em>value</em> is <tref>null</tref>,
-        then set <em>isUsableCurie</em> to <tref>true</tref>.
-      </li>
-      <li>
-        If <em>isUsableCurie</em> equals <tref>true</tref> and either
-        <em>choice</em> is <tref>null</tref> or <em>curie</em> is shorter
-        or the same length but lexicographically less than
-        <em>choice</em>, set <em>choice</em> to <em>curie</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    If <em>choice</em> is not <tref>null</tref>, return <em>choice</em>.
-  </li>
-  <li>
-    At this point, there is no <tref>compact IRI</tref> that <em>iri</em>
-    can be compacted to, so if <em>vocabRelative</em> equals
-    <tref>true</tref> and <tref>active context</tref> has a
-    <tref>vocabulary mapping</tref>:
-    <ol class="algorithm">
-      <li>
-        If <em>iri</em> begins with the
-        <tref title="vocabulary mapping">vocabulary mapping's</tref> value
-        but is longer, then initialize <em>suffix</em> to the substring
-        of <em>iri</em> that does not match. If <em>suffix</em> does not
-        have a <tref>term definition</tref> in <tref>active context</tref>,
-        then return <em>suffix</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    There are no <tref>compaction</tref> options for <em>iri</em> so
-    return <em>iri</em> as is.
-  </li>
-</ol>
-
-</section>
-
-<!-- end of IRI Compaction -->
-</section>
-
-<section>
-<h2>Inverse Context Creation Subalgorithm</h2>
-
-<p>
-When there is more than one <tref>term</tref> that could be chosen
-to compact an <tref>IRI</tref>, we want to ensure that our <tref>term</tref>
-selection is both deterministic and not unexpected, representing the most
-context-appropriate choice whilst taking into consideration algorithmic
-complexity.
-</p>
-
-<p>
-In order to make <tref>term</tref> selections the concept of an
-<tref>inverse context</tref> is introduced. An <tdef>inverse context</tdef>
-is essentially a reverse lookup table that maps
-<tref title="container mapping">container mappings</tref>,
-<tref title="type mapping">type mappings</tref>, and
-<tref title="language mapping">language mappings</tref> to a simple
-<tref>term</tref> and, if applicable, an <tref>array</tref> of potential
-<tref>property generator</tref> <tref title="term">terms</tref> for
-a given <tref>active context</tref>. A <tref>inverse context</tref> only
-needs to be generated for an <tref>active context</tref> if it is being
-used for <tref>compaction</tref>.
-</p>
-
-<p>
-To make use of an <tref>inverse context</tref>, a list of preferred
-<tref title="container mapping">container mappings</tref> and the
-<tref>type mapping</tref> or <tref>language mapping</tref> are gathered
-for a particular value associated with an <tref>IRI</tref>. These parameters
-are then fed to the <a href="#term-selection">Term Selection</a>
-subalgorithm, which will find the <tref>term</tref> that most appropriately
-matches the value's mappings.
-</p>
-
-<section>
-<h3>Problem</h3>
-
-An <tref>inverse context</tref> must be created for the given
-<tref>active context</tref>.
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-To create an <tref>inverse context</tref> for a given
-<tref>active context</tref>, each <tref>term</tref> in the
-<tref>active context</tref> is visited, ordered by length, shortest
-first (ties are broken by choosing the lexicographically least
-<tref>term</tref>). For each <tref>term</tref>, an entry is added to
-the <tref>inverse context</tref> for each possible combination of
-<tref>container mapping</tref> and <tref>type mapping</tref>
-or <tref>language mapping</tref> that would legally match the
-<tref>term</tref>. Illegal matches include differences between a
-value's <tref>type mapping</tref> or <tref>language mapping</tref> and
-that of the <tref>term</tref>. If a <tref>term</tref> has no
-<tref>container mapping</tref>, <tref>type mapping</tref>, or
-<tref>language mapping</tref> (or some combination of these), then it
-will have an entry in the <tref>inverse context</tref> using the special
-key <code>@none</code>. This allows the
-<a href="#term-selection">Term Selection</a> subalgorithm to fall back
-to choosing more generic <tref title="term">terms</tref> when a more
-specificly-matching <tref>term</tref> is not available for a particular
-<tref>IRI</tref> and value combination.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-The algorithm takes one required input: the <tref>active context</tref> that
-the <tref>inverse context</tref> is being created for.
-</p>
-
-<ol class="algorithm">
-  <li>
-    Initialize <em>result</em> to an empty <tref>JSON object</tref>.
-  <li>
-    Initialize <em>defaultLanguage</em> to <code>@none</code>. If the
-    <tref>active context</tref> has a <tref>default language</tref>, then
-    set <em>defaultLanguage</em> to it.
-  </li>
-  <li>
-    For each key <tref>term</tref> and value <term>term definition</tref> in
-    the <tref>active context</tref>, ordered by shortest <tref>term</tref>
-    first (breaking ties by choosing the lexicographically least
-    <tref>term</tref>):
-    <ol class="algorithm">
-      <li>
-        If the <tref>term definition</tref> is <tref>null</tref>, then
-        <tref>term</tref> cannot be selected during <tref>compaction</tref>,
-        so continue to the next <tref>term</tref>.
-      </li>
-      <li>
-        Initialize <em>iris</em> to the value of the <tref>IRI mapping</tref>
-        for the <tref>term definition</tref>. If <em>iris</em> is not an
-        <tref>array</tref>, then set it to an <tref>array</tref> containing
-        only <em>iris</em>.
-      </li>
-      <li>
-        For each item <em>iri</em> in <em>iris</em>:
-        <ol class="algorithm">
-          <li>
-            If <em>iri</em> is not a key in <em>result</em>, then add
-            a key-value pair where the key is <em>iri</em> and the value
-            is an empty <tref>JSON object</tref> to <em>result</em>.
-          </li>
-          <li>
-            Initialize <em>container map</em> to the value associated with
-            the <em>iri</em> key in <em>result</em>.
-          </li>
-          <li>
-            Initialize <em>container</em> to <code>@none</code>. If there
-            is a <tref>container mapping</tref> in
-            <tref>term definition</tref>, then set <em>container</em> to
-            its associated value.
-          </li>
-          <li>
-            If <em>container</em> is not a key in <em>container map</em>,
-            then initialize <em>typeOrLanguage map</em> to a new
-            <tref>JSON object</tref>. Add two key-value pairs to
-            <em>typeOrLanguage map</em>, where the first's key is
-            <code>@language</code> and its value is a new
-            <tref>JSON object</tref> and where the second's key is
-            <code>@type</code> and its value is a new
-            <tref>JSON object</tref>. Set the value of the key
-            <em>defaultLanguage</em> in the value associated with the
-            key <code>@language</code> in <em>typeOrLanguage map</em>
-            to a new <tref>JSON object</tref> containing a key-value pair
-            where the key is <code>term</code> and the value is
-            <tref>null</tref>.
-          </li>
-          <li>
-            Set <em>typeOrLanguage map</em> to the value associated with
-            the key <em>container</em> in <em>container map</em>.
-          </li>
-          <li>
-            If there is no <tref>type mapping</tref> in the
-            <tref>term definition</tref>:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>language map</em> to the value associated
-                with the key <code>@language</code> in
-                <em>typeOrLanguage map</em>.
-              </li>
-              <li>
-                If there is a <tref>language mapping</tref> in the
-                <tref>term definition</tref>:
-                <ol class="algorithm">
-                  <li>
-                    If the value of the <tref>language mapping</tref>
-                    is <tref>null</tref> initialize <em>language</em>
-                    to <code>@null</code>, otherwise initialize it to the
-                    value.
-                  </li>
-                  <li>
-                    If <em>language</em> is not a key in
-                    <em>language map</em>, then add a key-value
-                    pair to <em>language map</em> where the key is
-                    <em>language</em> and the value is a new
-                    <tref>JSON object</tref> with two key-value
-                    pairs, where the first's key is <code>term</code>
-                    and its value is <tref>null</tref>, and the second's
-                    key is <code>propertyGenerators</code> and the
-                    value is an empty <tref>array</tref>.
-                  </li>
-                  <li>
-                    Initialize <em>entry</em> to the value associated with
-                    the key <em>language</em> in <em>language map</em>.
-                  </li>
-                  <li>
-                    If <tref>term definition</tref> is a
-                    <tref>property generator</tref>, append the
-                    <tref>term</tref> to the <tref>array</tref> associated
-                    with the <code>propertyGenerators</code> key in
-                    <em>entry</em>.
-                  </li>
-                  <li>
-                    Otherwise, if the value associated with the key
-                    <code>term</code> in <em>entry</em> is <tref>null</tref>,
-                    set it to the <tref>term</tref>.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                Otherwise:
-                <ol class="algorithm">
-                  <li>
-                    If <em>defaultLanguage</em> is not a key in
-                    <em>language map</em>, then add a key-value
-                    pair to <em>language map</em> where the key is
-                    <em>defaultLanguage</em> and the value is a new
-                    <tref>JSON object</tref> with two key-value
-                    pairs, where the first's key is <code>term</code>
-                    and its value is <tref>null</tref>, and the second's
-                    key is <code>propertyGenerators</code> and the
-                    value is an empty <tref>array</tref>.
-                  </li>
-                  <li>
-                    Initialize <em>entry</em> to the value associated with
-                    the key <em>defaultLanguage</em> in <em>language map</em>.
-                  </li>
-                  <li>
-                    If <tref>term definition</tref> is a
-                    <tref>property generator</tref>, append the
-                    <tref>term</tref> to the <tref>array</tref> associated
-                    with the <code>propertyGenerators</code> key in
-                    <em>entry</em>.
-                  </li>
-                  <li>
-                    Otherwise, if the value associated with the key
-                    <code>term</code> in <em>entry</em> is <tref>null</tref>,
-                    set it to the <tref>term</tref>.
-                  </li>
-                  <li>
-                    If <code>@none</code> is not a key in
-                    <em>language map</em>, then add a key-value
-                    pair to <em>language map</em> where the key is
-                    <code>@none</code> and the value is a new
-                    <tref>JSON object</tref> with two key-value
-                    pairs, where the first's key is <code>term</code>
-                    and its value is <tref>null</tref>, and the second's
-                    key is <code>propertyGenerators</code> and the
-                    value is an empty <tref>array</tref>.
-                  </li>
-                  <li>
-                    Set <em>entry</em> to the value associated with
-                    the key <code>@none</code> in <em>language map</em>.
-                  </li>
-                  <li>
-                    If <tref>term definition</tref> is a
-                    <tref>property generator</tref>, append the
-                    <tref>term</tref> to the <tref>array</tref> associated
-                    with the <code>propertyGenerators</code> key in
-                    <em>entry</em>.
-                  </li>
-                  <li>
-                    Otherwise, if the value associated with the key
-                    <code>term</code> in <em>entry</em> is <tref>null</tref>,
-                    set it to the <tref>term</tref>.
-                  </li>
-                </ol>
-              </li>
-            </ol>
-          </li>
-          <li>
-            If there is no <tref>language mapping</tref> in the
-            <tref>term definition</tref>:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>type map</em> to the value associated
-                with the key <code>@type</code> in
-                <em>typeOrLanguage map</em>.
-              </li>
-              <li>
-                If there is a <tref>type mapping</tref> in the
-                <tref>term definition</tref> then initialize <em>type</em>
-                to its value, otherwise initialize it to
-                to <code>@none</code>.
-              </li>
-              <li>
-                If <em>type</em> is not a key in <em>type map</em>, then
-                add a key-value pair to <em>type map</em> where the key is
-                <em>type</em> and the value is a new <tref>JSON object</tref>
-                with two key-value pairs, where the first's key is
-                <code>term</code> and its value is <tref>null</tref>, and the
-                second's key is <code>propertyGenerators</code> and the
-                value is an empty <tref>array</tref>.
-              </li>
-              <li>
-                Initialize <em>entry</em> to the value associated with
-                the key <em>type</em> in <em>type map</em>.
-              </li>
-              <li>
-                If <tref>term definition</tref> is a
-                <tref>property generator</tref>, append the
-                <tref>term</tref> to the <tref>array</tref> associated
-                with the <code>propertyGenerators</code> key in
-                <em>entry</em>.
-              </li>
-              <li>
-                Otherwise, if the value associated with the key
-                <code>term</code> in <em>entry</em> is <tref>null</tref>,
-                set it to the <tref>term</tref>.
-              </li>
-            </ol>
-          </li>
-        </ol>
-      </li>
-    </ol>
-  </li>
-  <li>
-    Return <em>result</em>.
-  </li>
-</ol>
-
-</section>
-
-<!-- end of Inverse Context Creation subalgorithm -->
-</section>
-
-<section>
-<h2>Term Selection Subalgorithm</h2>
-
-<p>
-This subalgorithm, invoked via the
-<a href="#iri-compaction-algorithm">IRI Compaction</a> algorithm, makes use
-of an <tref title="active context">active context's</tref>
-<tref>inverse context</tref> to find the <tref>term</tref> that is best
-used to <tref title="compaction">compact</tref> an <tref>IRI</tref>. Other
-information about a value associated with the <tref>IRI</tref> is given,
-including which <tref title="container mapping">container mappings</tref>
-and which <tref>type mapping</tref> or <tref>language mapping</tref> would
-be best used to express the value.
-</p>
-
-<section>
-<h3>Problem</h3>
-
-An <tref>IRI</tref> with an associated <em>value</em> should be compacted
-to the most appropriate <tref>term</tref> in the <tref>active context</tref>.
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-The <tref title="inverse context">inverse context's</tref> entry for
-the <tref>IRI</tref> will be first searched according to the preferred
-<tref title="container mapping">container mappings</tref>, in the order
-that they are given. Amongst <tref title="term">terms</tref> with a matching
-<tref>container mapping</tref>, preference will be given to those
-with a matching <tref>type mapping</tref> or <tref>language mapping</tref>,
-over those without a <tref>type mapping</tref> or
-<tref>language mapping</tref>. If there is no <tref>term</tref>
-with a matching <tref>container mapping</tref> then the <tref>term</tref>
-without a <tref>container mapping</tref> that matches the given
-<tref>type mapping</tref> or <tref>language mapping</tref> is selected. If
-there is still no selected <tref>term</tref>, then a <tref>term</tref>
-with no <tref>type mapping</tref> or <tref>language mapping</tref> will
-be selected if available. No <tref>term</tref> will be selected that
-has a conflicting <tref>type mapping</tref> or <tref>language mapping</tref>.
-Ties between <tref title="term">terms</tref> that have the same
-mappings are resolved by first choosing the shortest terms, and then by
-choosing the lexicographically least term. Note that these ties are
-resolved automatically because they were previously resolved when the
-<a href="#inverse-context-creation">Inverse Context Creation algorithm</a>
-was used to create the <tref>inverse context</tref>.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-This subalgorithm has seven required inputs. They are:
-an <tref>active context</tref>, an <tref>IRI</tref> <em>iri</em>,
-a <em>value</em> associated with the <tref>IRI</tref>, the expanded
-<em>parent</em> element for <em>value</em> (which may be a
-<tref>JSON object</tref>, an <tref>array</tref>, or <tref>null</tref>), an
-<tref>array</tref> <em>containers</em> that represents ordered list of
-preferred <tref title="container mapping">container mappings</tref>, a
-<tref>string</tref> <em>typeOrLanguage</em> that indicates whether
-to look for a <tref>term</tref> with a matching <tref>type mapping</tref>
-or <tref>language mapping</tref>, and a <tref>string</tref>
-<em>typeOrLanguageValue</em> with the associated value for the
-<tref>type mapping</tref> or <tref>language mapping</tref> to look for.
-</p>
-
-<ol class="algorithm">
-  <li>
-    Append <code>@none</code> to <em>containers</em>. This represents
-    the non-existence of a <tref>container mapping</tref>, and it will
-    be the last <tref>container mapping</tref> value to be checked as it
-    is the most generic.
-  </li>
-  <li>
-    Initialize <em>container map</em> to the value associated with
-    <em>iri</em> in the <tref>inverse context</tref>.
-  </li>
-  <li>
-    If <em>typeOrLanguageValue</em> is <tref>null</tref>, set it to
-    <code>@null</code>. This is the key underwhich <tref>null</tref> values
-    are stored in the <tref>inverse context</tref> <em>entry</em>.
-  </li>
-  <li>
-    Initialize <em>preferred values</em> to an <tref>array</tref> containing
-    <em>typeOrLangageValue</em> and <code>@none</code>, in that order. This
-    <tref>array</tref> indicates, in order, the preferred values for
-    a <tref title="term">term's</tref> <tref>type mapping</tref> or
-    <tref>language mapping</tref>.
-  </li>
-  <li>
-    Initialize <em>selected term</em> to <tref>null</tref>.
-  </li>
-  <li>
-    For each item <em>container</em> in <em>containers</em> while
-    <em>selected term</em> is <tref>null</tref>:
-    <ol class="algorithm">
-      <li>
-        If <em>container</em> is not a key in <em>container map</em>, then
-        there is no <tref>term</tref> with a matching
-        <tref>container mapping</tref> for it, so continue to the next
-        <em>container</em>.
-      </li>
-      <li>
-        Initialize <em>typeOrLanguage map</em> to the value associated
-        with <em>container</em> in <em>container map</em>.
-      </li>
-      <li>
-        Initialize <em>typeOrLanguageValue map</em> to the value associated
-        with <em>typeOrLanguage</em> in <em>typeOrLanguage map</em>.
-      </li>
-      <li>
-        For each <em>item</em> in <em>preferred values</em> while
-        <em>selected term</em> is <tref>null</tref>:
-        <ol class="algorithm">
-          <li>
-            If <em>item</em> is not a key in <em>typeOrLanguageValue map</em>,
-            then there is no <tref>term</tref> with a matching
-            <tref>type mapping</tref> or <tref>language mapping</tref>,
-            so continue to the next <em>item</em>.
-          </li>
-          <li>
-            Initialize <em>termInfo</em> to the value associated with
-            <em>item</em> in <em>typeOrLanguageValue map</em>.
-          </li>
-          <li>
-            If <em>parent</em> is a <tref>JSON object</tref>,
-            then for each <tref>property generator</tref> <tref>term</tref>
-            <em>propertyGeneratorTerm</em> in <em>termInfo</em> while
-            <em>selected term</em> is <tref>null</tref>:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>iris</em> to the value of the
-                <tref>IRI mapping</tref> for <em>propertyGeneratorTerm</em>
-                in the <tref>active context</tref>.
-              </li>
-              <li>
-                Initialize <em>match</em> to <tref>true</tref>.
-              </li>
-              <li>
-                For each item <em>propertyGeneratorIri</em> in <em>iris</em>
-                while <em>match</em> equals <tref>true</tref>:
-                <ol class="algorithm">
-                  <li>
-                    If <em>propertyGeneratorIri</em> is not a key in
-                    <em>parent</em>, set <em>match</em> to <tref>false</tref>.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                If <em>match</em> equals <tref>true</tref>, then set
-                <em>selected term</em> to <em>propertyGeneratorTerm</em>.
-              </li>
-            </ol>
-          </li>
-          <li>
-            If <em>selected term</em> is <tref>null</tref>, then no
-            <tref>property generator</tref> match was found, so set
-            <em>selected term</em> to the non-<tref>property generator</tref>
-            <tref>term</tref> in <em>termInfo</em>, which may be
-            <tref>null</tref>.
-          </li>
-        </ol>
-      </li>
-    </ol>
-  </li>
-  <li>
-    Return <em>selected term</em>.
-  </li>
-</ol>
-
-</section>
-
-<!-- end of Term Selection subalgorithm -->
-</section>
-
-<section>
-<h2>Value Compaction</h2>
-
-<p>
-<tref>Expansion</tref> transforms all values into <tref>expanded form</tref>
-in JSON-LD. This algorithm performs the opposite operation, transforming
-a value into <tdef>compacted form</tdef>. This algorithm compacts a
-value according to the <tref>term definition</tref> in the given
-<tref>active context</tref> that is associated with the value's associated
-<tref>active property</tref>.
-</p>
-
-<section>
-<h3>Problem</h3>
-
-A <em>value</em> associated with an <tref>active property</tref> must
-be <tref title="compaction">compacted</tref> to <tref>compacted form</tref>.
-
-</section>
-
-<section>
-<h3>General Solution</h3>
-
-<p>
-The <em>value</em> to compact either contains the key <code>@value</code>
-or the key <code>@id</code>.
-</p>
-
-<p>
-We start with the former case, first trying to compact the
-<em>value</em> into just the value associated with its
-<code>@value</code> key. This can be done if the <em>value</em> is not
-going to be contained by an <code>@index</code> container and if the
-<tref>active property</tref> has a matching <tref>type mapping</tref> or
-<tref>language mapping</tref>. It can also be done if <code>@value</code>
-is the only key in <em>value</em> and either its associated value is
-not a <tref>string</tref>, there's no <tref>default language</tref>, or
-there's an explicit <tref>null</tref> <tref>language mapping</tref> for
-the <tref>active property</tref>.
-</p>
-
-<p>
-If we couldn't do the above optimal compaction, then we simply replace
-<tref title="keyword">keywords</tref> with aliases and compact any
-<tref title="IRI">IRIs</tref>.
-</p>
-
-<p>
-For the latter case, where the key <code>@id</code> appears in <em>value</em>,
-we compact the associated value using the
-<a href="#iri-compaction-algorithm">IRI Compaction</a> algorithm, and
-use its value if the <tref>type mapping</tref> associated with the
-<tref>active property</tref> is <code>@id</code> or the expanded value for
-the <tref>active property</tref> is <code>@graph</code>. Otherwise, we
-replace the <code>@id</code> key with its alias and its associated value
-with its compacted version.
-</p>
-
-</section>
-
-<section>
-<h3>Algorithm</h3>
-
-<p>
-This algorithm has three required inputs: an <tref>active context</tref>, an
-an <tref>active property</tref>, and a <em>value</em> to be compacted.
-</p>
-
-<ol class="algorithm">
-  <li>
-    If <em>value</em> contains the key <code>@value</code>:
-    <ol class="algorithm">
-      <li>
-        Initialize <em>preserveIndex</em> to <tref>false</tref>. If
-        <code>@index</code> is a key in <em>value</em> and
-        <tref>active property</tref> does not have a
-        <tref>container mapping</tref> in <tref>active context</tref> that
-        equals <code>@index</code>, set <em>preserveIndex</em> to
-        <tref>true</tref>.
-      </li>
-      <li>
-        If <em>preserveIndex</em> equals <tref>false</tref> and either
-        <em>value</em> has a <code>@type</code> key with a value that
-        matches <tref title="active property">active property's</tref>
-        <tref>type mapping</tref> in <tref>active context</tref> or
-        <em>value</em> has a <code>@language</code> key with a value that
-        matches <tref title="active property">active property's</tref>
-        <tref>language mapping</tref> in <tref>active context</tref>, then
-        return the value associated with the <code>@value</code> key in
-        <em>value</em>.
-      </li>
-      <li>
-        If <code>@value</code> is the only key in <em>value</em> or
-        <em>preserveIndex</em> equals <tref>false</tref> and either
-        there is no <tref>default language</tref> in
-        <tref>active context</tref>, the value associated with the
-        <code>@value</code> key in <em>value</em> is not a
-        <tref>string</tref>, or <tref>active property</tref>
-        has a <tref>null</tref> <tref>language mapping</tref> in
-        <tref>active context</tref>, then return the value
-        associated with the <code>@value</code> key in <em>value</em>.
-      </li>
-      <li>
-        Initialize <em>result</em> to an empty <tref>JSON object</tref>.
-      </li>
-      <li>
-        If <em>preserveIndex</em> equals <tref>true</tref>, then add
-        a key-value pair to <em>result</em> where the key is the result
-        using the <a href="#iri-compaction-algorithm">IRI compaction</a>
-        algorithm, passing <tref>active context</tref> and
-        <code>@index</code> for <em>iri</em>, and the value is
-        the value associated with the <code>@index</code> key in
-        <em>value</em>.
-      </li>
-      <li>
-        If <em>value</em> contains the key <code>@type</code>, then add
-        a key-value pair to <em>result</em> where the key is the result
-        using the <a href="#iri-compaction-algorithm">IRI compaction</a>
-        algorithm, passing <tref>active context</tref> and
-        <code>@type</code> for <em>iri</em>, and the value is the result
-        of using the <a href="#iri-compaction-algorithm">IRI compaction</a>
-        algorithm, passing <tref>active context</tref>, the value associated
-        with the <code>@type</code> key in <em>value</em> for <em>iri</em>,
-        <tref>true</tref> for <em>vocabRelative</em>, and
-        <tref>true</tref> for <em>documentRelative</em>.
-      </li>
-      <li>
-        Otherwise, if <em>value</em> contains the key <code>@language</code>,
-        then add a key-value pair to <em>result</em> where the key is the
-        result using the
-        <a href="#iri-compaction-algorithm">IRI compaction</a>
-        algorithm, passing <tref>active context</tref> and
-        <code>@language</code> for <em>iri</em>, and the value is the
-        value associated with the <code>@language</code> key in
-        <em>value</em>.
-      </li>
-      <li>
-        Add a key-value pair to <em>result</em> where the key is the result
-        using the <a href="#iri-compaction-algorithm">IRI compaction</a>
-        algorithm, passing <tref>active context</tref> and
-        <code>@value</code> for <em>iri</em>, and the value is the value
-        associated with the <code>@value</code> key in <em>value</em>.
-      </li>
-      <li>
-        Return <em>result</em>.
-      </li>
-    </ol>
-  </li>
-  <li>
-    Otherwise, <em>value</em> must contain the single key <code>@id</code>.
-    Initialize <em>expanded property</em> to the result of using the
-    <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-    passing <tref>active context</tref> and <em>value</em>.
-  </li>
-  <li>
-    Initialize <em>term</em> to the result of using the
-    <a href="#iri-compaction-algorithm">IRI compaction</a> algorithm,
-    passing <tref>active context</tref>, the value associated with
-    the key <code>@id</code> in <em>value</em> for <em>iri</em>,
-    and <tref>true</tref> for <em>documentRelative</em>.
-  </li>
-  <li>
-    If <tref>active property</tref> has a <tref>type mapping</tref> in
-    the <tref>active context</tref> that is equal to <code>@id</code> or
-    <em>expanded property</em> equals <code>@graph</code>, then return
-    <em>term</em>.
-  </li>
-  <li>
-    Initialize <em>result</em> to an empty <tref>JSON object</tref>. Add
-    a key-value pair to <em>result</em> where the key is the result of
-    using the <a href="#iri-compaction-algorithm">IRI compaction</a>
-    algorithm, passing <tref>active context</tref>, and <code>@id</code> for
-    <em>iri</em>, and the value is <em>term</em>.
-  </li>
-  <li>
-    Return <em>result</em>.
-  </li>
-</ol>
-
-</section>
-
-<!-- end of Value Compaction algorithm -->
-</section>
-
-<section>
-<h2>Find and Remove Property Generator Duplicates Subalgorithm</h2>
-
-<p>
-This algorithm checks if a specific value exists for all
-<tref title="IRI">IRIs</tref> associated with a
-<tref>property generator</tref> and, if so, it removes them.
-The algorithm takes five required inputs: an <tref>active context</tref>,
-<em>element</em>, <em>expanded property</em>, <em>value</em>, and
-<tref>active property</tref>.
-</p>
-
-<ol class="algorithm">
-  <li>
-    Initialize <em>iris</em> to the <tref>array</tref> associated with the
-    <tref>IRI mapping</tref> for <tref>active property</tref> in
-    <tref>active context</tref>.
-  </li>
-  <li>
-    For each <em>iri</em> in <em>iris</em>:
-    <ol class="algorithm">
-      <li>
-        If <em>iri</em> equals <em>expanded property</em>, then this
-        is the <em>iri</em> that is to be preserved, so continue to the next
-        <em>iri</em>.
-      </li>
-      <li>
-        Initialize <em>prospects</em> to the value associated with the
-        key that equals <em>iri</em> in <em>element</em>. This
-        <tref>array</tref> will be checked for a value that matches
-        the <tref>property generator</tref> <em>value</em>.
-      </li>
-      <li>
-        For each item <em>prospect</em> in <em>prospects</em>, until
-        a <tref>property generator</tref> duplicate is found for
-        <em>value</em>:
-        <ol class="algorithm">
-          <li>
-            Check to see if <em>prospect</em> and <em>value</em> are
-            <tref>property generator</tref> duplicates:
-            <ol class="algorithm">
-              <li>
-                If their types and values are equal, then they are duplicates.
-              </li>
-              <li>
-                Otherwise, if they are both
-                <tref title="JSON object">JSON objects</tref> that contain
-                the key <code>@value</code> and they both have the same
-                key-value pairs for the keys <code>@value</code>,
-                <code>@type</code>, <code>@language</code>, and
-                <code>@index</code>, then they are duplicates.
-              </li>
-              <li>
-                Otherwise, if they are both
-                <tref title="list object">list objects</tref> with the same
-                key-value pairs for the key <code>@index</code>, and the
-                <tref title="array">arrays</tref> associated with their
-                <code>@list</code> keys have the same length and their
-                corresponding items, by index, are duplicates, then they
-                are duplicates.
-              </li>
-              <li>
-                Otherwise, if they are both
-                <tref title="JSON object">JSON objects</tref> that contain
-                the key <code>@id</code> and the values associated with
-                those keys are equal, then they are duplicates.
-              </li>
-              <li>
-                Otherwise, they are not duplicates.
-              </li>
-            </ol>
-          </li>
-          <li>
-            If <em>prospect</em> and <em>value</em> are
-            <tref>property generator</tref> duplicates, then remove
-            <em>prospect</em> from <em>prospects</em> and, if
-            <em>prospects</em> is now empty, remove <em>iri</em>
-            from <em>element</em>.
-          </li>
-        </ol>
-      </li>
-    </ol>
-  </li>
-</ol>
-
-</section>
-
-<!-- FIXME -->
-<section>
-  <h2>Flattening Algorithm</h2>
-
-  <p>The algorithm takes two input variables, an <em>element</em> to flatten and a
-    <em>context</em> used to compact the flattened document.</p>
-
-  <ol class="algorithm">
-    <li>Expand <em>element</em> according the
-      <a href="#expansion-algorithm">Expansion algorithm</a>.</li>
-    <li>Generate a <em>nodeMap</em> according the
-      <a href="#node-map-generation">Node Map Generation algorithm</a>.</li>
-    <li>Let <em>defaultGraph</em> be the value of the <code>@default</code> member of
-      <em>nodeMap</em>; a <tref>JSON object</tref> representing the <tref>default graph</tref>.</li>
-    <li>For each other <em>graphName</em>-<em>graph</em> pair in <em>nodeMap</em>
-      perform the following steps:
-      <ol class="algorithm">
-        <li>If <em>defaultGraph</em> does not have a <em>graphName</em> member, create
-          one and initialize its value to a <tref>JSON object</tref> consisting of an
-          <code>@id</code> member whose value is set to <em>graphName</em>.</li>
-        <li>Add an <code>@graph</code> member set to an empty <tref>array</tref>
-          (referred to as <em>nodes</em>) to the <tref>JSON object</tref> which is the
-          value of the <em>graphName</em> member of <em>nodeMap</em>.</li>
-        <li>For each <em>id</em>-<em>node</em> pair in <em>graph</em> ordered by <em>id</em>,
-          add <em>node</em> to the <em>nodes</em> <tref>array</tref>.</li>
-      </ol>
-    </li>
-    <li>Initialize an empty <tref>array</tref> flattened.</li>
-    <li>For each <em>id</em>-<em>node</em> pair in <em>defaultGraph</em> ordered by <em>id</em>,
-      add <em>node</em> to <em>flattened</em>.</li>
-    <li>If <em>context</em> equals <tref>null</tref>, return <em>flattened</em>.</li>
-    <li>Otherwise, return the result of compacting <em>flattened</em> according the
-      <a href="#compaction-algorithm">Compaction algorithm</a> passing <em>context</em>
-      ensuring that the compaction result uses the <code>@graph</code> keyword (or its alias)
-      at the top-level, even if the context is empty or if there is only one element to
-      put in the <code>@graph</code> <tref>array</tref>. This ensures that the returned
-      document has a deterministic structure.</li>
-  </ol>
-</section>
-
-<!-- FIXME -->
-<section>
-  <h2>Node Map Generation</h2>
-
-  <p>This algorithm creates a <tref>JSON object</tref> <em>nodeMap</em> holding an indexed
-    representation of the <tref title="JSON-LD graph">graphs</tref> and <tref title="node">nodes</tref>
-    represented in the passed, expanded document. All <tref title="node">nodes</tref> that are not
-    uniquely identified by an IRI get assigned a (new) <tref>blank node identifier</tref>.
-    The resulting <em>nodeMap</em> will have a member for every graph in the document whose
-    value is another object with a member for every <tref>node</tref> represented in the document.
-    The default graph is stored under the <code>@default</code> member, all other graphs are
-    stored under their graph name</tref>.</p>
-
-  <p>The algorithm takes as input an expanded JSON-LD document <em>element</em> and a reference to
-    a <tref>JSON object</tref> <em>nodeMap</em>. Furthermore it has the optional parameters
-    <tref>active graph</tref> (which defaults to <code>@default</code>), an <tref>active subject</tref>,
-    <tref>active property</tref>, and a reference to a <tref>JSON object</tref> <em>list</em>. The
-    <em>nodeMap</em> must be initialized to a <tref>JSON object</tref> consisting of a single member
-    whose name corresponds with <tref>active graph</tref> and whose value is an empty <tref>JSON object</tref>.</p>
-
-  <ol class="algorithm">
-    <li>If <em>element</em> is an array, process each entry in <em>element</em> recursively, using this algorithm
-      and return.</li>
-    <li>Otherwise <em>element</em> is a <tref>JSON object</tref>. Let <em>activeGraph</em> be the
-      <tref>JSON object</tref> which is the value of the <tref>active graph</tref> member of
-      <em>nodeMap</em>.</li>
-    <li>If it has an <code>@type</code> member, perform for each <em>item</em> the following
-      steps:
-      <ol class="algorithm">
-        <li>If <em>item</em> is a <tref>blank node identifier</tref>, replace it with a
-          <a href="#generate-blank-node-identifier">new blank node identifier</a>.</li>
-        <li>If <em>activeGraph</em> has no member <em>item</em>, create it and initialize its
-          value to a <tref>JSON object</tref> consisting of a single member <code>@id</code>
-          with the value <em>item</em>.</li>
-      </ol>
-    </li>
-    <li>If <em>element</em> has an <code>@value</code> member, perform the following steps:
-      <ol class="algorithm">
-        <li>If no <em>list</em> has been passed, merge <em>element</em> into the
-          <tref>active property</tref> member of the <tref>active subject</tref> in
-          <em>activeGraph</em>.</li>
-        <li>Otherwise, append <em>element</em> to the <code>@list</code> member of <em>list</em>.</li>
-      </ol>
-    </li>
-    <li>Otherwise, if <em>element</em> has an <code>@list</code> member, perform
-      the following steps:
-      <ol class="algorithm">
-        <li>Initialize a new <tref>JSON object</tref> <em>result</em> having a single member
-          <code>@list</code> whose value is initialized to an empty <tref>array</tref>.</li>
-        <li>Recursively call this algorithm passing the value of <em>element's</em>
-          <code>@list</code> member as new <em>element</em> and <em>result</em> as <em>list</em>.</li>
-        <li>If <tref>active property</tref> equals <tref>null</tref> or <code>@graph</code>,
-          <a href="#generate-blank-node-identifier">generate a blank node identifier</a> <em>id</em>
-          and store <em>result</em> as value of the member <em>id</em> in <em>activeGraph</em>.</li>
-        <li>Otherwise, add <em>result</em> to the the value of the <tref>active property</tref> member
-          of the <tref>active subject</tref> in <em>activeGraph</em>.</li>
-      </ol>
-    </li>
-    <li>Otherwise <em>element</em> is a <tref>node object</tref>, perform the following
-      steps:
-      <ol class="algorithm">
-        <li>If <em>element</em> has an <code>@id</code> member, store its value in <em>id</em> and remove
-          the member from <em>element</em>. If <em>id</em> is a <tref>blank node identifier</tref>, replace it with
-          <a href="#generate-blank-node-identifier">a new blank node identifier</a>.</li>
-        <li>Otherwise <a href="#generate-blank-node-identifier">generate a new blank node identifier</a>
-          and store it as <em>id</em>.</li>
-        <li>If <em>activeGraph</em> does not contain a member <em>id</em>, create one and initialize
-          it to a <tref>JSON object</tref> consisting of a single member <code>@id</code> whose
-          value is set to <em>id</em>.</li>
-        <li>If <tref>active property</tref> is not <tref>null</tref>, perform the following steps:
-          <ol class="algorithm">
-            <li>Create a new <tref>JSON object</tref> <em>reference</em> consisting of a single member
-              <code>@id</code> whose value is <em>id</em>.</li>
-            <li>If no <em>list</em> has been passed, merge <em>element</em> into the
-              <tref>active property</tref> member of the <tref>active subject</tref> in
-              <em>activeGraph</em>.</li>
-            <li>Otherwise, append <em>element</em> to the <code>@list</code> member of <em>list</em>.</li>
-          </ol>
-        </li>
-        <li>If <em>element</em> has an <code>@type</code> member, merge each value into the <code>@type</code>
-          of <tref>active subject</tref> in <em>activeGraph</em>. Then remove the <code>@type</code> member
-          from <em>element</em>.</li>
-        <li>If <em>element</em> has an <code>@index</code> member, set the <code>@index</code>
-          of <tref>active subject</tref> in <em>activeGraph</em> to its value. If such a member already
-          exists in <tref>active subject</tref> and has a different value, raise a
-          <code class="error">CONFLICTING_ANNOTATION</code> error. Otherwise continue and remove the
-          <code>@index</code> from <em>element</em>.</li>
-        <li>If <em>element</em> has an <code>@graph</code> member, recursively invoke this algorithm passing
-          the value of the <code>@graph</code> member as new <em>element</em> and <em>id</em> as new
-          <tref>active subject</tref>. Then remove the <code>@graph</code> member from <em>element</em>.</li>
-        <li>Finally for each <em>property</em>-<em>value</em> pair in <em>element</em> ordered by
-          <em>property</em> perform the following steps:
-          <ol class="algorithm">
-            <li>If no <em>property</em> member exists in the <tref>JSON object</tref> which is the
-              value of the <em>id</em> member of <em>activeGraph</em> create the member and initialize
-              its value to an empty <tref>array</tref>.</li>
-            <li>Recursively invoke this algorithm passing <em>value</em> as new <em>element</em>, <em>id</em>
-              as new <tref>active subject</tref>, and <em>property</em> as new <tref>active property</tref>.</li>
-          </ol>
-        </li>
-      </ol>
-    </li>
-  </ol>
-</section>
-
-<!-- FIXME -->
-  <section>
-    <h2>RDF Conversion Algorithms</h2>
-
-    <p>This section describes algorithms to transform JSON-LD documents to an array of
-      RDF <tref title="quad">quads</tref> and vice-versa. Note that many uses of JSON-LD
-      may not require generation of RDF.</p>
-
-    <p>The processing algorithms described in this section are provided in order to demonstrate
-      how one might implement a JSON-LD to RDF processor. Conformant implementations are only
-      required to produce the same type and number of <tref title="quad">quads</tref> but are
-      not required to implement the algorithm exactly as described.</p>
-
-    <section>
-      <h3>Convert to RDF Algorithm</h3>
-
-      <p>
-        The algorithm below is designed for in-memory implementations with random access to <tref>JSON object</tref> elements.
-      </p>
-
-      <p>
-        A conforming JSON-LD processor implementing RDF conversion MUST implement a
-        processing algorithm that results in the same set of RDF <tref title="quad">quads</tref> that the following
-        algorithm generates.
-      </p>
-
-      <p>The algorithm takes five input variables: an <em>element</em> to be converted, an
-        <tref>active subject</tref>, an <tref>active property</tref>, a <tref>graph name</tref>,
-        and an <tref>array</tref> <em>quads</em> of <tref title="quad">Quads</tref>.
-        To begin, the <tref>active subject</tref>, <tref>active property</tref>, and <tref>graph name</tref>
-        are set to <tref>null</tref>, <em>quads</em> is set to an empty <tref>array</tref>, and <em>element</em> is
-        set to the result of performing the <a href="#expansion-algorithm">Expansion Algorithm</a> on
-        the <tref>JSON-LD input</tref> which is expected to be a a well-formed JSON-LD document as defined in [[!JSON-LD]].</p>
-
-      <p class="issue">This algorithm hasn't been updated to use [[!RDF-CONCEPTS]]
-      yet.</p>
-      <p class="issue">This algorithm needs some clarification on its details.</p>
-
-      <ol class="algorithm">
-        <li>
-          If <em>element</em> is an <tref>array</tref>, then for each <em>item</em>
-          in <em>element</em> invoke this algorithm recursively, passing
-          <em>item</em> for <em>element</em>, <tref>active subject</tref>,
-          <tref>active property</tref>, <tref>graph name</tref>, and <em>quads</em>.
-        </li>
-        <li>
-          Otherwise, if <em>element</em> is a <tref>string</tref>, then
-          generate a <tref>quad</tref> using <tref>active subject</tref>,
-          <tref>active property</tref>, an <tref>IRI</tref> with the value
-          of <em>element</em> for <tref>RDF object</tref>, and
-          <tref>graph name</tref>. Append the <tref>quad</tref> to
-          <em>quads</em>.
-        </li>
-        <li>
-          Otherwise, if <em>element</em> is a <tref>list object</tref>:
-          <ol class="algorithm">
-            <li>
-              Initialize <em>list</em> to the result of the
-              <a href="#list-conversion">List Conversion</a> algorithm, passing
-              the value associated with the <code>@list</code> key.
-            </li>
-            <li>
-              Invoke this algorithm recursively, passing <em>list</em> for
-              <em>element</em>, <tref>active subject</tref>,
-              <tref>active property</tref>, <tref>graph name</tref>, and
-              <em>quads</em>.
-            </li>
-          </ol>
-        </li>
-        <li>
-          Otherwise, if <em>element</em> is a <tref>JSON object</tref> that
-          contains the key <code>@value</code>:
-          <ol class="algorithm">
-            <li>
-              Initialize <em>value</em> to the value associated with the
-              <code>@value</code> key in <em>element</em>. Initialize
-              <em>datatype</em> to the value associated with the <code>@type</code>
-              key in <em>element</em>, or <tref>null</tref> if <em>element</em>
-              does not contain that key.
-            </li>
-            <li>
-              Otherwise, if <em>value</em> equals <tref>true</tref> or
-              <tref>false</tref>, then set <em>value</em> its
-              <tref>canonical lexical form</tref> as defined
-              in the section <a href="#data-round-tripping">Data Round Tripping</a>.
-              If <em>datatype</em> is <tref>null</tref>, set it to
-              <code>xsd:boolean</code>.
-            </li>
-            <li>
-              Otherwise, if <em>value</em> is a <tref>number</tref>, then set
-              <em>value</em> to its <tref>canonical lexical form</tref> as defined
-              in the section <a href="#data-round-tripping">Data Round Tripping</a>.
-              If <em>datatype</em> is <tref>null</tref>, set it to either
-              <code>xsd:integer</code> or <code>xsd:double</code>, depending
-              on if the value contains a fractional and/or an exponential
-              component.
-            </li>
-            <li>
-              Otherwise, if <em>datatype</em> is <tref>null</tref>, set it to
-              <code>xsd:string</code>.
-            </li>
-            <li>
-              Initialize <tref>active object</tref> using <em>value</em> and
-              <em>datatype</em>. If <em>element</em> has the key
-              <code>@language</code> and <em>datatype</em> equals
-              <code>xsd:string</code>, then add the value associated with the
-              <code>@language</code> key as the language of the
-              <tref>active object</tref>.
-            </li>
-            <li>
-              Generate a <tref>quad</tref> using <tref>active subject</tref>,
-              <tref>active property</tref>, <tref>active object</tref>, and
-              <tref>graph name</tref>. Append the <tref>quad</tref> to
-              <em>quads</em>.
-            </li>
-          </ol>
-        </li>
-        <li>
-          Otherwise, <em>element</em> must represent the next
-          <tref>RDF subject</tref> to be processed:
-          <ol class="algorithm">
-            <li>
-              If <em>element</em> contains the key <code>@id</code>, then
-              initialize <em>id</em> to its associated value, otherwise initialize
-              it to <tref>null</tref>. If <em>element</em> is a
-              <tref>blank node</tref>, then set <em>id</em> to the result of
-              using the
-              <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a>
-              algorithm, passing <em>id</em> for <em>identifier</em>.
-            </li>
-            <li>
-              Initialize <tref>active object</tref> to an <tref>IRI</tref> or
-              <tref>blank node</tref>, as appropriate, with the value of
-              <em>element</em>.
-            </li>
-            <li>
-              If <tref>active subject</tref> is not <tref>null</tref>, then
-              generate a <tref>quad</tref> using <tref>active subject</tref>,
-              <tref>active property</tref>, <tref>active object</tref>, and
-              <tref>graph name</tref>. Append the <tref>quad</tref> to
-              <em>quads</em>.
-            </li>
-            <li>
-              Set <tref>active subject</tref> to <tref>active object</tref>.
-            </li>
-            <li>
-              For each <em>key</em>-<em>value</em> pair in <em>element</em>,
-              sorted lexicographically by <em>key</em>:
-              <ol class="algorithm">
-                <li>
-                  Set <tref>active property</tref> to <em>value</em>.
-                </li>
-                <li>
-                  If <tref>active property</tref> equals <code>@graph</code>, then
-                  use this algorithm recursively, passing <em>value</em> for
-                  <em>element</em>, <tref>null</tref> for
-                  <tref>active subject</tref> and <tref>active property</tref>,
-                  <tref>active subject</tref> for <tref>graph name</tref>,
-                  and <em>quads</em>. Then continue to the next <em>key</em>.
-                </li>
-                <li>
-                  If <em>key</em> equals <code>@type</code>, then set
-                  <tref>active property</tref> to <code>rdf:type</code>.
-                </li>
-                <li>
-                  If <tref>active property</tref> is a <tref>keyword</tref>,
-                  then continue to the next <em>key</em>.
-                </li>
-                <li>
-                  Use this algorithm recursively, passing <em>value</em> for
-                  <em>element</em>, <tref>active subject</tref>,
-                  <tref>active property</tref>, <tref>graph name</tref>,
-                  and <em>quads</em>.
-                </li>
-              </ol>
-            </li>
-          </ol>
-        </li>
-      </ol>
-    </section>
-
-    <section id="list-conversion">
-      <h3>List Conversion</h3>
-
-      <p>List Conversion is the process of taking an <tref>array</tref> of values and
-        converting it to a JSON-LD linked list of
-        <tref title="JSON object">JSON objects</tref>. Each element of the list is
-        linked by using <code>rdf:first</code> and <code>rdf:rest</code>, terminating
-        the list with <code>rdf:nil</code>.</p>
-
-      <p>The algorithm takes a single input: an <tref>array</tref> <em>list</em>.</p>
-
-      <div class="note">This algorithm does not support lists containing lists.</div>
-
-      <ol class="algorithm">
-        <li>
-          Initialize <em>length</em> to the length of <em>list</em>.
-        </li>
-        <li>
-          Initialize <em>tail</em> to a <tref>JSON object</tref> containing
-          one key-value pair, (<code>@id</code>-<code>rdf:nil</code>).
-        </li>
-        <li>
-          Starting <em>itr</em> at <em>length</em> minus <code>1</code>, loop
-          until <em>itr</em> is <code>0</code> (inclusive):
-          <ol class="algorithm">
-            <li>
-              Initialize <em>element</em> to an empty <tref>JSON object</tref>.
-            </li>
-            <li>
-              Add a key-value pair to <em>element</em> where the key is
-              <code>rdf:first</code> and the value is an <tref>array</tref>
-              containing the value associated with the index <em>itr</em>
-              in <em>list</em>.
-            </li>
-            <li>
-              Add a key-value pair to <em>element</em> where the key is
-              <code>rdf:rest</code> and the value is an <tref>array</tref>
-              containing <em>tail</em>.
-            </li>
-            <li>
-              Set <em>tail</em> to <em>element</em>.
-            </li>
-            <li>
-              Decrement <em>itr</em> by <code>1</code>.
-            </li>
-          </ol>
-        </li>
-        <li>
-          Return <em>tail</em>.
-        </li>
-      </ol>
-    </section>
-
-<!-- FIXME -->
-    <section>
-      <h2>Convert from RDF Algorithm</h2>
-      <p>In some cases, data exists natively in the form of triples or or <tref title="quad">quads</tref>;
-        for example, if the data was originally represented in an RDF graph or triple/quad store. This
-        algorithm is designed to simply translate an array of <tref title="quad">quads</tref> into a
-        JSON-LD document.</p>
-      <p>When expanding <tref title="typed value">typed values</tref> having a datatype of <code>xsd:string</code>,
-        the <code>@type</code> MUST NOT be set to <code>xsd:string</code> and the resulting value
-        MUST have only an <code>@value</code> property.</p>
-
-      <p>The conversion algorithm takes a single parameter <em>input</em> in the form of an
-        array of <tref>Quad</tref> representations.</p>
-
-      <p class="issue">This algorithm hasn't been updated to use [[!RDF-CONCEPTS]] yet.</p>
-
-      <ol class="algorithm">
-        <li id="new_graph">Construct <em>defaultGraph</em> as a <tref>JSON object</tref>
-          containing <em>nodes</em> and <em>listMap</em>, each an empty <tref>JSON object</tref>.</li>
-        <li>Construct <em>graphs</em> as a <tref>JSON object</tref> containing <em>defaultGraph</em>
-          identified by
-          an empty <tref>string</tref>.</li>
-        <li>For each <tref>quad</tref> in <em>input</em>:
-          <ol class="algorithm">
-            <li>Set <em>graph</em> to the entry in <em>graphs</em> identified
-              by <em>name</em>, initializing it to a new entry using the mechanism
-              described in <a href="#new_graph">Step 1</a>.</li>
-            <li>If <em>property</em> is <code>rdf:first</code>,
-              use the entry in <em>graph.listMap</em> indexed by <em>subject</em>,
-              initializing it to a new <tref>JSON object</tref> if nesessary. Represent
-              <em>object</em> in <tref>expanded form</tref>, as described in
-              <a href="#value-expansion">Value Expansion</a>. Add the
-              resulting <em>object representation</em> to the entry indexed by
-              <em>first</em>, and skip to the next <tref>quad</tref>.</li>
-            <li>If <em>property</em> is <code>rdf:rest</code>:
-              <ol class="algorithm">
-                <li>If <em>object</em> is a <tref>blank node</tref>, use the entry in
-                  <em>graph.listMap</em> indexed by <em>subject</em>, initializing it
-                  to a new <tref>JSON object</tref> if necessary. Add the <em>nominalValue</em> of
-                  <em>object</em> to the entry indexed by <em>rest</em>.
-                </li>
-                <li>Skip to the next <tref>quad</tref>.</li>
-              </ol>
-            </li>
-            <li>If <em>name</em> is not <tref>null</tref>, and <em>defaultGraph.nodes</em>
-              does not contain an entry for <em>name</em>,
-              create a new entry for <em>name</em> from a new
-              <tref>JSON object</tref> with key/value pair of <code>@id</code> and
-              <em>name</em> represented in <tref>expanded IRI form</tref>.</li>
-            <li>Set <em>value</em> as the entry from <em>graph.nodes</em> for
-              <em>subject</em>, initializing it to a new
-              <tref>JSON object</tref> with key/value pair of <code>@id</code> and
-              <em>subject</em> represented in <tref>expanded IRI form</tref> if necessary.</li>
-            <li>If <em>property</em> is <code>rdf:type</code>, <em>object</em> is not a <tref>JSON-LD value</tref>, and the
-              <code class="idlMemberName"><a href="#widl-JsonLdOptions-useRdfType">useRdfType</a></code>
-              option is not present or <tref>false</tref>:
-              <ol class="algorithm">
-                <li>Append <em>object</em> represented in <tref>expanded IRI form</tref> to the array value for the
-                  key <code>@type</code>, creating an entry in <em>value</em> if necessary.</li>
-              </ol>
-            </li>
-
-            <li>Otherwise, if <em>object</em> is a <tref>typed value</tref> and the
-              <code class="idlMemberName"><a href="#widl-JsonLdOptions-useNativeTypes">useNativeTypes</a></code>
-              option is set to <tref>true</tref>:
-              <ol class="algorithm">
-                <li>Generate a <em>converted value</em>:
-                  <ol class="algorithm">
-                    <li>If the literal's type is <code>xsd:boolean</code>, the
-                      <em>converted value</em> is <tref>true</tref> if the literal
-                      matches the value <code>true</code> or <code>false</code> if
-                      the literal matches the value <code>false</code>.</li>
-                    <li>If the literal's type is <code>xsd:integer</code> or
-                      <code>xsd:double</code>, try to convert the literal to a
-                      JSON <tref>number</tref>. If the conversion is successful,
-                      store the result in <em>converted value</em>, otherwise
-                      set <em>converted value</em> to <em>value</em>.</li>
-                    <li>Otherwise, do not perform a conversion. Set
-                      the <em>converted value</em> to the <em>value</em>.</li>
-                  </ol>
-                </li>
-                <li>Append the <em>converted value</em> to the array value for the
-                  key, creating an entry in <em>value</em> if necessary.</li>
-              </ol>
-            </li>
-
-            <li>Otherwise, if <em>object</em> is <code>rdf:nil</code>:
-              <ol class="algorithm">
-                <li>Let <em>key</em> be <em>property</em> expressed in <tref>expanded IRI form</tref>.</li>
-                <li>Append an empty <code>@list</code> representation to the array value for
-                  <em>key</em>, creating an entry in <em>value</em> if necessary.</li>
-              </ol>
-            </li>
-            <li>Otherwise,
-              <ol class="algorithm">
-                <li>Let <em>key</em> be <em>property</em> expressed in <tref>expanded IRI form</tref> and let
-                  <em>object representation</em>
-                  be <em>object</em> represented in <tref>expanded form</tref> as described in
-                  <a href="#value-expansion">Value Expansion</a>.</li>
-                <li>If <em>object</em> is a <tref>blank node</tref>,
-                  use the entry in <em>graph.listMap</em> indexed by <em>object</em>,
-                  initializing it to a new <tref>JSON object</tref> if nesessary.
-                  Add an entry for <em>head</em> with <em>object representation</em>.</li>
-                <li>Append <em>object representation</em> to the array value for
-                  <em>key</em>, creating an entry in <em>value</em> if necessary.</li>
-              </ol>
-            </li>
-          </ol>
-        </li>
-        <li>For each <em>name</em> and <em>graph</em> in <em>graphs</em>:
-          <ol class="algorithm">
-            <li>For each <em>subject</em> and <em>entry</em> in <em>graph</em>
-              where <em>entry</em> has both <em>head</em> and <em>first</em> keys:
-              <ol class="algorithm">
-                <li>Set <em>value</em> to the value of <em>head</em> in <em>entry</em>.</li>
-                <li>Remove the entry for <code>@id</code> in <em>value</em>.</li>
-                <li>Add an entry to <em>value</em> for <code>@list</code> initialized to a new array
-                  containing the value of <em>first</em> from <em>entry</em>.</li>
-                <li>While <em>entry</em> has a key for <em>rest</em>:
-                  <ol class="algorithm">
-                    <li>Set <em>entry</em> to the value of <em>graph.listMap</em> for <em>entry.rest</em>.</li>
-                    <li>Add the value for <em>entry.first</em> to the list array.</li>
-                  </ol>
-                </li>
-              </ol>
-            </li>
-          </ol>
-        </li>
-        <li>Create <em>array</em> as an empty <tref>array</tref>.</li>
-        <li>For each <em>subject</em> and <em>entry</em> in <em>defaultGraph.nodes</em>
-          ordered by <em>subject</em>:
-          <ol class="algorithm">
-            <li>Add <em>entry</em> to <em>array</em>.</li>
-            <li>If <em>graphs</em> has an entry for <em>subject</em>, add a property
-              <code>@graph</code> in <em>entry</em> containing the ordered entries
-              from <em>graphs[subject].nodes</em>.</li>
-          </ol>
-        </li>
-        <li>Return <em>array</em> as the result.</li>
-      </ol>
-    </section>
-
-<!-- FIXME -->
-    <section>
-      <h3>Data Round Tripping</h3>
-
-      <p>When <a href="#rdf-conversion">converting JSON-LD to RDF</a> JSON-native types such as
-        <em>numbers</em> and <em>booleans</em> are automatically coerced to <strong>xsd:integer</strong>,
-        <strong>xsd:double</strong>, or <strong>xsd:boolean</strong>. Implementers MUST ensure that the
-        result is in <tref>canonical lexical form</tref>. A
-        <tdef>canonical lexical form</tdef> is a set of literals from among the valid set of literals for
-        a datatype such that there is a one-to-one mapping between the <tref>canonical lexical form</tref> and a value
-        in the value space as defined in [[!XMLSCHEMA11-2]]. In other words, every value MUST be converted
-        to a deterministic <tref>string</tref> representation.</p>
-
-      <p>The canonical lexical form of an <em>integer</em>, i.e., a number without fractions
-        or a number coerced to <strong>xsd:integer</strong>, is a finite-length sequence of decimal
-        digits (<code>0-9</code>) with an optional leading minus sign; leading zeroes are prohibited.
-        To convert the number in JavaScript, implementers can use the following snippet of code:</p>
-
-      <pre class="example" data-transform="updateExample"
-           title="Sample integer serialization implementation in JavaScript">
-      <!--
-      (value).toFixed(0).toString()
-      -->
-      </pre>
-
-      <p>The canonical lexical form of a <em>double</em>, i.e., a number with fractions
-        or a number coerced to <strong>xsd:double</strong>, consists of a mantissa followed by the
-        character "E", followed by an exponent. The mantissa MUST be a decimal number. The exponent
-        MUST be an integer. Leading zeroes and a preceding plus sign (<code>+</code>) are prohibited
-        in the exponent. If the exponent is zero, it must be indicated by <code>E0</code>.
-        For the mantissa, the preceding optional plus sign is prohibited and the decimal point is
-        required. Leading and trailing zeroes are prohibited subject to the following: number
-        representations must be normalized such that there is a single digit which is non-zero to the
-        left of the decimal point and at least a single digit to the right of the decimal point unless
-        the value being represented is zero. The canonical representation for zero is <code>0.0E0</code>.
-        <strong>xsd:double</strong>'s value space is defined by the IEEE double-precision 64-bit
-        floating point type [[!IEEE-754-1985]]; in JSON-LD the mantissa is rounded to 15 digits after the
-        decimal point.</p>
-
-      <p>To convert the number in JavaScript, implementers can use the following snippet of code:</p>
-
-      <pre class="example" data-transform="updateExample"
-           title="Sample floating point number serialization implementation in JavaScript">
-      <!--
-      (value).toExponential(15).replace(/(\d)0*e\+?/,'$1E')
-      -->
-      </pre>
-
-      <p class="note">When data such as decimals need to be normalized, JSON-LD authors should
-        not use values that are going to undergo automatic conversion. This is due to the lossy nature
-        of <strong>xsd:double</strong> values. Authors should instead use the expanded object form to
-        set the canonical lexical form directly.</p>
-
-      <p>The canonical lexical form of the <em>boolean</em> values <code>true</code> and <code>false</code>
-        are the strings <strong>true</strong> and <strong>false</strong>.</p>
-
-      <p>When JSON-native <tref>number</tref>s, are type coerced, lossless data round-tripping can not
-        be guaranted as rounding errors might occur. Additionally, only literals typed as
-        <strong>xsd:integer</strong>, <strong>xsd:double</strong>, and  <strong>xsd:boolean</strong> are
-        automatically converted back to their JSON-native counterparts in when
-        <a href="#rdf-conversion">converting from RDF</a>.</p>
-
-      <p>Some JSON serializers, such as PHP's native implementation in some versions,
-        backslash-escape the forward slash character. For example, the value
-        <code>http://example.com/</code> would be serialized as <code>http:\/\/example.com\/</code>.
-        This is problematic as other JSON parsers might not understand those escaping characters.
-        There is no need to backslash-escape forward slashes in JSON-LD. To aid interoperability
-        between JSON-LD processors, a JSON-LD serializer MUST NOT backslash-escape forward slashes.</p>
-    </section>
-
-  <!-- end of RDF algorithms -->
-  </section>
-
-<!-- end of Algorithms -->
-</section>
-
-<section>
-  <h2>The Application Programming Interface</h2>
-
-  <p>This API provides a clean mechanism that enables developers to convert
-  JSON-LD data into a a variety of output formats that are easier to work
-  with in JavaScript. If a JavaScript JSON-LD API is provided, the entirety
-  of the following API MUST be implemented.</p>
-
-  <section>
-    <h3>JsonLdProcessor</h3>
-
-    <p>The JSON-LD Processor interface is the high-level programming structure
-      that developers use to access the JSON-LD transformation methods.</p>
-
-    <p>It is important to highlight that conformant <tref title="JSON-LD Processor">JSON-LD processors</tref>
-      MUST NOT modify the input parameters.</p>
-
-    <dl title="[Constructor] interface JsonLdProcessor" class="idl">
-
-      <dt>void expand()</dt>
-      <dd>
-        <a href="#expansion">Expands</a> the given <code>input</code> according to
-        the steps in the <a href="#expansion-algorithm">Expansion Algorithm</a>.
-
-        <dl class="parameters">
-          <dt>(object or object[] or DOMString) input</dt>
-          <dd>The JSON-LD object or array of JSON-LD objects to perform the expansion upon or an
-            <tref>IRI</tref> referencing the JSON-LD document to expand.</dd>
-          <dt>JsonLdCallback callback</dt>
-          <dd>A callback that is called when processing completed successfully
-            on the given <code>input</code>, or a fatal error prevented
-            processing from completing.</dd>
-          <dt>optional JsonLdOptions? options</dt>
-          <dd>A set of options to configure the used algorithms such. This allows, e.g.,
-            to set the input document's base <tref>IRI</tref>.</dd>
-        </dl>
-      </dd>
-
-      <dt>void compact()</dt>
-      <dd>
-        <a href="#compaction">Compacts</a> the given <code>input</code> using the
-        <code>context</code> according to the steps in the
-        <a href="#compaction-algorithm">Compaction Algorithm</a>.
-
-        <dl class="parameters">
-          <dt>(object or object[] or DOMString) input</dt>
-           <dd>The JSON-LD object or array of JSON-LD objects to perform the compaction upon or an
-            <tref>IRI</tref> referencing the JSON-LD document to compact.</dd>
-          <dt>(object or DOMString) context</dt>
-          <dd>The context to use when compacting the <code>input</code>; either in the
-            form of an <tref>JSON object</tref> or as <tref>IRI</tref>.</dd>
-          <dt>JsonLdCallback callback</dt>
-          <dd>A callback that is called when processing completed successfully
-            on the given <code>input</code>, or a fatal error prevented
-            processing from completing.</dd>
-          <dt>optional JsonLdOptions? options</dt>
-          <dd>A set of options to configure the used algorithms such. This allows, e.g.,
-            to set the input document's base <tref>IRI</tref>. This also includes
-            the <code>optimize</code> flag, which, if set, will allow processor-specific
-            optimization.</dd>
-        </dl>
-      </dd>
-
-      <dt>void flatten()</dt>
-      <dd>
-        <a href="#flattening">Flattens</a> the given <code>input</code> and
-        <a href="#compaction">compacts</a> it using the passed <code>context</code>
-          according to the steps in the <a href="#flattening-algorithm">Flattening Algorithm</a>.
-
-        <dl class="parameters">
-          <dt>(object or object[] or DOMString) input</dt>
-           <dd>The JSON-LD object or array of JSON-LD objects or an <tref>IRI</tref>
-            referencing the JSON-LD document to flatten.</dd>
-          <dt>(object or DOMString)? context</dt>
-          <dd>The context to use when compacting the flattened <code>input</code>; either
-            in the form of an <tref>JSON object</tref> or as <tref>IRI</tref>. If
-            <tref>null</tref> is passed, the result will not be compacted but keept
-            in expanded form.</dd>
-          <dt>JsonLdCallback callback</dt>
-          <dd>A callback that is called when processing completed successfully
-            on the given <code>input</code>, or a fatal error prevented
-            processing from completing.</dd>
-          <dt>optional JsonLdOptions? options</dt>
-          <dd>A set of options to configure the used algorithms such. This allows, e.g.,
-            to set the input document's base <tref>IRI</tref>.</dd>
-        </dl>
-      </dd>
-    </dl>
-
-  </section>
-
-  <section>
-    <h3>Callbacks</h3>
-
-    <p>JSON-LD processors utilize callbacks in order to return information in an
-      asynchronous manner to calling applications. This section details the
-      parameters sent to those callbacks.</p>
-
-    <section>
-      <h3>JsonLdCallback</h3>
-      <p>The <a>JsonLdCallback</a> is called when an API method of
-        <a>JsonLdProcessor</a> has been completed, either successfully or
-        by a fatal error.</p>
-
-      <dl title="callback JsonLdCallback = void" class="idl">
-        <dt>JsonLdError error</dt>
-        <dd>If the value is <tref>null</tref>, then no issue was detected
-          during processing. Otherwise, a processing issue was detected and
-          the details are contained within the <em>error</em> object.</dd>
-        <dt>object or object[] document</dt>
-        <dd>The processed JSON-LD document.</dd>
-      </dl>
-    </section>
-  </section>
-
-  <section>
-    <h3>Data Structures</h3>
-    <p>This section describes datatype definitions used within the JSON-LD API.</p>
-
-    <section>
-      <h3>JsonLdOptions</h3>
-      <p>The <a>JsonLdOptions</a> type is used to pass various options to the <a>JsonLdProcessor</a> methods.</p>
-      <dl title="dictionary JsonLdOptions" class="idl">
-        <dt>DOMString base</dt>
-        <dd>The Base IRI to use when expanding the document. This overrides the value of
-          <em>input</em> if it is a <a>IRI</a>. If not specified and <em>input</em> is not
-          an <a>IRI</a>, the base IRI defaults to the current document IRI if in a browser context,
-          or the empty string if there is no document context.
-          <p class="issue atrisk" title="Feature at risk">The default value of this option
-            implies that all IRIs that cannot be compacted otherwise are transformed to relative IRIs
-            during compaction. To avoid that data is being lost, developers thus have to store the
-            base IRI along with the compacted document. This might be problematic in practice and
-            thus the default behavior might be changed in future.</p>
-        </dd>
-        <dt>object or DOMString expandContext = null</dt>
-        <dd>A context that is used to initialize the active context when expanding a document.</dd>
-        <dt>boolean compactArrays = true</dt>
-        <dd>If set to <code>true</code>, the JSON-LD processor replaces arrays with just
-          one element with that element during compaction. If set to <code>false</code>,
-          all arrays will remain arrays even if they have just one element.
-        </dd>
-        <dt>boolean optimize = false</dt>
-        <dd>If set to <code>true</code>, the JSON-LD processor is allowed to
-          optimize the output of the <a href="#compaction-algorithm">Compaction Algorithm</a>
-          to produce even compacter representations. The algorithm for compaction
-          optimization is beyond the scope of this specification and thus
-          not defined. Consequently, different implementations MAY implement
-          different optimization algorithms.
-        </dd>
-        <dt>boolean useRdfType = false</dt>
-        <dd>If set to <code>true</code>, the JSON-LD processor will use the
-          expanded <code>rdf:type</code> IRI as the property instead of
-          <code>@type</code> when <a href="#convert-from-rdf-algorithm">converting from RDF</a>.
-        </dd>
-        <dt>boolean useNativeTypes = true</dt>
-        <dd>If set to <code>true</code>, the JSON-LD processor will try to convert
-          <tref title="typed value">typed values</tref> to JSON native types instead of using the
-          expanded object form when <a href="#convert-from-rdf-algorithm">converting from RDF</a>.
-          <code>xsd:boolean</code> values will be converted to <tref>true</tref> or <tref>false</tref>.
-          <code>xsd:integer</code> and <code>xsd:double</code> values will be
-          converted to
-          <tref title="number">JSON numbers</tref>.
-        </dd>
-      </dl>
-    </section>
-
-    <section>
-      <h3>JsonLdError</h3>
-
-      <p>The <a>JsonLdError</a> type is used to report processing errors
-        to a <a>JsonLdCallback</a>.</p>
-
-      <dl title="dictionary JsonLdError" class="idl">
-        <dt>JsonLdErrorCode code</dt>
-        <dd>a string representing the particular error type, as described in
-          the various algorithms in this document.</dd>
-        <dt>DOMString? message</dt>
-        <dd>an optional error message containing additional debugging information.
-          The specific contents of error messages are outside the scope of this
-          specification.</dd>
-      </dl>
-    </section>
-
-    <section>
-      <h3>JsonLdErrorCode</h3>
-      <p>The <a>JsonLdErrorCode</a> represents the collection of valid JSON-LD error
-        codes.</p>
-
-      <dl title="enum JsonLdErrorCode" class="idl">
-        <dt>invalid syntax</dt>
-        <dd>The document could not be parsed as JSON.</dd>
-        <dt>list of lists detected</dt>
-        <dd>A list of lists was detected. List of lists are not supported in
-          this version of JSON-LD due to the algorithmic complexity associated
-          with conversion to RDF.</dd>
-        <dt>invalid @index value</dt>
-        <dd>An <code>@index</code> member was encountered whose value was
-          not a <tref>string</tref>.</dd>
-        <dt>invalid @id value</dt>
-        <dd>An <code>@id</code> member was encountered whose value was not a
-          <tref>string</tref>.</dd>
-        <dt>invalid local context</dt>
-        <dd>In invalid <tref>local context</tref> was detected.</dd>
-        <dt>loading remote context failed</dt>
-        <dd>There was a problem encountered loading a remote context.</dd>
-        <dt>invalid remote context</dt>
-        <dd>No valid context document has been found for a referenced,
-         remote context.</dd>
-        <dt>recursive context inclusion</dt>
-        <dd>A cycle in remote context inclusions has been detected.</dd>
-        <dt>invalid default language</dt>
-        <dd>The value of the <tref>default language</tref> is not a <tref>string</tref>
-          or <tref>null</tref> and thus invalid.</dd>
-        <dt>invalid vocab mapping</dt>
-        <dd>An invalid <tref>vocabulary mapping</tref> has been detected, i.e.,
-          it is neither an <tref>absolute IRI</tref> nor <tref>null</tref>.</dd>
-        <dt>keyword redefinition</dt>
-        <dd>A <tref>keyword</tref> redefinition has been detected.</dd>
-        <dt>invalid term definition</dt>
-        <dd>An invalid <tref>term definition</tref> has been detected.</dd>
-        <dt>invalid term IRI mapping</dt>
-        <dd>A <tref>local context</tref> contains a <tref>term</tref> that
-          has not been mapped to an <tref>absolute IRI</tref>.</dd>
-        <dt>cyclic IRI mapping</dt>
-        <dd>A cycle in <tref title="IRI mapping">IRI mappings</tref> has been detected.</dd>
-        <dt>invalid type mapping</dt>
-        <dd>An <code>@type</code> member in a <tref>term definition</tref>
-          was encountered whose value could not be expanded to an
-          <tref>absolute IRI</tref>.</dd>
-        <dt>invalid language mapping</dt>
-        <dd>An <code>@language</code> member in a <tref>term definition</tref>
-          was encountered whose value was neither a <tref>string</tref> nor
-          <tref>null</tref> and thus invalid.</dd>
-        <dt>invalid container mapping</dt>
-        <dd>An <code>@container</code> member was encountered whose value was
-          not one of the following <tref title="string">strings</tref>:
-          <code>@list</code>, <code>@set</code>, or <code>@index</code>.</dd>
-        <dt>invalid property generator</dt>
-        <dd>A non-<tref>string</tref> value has been detected in a
-          <tref title="property generator">property generator's</tref>
-          <tref>IRI mapping</tref>.</dd>
-        <dt>invalid property generator IRI mapping</dt>
-        <dd>Expanding all values of a
-          <tref title="property generator">property generator's</tref>
-          <tref>IRI mapping</tref> to <tref>absolute IRI</tref> failed.</dd>
-        <dt>property generator in term definition</dt>
-        <dd>A <tref>property generator</tref> was used in the
-          <tref>IRI mapping</tref> of another <tref>term</tref> or
-          <tref>property generator</tref>.</dd>
-        <dt>invalid type value</dt>
-        <dd>An invalid value for an <code>@type</code> member has been detected,
-          i.e., the value was neither a <tref>string</tref> nor an <tref>array</tref>
-          of <tref title="string">strings</tref>.</dd>
-        <dt>invalid value object</dt>
-        <dd>A <tdef>value object</tdef> with disallowed members has been
-          detected.</dd>
-        <dt>invalid value object value</dt>
-        <dd>An invalid value for the <code>@value</code> member of a
-          <tref>value object</tref> has been detected, i.e., it is neither
-          a <tref>scalar</tref> nor <tref>null</tref>.</dd>
-        <dt>invalid language tagged string</dt>
-        <dd>A <tref>language-tagged string</tref> with disallowed members has
-          been detected.</dd>
-        <dt>invalid language value</dt>
-        <dd>A <tref>language-tagged string</tref> with an invalid language
-          value was detected.</dd>
-        <dt>invalid typed value</dt>
-        <dd>A <tref>typed value</tref> with disallowed members has been
-          detected.</dd>
-        <dt>invalid set or list object</dt>
-        <dd>A <tdef>set object</tref> or <tref>list object</tref> with
-          disallowed members has been detected.</dd>
-        <dt>language map invalid value</dt>
-        <dd>An invalid value in a <tdef>language map</tdef> was detected. It has
-          to be a <tref>string</tref> or an <tref>array</tref> of
-          <tref title="string">strings</tref>.</dd>
-        <dt>compaction to list of lists</dt>
-        <dd>The compacted document contains a list of lists as multiple
-          lists have been compacted to the same term.</dd>
-      </dl>
-    </section>
-
-  </section>
-</section>
-
-<section class="appendix">
-  <h1>Acknowledgements</h1>
-
-  <p>A large amount of thanks goes out to the JSON-LD Community Group
-    participants who worked through many of the technical issues on the mailing
-    list and the weekly telecons - of special mention are Niklas Lindström,
-    François Daoust, Lin Clark, and Zdenko 'Denny' Vrandečić.
-    The editors would like to thank Mark Birbeck, who provided a great deal of
-    the initial push behind the JSON-LD work via his work on RDFj.
-    The work of Dave Lehn and Mike Johnson are appreciated for reviewing,
-    and performing several implementations of the specification. Ian Davis is
-    thanked for his work on RDF/JSON. Thanks also to Nathan Rixham,
-    Bradley P. Allen, Kingsley Idehen, Glenn McDonald, Alexandre Passant,
-    Danny Ayers, Ted Thibodeau Jr., Olivier Grisel, Josh Mandel, Eric Prud'hommeaux,
-    David Wood, Guus Schreiber, Pat Hayes, Sandro Hawke, and Richard Cyganiak
-    or their input on the specification.</p>
-</section>
-
-</body>
-</html>