From ed7a05ecc93b3293023f5e4e04bab303c8b5b9dd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jesper=20=C3=96qvist?= <jesper.oqvist@cs.lth.se>
Date: Thu, 14 Jan 2016 19:13:45 +0100
Subject: [PATCH] Update reference manual and release notes

Updated documentation and release script for release 2.2.0.
---
 .gitignore              |    2 +
 LICENSE                 |    2 +-
 README-binary-dist.md   |    2 +-
 README.md               |    9 +-
 build.gradle            |   26 +-
 build.xml               |    6 +-
 doc/reference-manual.md | 2767 ++++++++++++++++++++-------------------
 doc/release-notes.md    |   40 +
 licenses/markdown-BSD   |   30 -
 release.sh              |   97 +-
 tools/Markdown.pl       | 1450 --------------------
 tools/pymarkdown.py     |   44 +
 12 files changed, 1566 insertions(+), 2909 deletions(-)
 delete mode 100644 licenses/markdown-BSD
 delete mode 100755 tools/Markdown.pl
 create mode 100644 tools/pymarkdown.py

diff --git a/.gitignore b/.gitignore
index 037831d4..2df469b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,4 +29,6 @@
 
 /notes
 
+# Local git repos.
 /website/
+/tests/
diff --git a/LICENSE b/LICENSE
index 757f7592..4af41102 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2005-2013, The JastAdd Team
+Copyright (c) 2005-2016, The JastAdd Team
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/README-binary-dist.md b/README-binary-dist.md
index e2326ec0..d08c20d3 100644
--- a/README-binary-dist.md
+++ b/README-binary-dist.md
@@ -10,7 +10,7 @@ For additional contributors, see the change logs.
 License
 -------
 
-Copyright (c) 2005-2013, The JastAdd Team. All rights reserved.
+Copyright (c) 2005-2016, The JastAdd Team. All rights reserved.
 
 JastAdd2 is covered by the modified BSD License. For the full license text
 see the LICENSE file.
diff --git a/README.md b/README.md
index c7f319fe..aad2c4e5 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ For additional contributors, see the change logs.
 License
 -------
 
-Copyright (c) 2005-2013, The JastAdd Team. All rights reserved.
+Copyright (c) 2005-2016, The JastAdd Team. All rights reserved.
 
 JastAdd2 is covered by the modified BSD License. For the full license text
 see the LICENSE file.
@@ -33,9 +33,10 @@ Ant. See licenses/javacc-BSD for the full license text.
 The context-free grammar used in JastAdd is based on an example from JavaCC.
 
 The README file for the binary distribution (README-binary-dist.md) is written
-in the language Markdown. This file is then converted to HTML during the
-release process with the Markdown tool. See licenses/markdown-BSD for the full
-license text.
+in the markup language Markdown. This file is converted to HTML using a Python
+script during the build script. The Python script requires the Python-Markdown
+package for Python. The Python-Markdown package can be installed using `pip
+install markdown`.
 
 Building
 --------
diff --git a/build.gradle b/build.gradle
index 88123b13..28e4f24d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,22 +6,20 @@ apply plugin: 'signing'
 defaultTasks 'jar'
 
 /** Helper function to run a command. Returns the command output if the command succeeded. */
-def tryCommand(List command, boolean failOnError = false) {
+def tryCommand(List command) {
 	def out = new StringBuilder()
 	def err = new StringBuilder()
 	def proc = command.execute()
 	proc.waitForProcessOutput(out, err)
 	if (proc.exitValue()) {
 		def msg = "failed to run '${command[0]}' command (args: ${command.tail()})\n$err$out"
-		if (failOnError) {
-			throw new GradleException(msg)
-		} else {
-			print 'Warning: '
-			println msg
-		}
+		print 'Warning: '
+		println msg
 		""
 	} else {
-		if (err) println "${err}"
+		if (err) {
+			println "${err}"
+		}
 		out.toString()
 	}
 }
@@ -92,13 +90,9 @@ task copyResources(type: Copy) {
 
 task release(dependsOn: [ 'sourceZip', 'binaryZip' ]) << {
 	if (!project.hasProperty('newVersion')) {
-		throw new GradleException('You must set -PnewVersion=<VERSION> when running the release task!')
+		throw new GradleException('You should add -PnewVersion=<VERSION> so the release task embeds the correct version string!')
 	}
 	assert version.equals(newVersion)
-	def versionFile = file('src/res/Version.properties')
-	tryCommand(['git', 'add', versionFile.path], true)
-	tryCommand(['git', 'commit', '-m', "Release $version"], true)
-	tryCommand(['git', 'tag', '-a', "$version", '-m', "Version $version"], true)
 }
 
 task sourceZip(type: Zip, dependsOn: 'documentation') {
@@ -137,7 +131,7 @@ task sourceZip(type: Zip, dependsOn: 'documentation') {
 
 task binaryDistReadme(type: Exec) {
 	description 'Generate the README for binary distributions'
-	commandLine 'perl', file('tools/Markdown.pl').path, 'README-binary-dist.md'
+	commandLine 'python', file('tools/pymarkdown.py').path, 'README-binary-dist.md'
 
 	inputs.file 'tools/Markdown.pl'
 	inputs.file 'README-binary-dist.md'
@@ -179,8 +173,8 @@ task documentation << {
 		flattenmapper()
 		globmapper(from: '*.md', to: "doc${File.separator}*.html")
 	}
-	ant.apply(executable: 'perl', dest: 'doc') {
-		arg(value: 'tools/Markdown.pl')
+	ant.apply(executable: 'python', dest: 'doc') {
+		arg(value: 'tools/pymarkdown.py')
 		srcfile()
 		fileset(dir: 'doc', includes: '*.md')
 		mapper(refid: 'mdmapper')
diff --git a/build.xml b/build.xml
index d1fc1420..edaf7cda 100644
--- a/build.xml
+++ b/build.xml
@@ -225,6 +225,8 @@ OPTIONS:
 		</zip>
 	</target>
 
+	<!-- This Ant build is no longer used for releases. The Gradle build should be used
+		 instead via the release script (release.sh). -->
 	<target name="release" if="version" depends="-timestamp"
 		description="tag and commit new JastAdd2 release">
 		<!-- NB: update release-notes.md before release! -->
@@ -272,8 +274,8 @@ OPTIONS:
 			<flattenmapper/>
 			<globmapper from="*.md" to="doc${file.separator}*.html"/>
 		</chainedmapper>
-		<apply executable="perl" dest="doc">
-			<arg value="${jastadd2.tools.dir}/Markdown.pl"/>
+		<apply executable="python" dest="doc">
+			<arg value="${jastadd2.tools.dir}/pymarkdown.py"/>
 			<srcfile/>
 			<fileset dir="doc" includes="*.md"/>
 			<mapper refid="mdmapper"/>
diff --git a/doc/reference-manual.md b/doc/reference-manual.md
index 4f237cc8..79534eb9 100644
--- a/doc/reference-manual.md
+++ b/doc/reference-manual.md
@@ -1,557 +1,658 @@
-# Reference manual for JastAdd2
+Reference Manual for JastAdd 2.2.0
+==================================
+
+[Click here](/releases/jastadd2/2.1.13/reference-manual.php) to read the
+JastAdd 2.1.13 manual.
 
 ## Index
 
+* [Syntax overview](#Cheatsheet)
 * [Abstract Syntax](#AbstractSyntax)
     * [Predefined AST classes](#Predefined)
-    * [Basic constructs](#Basic), [Naming](#Naming), [Tokens](#Tokens), [Class hierarchy](#Hierarchy), [Inheritance](#Inheriting), [NTAs](#ASTNTAs)
-    * [Lists &amp; Opts](#ListsAndOpts), [Creating](#creationAPI), [Using JJTree](#JJTree)
+    * [Basic constructs](#Basic), [Naming](#Naming), [Tokens](#Tokens),
+      [Inheritance](#Inheriting), [NTAs](#ASTNTAs)
+    * [Lists &amp; Opts](#ListsAndOpts), [Building](#treeBuilding), [Using JJTree](#JJTree)
 * [Aspects](#Aspects)
-    * [Aspect files](#jadd) (defined in .jadd and .jrag files)
-    * [Supported AOP features](#AOPfeatures), [Differences from AspectJ](#AspectJ), [Idiom for aspect variables](#IdiomPrivate)
-      
+    * [Aspect files](#jadd) (`.jadd` and `.jrag` files)
+    * [Supported AOP features](#AOPfeatures), [Differences from AspectJ](#AspectJ),
+      [Idiom for aspect variables](#IdiomPrivate)
 * [Attributes](#Attributes)
-    * [Synthesized](#Synthesized), [inherited](#Inherited), [method syntax](#Method), [lazy/caching](#Lazy), [refine](#RefineAttr)
-    * [Parameterized](#Parameterized), [broadcasting](#Broadcasting), [rewrites](#Rewrites), [circular](#Circular), [NTAs](#Nonterminal), [collections](#Collection)
+    * [Synthesized](#Synthesized), [inherited](#Inherited), [method syntax](#Method),
+      [lazy/caching](#Lazy), [refine](#RefineAttr)
+    * [Parameterized](#Parameterized), [broadcasting](#Broadcasting),
+      [circular](#Circular), [NTAs](#Nonterminal), [collections](#Collection)
+* [Rewrites](#Rewrites)
 * [Command line syntax](#Command)
 
-# <a id="AbstractSyntax"></a>Abstract syntax
-
-Abstract grammars are specified in .ast files and correspond to a
-Java class hierarchy.
-
-### <a id="Predefined"></a>Predefined Java classes in the hierarchy:
-
-<TABLE BORDER=1>
-<TR>
-<TD>
-<B>Predefined AST class</B>
-</TD>
-<TD>
-<B>Description</B>
-</TD>
-<TD>
-**Java API for <a id="untyped"></a>untyped traversal**
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE><a id="ASTNode"></a>ASTNode</PRE>
-</TD>
-<TD>
-The topmost node in the hierarchy.
-
-Supports traversal at the relatively "untyped" level of ASTNode.<br />
-Children are numbered from 0 to getNumChild()-1.<br />
-</TD>
-<TD>
-<PRE>class ASTNode extends Object implements Iterable {
+## <a id="Cheatsheet"></a>Quick syntax overview
+
+### AST Specification Syntax
+
+Syntax for AST class declarations in `.ast` files:
+
+Syntax                  | Meaning
+------------------------|--------
+`A;`                    | AST class
+`B: S;`                 | AST subclass (B is a subclass of S)
+`abstract A;`           | AST class, abstract
+`B ::= Y;`              | Child component `Y`.
+`B ::= MyY:Y;`          | Child component `MyY` of type `Y`.
+`X ::= C*;`             | List component `C`, containing `C` nodes.
+`X ::= MyC:C*;`         | List component `MyC`, containing `C` nodes.
+`Y ::= [D];`            | Optional component `D`.
+`Y ::= [MyD:D];`        | Optional component `MyD` of type `D`.
+`Z ::= <E>;`            | Token component `E` of type `String`.
+`Z ::= <F:Integer>;`    | Token component `F` of type `Integer`.
+
+### Aspect declarations
+
+Syntax for attribute declarations in `.jrag` and `.jadd` files:
+
+Declaration                         | Meaning
+------------------------------------|--------
+`aspect N { decl* }`                | Aspect declaration
+`syn T A.c();`                      | Synthesized attribute
+`syn T A.c() = exp;`                | Synthesized attribute, default equation
+`syn T A.c() { stmt* }`             | Synthesized attribute, method body
+`syn lazy T A.c() { stmt* }`        | Synthesized attribute, cached
+`syn circular X A.c() [bot] = exp;` | Synthesized attribute, circular
+`syn nta X A.c() = exp;`            | Nonterminal attribute (NTA)
+`eq B.c() = exp;`                   | Synthesized equation
+`eq B.c() { stmt* }`                | Synthesized equation, method body
+`inh X A.i();`                      | Inherited attribute
+`inh lazy X A.i();`                 | Inherited attribute, cached
+`eq B.getChild().i() = exp;`        | Inherited equation, broadcast
+`eq B.getChild().i() { stmt* }`     | Inherited equation, broadcast, method body
+`eq B.getA().i() = exp;`            | Inherited equation for the `A` child of `B` nodes.
+`eq B.getDecl(int index).i() = exp;` | Inherited equation for the `Decl` list component of `B` nodes.
+`coll LinkedList<B> A.c() [new LinkedList<B>()] root A;` | Collection attribute
+`coll LinkedList<B> A.c();`         | Collection attribute, short form
+`B contributes exp when cond to A.c() for targetexp;` | Collection contribution
+`B contributes exp when cond to A.c();` | Collection root contribution
+`refine FileName thing = exp;`      | Refine an attribute equation (synthesized or inherited)
+`refine FileName thing { stmt* }`   | Refine an attribute or intertype method
+`rewrite A { when condition to B { stmt* } }` | AST node rewrite
+`uncache A.x();`                    | Never cache `A.x()`
+`cache A.y(int a);`                 | Please cache `A.y(int)`
+`public void A.m(int x) { stmt* }`  | Intertype declared method
+`public String A.f = exp;`          | Intertype declared field
+
+
+## <a id="AbstractSyntax"></a>Abstract syntax
+
+Abstract grammars are specified in `.ast` files and are used to generate a Java
+class hierarchy. The classes in an abstract grammar are referred to as AST
+classes. The AST classes are used by the parser to build Abstract Syntax Trees
+(ASTs).
+
+### <a id="Predefined"></a>Predefined AST classes
+
+The AST classes include user declared classes in the abstract grammar, as well
+as a few predefined AST classes that are implicitly generated. The predefined
+AST classes are described in the table below.
+
+<table border=1>
+<tr>
+    <th>Predefined AST class</th>
+    <th>Purpose</th>
+    <th>Accessing children</th>
+</tr>
+<tr>
+    <td>
+        <a id="ASTNode"></a><pre>ASTNode</pre>
+    </td>
+    <td>
+        This is the base class which all other AST classes extend.
+        Children are numbered from <code>0</code> to <code>getNumChild() - 1</code>.
+    </td>
+    <td>
+        Children are accessed using the generated methods <code>getNumChild()</code> and <code>getChild(int)</code>.
+
+        <p><pre>public ASTNode&lt;T extends ASTNode&gt; implements Cloneable {
   int getNumChild();
-  ASTNode getChild(int);
+  ASTNode getChild(int index);
   ASTNode getParent();
-}</PRE>
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE><a id="List"></a>List</PRE>
-</TD>
-<TD>
-Used to implement lists.
-</TD>
-<TD>
-<PRE>class List extends ASTNode { }</PRE>
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE><a id="Opt"></a>Opt</PRE>
-</TD>
-<TD>
-Used to implement optionals.
-
-Has 0 or 1 child.
-</TD>
-<TD>
-<PRE>class Opt extends ASTNode { }</PRE>
-</TD>
-</TR>
-</TABLE>
-
-*Note!* The traversal at this &quot;untyped&quot; level includes List and Opt nodes. See also &quot;[About Lists and Opts](#ListsAndOpts)&quot;.
-
-<!--- TODO:
-Example traversal of the complete AST:
-
-<TABLE BORDER = 1>
-<TR>
-<TD>
-**Java 1.4 style traversal**
-</TD>
-<TD>
-**Java 5 style traversal**
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE>for (int k=0;k&lt;getNumChild()) {
-  ...getChild(k)...
-}</PRE>
-</TD>
-<TD>
-<PRE>for (ASTNode n : this) {
-  // access each child n here
-}</PRE>
-</TD>
-</TR>
-</TABLE>
--->
-
-### <a id="constructs"></a>Abstract syntax constructs in the .ast file
-
-<!--- TODO: Show List and Opt interfaces individually, before the mixed example. And add getBOpt and getCList ops. -->
-
-<TABLE BORDER=1>
-<TR>
-<TD>
-**<a id="Basic"></a>Basic constructs**
-</TD>
-<TD></TD>
-<TD>
-<B><a id="typedTraversalAPI">Java API for typed
-traversal</a></B>
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE>abstract A;</PRE>
-</TD>
-<TD>
-<a id="abstract"></a>A is an abstract class.<BR>
-A corresponds to a nonterminal
-</TD>
-<TD>
-<PRE>abstract class A extends ASTNode { }</PRE>
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE>B: A ::= ...;</PRE>
-</TD>
-<TD>
-<a id="subclass"></a>B is a concrete subclass of A<BR>
-B corresponds to a production of A
-</TD>
-<TD>
-<PRE>class B extends A { }</PRE>
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE>C: A ::= A B C;</PRE>
-</TD>
-<TD>
-C has three <a id="children"></a>children of types A, B, and C.
-
-The API supports typed traversal of the children.
-</TD>
-<TD>
-<PRE>class C extends A {
+  Iterable&lt;T&gt; astChildren();
+  Iterator&lt;T&gt; astChildIterator();
+}</pre>
+    </td>
+</tr>
+<tr>
+    <td>
+        <pre><a id="List"></a>List</pre>
+    </td>
+    <td>
+        Contains elements of list components in AST classes.
+    </td>
+    <td>
+        <code>getNumChild()</code> and <code>getChild(int)</code> are inherited
+        from <code>ASTNode</code>. The enhanced <code>for</code> statement can
+        be used on the list since <code>List</code> implements
+        <code>Iterable&lt;ASTNode&gt;</code>.
+
+        <p><pre>public List&lt;T extends ASTNode&gt; extends ASTNode&lt;T&gt; implements Iterable&lt;T&gt; {
+}</pre>
+    </td>
+</tr>
+<tr>
+    <td>
+        <a id="Opt"></a><pre>Opt</pre>
+    </td>
+    <td>
+        Used to implement optional components in AST classes. Has 0 or 1 child.
+    </td>
+    <td>
+        <code>getNumChild()</code> and <code>getChild(int)</code> inherited
+        from <code>ASTNode</code> can be used when accessing <code>Opt</code> nodes directly.
+
+        <p><pre>public Opt&lt;T extends ASTNode&gt; extends ASTNode&lt;T&gt; {
+}</pre>
+    </td>
+</tr>
+</table>
+
+See also &quot;[About Lists and Opts](#ListsAndOpts)&quot;.
+
+### Abstract syntax constructs
+
+The table below documents the syntax used to declare user declared AST classes
+in `.ast` files.
+
+#### <a id="Basic"></a>Basic constructs
+
+<table border=1>
+<tr>
+    <th>Construct</th>
+    <th>Meaning</th>
+    <th><a id="typedTraversalAPI">Generated API</a></th>
+</tr>
+<tr>
+    <td>
+        <pre>abstract A;</pre>
+    </td>
+    <td>
+        <a id="abstract"></a><code>A</code> is an abstract AST class.
+        <code>A</code> corresponds to a nonterminal in the context free grammar.
+    </td>
+    <td>
+        <pre>abstract class A extends ASTNode { }</pre>
+    </td>
+</tr>
+<tr>
+    <td>
+        <pre>B: A ::= ...;</pre>
+    </td>
+    <td>
+        <a id="subclass"></a><code>B</code> is a concrete subclass of <code>A</code>.
+        <code>B</code> corresponds to a production of <code>A</code> in the context-free grammar.
+    </td>
+    <td>
+        <pre>class B extends A { }</pre>
+    </td>
+</tr>
+<tr>
+    <td>
+        <pre>C: A ::= A B C;</pre>
+    </td>
+    <td>
+        C has three <a id="children"></a>children of types A, B, and C.
+
+        The API supports typed traversal of the children.
+    </td>
+    <td>
+        <pre>class C extends A {
   A getA();
   B getB();
-  C getC();</PRE>
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE>D: A;</PRE>
-</TD>
-<TD>
-D has no children.
-
-D corresponds to an <a id="empty"></a>empty production of A
-</TD>
-<TD>
-<PRE>class D extends A { }</PRE>
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE>E: A ::= A &#91;B&#93; C* &lt;D&gt;;</PRE>
-</TD>
-<TD>
-E has a child of type A, an optional child of<a id="optional"></a> type B, a
-list of zero or more C children, and a token of type D.
-</TD>
-<TD>
-<PRE>class E extends A {
+  C getC();
+}</pre>
+    </td>
+</tr>
+<tr>
+    <td>
+        <pre>D: A;</pre>
+    </td>
+    <td>
+        <code>D</code> has no children.
+
+        <code>D</code> corresponds to an <a id="empty"></a>empty production of <code>A</code>.
+    </td>
+    <td>
+        <pre>class D extends A { }</pre>
+    </td>
+</tr>
+<tr>
+    <td>
+        <pre>E1 ::= A;</pre>
+    </td>
+    <td>
+        <code>E1</code> has a child of type <code>A</code>.
+    </td>
+    <td>
+        <pre>class E1 {
   A getA();
+}</pre>
+    </td>
+</tr>
+<tr>
+    <td>
+        <pre>E2 ::= &#91;B&#93;;</pre>
+    </td>
+    <td>
+        <a id="optional"></a><code>E2</code> has an optional component of type <code>B</code>.
+    </td>
+    <td>
+        <pre>class E2 {
   boolean hasB();
   B getB();
+}</pre>
+    </td>
+</tr>
+<tr>
+    <td>
+        <pre>E3 ::= C&#42;;</pre>
+    </td>
+    <td>
+        <code>E3</code> has a list component of zero or more <code>C</code> nodes.
+    </td>
+    <td>
+        <pre>class E3 {
   int getNumC();
   C getC(int);
+  List&lt;C&gt; getCList();
+}</pre>
+    </td>
+</tr>
+<tr>
+    <td>
+        <pre>E4 ::= &lt;D&gt;;</pre>
+    </td>
+    <td>
+        <code>E4</code> has a token component of type <code>D</code>.
+
+        <p>The set method is intended to be used only by the parser to set the token
+        value. The token value should not be changed after tree construction, and
+        the set method should not be used by an attribute equation as it has side
+        effects.
+    </td>
+    <td>
+        <pre>class E4 {
   String getD();
-  setD(String);
-}</PRE>
-</TD>
-</TR>
-</TABLE>
-
-<TABLE BORDER=1>
-<TR>
-<TD>
-<B><a id="Naming"></a>Naming children</B>
-</TD>
-<TD></TD>
-<TD></TD>
-</TR>
-<TR>
-<TD>
-<PRE>F: A ::= Foo:A Bar:B;</PRE>
-</TD>
-<TD>
-It is possible to name children.
-</TD>
-<TD>
-<PRE>class F extends A {
+  void setD(String);
+}</pre>
+    </td>
+</tr>
+<tr>
+    <td>
+        <a id="ASTNTAs"></a><pre>A ::= /D/;</pre>
+    </td>
+    <td>
+        <code>A</code> has a nonterminal attribute (NTA) component <code>D</code>.
+        The <code>D</code> component is not created by the parser, it is instead
+        computed on demand, using an attribute equation.
+        See <a href="#Nonterminal">specifying NTAs</a> for more info.
+    </td>
+    <td>
+        <pre>class A {
+  D getD();
+}</pre>
+    </td>
+</tr>
+</table>
+
+#### <a id="Naming"></a>Naming children
+
+<table border=1>
+<tr>
+    <th>Construct</th>
+    <th>Meaning</th>
+    <th>Generated API</th>
+</tr>
+<tr>
+    <td>
+        <pre>F ::= Foo:A Bar:B;</pre>
+    </td>
+    <td>
+        It is possible to give components custom names.
+
+        <p><em>Note!</em> If there is more than one child of the same type, they <em>must</em> be named.
+    </td>
+    <td>
+        <pre>class F {
   A getFoo();
   B getBar();
-}</PRE>
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE>G: A ::=
-  A
-  First:B
-  C 
-  Second:B
-  D;</PRE>
-</TD>
-<TD>
-*Note!* If there is more than one child of the same type, they *must* be named.
-Here there are two children of type B. They are distinguished with the names
-"First" and "Second".
-</TD>
-<TD>
-<PRE>class G extends A {
-  A getA();
-  B getFirst();
-  C getC();
-  B getSecond();
-  D getD();
-}</PRE>
-</TD>
-</TR>
-</TABLE>
-
-<!--- TODO Add discussion of intrinsic attributes and inter-ast refs-->
-<TABLE BORDER=1>
-<TR>
-<TD>
-<B><a id="Tokens"></a>Typed tokens</B>
-</TD>
-<TD>
-Tokens are implictly typed by String. But you can also give a token an explicit
-type.
-</TD>
-<TD></TD>
-</TR>
-<TR>
-<TD>
-<PRE>A ::= &lt;T&gt;</PRE>
-</TD>
-<TD>
-Here, T is a token of the Java type String.<BR> (The set method is intended to
-be used only by the parser, to set the token value. This is useful when you are
-using JavaCC with JJTree for parsing, since JJTree can construct the AST nodes
-for you, but you will need to set the token values explicitly using the set
-method.)
-</TD>
-<TD>
-<PRE>class A extends ASTNode {
+}</pre>
+    </td>
+</tr>
+<tr>
+    <td>
+        <pre>G ::= Thing:B*;</pre>
+    </td>
+    <td>
+        List components can be named.
+    </td>
+    <td>
+        <pre>class G {
+  int getNumThing();
+  B getThing(int);
+  List&lt;B&gt; getThingList();
+}</pre>
+    </td>
+</tr>
+<tr>
+    <td>
+        <pre>H ::= [Foo:X];</pre>
+    </td>
+    <td>
+        Optional components can be named.
+    </td>
+    <td>
+        <pre>class H {
+  boolean hasFoo();
+  X getFoo();
+}</pre>
+    </td>
+</tr>
+</table>
+
+#### <a id="Tokens"></a>Typed tokens
+
+Tokens are implictly <code>String</code> typed. But you can also give a token
+an explicit type:
+
+<table border=1>
+<tr>
+    <th>Construct</th>
+    <th>Meaning</th>
+    <th>Generated API</th>
+</tr>
+<tr>
+    <td>
+        <pre>A ::= &lt;T&gt;;</pre>
+    </td>
+    <td>
+        Here, <code>T</code> is a token of the type <code>String</code>.
+    </td>
+    <td>
+        <pre>class A {
   String getT();
-  setT(String);
-}</PRE>
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE>A ::= &lt;T:String&gt;</PRE>
-</TD>
-<TD>
-This is equivalent to the example above.
-</TD>
-<TD>
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE>A ::= &lt;T:int&gt;</PRE>
-</TD>
-<TD>
-Here, T is a token of the Java primitive type int.
-</TD>
-<TD>
-<PRE>class A extends ASTNode {
+  void setT(String);
+}</pre>
+    </td>
+</tr>
+<tr>
+    <td>
+        <pre>A ::= &lt;T:String&gt;;</pre>
+    </td>
+    <td>
+        This is equivalent to the example above.
+    </td>
+    <td></td>
+</tr>
+<tr>
+    <td>
+        <pre>A ::= &lt;T:int&gt;;</pre>
+    </td>
+    <td>
+        Here, T is a token of the Java primitive type int.
+    </td>
+    <td>
+        <pre>class A {
   int getT();
-  setT(int);
-}</PRE>
-</TD>
-</TR>
-</TABLE>
-
-<TABLE BORDER=1>
-<TR>
-<TD>
-<B>Class <a id="Hierarchy"></a>hierarchy</B>
-</TD>
-<TD>
-The class hierarchy can contain any number of levels.
-</TD>
-<TD></TD>
-</TR>
-<TR>
-<TD>
-For example:
-</TD>
-<TD>
-<PRE>abstract A;
-abstract B: A;
-C: B;
-D: C;</PRE>
-</TD>
-<TD>
-<PRE>abstract class A extends ASTNode { }
-abstract class B extends A { }
-class C extends B { }
-class D extends C { }</PRE>
-</TD>
-</TR>
-</TABLE>
-
-<TABLE BORDER=1>
-<TR>
-<TD>
-<B><a id="Inheriting"></a>Inheriting children</B>
-</TD>
-<TD>
-
-</TD>
-<TD>
-
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE>abstract A ::= B C;
+  void setT(int);
+}</pre>
+    </td>
+</tr>
+<tr>
+    <td>
+        <pre>A ::= &lt;Ref:B&gt;;</pre>
+    </td>
+    <td>
+        Here, Ref is an intra-AST reference to a node of type B. This is a
+        static reference to another node in the AST. The reference is not
+        computed, rather it is set once during tree building.
+    </td>
+    <td>
+        <pre>class A {
+  B getRef();
+  void setRef(B);
+}</pre>
+    </td>
+</tr>
+</table>
+
+#### <a id="Inheriting"></a>Inheriting children
+
+AST class children are inherited by subtypes.
+
+<table border=1>
+<tr>
+    <th>Construct</th>
+    <th>Meaning</th>
+    <th>Generated API</th>
+</tr>
+<tr>
+    <td>
+<pre>abstract A ::= B C;
 D: A;
-E: A;</PRE>
-</TD>
-<TD>
-Children are inherited by subclasses
-</TD>
-<TD>
-<PRE>abstract class A extends ASTNode {
+E: A;</pre>
+    </td>
+    <td>
+        <code>D</code> and <code>E</code> are subclasses of <code>A</code> and
+        inherit the children of <code>A</code>.
+    </td>
+    <td>
+        <pre>abstract class A extends ASTNode {
   B getB();
   C getC();
 }
 class D extends A { }
-class E extends A { }</PRE>
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE>abstract A ::= B C;
-D: A ::= F;</PRE>
-</TD>
-<TD>
-Subclasses can add children to those specified by the
-superclass.
-</TD>
-<TD>
-<PRE>abstract class A extends ASTNode {
+class E extends A { }</pre>
+    </td>
+</tr>
+<tr>
+    <td>
+        <pre>A ::= B C;
+D: A ::= F;</pre>
+    </td>
+    <td>
+        A subclass declaration can add children, but not remove children from the superclass.
+        Here, <code>D</code> has the children <code>B</code>, <code>C</code>,
+        <code>F</code>.
+    </td>
+    <td>
+        <pre>class A extends ASTNode {
   B getB();
   C getC();
 }
 class D extends A {
   F getF();
-}</PRE>
-</TD>
-</TR>
-<TR>
-<TD>
-... example to be added ...
-</TD>
-<TD>
-Subclasses can repeat/override children ... (to be explained)
-</TD>
-<TD> </TD>
-</TR>
-</TABLE>
-
-<TABLE BORDER=1>
-<TR>
-<TD>
-<B>Nonterminal attributes (<a id="ASTNTAs"></a>NTAs)</B>
-</TD>
-<TD> </TD>
-<TD> </TD>
-</TR>
-<TR>
-<TD>
-<PRE>A ::= B C /D/</PRE>
-</TD>
-<TD>
-A has three children: a B child, a C child, and a D child. The D child is an
-NTA (nonterminal attribute): It is not created by the parser, but must be
-defined by an equation. See [specifying NTAs](#Nonterminal).
-</TD>
-<TD>
-<PRE>class A {
+}</pre>
+    </td>
+</tr>
+<tr>
+    <td>
+        <pre>A ::= B C;
+D: A ::= C F B;</pre>
+    </td>
+    <td>
+        Subclasses can repeat superclass children to change the child order.
+        Here, the order of children in <code>D</code> is: <code>C</code>,
+        <code>B</code>, <code>F</code>. This affects the generated constructors
+        of <code>D</code> and the children accessed by <code>getChild(int)</code>.
+        See below for <a href="#treeBuilding">more info about generated constructors</a>.
+    </td>
+    <td>
+        Same as above.
+    </td>
+</tr>
+</table>
+
+### <a id="ListsAndOpts"></a>List and Opt components
+
+JastAdd generates accessor methods to access optional and list components. The
+generated methods can be used instead of accessing the `Opt` and `List`
+container directly.  The generated accessor methods are listed in the table
+below.  The `Opt` and `List` nodes can be accessed by `getXOpt()` and
+`getXList()`, if needed.
+
+<table border=1>
+<tr>
+    <th>Construct</th>
+    <th>Generated API</th>
+    <th>Example use</th>
+</tr>
+<tr>
+    <td>
+        <pre>A ::= &#91;B&#93;;</pre>
+    </td>
+    <td>
+        <pre>class A {
+  boolean hasB();
   B getB();
-  C getC();
-  D getD();
-}</PRE>
-</TD>
-</TR>
-</TABLE>
-
-### About Lists and Opts<a id="ListsAndOpts"></a>
-
-The AST representation has additional Opt and List nodes in order
-to implement children that are optionals or lists. By using hasX(), getX(), and getX(int), you need not access the Opt and List nodes to traverse the AST. But the Opt and List nodes can be accessed by getXOpt() and getXList(), making it convenient to iterate over the optional/list children. See examples below. Note also that if you use the untyped traversal methods
-(getChild(), etc.), you will stop also on the Opt and List nodes.
-
-<TABLE BORDER=1>
-<TR>
-<TD>
-<B>.ast construct</B>
-</TD>
-<TD>
-<B>Java API</B>
-</TD>
-<TD>
-<B>Example use</B>
-</TD>
-</TR>
-<!--- TODO: Check Opt in Test case before showing example here.
-<TR>
-<TD>
-<PRE>A ::= &#91;B&#93;</PRE>
-</TD>
-<TD>
-<PRE>class A extends ASTNode {
+  Opt&lt;B&gt; getBOpt();
+}</pre>
+    </td>
+    <td>
+        <pre>A a = ...;
+if (a.hasB()) {
+  B b = a.getB();
   ...
-  Opt getBOpt();
-}</PRE>
-</TD>
-<TD>
-<PRE>A a = ...;
-for (B b : getBOpt()) {
-  // Access b (the optional child).
 }
-</PRE>
-</TD>
-</TR>
--->
-<TR>
-<TD>
-<PRE>C ::= D*</PRE>
-</TD>
-<TD>
-<PRE>class C extends ASTNode {
-  ...
-    List getDList();
-}</PRE>
-</TD>
-<TD>
-<PRE>C c = ...;
-for (D d : getDList()) {
-  // Access each d (list children).
-}</PRE>
-</TD>
-</TR>
-</TABLE>
-
-### <a id="creationAPI"></a>Creating AST nodes
-
-Use the following constructor API to create the AST. Typically you create the
+</pre>
+    </td>
+</tr>
+<tr>
+    <td>
+        <pre>C ::= D&#42;;</pre>
+    </td>
+    <td>
+        <pre>class C {
+  int getNumD();
+  D getD(int index);
+  List&lt;D&gt; getDList();
+}</pre>
+    </td>
+    <td>
+        <pre>C c = ...;
+for (D d : c.getDList()) {
+    ...
+}</pre>
+</td>
+</tr>
+</table>
+
+### <a id="treeBuilding"></a>Building AST nodes
+
+Use the following constructor API to build the AST. Typically you build the
 AST in the action routines of your parser.  But you can of course also create
-an AST by coding it explicitly, e.g., in a test case. If you use JavaCC+JJTree,
-see below.
-
-<TABLE BORDER=1>
-<TR>
-<TD>
-<B>AST class</B>
-</TD>
-<TD>
-<B>Java API for creating AST nodes</B>
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE>A ::= B C &#91;D&#93; E* &lt;G&gt;</PRE>
-</TD>
-<TD>
-<PRE>class A extends ASTNode {
-  A(B, C, Opt, List, String); //Arguments must not be null
-}</PRE>
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE>List</PRE>
-</TD>
-<TD>
-<PRE>class List extends ASTNode {
-  List();
-  add(ASTNode); // Returns the same List object
-}</PRE>
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE>Opt</PRE>
-</TD>
-<TD>
-<PRE>class Opt extends ASTNode {
-  Opt();
-  Opt(ASTNode); // The argument may be null
-}</PRE>
-</TD>
-</TR>
-</TABLE>
-
-### Building ASTs using <a id="JJTree"></a>JJTree
-
-If you use JJTree, the creational code is generated. You use the "#X" notation
-in the JJTree specification to guide the node creation.
+an AST by coding it explicitly, e.g., in a test case. If you use JavaCC and
+JJTree, [see below](#JJTree).
+
+<table border=1>
+<tr>
+    <th>AST declaration</th>
+    <th>Generated constructor</th>
+    <th>Comment</th>
+</tr>
+<tr>
+    <td>
+        <pre>A ::= B C &#91;D&#93; E&#42; &lt;G&gt;;</pre>
+    </td>
+    <td>
+        <pre>A(B, C, Opt&lt;D&gt;, List&lt;E&gt;, String)</pre>
+    </td>
+    <td>The constructor parameter order is same as the child order.</td>
+</tr>
+<tr>
+    <td>
+        <pre>A ::= A /B/ C;</pre>
+    </td>
+    <td>
+        <pre>A(A, C)</pre>
+    </td>
+    <td>Nonterminal attributes are not initialized via the constructor.</td>
+</tr>
+</table>
+
+The predefined AST classes `Opt` and `List` have some default constructors to help
+with building trees:
+
+<table border=1>
+<tr>
+    <th>Predefined AST class</th>
+    <th>Generated constructors</th>
+</tr>
+<tr>
+    <td>
+        <pre>List&lt;T&gt;</pre>
+    </td>
+    <td>
+        <ul>
+            <li><code>List()</code> create an empty list.
+            <li><code>List(T...)</code> this constructor accepts a variable
+            number of AST nodes as arguments, and adds the arguments as
+            children of the constructed list.
+            <li><code>List(Collection&lt;T&gt;)</code> adds all AST nodes in a
+            collection to the list.
+        </ul>
+    </td>
+    <td>The constructor parameter order is same as the child order.</td>
+</tr>
+<tr>
+    <td>
+        <pre>Opt&lt;T&gt;</pre>
+    </td>
+    <td>
+        <p><ul>
+            <li><code>Opt()</code> creates an empty optional.
+            <li><code>Opt(T)</code> creates an optional containing the given AST node.
+        </ul>
+    </td>
+    <td>Nonterminal attributes are not initialized via the constructor.</td>
+</tr>
+</table>
+
+The `List` node constructor that takes no arguments can be used together with
+the `add` method which returns the list itself, so you can chain multiple list
+additions after creating a new node, like this:
+
+    A1 a = ...;
+    A2 a = ...;
+    List<A> list = new List<A>().add(a1).add(a2);
+
+Below is an example of building an AST based on the grammar
+
+    A ::= B*;
+    B ::= C;
+    C ::= <ID>;
+
+An example AST for this grammar can be built like this:
+
+    A = new A(new List<B>(new B(new C("foo")), new B(new C("bar"))));
+
+
+### <a id="JJTree"></a>Building ASTs using JJTree
+
+If you use JJTree, the tree building code is generated by JJTree. You can use
+the "#X" notation in the JJTree specification to guide the node creation.
 
 JJTree maintains a stack of created nodes. The "#X" notation means:
 
-* create a new object of type X
-   
-* pop the nodes that were created during this parse method and
-insert them as children to the new X node
-   
-* then push the new X node
+1. Create a new object of type `X`.
+2. Pop the nodes that were created during this parse method and insert them as
+   children to the new `X` node.
+3. Push the new `X` node.
 
-You need to explicitly create List and Opt nodes. When the parsing structure
+You need to explicitly create `List` and `Opt` nodes. When the parsing structure
 does not fit the abstract tree, e.g. when parsing expressions, you need to use
-some additional tricks. You also need to set token values explicitly. An
-example is available in [assignment
-3](http://cs.lth.se/kurs/eda180_compiler_construction/assignments/3_tree_building/)
-in the Lund University compiler course. Download the example zip file and look
-at the file CalcTree/specification/Parser.jjt .
+some additional tricks. You also need to set token values explicitly.
 
 ### <a id="Aspects"></a>Aspects
 
-JastAdd aspects support <I>intertype declarations</I> for AST classes. An
+JastAdd aspects support *intertype declarations* for AST classes. An
 intertype declaration is a declaration that appears in an aspect file, but that
 actually belongs to an AST class. The JastAdd system reads the aspect files and
-weaves the intertype declarations into the appropriate AST classes.
+weaves intertype declarations into the target AST classes.
 
 The kinds of intertype declarations that can occur in an aspect include
 ordinary Java declarations like methods and fields, and attribute grammar
@@ -570,31 +671,36 @@ An aspect file can contain import declarations and one or more aspects, e.g.:
       private boolean Stmt.count = 0;
     }
 
-The aspect syntax is similar to AspectJ. But in contrast to AspectJ, the
+The aspect syntax is similar to that of AspectJ, but in contrast JastAdd
 aspects are not real language constructs. The JastAdd system simply reads the
 aspect files and inserts the intertype declarations into the appropriate AST
-classes. For example, the method "m" and its implementations are inserted into
-classes Stmt, WhileStmt, and IfStmt. And the declaration of the field "count"
-is inserted into the class Stmt. Import declarations are inserted into all AST
-classes for which there are intertype declarations in the aspect. So, the
-import of java.lang.util.* is inserted into Stmt, WhileStmt, and IfStmt. For a
-more detailed discussion on the similarities and differences between JastAdd
-aspects and AspectJ, see [below](#AspectJ).
-
-The aspect names, e.g., A and B above, do not show up in the woven Java code.
-They can be regarded simply as a way to name the purpose of the aspect, for
-readability. The aspect names are also used for controlling the order of refine
-declarations.
-
-### <a id="jadd"></a>.jadd and .jrag files
-
-An aspect file can have the suffix .jadd or .jrag. The JastAdd system does not
-differ between these two types of files, but we recommend the following use:
-
-* Use .jrag files for declarative aspects, i.e., where you add
+classes. For example, the method `m()` and its implementations are inserted
+into classes `Stmt`, `WhileStmt`, and `IfStmt`. And the declaration of the
+field `count` is inserted into the class `Stmt`. Import declarations are
+inserted into all AST classes for which there are intertype declarations in the
+aspect. So, the import of `java.lang.util.*` is inserted into `Stmt.java`,
+`WhileStmt.java`, and `IfStmt.java`. For a more detailed discussion on the
+similarities and differences between JastAdd aspects and AspectJ, see
+[below](#AspectJ).
+
+The aspect names, e.g., A and B above, do not show up in the woven Java code,
+other than in generated documentation comments for woven attributes and
+intertype declarations. Aspect names are used for [refine
+declarations](#refine).
+
+Aspect names are a way to indicate the purpose of the aspect. A common idiom
+for naming aspects is to have one aspect per aspect file, and give the aspect
+the same name as the filename sans the extension.
+
+### <a id="jadd"></a>JADD and JRAG files
+
+An aspect file can have the suffix `.jadd` or `.jrag`. The JastAdd system does
+not differ between these two types of files, but we recommend the following
+use:
+
+* Use `.jrag` files for declarative aspects, i.e., where you add
 attributes, equations, and rewrites to the AST classes
-   
-* Use .jadd files for imperative aspects, i.e., where you add
+* Use `.jadd` files for imperative aspects, i.e., where you add
 ordinary fields and methods to the AST classes
 
 
@@ -602,141 +708,133 @@ It is perfectly fine to not follow this convention, i.e., to mix both
 imperative and declarative features in the same aspect, but we try to follow
 the convention in our examples in order to enhance the readability of a system.
 
-### <a id="example"></a></a>Example <a id="imperative"> imperative aspect (.jadd)
+### <a id="example"></a><a id="imperative"></a>Example imperative aspect (JADD)
 
-Here is an example <em>imperative</em> aspect that adds pretty printing
-behavior to some AST classes. Typically, this file would be named
-PrettyPrinter.jadd:
+Here is an example *imperative* aspect that adds pretty printing behavior to
+some AST classes. Typically, this file would be named `PrettyPrint.jadd`:
 
-    aspect PrettyPrinter {
-      void ASTNode.pp(String indent) { }
-      void WhileStmt.pp(String indent) {
-         System.out.println(indent + "while " + getExp().pp(indent + "   ") + " do");
-            getStmt().pp(indent + "   ");
+    aspect PrettyPrint {
+      void WhileStmt.pp() {
+        System.out.format("while %s do %s%n", getExp().pp(), getStmt().pp());
       }
-      void IfStmt.pp(String indent) { ... }
-      ...
+      void IfStmt.pp() { ... }
+      void Exp.pp() { ... }
     }
 
-### Example <a id="declarative"></a>declarative aspect (.jrag)
+### <a id="declarative"></a>Example declarative aspect (JRAG)
 
-Here is an example <em>declarative</em> aspect that adds type checking to some
-AST classes. Typically, this file would be named TypeChecking.jrag:
+Here is an example *declarative* aspect that adds type checking to some
+AST classes. Typically, this file would be named `TypeCheck.jrag`:
 
     import TypeSystem.Type;
-    aspect TypeChecking {
+    aspect TypeCheck {
       syn Type Exp.actualType();
-      inh Type Exp.expectedType();
       eq LogicalExp.actualType() = Type.boolean();
       eq IdUse.actualType() = decl().getType();
       ...
+      inh Type Exp.expectedType();
       eq WhileStmt.getExp().expectedType() = Type.boolean();
-      syn boolean Exp.typeError() = ! (actualType().equals(expectedType());
+      syn boolean Exp.typeError() = !(actualType().equals(expectedType());
     }
 
-### Supported AOP <a id="AOPfeatures"></a>features
-
-<TABLE BORDER=1>
-<TR>
-<TD>
-<B>Feature</B>
-</TD>
-<TD>
-<B>Comment</B>
-</TD>
-</TR>
-<TR>
-<TD>
-intertype declaration of AST fields, methods, and
-constructors.
-</TD>
-<TD>
-See the prettyprinting example above. The declarations are inserted into the
-corresponding AST classes by the AST weaver. Any modifiers (public, private,
-static, etc.), are interpreted in the context of the AST class. I.e., not as in
-AspectJ where the public/private modifiers relate to the aspect.
-</TD>
-</TR>
-<TR>
-<TD>
-intertype declaration of attributes, equations, and
-rewrites
-</TD>
-<TD>
-See the type checking example above. For more details,
-[Attributes](#Attributes).
-
-Note that access modifiers (public, private, etc.) are not supported for
-attributes. All declared attributes generate public accessor methods in the AST
-classes.
-</TD>
-</TR>
-<TR>
-<TD>
-declare additional interfaces for AST classes
-</TD>
-<TD>
-E.g., in an aspect you can write
-
-<PRE>WhileStmt implements LoopInterface;</PRE>
-
-This will insert an "implements LoopInterface" clause in
-the generated WhileStmt class.
-</TD>
-</TR>
-<TR>
-<TD>
-declare classes and interfaces in an aspect
-</TD>
-<TD>
-E.g., in an aspect you can write
-
-<PRE>interface I { ... }
-class C { ... }</PRE>
-
-This is equivalent to declaring the interface and class
-in separate ordinary Java files. The possibility to declare
-them inside an aspect is just for convenience.
-</TD>
-</TR>
-<TR>
-<TD>
-<a id="refine"></a>refine a method declared in another aspect
-(This feature is available in JastAdd version R20051107 and later.)
-</TD>
-<TD>
-Often, it is useful to be able to replace or refine methods declared in
-another aspect.  This can be done using a "refine" clause. In the following
-example, the aspect A declares a method m() in the class C. In the aspect B,
-the method is replaced, using a "refine" clause. This is similar to overriding
-a method in a subclass, but here the "overridden" method is in the same class,
-just defined in another aspect.  Inside the body of the refined method, the
-original method can be called explicitly.  This is similar to a call to super
-for overriding methods.
-
-<PRE>aspect A {
+### <a id="AOPfeatures"></a>Supported AOP features
+
+<table border=1>
+<tr>
+    <th>Feature</th>
+    <th>Comment</th>
+</tr>
+<tr>
+    <td>
+        Intertype declaration of AST fields, methods, and constructors.
+    </td>
+    <td>
+        See the prettyprinting example above. The declarations are inserted into the
+        corresponding AST classes by the AST weaver. Any modifiers (public, private,
+        static, etc.), are interpreted in the context of the AST class. I.e., not as in
+        AspectJ where the public/private modifiers relate to the aspect.
+    </td>
+</tr>
+<tr>
+    <td>
+        Intertype declaration of attributes, equations, and rewrites.
+    </td>
+    <td>
+        See the type checking example above. For more details,
+        see <a href="#Attributes">Attributes</a>.
+
+        Note that access modifiers (public, private, etc.) are not supported for
+        attributes. All declared attributes generate public accessor methods in the AST
+        classes.
+    </td>
+</tr>
+<tr>
+    <td>
+        Declare additional interfaces for AST classes.
+    </td>
+    <td>
+        In an aspect you can write
+
+        <p><pre>WhileStmt implements LoopInterface;</pre>
+
+        <p>This inserts an "implements LoopInterface" clause in the generated
+        <code>WhileStmt</code> class.
+    </td>
+</tr>
+<tr>
+    <td>
+        Declare classes and interfaces in an aspect.
+    </td>
+    <td>
+        In an aspect you can write
+
+        <p><pre>interface I { ... }
+class C { ... }</pre>
+
+        <p>This is equivalent to declaring the interface and class
+        in separate ordinary Java files. The possibility to declare
+        them inside an aspect is just for convenience.
+    </td>
+</tr>
+<tr>
+    <td>
+        <a id="refine"></a>Refine a method declared in another aspect.
+    </td>
+    <td>
+        For extensibility it is often useful to be able to replace or refine
+        methods declared in another aspect.  This can be done using a "refine"
+        clause. In the following example, the aspect A declares a method
+        <code>m()</code> in the class <code>C</code>. In the aspect
+        <code>B</code>, the method is replaced, using a "refine" clause. This
+        is similar to overriding a method in a subclass, but here the
+        "overridden" method is in the same class, just defined in another
+        aspect.  Inside the body of the refined method, the original method can
+        be called explicitly.  This is similar to a call to super for
+        overriding methods.
+
+        <p><pre>aspect A {
   void C.m() { ... }
 }
 
 aspect B {
-  refine A void C.m() { // similar to overriding
+  refine A void C.m() { // Similar to overriding.
     ...
-    refined(); // similar to call to super
+    refined(); // Similar to call to super.
     ...
   }
-}</PRE>
-         
-Note that the refine clause explicitly states which aspect is refined (A in
-this case).  Additional aspects may further refine the method. For example, an
-aspect C can refine the method refined in B.
-
-The original method can be called using the keyword "refined". JastAdd2
-replaces all occurrences of this keyword with the new name of the refined
-method. Be careful with how you use refined - even occurrences in string
-literals or comments are replaced!  With the command line flag "--refineLegacy"
-you can use the legacy syntax for calling the refined method:
-
-<PRE>aspect A {
+}</pre>
+
+        <p>Note that the refine clause explicitly states which aspect is refined (A in
+        this case).  Additional aspects may further refine the method. For example, an
+        aspect C can refine the method refined in B.
+
+        <p>The original method can be called using the keyword "refined". JastAdd2
+        replaces all occurrences of this keyword with the new name of the refined
+        method. Be careful with how you use refined - even occurrences in string
+        literals or comments are replaced!  With the command line flag "--refineLegacy"
+        you can use the legacy syntax for calling the refined method:
+
+        <p><pre>aspect A {
   void C.m() { ... }
 }
 
@@ -746,57 +844,47 @@ aspect B {
     AspectFile.C.m();
     ...
   }
-}</PRE>
+}</pre>
 
-*Note:* AspectFile is the name of the file (minus extension) that contains the
-original declaration.
-</TD>
-</TR>
-</TABLE>
+        <p><em>Note:</em> AspectFile is the name of the file (minus extension)
+        that contains the original declaration.
+    </td>
+</tr>
+</table>
 
 ### <a id="AspectJ"></a>Similarities and differences from AspectJ
 
 The aspect concept in JastAdd was developed in parallel to the AspectJ
-development, and we have gradually adopted the AspectJ syntax, for  features
+development, and we have gradually adopted the AspectJ syntax, for features
 that are similar.  The important similarity between JastAdd aspects and AspectJ
 aspects is the intertype declarations. In addition, JastAdd aspects support
 attribute grammar features which AspectJ does not. Note, however, that JastAdd
 supports intertype declarations only for the AST classes, not for classes in
-general like AspectJ. There are many other features of AspectJ that are not
-supported in JastAdd, e.g.:
-
-* Fields and methods private to an aspect are not
-   supported.
-   
-* Declaration of additional parent classes is not
-   supported.
-   
-* Dynamic features like AspectJ's pointcuts or advice are not
-   supported.
-</UL>
+general as AspectJ does. There are many other features of AspectJ that are not
+supported in JastAdd, for example:
+
+* Fields and methods private to an aspect are not supported.
+* Declaration of additional parent classes is not supported.
+* Dynamic features like AspectJ's pointcuts or advice are not supported.
 
 ### <a id="IdiomPrivate"></a>Idiom for private fields and methods
 
 As mentioned, JastAdd does not support fields and methods that are private to
 an aspect. As a workaround idiom, such fields and methods can be implemented as
-(non-private) static fields and methods in class ASTNode. As an example,
-consider the pretty printer. We might want to parameterize the prettyprinter so
-that it can pretty print on any PrintStream object and not only on System.out.
+(non-private) static fields and methods in class `ASTNode`. As an example,
+consider the pretty printer. We might want to parameterize the pretty printer methods so
+that it can pretty print to any `PrintStream` object, not only on `System.out`.
 Here is how you could write this in AspectJ and the corresponding JastAdd
 implementation:
 
-<TABLE BORDER=1>
-<TR>
-<TD>
-<B>AspectJ code</B>
-</TD>
-<TD>
-<B>JastAdd code</B>
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE>aspect PrettyPrinter {
+<table border=1>
+<tr>
+    <th>AspectJ code</th>
+    <th>JastAdd code</th>
+</tr>
+<tr>
+    <td>
+        <pre>aspect PrettyPrinter {
   private PrintStream ppStream = null;
   public void prettyprint(ASTNode n, PrintStream s) {
     ppStream = s;
@@ -810,10 +898,10 @@ implementation:
     ...
   }
   ...
-}</PRE>
-</TD>
-<TD>
-<PRE>aspect PrettyPrinter {
+}</pre>
+    </td>
+    <td>
+        <pre>aspect PrettyPrinter {
   static PrintStream ASTNode.ppStream = null;
   public void ASTNode.prettyprint(PrintStream s) {
     ppStream = s;
@@ -827,394 +915,572 @@ implementation:
     ...
   }
   ...
-}</PRE>
-</TD>
-</TR>
-</TABLE>
+}</pre>
+    </td>
+</tr>
+</table>
 
-<h2><a id="Attributes"></a>Attributes</h2>
+## <a id="Attributes"></a>Attributes
 
 Attributes are specified in [JastAdd aspect files](#Aspects).
 
-### <a id="Basic"></a>Basic attribute mechanisms
-
-<TABLE BORDER=1>
-
-<TR>
-<TD WIDTH=266>
-<B><a id="Synthesized"></a>Synthesized attributes</B>
-</TD>
-<TD>
-
-</TD>
-</TR>
-<TR>
-<TD WIDTH=266>
-<PRE>syn T A.x();</PRE>
-</TD>
-<TD>
-x is a synthesized attribute in class A and of type T.
-
-There must be equations defining x in A (if A is concrete) or in all concrete
-subclasses of A (if A is abstract).
-
-*Note!* Synthesized attributes are conceptually equivalent to abstract
-virtual functions (without side-effects). The main difference is that their
-values may be cached (see below). They can be accessed in the same way as
-virtual functions. I.e., the declaration generates the following Java API:
-
-<PRE>T A.x();</PRE>
-</TD>
-</TR>
-<TR>
-<TD WIDTH=266>
-<PRE>eq A.x() = <I>Java-expr;</I></PRE>
-</TD>
-<TD>
-The equation defines the value of the synthesized attribute x of AST nodes of
-type A.
-
-The Java-expression that defines the value must be free from externally visible
-side-effects. The context of the expression is the class A, and any part of the
-class A's API may be used in the computation, including accesses to other
-attributes.
-
-*Note!* Equations defining synthesized attributes are conceptually
-equivalent to virtual method implementations (without side-effects).
-</TD>
-</TR>
-<TR>
-<TD WIDTH=266>
-<PRE>eq B.x() = <I>Java-expr;</I></PRE>
-</TD>
-<TD>
-Suppose B is a subclass to A. This equation overrides the
-corresponding (default) equation for A.x().
-
-*Note!* This is equivalent to overriding method
-implementations.
-</TD>
-</TR>
-<TR>
-<TD WIDTH=266>
-<B><a id="Shorthand"></a>Shorthand for synthesized
-attributes</B>
-</TD>
-<TD></TD>
-</TR>
-<TR>
-<TD WIDTH=266 HEIGHT=70>
-<PRE>syn T A.x() = <I>Java-expr;</I></PRE>
-</TD>
-<TD HEIGHT=70>
-The declaration of a synthesized attribute and the
-(default) equation for it can be written in one clause. So
-the clause to the left is equivalent to:
-
-<PRE>syn T A.x();
-eq A.x() = <I>Java-expression;</I></PRE>
-</TD>
-</TR>
-</tbody>
-</TABLE>
-
-<TABLE BORDER=1>
-<tbody>
-<TR>
-<TD WIDTH=266>
-<B><a id="Inherited"></a>Inherited attributes</B>
-</TD>
-<TD>
-
-</TD>
-</TR>
-<TR>
-<TD WIDTH=266>
-<PRE>inh T A.y();</PRE>
-</TD>
-<TD>
-y is an inherited attribute in class A and of type T.
-There must be equations defining y in all classes that have
-children of type A. If a class has several children of type
-A, there must be one equation for each of them.
-
-Inherited attributes can be accessed in the same way as
-synthesized attributes. I.e., the declaration generates the
-following Java API:
-
-<PRE>T A.y();</PRE>
-
-<I>Note! </I>Inherited attributes differ from ordinary
-virtual functions in that their definitions
-(equations/method implementations) are located in the
-<I>parent</I> AST node, rather than in the node itself.
-
-<I>Note!</I> The concept of <I>inherited</I> attributes
-in this Attribute Grammar sense is completely different from
-object-oriented inheritance. Both attribute grammars and
-object-orientation were invented in the late 60's and the
-use of the same term "inheritance" is probably a mere
-coincidence: In AGs, inheritance takes place between nodes
-in a syntax tree. In OO, inheritance takes place between
-classes in a class hierarchy.
-</TD>
-</TR>
-<TR>
-<TD WIDTH=266>
-<PRE>eq C.getA().y() = <I>Java-expr;</I></PRE>
-</TD>
-<TD>
-This equation defines the value of the inherited attribute
-y() of the A child of a C node.
-
-<I>Note! </I>The Java-expression executes in the context of
-C.
-
-<I>Note!</I> The equation is similar to a method
-implementation.
-
-<I>Note!</I> The equation actually applies to all inherited
-attributes y in the subtree rooted at A, provided that they
-declare the y attribute. See below under broadcast
-attributes.
-</TD>
-</TR>
-<TR>
-<TD WIDTH=266>
-<PRE>eq D.getA().y() = <I>Java-expr</I>;</PRE>
-</TD>
-<TD>
-Suppose D is a subclass of C. In this case, the equation
-overrides the previous one.
-
-<I>Note!</I> This is analogous to overriding a virtual
-method implementation.
-</TD>
-</TR>
-</tbody>
-</TABLE>
-
-<TABLE BORDER=1>
-<tbody>
-<TR>
-<TD WIDTH=266>
-<B><a id="Method"></a>Method syntax</B>
-</TD>
-<TD>
-
-</TD>
-</TR>
-<TR>
-<TD WIDTH=266>
-<PRE>syn T A.x() {
+Different kinds of attributes are documented in the following sections.
+
+### <a id="Basic"></a><a id="Synthesized"></a>Synthesized attributes
+
+<table border=1>
+<tr>
+    <th>Syntax</th>
+    <th>Meaning</th>
+</tr>
+<tr>
+    <td>
+        <pre>syn T A.x();</pre>
+    </td>
+    <td>
+        Declares a synthesized attribute <code>x</code> of type <code>T</code> in class A.
+
+        <p>There must be equations defining x in A (if A is concrete) or in all
+        concrete subclasses of A (if A is abstract).
+
+        <p><em>Note!</em> Synthesized attributes are conceptually equivalent to abstract
+        virtual functions (without side-effects). The main difference is that their
+        values may be cached (see below). They can be accessed in the same way as
+        virtual functions. I.e., the declaration generates the following Java API:
+
+        <p><pre>T A.x();</pre>
+    </td>
+</tr>
+<tr>
+    <td>
+        <pre>eq A.x() = <em>Java-expr;</em></pre>
+    </td>
+    <td>
+        The equation defines the value of the synthesized attribute x of AST nodes of
+        type A.
+
+        <p>The Java-expression that defines the value must be free from externally visible
+        side-effects. The context of the expression is the class A, and any part of the
+        class A's API may be used in the computation, including accesses to other
+        attributes.
+
+        <p><em>Note!</em> Equations defining synthesized attributes are conceptually
+        equivalent to virtual method implementations (without side-effects).
+    </td>
+</tr>
+<tr>
+    <td>
+        <pre>eq B.x() = <em>Java-expr</em>;</pre>
+    </td>
+    <td>
+        Suppose B is a subclass of A. This equation overrides the corresponding
+        (default) equation for A.x().
+
+        <p><em>Note!</em> This is equivalent to overriding method implementations.
+    </td>
+</tr>
+<tr>
+    <td height=70>
+        <pre>syn T A.x() = <em>Java-expr;</em></pre>
+    </td>
+    <td height=70>
+        <a id="Shorthand"></a>The declaration of a synthesized attribute and the
+        (default) equation for it can be written in one clause. So
+        the clause to the left is equivalent to:
+
+        <p><pre>syn T A.x();
+eq A.x() = <em>Java-expression;</em></pre>
+    </td>
+</tr>
+</table>
+
+### <a id="Inherited"></a>Inherited attributes
+
+Inherited attributes propagate information down in the AST. When an inherited
+attribute is evaluated, the evaluation code first searches upward in the AST
+for a node that can compute the inherited attribute. The equation may be on the
+parent of the current node, or an ancestor, even the root of the tree.
+
+<table border=1>
+<tr>
+    <th>Syntax</th>
+    <th>Meaning</th>
+</tr>
+<tr>
+    <td width=266>
+        <pre>inh T A.y();</pre>
+    </td>
+    <td>
+        y is an inherited attribute in class A and of type T.
+        There must be equations defining y in all classes that have
+        children of type A. If a class has several children of type
+        A, there must be one equation for each of them.
+
+        Inherited attributes can be accessed in the same way as
+        synthesized attributes. I.e., the declaration generates the
+        following Java API:
+
+        <pre>T A.y();</pre>
+
+        <em>Note!</em> Inherited attributes differ from ordinary
+        virtual functions in that their definitions
+        (equations/method implementations) are located in the
+        <em>parent</em> AST node, rather than in the node itself.
+
+        <em>Note!</em> The concept of <em>inherited</em> attributes
+        in this Attribute Grammar sense is completely different from
+        object-oriented inheritance. Both attribute grammars and
+        object-orientation were invented in the late 60's and the
+        use of the same term "inheritance" is probably a mere
+        coincidence: In AGs, inheritance takes place between nodes
+        in a syntax tree. In OO, inheritance takes place between
+        classes in a class hierarchy.
+    </td>
+</tr>
+<tr>
+    <td width=266>
+        <pre>eq C.getA().y() = <em>Java-expr;</em></pre>
+    </td>
+    <td>
+        This equation defines the value of the inherited attribute
+        y() of the A child of a C node.
+
+        <em>Note!</em> The Java-expression executes in the context of
+        C.
+
+        <em>Note!</em> The equation is similar to a method
+        implementation.
+
+        <em>Note!</em> The equation actually applies to all inherited
+        attributes y in the subtree rooted at A, provided that they
+        declare the y attribute. See below under broadcast
+        attributes.
+    </td>
+</tr>
+<tr>
+    <td width=266>
+        <pre>eq D.getA().y() = <em>Java-expr</em>;</pre>
+    </td>
+    <td>
+        Suppose D is a subclass of C. In this case, the equation
+        overrides the previous one.
+
+        <p><em>Note!</em> This is analogous to overriding a virtual
+        method implementation.
+    </td>
+</tr>
+</table>
+
+### <a id="Method"></a>Method syntax
+
+It is possible to write the computation of an attribute value as a
+method body instead of as a single expression.  This may be convenient
+when the computation is complex.  Inside the method body it is possible
+to use ordinary imperative Java code with local variables, assignments,
+loops, etc. However, the net result of the computation must not have
+any side-effects. (Currently, JastAdd does not check the absence of
+such side-effects, but future versions might do so.)
+
+Example of a method body in a synthesized attribute:
+
+<pre>syn T A.x() {
   ...
-    return <I>Java-expr</I>;
-}</PRE>
-</TD>
-<TD>
-It is possible to write the computation of an attribute value as a method body
-instead of as a single expression.  This may be convenient when the computation
-is complex.  Inside the method body it is possible to use ordinary imperative
-Java code with local variables, assignments, loops, etc. However, the net
-result of the computation must not have any side-effects. (Currently, JastAdd
-does not check the absence of such side-effects, but future versions might do
-so.)
-</TD>
-</TR>
-<TR>
-<TD WIDTH=266>
-**<a id="Lazy"></a>Lazy attributes**<br /> (cached attributes)
-</TD>
-<TD>
-An attribute can be declared <em>lazy</em> in order to speed up the evaluation.
-An attribute that is declared lazy will automatically have its value is cached
-after the first access to it. The next time the attribute is accessed, the
-cached value is returned directly. We recommend that attributes that are
-expensive to compute and that are accessed multiple times should be declared
-lazy. For example, declaration bindings and type attributes are good candidates
-for caching. JastAdd has facilities for automatically computing good cache
-configurations based on profiling, but this is not yet documented here.
-</TD>
-</TR>
-<TR>
-<TD WIDTH=266>
-<PRE>syn lazy A.x();</PRE>
-</TD>
-<TD>
-Here, the attribute x of class A is declared lazy.
-</TD>
-</TR>
-<TR>
-<TD WIDTH=266>
-<B><a id="RefineAttr"></a>Refine attribute</B>
-</TD>
-<TD> </TD>
-</TR>
-<TR>
-<TD WIDTH=266>
-<PRE>refine S eq B.x() = <I>Java-expr;</I></PRE>
-</TD>
-<TD>
+  return <em>Java-expr</em>;
+}</pre>
+
+
+### <a id="Lazy"></a>Cached attributes
+
+An attribute can be declared *lazy* in order to speed up subsequent
+evaluations of the attribute.  An attribute that is declared lazy will have its
+value is cached after the first access to it. The next time the attribute is
+accessed, the cached value is returned directly. We recommend that attributes
+that are expensive to compute and that are accessed multiple times should be
+declared lazy. For example, declaration bindings and type attributes are good
+candidates for caching. JastAdd has facilities for automatically computing good
+cache configurations based on profiling, but this is not yet documented here.
+
+Example lazy attribute declaration:
+
+    syn lazy A.x();
+
+
+Another way to change the caching behaviour of attributes is to use a separate
+cache declaration:
+
+
+<table border=1>
+<tr>
+    <th>Syntax</th>
+    <th>Meaning</th>
+</tr>
+<tr>
+    <td>
+        <pre>uncache A.x();</pre>
+    </td>
+    <td>
+        This prevents attribute x of class A from ever being cached, though
+        attributes with the same name in subtypes of A can still be cached if
+        declared lazy.
+    </td>
+</td>
+<tr>
+    <td>
+        <pre>cache A.x();</pre>
+    </td>
+    <td>
+        This tells JastAdd to cache attribute x of class A.
+    </td>
+</td>
+</table>
+
+Cache declarations take precedence over the `lazy` keyword, but conflicting
+cache declarations for a single attribute will cause JastAdd to report an error
+as there is no way to select the proper caching strategy.
+
+### <a id="RefineAttr"></a>Refining attributes
+
 Equations defined in one aspect can be refined in another aspect, in the same
-way as methods can be refined, see [JastAdd aspect files](#Aspects).  In this
-example, the equation replaces the corresponding equation declared in the
-aspect S. The value from the original equation in S can be accessed by the
-expression S.B.x() (This feature is available in JastAdd version R20051107 and
-later.)
-</TD>
-</TR>
+way as methods can be refined, see [JastAdd aspect files](#Aspects).  In the
+example below, the equation replaces the corresponding equation declared in the
+aspect named `S`:
 
-</tbody>
-</TABLE>
+<pre>refine S eq B.x() = <em>Java-expr;</em></pre>
 
+The value of the original equation in `S` can be accessed by the expression
+`S.B.x()`. Older JastAdd code accessed the original equation by using the
+expression `refined()`.
 
 ### <a id="Parameterized"></a>Parameterized attributes
 
-<TABLE BORDER=1><tbody>
-<TR>
-<TD WIDTH=266>
-<B>Parameterized attributes</B>
-</TD>
-<TD>
 Attributes can have parameters. This is a bit unusual for attribute grammars,
-but a natural generalization when you view attributes as virtual functions.
-</TD>
-</TR>
-<TR>
-<TD WIDTH=266>
-<PRE>syn T A.x(int a);
+but a natural generalization when attributes are viewed as virtual functions.
+
+<table border=1>
+<tr>
+    <th>Syntax</th>
+    <th>Meaning</th>
+</tr>
+<tr>
+    <td width=266>
+        <pre>syn T A.x(int a);
 eq A.x(int a) {
-  return <I>Java-expr</I>;
-}</PRE>
-</TD>
-<TD>
-Here, x is a parameterized synthesized attribute. The equation is similar to a
-method implementation and the argument values can be used in the computation of
-the resulting value.
-</TD>
-</TR>
-<TR>
-<TD WIDTH=266>
-<PRE>inh T A.y(int a);
+  return <em>Java-expr</em>;
+}</pre>
+    </td>
+    <td>
+        Here, x is a parameterized synthesized attribute. The equation is
+        similar to a method implementation and the argument values can be used
+        in the computation of the resulting value.
+    </td>
+</tr>
+<tr>
+    <td width=266>
+        <pre>inh T A.y(int a);
 eq C.getA().y(int a) {
-  return <I>Java-expr</I>;
-}</PRE>
-</TD>
-<TD>
-Here, y is a parameterized inherited attribute. The equation executes in the
-context of C and can in addition access the arguments (a in this case).
-</TD>
-</TR></tbody>
-</TABLE>
+  return <em>Java-expr</em>;
+}</pre>
+    </td>
+    <td>
+        Here, y is a parameterized inherited attribute. The equation executes
+        in the context of C and can in addition access the arguments (a in this
+        case).
+    </td>
+</tr>
+</table>
 
 ### <a id="Broadcasting"></a>Broadcasting inherited attributes
 
-<TABLE BORDER=1><tbody>
-<TR>
-<TD WIDTH=266>
-<B>Broadcasting inherited attributes</B>
-</TD>
-<TD>
 Often, an inherited attribute is used in a number of places in a subtree. If
 basic inherited attributes are used, the value needs to be copied explicitly
 using inherited attributes in all the intermediate nodes. For convenience,
-JastAdd supports another technique, namely broadcasting of an inherited
-attribute to a complete subtree. An equation defining an inherited attribute
-actually broadcasts the value to the complete subtree of the child. By using
-this technique, no explicit copy attributes are needed.
-</TD>
-</TR>
-<TR>
-<TD WIDTH=266>
-<PRE>eq C.getA().y() = ...;
-inh T A.y();</PRE>
-</TD>
-<TD>
-Here, the equation defines an inherited attribute y() declared in the A child
-of a C node. This equation actually applies not only to the inherited y()
-attribute of the A child, but to all inherited y() attributes in the whole
-subtree of A. In order to for a node N in the subtree to access y(), the
-attribute must, however, be exposed by declaring y() as an inherited attribute
-of N.
-</TD>
-</TR>
-<TR>
-<TD WIDTH=266>
-<PRE>inh T B.y();</PRE>
-</TD>
-<TD>
-Here, the attribute y() is exposed in B by declaring it as an inherited
-attribute there. If there is a B node that is in the subtree rooted at the A
-that is a child of a C node, then the equation above will apply.
-</TD>
-</TR>
-<TR>
-<TD WIDTH=266 HEIGHT=22>
-<B>Overruling broadcast definitions</B>
-</TD>
-<TD HEIGHT=22>
+JastAdd supports another technique called broadcasting, where an inherited
+attribute is available in every node of a complete subtree. An equation
+defining an inherited attribute actually broadcasts the value to the complete
+subtree of the child. By using this technique, no explicit copy attributes are
+needed.
+
+<table border=1>
+<tr>
+    <th>Syntax</th>
+    <th>Meaning</th>
+</tr>
+<tr>
+    <td width=266>
+        <pre>eq C.getA().y() = ...;
+inh T A.y();</pre>
+    </td>
+    <td>
+        Here, the equation defines an inherited attribute y() declared in the A
+        child of a C node. This equation actually applies not only to the
+        inherited y() attribute of the A child, but to all inherited y()
+        attributes in the whole subtree of A. In order to for a node N in the
+        subtree to access y(), the attribute must, however, be exposed by
+        declaring y() as an inherited attribute of N.
+    </td>
+</tr>
+<tr>
+    <td width=266>
+        <pre>inh T B.y();</pre>
+    </td>
+    <td>
+        Here, the attribute y() is exposed in B by declaring it as an inherited
+        attribute there. If there is a B node that is in the subtree rooted at the A
+        that is a child of a C node, then the equation above will apply.
+    </td>
+</tr>
+</table>
+
+#### Overruling broadcast definitions
+
 A broadcast definition of an attribute a() applies to all nodes in a subtree
 rooted by N. If, however, there is a node in the subtree which has another
 equation that defines a() for a child M, that equation will take precedence for
 defining a() in M and its subtree.
-</TD>
-</TR>
-<TR>
-<TD WIDTH=266>
-<B>Differentiating between children in a list</B>
-</TD>
-<TD>
+
+#### Differentiating between children in a list
+
 When defining an inherited attribute of a child node that
 is an element of a list, it is sometimes useful to know
 which index the child node has. This can be done as
 follows:
-</TD>
-</TR>
-<TR>
-<TD WIDTH=266>
-<PRE>C ::= E*;
-eq C.getE(int index).y() = ...index...</PRE>
-</TD>
-<TD>
-Here, a C node has a list of E children. When defining the y() attribute of a
-given (subtree of an) E child, the value might depend on the index of the
-child. For example, if the E nodes are actual arguments of a procedure, we
-might want to pass down the expected type of each argument.
+
+<pre>C ::= E&#42;;
+eq C.getE(int index).y() = expr;</pre>
+
+Here, a `C` node has a list of `E` children. When defining the `y()` attribute
+of a given (subtree of an) `E` child, the value might depend on the index of
+the child. For example, if the `E` nodes are actual arguments of a procedure,
+we might want to pass down the expected type of each argument.
 
 The example equation shows how to declare the index as a parameter of the
-getE() method, and to access the index in the equation body.
-</TD>
-</TR></tbody>
-</TABLE>
-
-### <a id="Rewrites"></a>Rewrites
-
-<TABLE BORDER=1><tbody>
-<TR>
-<TD>
-<B><a id="Unconditional"></a>Unconditional rewrite
-rule</B>
-</TD>
-<TD> </TD>
-</TR>
-<TR>
-<TD>
-<PRE>rewrite A {
+`getE()` method, and to access the index in the equation body.
+
+### <a id="Circular"></a>Circular attributes
+
+Attributes can be circularly defined, meaning that the value of the attribute
+can depend (indirectly) on itself. Circular attributes are evaluated
+iteratively, starting with a start value given in the declaration of the
+attribute. The evaluation stops when the value equals that for the previous
+iteration.
+
+Circular attributes are always cached. They do not need to be declared "lazy".
+
+It is an error if a lazy attribute is circular, but not declared as such.  With
+the `visitCheck` and `componentCheck` options this can be detected at runtime,
+and an exception will be generated. To be sure that the evaluation of circular
+attributes will converge, the values should be arranged into lattices of finite
+height, the bottom values should be used as starting values, and each equation
+on the cycle should be monotonic with respect to the lattices.
+
+<pre>syn T A.x(int a) circular &#91;<span style="font-style: italic;">bv</span>&#93;;
+eq A.x(int a) = <span style="font-style: italic;">rv</span>;</pre>
+
+Here, the attribute x is a circular attribute. The starting value is *bv* (a
+Java expression).
+
+The equation defines x as having the value computed by the Java expression
+`rv`.  Note that `rv` may depend (directly or indirectly) on x.
+
+If an attribute `A.x()` that was not declared circular becomes part of a
+circular evaluation, for example by adding an extension aspect, then it is
+essential that the original attribute is never cached. This can ensured using
+the `uncache` declaration described above:
+
+    uncache A.x();
+
+
+Attribute systems with circular attributes are well defined if at least one
+attribute on every possible circular dependency cycle is declared circular and
+the other attributes on all cycles are either also declared circular or
+declared uncached as above.
+
+### <a id="Nonterminal"></a>Nonterminal attributes
+
+Nonterminal attributes (NTAs) are nodes in the AST. Whereas normal AST nodes
+are built by the parser, the NTAs are viewed as attributes and are defined by
+equations.
+
+* NTAs can be inherited or synthesized.
+* The value in the equation should be a freshly built AST subtree. It should
+  be complete in the sense that all its children should also be freshly
+  created nodes (i.e., they are not allowed to be initialized to null).
+* The NTA can itself have attributes that can be accessed like normal
+  attributes.
+* If the NTA has inherited attributes, there must be equations for those
+  attributes in some ancestor, as for normal children.
+
+#### Declaration Syntax
+
+    syn nta C A.anNTA() = new C();
+
+
+#### Older syntax
+
+In the older syntax, a nonterminal attribute is added as follows:
+
+* Declare the NTA in the ast file, see also [NTAs in the abstract
+  syntax](#ASTNTAs).
+* Declare the NTA as an attribute in a jrag file. It can be declared as a
+  synthesized or an inherited attribute.  The name of the attribute should be
+  the same as in the [AST traversal API](#typedTraversalAPI), e.g.,
+  *getX* if the NTA is called *X*.
+* Add equations defining the NTA. The defining value should be a new AST of the
+  appropriate type, created using the [AST building API](#treeBuilding).
+
+Note that if the NTA is a list or an optional node, you need to create the
+appropriate AST with a `List` or an `Opt` node as its root. See examples below.
+
+#### Simple synthesized NTA
+
+*In an .ast file:*
+
+    A ::= B /C/;
+
+
+*In a .jrag file:*
+
+    syn C A.getC() = new C();
+
+
+The NTA *C* is declared in the .ast file. It is then declared as a
+synthesized attribute *getC()* in the .jrag file.  The equation is
+provided directly in the declaration and creates a new *C* node.
+
+#### List NTA
+
+*In an .ast file:*
+
+    A ::= B /C*/;
+
+
+*In a .jrag file:*
+
+    syn C A.getCList() =
+        new List()
+            .add(new C())
+            .add(new C());
+
+The list NTA *C* is declared in the .ast file. It is then declared as a
+synthesized attribute *getCList()* (the same name as in the [implementation
+level traversal API](#ListsAndOpts)) in the `.jrag` file.  The equation is
+provided directly in the declaration and creates a *List* node to which is
+added a number of *C* nodes (two in this example).
+
+### <a id="Collection"></a>Collection attributes
+
+Collection attributes have composite values that are defined by so called
+*contributions* that each add a small piece to the composite value. The
+contributions may be located in any nodes in the AST.
+
+#### Declaration syntax
+
+The syntax for declaring a collection attribute looks like this:
+
+    coll T A.c() [fresh] with m root R;
+
+
+The individual parts of the declaration above are:
+
+1. **T** is the type of the attribute. Usually `T` is a subtype of
+   `java.lang.Collection`.
+2. **A** is AST class on which the attribute is evaluated.
+3. The **.c()** part declares the attribute name, in this case `c`.
+4. (optional) **[fresh]** tells JastAdd how the intermediate collection result
+   is initialized. The Java expression **fresh** creates an empty instance of
+   the result type.  This part is optional if `T` is a concrete type with a
+   default constructor, if it is omitted the default constructor of the type
+   `T` is used, i.e. `new T()`.
+5. (optional) **with m** specifies the name of a method to be used for updating
+   the intermediate collection object. This part is optional and the default
+   method `add` is used if no update method is specified.  The update method
+   must fulfill these requirements:
+    * The method `m`, should be a one-argument method of `T`.
+    * The method `m` should mutate the `T` object by adding one object to it.
+    * The method `m` should be commutative, in the sense that the order of
+      calling `m` for different contributions should yield the same resulting
+      `T` value.
+6. (optional) The **root R** part declares the collection root type. The
+   collection mechanism starts by finding the nearest ancestor node of type `R`
+   for the `A` node which the collection attribute is evaluated on. The subtree
+   rooted at that nearest `R` ancestor is searched for contributions to
+   `A.c()`, this means that the collection is scoped to the subtree of `R`, and
+   contributions outside that tree are not visible.
+
+
+#### Contribution declaration
+
+When JastAdd evaluates a collection attribute it first performs a "survey" of the AST,
+searching for contributions to the given collection attribute. Contributions are added
+by using contribution statements like below:
+
+    N1 contributes value-exp
+        when cond-exp
+        to N2.a()
+        for N2-ref-exp;
+
+Let's look at each part of the above template statement:
+
+* **N1** is the type of AST nodes that provide this particular contribution to
+  the target collection attribute.
+* **value-exp** is a Java expression that evaluates to an object to be added to
+  the intermediate collection of the target collection attribute.
+* (optional) **when cond-exp** is an optional contribution condition: the contribution is
+  only added to the target collection attribute if the Java expression
+  `cond-exp` evaluates to `true`.
+* **N2** is the node type where the target collection attribute is declared.
+* **.a()** is the name of the target collection attribute.
+* (optional) **for N2-ref-exp** gives a Java expression, `N2-ref-exp`, which evaluates to
+  a reference to the AST node that owns the collection attribute this
+  contribution is contributing to. This is the target expression, and it can be
+  omitted if the target node is identical to the collection root node.
+
+One can optionally contribute one contribution to multiple target nodes by using this syntax:
+
+    N1 contributes value-exp
+        when cond-exp
+        to N2.a()
+        for each N2-ref-set;
+
+where `N2-ref-set` is a Java expression that evaluates to an `Iterable<N2>` containing
+references for the set of contribution target nodes.
+
+It is possible to contribute multiple values in a single contribution by using this syntax:
+
+    N1 contributes each value-exp
+        when cond-exp
+        to N2.a()
+        for each N2-ref-set;
+
+Note the **each** before `value-exp`. This syntax works if `value-exp` has the
+type `Iterable<E>` where `E` is the element type of the collection attribute.
+For example, if the collection attribute is declared as `coll
+LinkedList<String> ...` then `value-exp` should have the type
+`Iterable<String>`.
+
+## <a id="Rewrites"></a>Rewrites
+
+JastAdd has a mechanism for replacing AST nodes by a rewritten version of the
+node whenever the node is first accessed. Rewrites are declared using rewrite
+rules, described below.
+
+### <a id="Unconditional"></a>Unconditional rewrite rule
+
+<pre>rewrite A {
   to B {
     ...
-    return <I>exp</I>;
+    return <em>exp</em>;
   }
-}</PRE>
-</TD>
-<TD>
+}</pre>
+
 An A node will be replaced by the node specified in the Java expression
-<I>exp</I>. This will happen as soon as the A node is accessed (by a get()
+*exp*. This will happen as soon as the A node is accessed (by a get()
 method from its parent), so if you traverse the tree you will only be able to
 access the final rewritten nodes.
 
 A and B must be AST classes.
 
-The <I>exp</I> must be of type B.
+The *exp* must be of type B.
 
 Let the set S be the superclasses of A (including A) that occur on right-hand
 sides of productions in the abstract syntax. B must be a subclass of all
@@ -1224,66 +1490,42 @@ break the rules in the abstract syntax.
 The code in the body of the rewrite may access and rearrange the nodes in the
 subtree rooted at A, but not any other nodes in the AST. Furthermore, the code
 may not have any other side effects.
-</TD>
-</TR>
-<TR>
-<TD>
-<B><a id="Conditional"></a>Conditional rewrite
-rule</B>
-</TD>
-<TD>
-
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE>rewrite A {
-  when ( <I>condition</I> )
+
+### <a id="Conditional"></a>Conditional rewrite rule
+
+<pre>rewrite A {
+  when ( <em>condition</em> )
     to B {
       ...
-      return <I>exp</I>;
+      return <em>exp</em>;
     }
-}</PRE>
-</TD>
-<TD>
+}</pre>
+
 The conditional rewrite works in the same way as the unconditional one, but
-performs the replacement only if the boolean expression <I>condition</I> is
+performs the replacement only if the boolean expression *condition* is
 true. The condition may access anything in the AST, e.g., attributes, other
 tree nodes and their attributes, etc.
-</TD>
-</TR>
-<TR>
-<TD>
-<B><a id="Iterative"></a>Iterative rewriting</B>
-</TD>
-<TD>
+
+### <a id="Iterative"></a>Iterative rewriting
+
 After a node has been replaced according to a rewrite rule, all conditional
 rewrite rules are checked again, and a new rewrite may be performed. This is
 iterated until no rule conditions hold.
-</TD>
-</TR>
-<TR>
-<TD>
-<B><a id="Order"></a>Order of rewriting</B>
-</TD>
-<TD>
+
+### <a id="Order"></a>Order of rewriting
+
 At each iteration of rewriting, the rule conditions are evaluated in a certain
 order. The first condition that is true is used for rewriting in that
 iteration. The order in which rule condition evaluation occurs is the
 following:
 
 * conditions in superclasses are evaluated before conditions in subclasses
-
 * conditions within an aspect file are evaluated in lexical order
-
 * conditions in different aspect files are evaluated in the order the files are
-listed in the jastadd command.
-</TR>
-<TR>
-<TD>
-**<a id="Confluency"></a>Confluency**
-</TD>
-<TD>
+  listed in the jastadd command.
+
+### <a id="Confluency"></a>Confluency
+
 If the order of rewriting of a node does not effect the final result, the rules
 are said to be *confluent*.  This is highly desirable, since it makes the
 specification more readable to not have to take lexical order of rules into
@@ -1294,351 +1536,124 @@ non-confluent. In that case, we recommend you to refine the conditions so that
 only one can apply at a time. This makes your specification independent of
 lexical order. Note that it is often useful to have several different rules
 that apply at the same time for a given node, but which are confluent.
-</TD>
-</TR>
-<TR>
-<TD>
-<B><a id="ShorthandRewrite"></a>Shorthand
-notation</B>
-</TD>
-<TD> </TD>
-</TR>
-<TR>
-<TD>
-If you have several conditional rewrite rules, you may write them together. So,
-e.g., writing
-
-<PRE>rewrite A {
-  when ( <I>condition-1</I> )
+
+
+### <a id="ShorthandRewrite"></a>Shorthand notation
+
+If you have several conditional rewrite rules, you may write them inside
+the same rewrite block. So, e.g., writing
+
+<table>
+<tr>
+<td>
+<pre>rewrite A {
+  when ( <em>condition-1</em> )
   to B {
     ...
-    return <I>exp-1</I> 
+    return <em>exp-1</em>
   }
-  when ( <I>condition-2</I> )
+  when ( <em>condition-2</em> )
   to C {
     ...
-    return <I>exp-2</I> 
+    return <em>exp-2</em>
   }
-}</PRE>
-</TD>
-<TD>
+}</pre>
+</td>
+<td style="padding: 2em">
 ... is equivalent to:
-
-<PRE>rewrite A {
-   when <I>condition-1</I> 
+</td>
+<td>
+<pre>rewrite A {
+   when <em>condition-1</em>
    to B {
       ...
-      return <I>exp-1</I> 
+      return <em>exp-1</em>
    }
 }
 rewrite A {
-  when <I>condition-2</I> 
+  when <em>condition-2</em>
   to C {
     ...
-    return <I>exp-2</I> 
+    return <em>exp-2</em>
   }
-}</PRE>
-</TD>
-</TR>
-<TR>
-<TD>
-Sometimes you don't need a block for computing the resulting node. It may be
-sufficient with an expression. In that case, you may simply write the
-expression instead of the block, e.g., as follows:
-
-<PRE>rewrite A {
-  when ( <I>condition-1</I> )
-  to B <I>exp-1</I> 
-  when ( <I>condition-2</I> )
-  to C <I>exp-2</I> 
-}</PRE>
-</TD>
-<TD>
-... which is equivalent to
-
-<PRE>rewrite A {
-   when ( <I>condition-1</I> )
-   to B { return <I>exp-1</I> }
-   when ( <I>condition-2</I> )
-   to C { <I>return exp-2</I> }
-}</PRE>
-</TD>
-</TR></tbody>
-</TABLE>
-
-### <a id="Circular"></a>Circular attributes
-
-<TABLE BORDER=1><tbody>
-<TR>
-<TD>
-<B>Circular attributes</B>
-</TD>
-<TD>
-Attributes can be circularly defined. I.e., the value of the attribute can
-depend (indirectly) on itself. Circular attributes are evaluated iteratively,
-starting with a start value given in the declaration of the attribute. The
-evaluation stops when the value equals that for the previous iteration.
-
-Circular attributes are always cached. They do not need to be declared "lazy".
-
-If a lazy attribute is circular, but not declared as such, this will be
-detected at runtime, and an exception will be generated.<BR> To be sure that
-the evaluation of circular attributes will converge, the values should be
-arranged into lattices of finite height, the bottom values should be used as
-starting values, and each equation on the cycle should be monotonic with
-respect to the lattices.
-</TD>
-</TR>
-<TR>
-<TD>
-<PRE>syn T A.x(int a) circular &#91;<span style="font-style: italic;">bv</span>&#93;;
-eq A.x(int a) = <span style="font-style: italic;">rv</span>;</PRE>
-</TD>
-<TD>
-Here, the attribute x is a circular attribute. The starting value is <span
-style="font-style: italic;">bv</span> (a Java expression).
-
-The equation defines x as having the value computed by the Java expression
-`rv`.  Note that `rv` may depend (directly or indirectly) on x.
-</TD>
-</TR></tbody>
-</TABLE>
-
-### <a id="Nonterminal"></a>Nonterminal attributes
-
-<TABLE BORDER="1">
-<tr>
-<td>
-**Newer syntax**
-
-<pre>syn nta C A.anNTA() = new C();</pre>
-</td>
-<td>
-Nonterminal attributes (NTAs) are nodes in the AST. Whereas normal AST nodes
-are built by the parser, the NTAs are viewed as attributes and are defined by
-equations.
-
-*   NTAs can be inherited or synthesized.
-
-*   The value in the equation should be a freshly built AST subtree. It should
-    be complete in the sense that all its children should also be freshly
-    created nodes (i.e., they are not allowed to be initialized to null).
-
-*   The NTA can itself have attributes that can be accessed like normal
-    attributes.
-
-*   If the NTA has inherited attributes, there must be equations for those
-    attributes in some ancestor, as for normal children.
-
-</td>
-</tr>
-<tr>
-<td>
-**Older syntax**
-</td>
-<td>
-In the older syntax, you introduce a nonterminal attribute as follows:
-
-*   Declare the NTA in the ast file, (See also [NTAs in the abstract syntax](#ASTNTAs)).
-
-*   Declare the NTA as an attribute in a jrag file. It can be declared as a
-    synthesized or an inherited attribute.
-    The name of the attribute should be the same as in the
-    [AST traversal API](#typedTraversalAPI), e.g., <em>getX</em> if the NTA
-    is called <em>X</em>.
-
-*   Add equations defining the NTA. The defining value should be a new AST of
-    the appropriate type, created using the [AST creation API](#creationAPI).
-
-Note that if the NTA is a List or an Optional node, you need to create the
-appropriate AST with a List or an Opt node as its root. See examples below.
-</td>
-</tr>
-<tr>
-<td>
-**Simple synthesized NTA**
-</td>
-<td> </td>
-</tr>
-<tr>
-<td>
-*In an .ast file:*
-
-<pre>A ::= B /C/;</pre>
-<em>In a .jrag file:</em>
-<pre>syn C A.getC() = new C();</pre>
-</td>
-<td>
-The NTA *C* is declared in the .ast file. It is then declared as a
-synthesized attribute *getC()* in the .jrag file.  The equation is
-provided directly in the declaration and creates a new *C* node.
-</td>
-</tr>
-<tr>
-<td>
-**List NTA**
-</td>
-<td> </td>
-</tr>
-<tr>
-<td>
-*In an .ast file:*
-
-<pre>A ::= B /C*/;</pre>
-
-*In a .jrag file:*
-
-<pre>syn C A.getCList() =
-new List().
-add(new C()).
-add(new C());</pre>
-</td>
-<td>
-The list NTA *C* is declared in the .ast file. It is then declared as a synthesized attribute *getCList()*
-(the same name as in the [implementation level traversal API](#ListsAndOpts)) in the .jrag file.
-The equation is provided directly in the declaration and creates a <em>List</em> node to which is added a number of
-<em>C</em> nodes (two in this example).
-
-</td>
-</tr>
-</TABLE>
-
-### <a id="Collection"></a>Collection attributes
-
-<TABLE BORDER="1">
-<tr>
-<td>
-**Collection attributes**
-</td>
-<td>
-Collection attributes have composite values that are defined by so called
-<em>contributions</em> that each add a small piece to the composite value. The
-contributions may be located in any nodes in the AST.
+}</pre>
 </td>
 </tr>
-<tr>
-<td>
-**Collection attribute declaration**
-
-<pre>coll T A.c() [fresh] with m;</pre>
-</td>
-<td>
-This example shows a declaration of the collection attribute c in nodetype A, and with type T.
-
-*   Within square brackets, a Java expression, <em>fresh</em>, should be
-    written that provides a fresh object of type T. For example, new T().
-
-*   The composite value will be built by the underlying JastAdd machinery by
-    calling the method m for each contribution.
-
-*   The method m, should be a one-argument method of T.
-
-*   The method m should mutate the T object by adding a contribution to it.
-
-*   The method m should be commutative, in the sense that the order of calling
-    m for different contributions should yield the same resulting T value.
-</td>
-</tr>
-<tr>
-<td>
-**Contribution declaration**
-
-<pre>N1 contributes value-exp
-  when cond-exp
-  to N2.a()
-  for N2-ref-exp;</pre>
-</td>
-<td>
-This declares that the nodetype N1 contributes <em>value-exp</em> to a
-collection attribute N2.a(), or more precisely, to the attribute a in the N2
-object denoted by the expression <em>N2-ref-exp</em>.
-
-*   N<em>2-ref-exp</em> should be a Java expression denoting an object of type N2.
-
-*   The *value-exp* should be a Java expression of the argument type of the method m.
+</table>
 
-*   The contribution is only applied when the boolean condition *cond-exp* is
-    true.
+Sometimes you don't need a block for computing the resulting node. It may be
+sufficient with an expression. In that case, you may simply write the
+expression instead of the block, e.g., as follows:
 
-*   The "when"-clause may be omitted.
-</td>
-</tr>
+<table>
 <tr>
 <td>
-**Contributions to a set of collections**
-
-<pre>N1 contributes value-exp
-  to N2.a()
-  for each N2-ref-set-exp;</pre>
-</td>
-<td>
-A contribution declaration can define that a certain value is contributed to
-a whole set of collection attributes by using the "for each" form.
-
-*   N2-ref-set-exp should denote an object of the Java type java.lang.Iterable, which should contain objects of type N2.
-
-*   The contribution is added to each of these N2 objects.
-
+<pre>rewrite A {
+   when ( <em>condition-1</em> )
+   to B <em>exp-1</em>
+   when ( <em>condition-2</em> )
+   to C <em>exp-2</em>
+}</pre>
 </td>
-</tr>
-<tr>
-<td>
-**Scoped collections**
-
-<pre>coll N1.a [fresh] with m root R</pre>
+<td style="padding: 2em">
+... which is equivalent to:
 </td>
 <td>
-  A collection may be scoped to a certain subtree of the AST. This means that
-only contributions inside that subtree will be applied when constructing the
-collection value.
-
-*   If R is the same nodetype as N1 (or a subtype of N1), then the subtree root will be the N1 object.
-
-*   If R is some other nodetype, the subtree root will be the closets object of type R on the way from N1 towards the AST root.
+<pre>rewrite A {
+   when ( <em>condition-1</em> )
+   to B { return <em>exp-1</em> }
+   when ( <em>condition-2</em> )
+   to C { <em>return exp-2</em> }
+}</pre>
 </td>
 </tr>
 </table>
 
+
 ## <a id="Command"></a>Running JastAdd from the command line
 
 ### Synopsis
 
-<PRE>
-  java -jar jastadd2.jar <I>options arguments</I>
-</PRE>
+    java -jar jastadd2.jar [options] <source files>
+
+Source file arguments are names of `.ast`, `.jrag` and `.jadd` files.  At least
+one `.ast` file must be provided, otherwise JastAdd will not generate any code.
+Some of the available options are listed below.
+
 
 ### Options
 
-<PRE>
-  --help <I>(prints help text and stops)</I>
-  --version <I>(prints version information and stops)</I>
-  --package=PPP <I>(optional package for generated files, default is none)</I>
-  --o=DDD <I>(optional base output directory, default is current directory)</I>
-  --beaver <I>(use beaver base node)</I>
-  --jjtree <I>(use jjtree base node, this requires --grammar to be set)</I>
-  --grammar=GGG <I>(the parser for the grammar is called GGG, required when using jjtree)</I>
-  --rewrite <I>(enable ReRAGs support)</I>
-  --visitCheck=false <I>(disable circularity check for attributes)</I>
-  --cacheCycle=false <I>(disable cache cyle optimization for circular attributes)</I>
-</PRE>
+More details about JastAdd options can be printed by passing the `--help` option
+to JastAdd.
 
-### Arguments
+Here is a short summary of available options:
 
-Names of .ast, .jrag and .jadd source files.
+Option                 | Purpose
+-----------------------|--------
+`--help`               | Prints help text and stops.
+`--version`            | Prints version information and stops.
+`--package=PPP`        | Optional package for generated files, default is none.
+`--o=DDD`              | Optional base output directory, default is current directory.
+`--beaver`             | Use beaver base node.
+`--jjtree`             | Use jjtree base node, this requires `--grammar` to be set.
+`--grammar=GGG`        | The parser for the grammar is called GGG, required when using jjtree.
+`--rewrite=regular`    | Enable ReRAGs support.
+`--visitCheck=false`   | Disable circularity check for attributes.
+`--cacheCycle=false`   | Disable cache cyle optimization for circular attributes.
 
 ### Example
 
-  The following command generates classes according to the AST description in Toy.ast.
-  The generated classes are placed in the package ast. The specifications in the jrag and jadd
-  files are translated and woven into the generated classes.
+The following command generates classes according to the AST description in
+`Toy.ast`.  The generated classes are placed in the package `ast`. The
+specifications in the Jrag and Jadd files are translated and woven into the
+generated classes.
 
-<PRE>
-  java -jar jastadd2.jar --package=ast Toy.ast \
-    NameAnalysis.jrag TypeAnalysis.jrag PrettyPrinter.jadd
-</PRE>
+    java -jar jastadd2.jar --package=ast Toy.ast \
+        NameAnalysis.jrag TypeAnalysis.jrag PrettyPrinter.jadd
 
 ### ANT task
 
-The options above are also available in an ANT task. For generating Java 1.4
-source code, write "java14=true" (without the decimal point). For the other
-options, use the same names as above.
+The options above are also available in an ANT task. The names for the options
+are the same as above, and for flag options like `--beaver` you specify
+`beaver="true"`, for other multi-value options you specify the option value you
+want, for example `grammar="GGG"` as above.
diff --git a/doc/release-notes.md b/doc/release-notes.md
index b065cc84..234fabca 100644
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -1,6 +1,46 @@
 JastAdd2 Release Notes
 ======================
 
+2.2.0 - 2016-01-13
+------------------
+
+### Bugfixes
+
+* Fixed circular attribute evaluation bug causing lazy attributes to cache intermediate results. [More info](https://bitbucket.org/jastadd/jastadd2/issues/244/lazy-attribute-connecting-two-separate)
+* Fixed declaration order dependency between inherited attributes and aspect interface declarations. [More info](https://bitbucket.org/jastadd/jastadd2/issues/248/declaration-order-dependency-between)
+* Fixed some duplicate documentation comments in generated code. [More info](https://bitbucket.org/jastadd/jastadd2/issues/239/duplicate-documentation-comments-for)
+
+###  Collection attributes
+
+* Removed multiple value expressions in collection contribution statements. [More info](https://bitbucket.org/jastadd/jastadd2/issues/250/remove-multiple-value-expressions-per)
+* Added multi-value collection contributions using the `each` keyword. [More info](https://bitbucket.org/jastadd/jastadd2/issues/249/multi-value-collection-contributions)
+* The initialization expression for collection attributes is now optional. [More info](https://bitbucket.org/jastadd/jastadd2/issues/232/optional-initial-expression-for-collection)
+* Made contribution target optional when the collection root is the target node. [More info](https://bitbucket.org/jastadd/jastadd2/issues/242/make-contribution-target-optional-when-the)
+* Default update method for collection attributes. [More info](https://bitbucket.org/jastadd/jastadd2/issues/219/default-update-method-for-collection)
+* Misspelling `with` and `root` keywords in a collection attribute declaration now causes a sytax error. [More info](https://bitbucket.org/jastadd/jastadd2/issues/237/collection-attribute-keywords-with-and)
+
+### Aspect declarations
+
+* The aspect parser now allows nested generic types. [More info](https://bitbucket.org/jastadd/jastadd2/issues/246/nested-generic-types)
+* Added cache declarations in aspects. [More info](https://bitbucket.org/jastadd/jastadd2/issues/252/cache-declarations-in-aspect)
+    * Added `cache` and `uncache` declarations, allowing more control of attribute caching behaviour.
+    * Removed support for cache configuration files. They have been replaced by cache declarations in aspects.
+    * Removed the `--cache=implicit` and `--cache=config` options, as they were obsolete.
+
+### Code generation changes
+
+* Attributes are now annotated using the ASTNodeAnnotations.DeclaredAt annotation. [More info](https://bitbucket.org/jastadd/jastadd2/issues/240/generate-declaredat-annotations)
+* Removed the `Iterable<ASTNode>` interface from `ASTNode`. [More info](https://bitbucket.org/jastadd/jastadd2/issues/247/remove-iterable-interface-from-astnode)
+* Added `astChildren()` returning an `Iterable<ASTNode>` object for iterating over the children of an AST node. This replaces using `ASTNode` as an iterable.
+* Fixed error in generated code for collection attribute contributions on `ASTNode`. [More info](https://bitbucket.org/jastadd/jastadd2/issues/245/collection-attribute-contributions-on)
+* Renamed parameter names in generated inherited attribute code to avoid name collisions. [More info](https://bitbucket.org/jastadd/jastadd2/issues/236/caller-and-child-arguments-of-inh)
+
+### Error reporting
+
+* The error message for a missing collection attribute declaration now includes the attribute name. [More info](https://bitbucket.org/jastadd/jastadd2/issues/241/error-message-for-undeclared-collection)
+* An error message is now reported when JastAdd does not find a matching inherited attribute declaration. [More info](https://bitbucket.org/jastadd/jastadd2/issues/189/missing-inherited-declarations-cause-stack)
+* Fixed a problem in collection attribute runtime debug check. [More info](https://bitbucket.org/jastadd/jastadd2/issues/238/collection-attribute-runtime-debug-check)
+
 2.1.13 - 2015-09-11
 -------------------
 
diff --git a/licenses/markdown-BSD b/licenses/markdown-BSD
deleted file mode 100644
index 6d765065..00000000
--- a/licenses/markdown-BSD
+++ /dev/null
@@ -1,30 +0,0 @@
-Copyright (c) 2004, John Gruber  
-<http://daringfireball.net/>  
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-* Redistributions of source code must retain the above copyright notice,
-  this list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright
-  notice, this list of conditions and the following disclaimer in the
-  documentation and/or other materials provided with the distribution.
-
-* Neither the name "Markdown" nor the names of its contributors may
-  be used to endorse or promote products derived from this software
-  without specific prior written permission.
-
-This software is provided by the copyright holders and contributors "as
-is" and any express or implied warranties, including, but not limited
-to, the implied warranties of merchantability and fitness for a
-particular purpose are disclaimed. In no event shall the copyright owner
-or contributors be liable for any direct, indirect, incidental, special,
-exemplary, or consequential damages (including, but not limited to,
-procurement of substitute goods or services; loss of use, data, or
-profits; or business interruption) however caused and on any theory of
-liability, whether in contract, strict liability, or tort (including
-negligence or otherwise) arising in any way out of the use of this
-software, even if advised of the possibility of such damage.
diff --git a/release.sh b/release.sh
index b776825d..838f07a8 100755
--- a/release.sh
+++ b/release.sh
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-# Copyright (c) 2011-2015, The JastAdd Team
+# Copyright (c) 2011-2016, The JastAdd Team
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,10 +27,23 @@
 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 # POSSIBILITY OF SUCH DAMAGE.
 
-# This script is used to simplify and standardize the release process. Things
-# that we should add at some point:
-#
-# * Signing the JastAdd Jar file and publishing the cryptographic signature.
+# This script is used to automate the JastAdd release process.
+# The script does the following:
+# 1. Ask if doc/release-notes.md is up-to-date.
+# 2. Build binary and source Zip files for the release.
+# 3. Add updated release notes and Version.properties in release commit with Git.
+# 4. Tag the release in Git.
+# 5. Update web pages.
+#    a. Clone the web repository in ./website
+#    b. Copy release files (refman, releasenotes, bin/src zip) to web repo.
+#    c. Update version names in web files.
+#    d. Publish web changes to staging website.
+#    e. Publish web changes to live website.
+#    f. Push web changes to Bitbucket.
+# 6. Tag the test suite for this release.
+#    a. Clone the test repository in ./jastadd-test
+#    b. Tag the latest commit with the current JastAdd release version.
+#    c. Push the tag to Bitbucket.
 
 set -eu
 
@@ -43,8 +56,10 @@ update_website ()
 {
     echo "Updating webpages..."
     if [ ! -d website ]; then
+        echo "Cloning jastadd/web.git into ./website"
         git clone git@bitbucket.org:jastadd/web.git website
     else
+        echo "Updating jastadd/web.git clone in ./website"
         pushd website
         git clean -fd
         git fetch origin
@@ -65,21 +80,29 @@ update_website ()
 
     # Update links.
     echo "Updating links..."
+    echo "Updating website/web/index.md"
     vim -e website/web/index.md <<EOF
-%s/^\(News:\n-----\n\)/\1\r### Date: JastAdd2 Release ${VERSION}\r\rVersion ${VERSION} of JastAdd2 has been released!\r\r* [Download it here!](\/releases\/jastadd2\/${VERSION}\/index.php)\r* [View Release Notes](http:\/\/jastadd.org\/releases\/jastadd2\/${VERSION}\/release-notes.php)\r/
+%s/^\(News:\n-----\n\)/\1\r### Date: JastAdd2 Release ${VERSION}\r\rVersion ${VERSION} of JastAdd2 has been released!\r\r* [Download it here!](\/releases\/jastadd2\/${VERSION}\/index.php)\r* [View Release Notes](\/releases\/jastadd2\/${VERSION}\/release-notes.php)\r/
 w
 EOF
+    echo "Updating website/web/download.md"
     vim -e website/web/download.md <<EOF
 %s/^\(JastAdd2\n--------\n\n\)/\1* [JastAdd2 Release ${VERSION}](\/releases\/jastadd2\/${VERSION})\r/
 w
 EOF
+    echo "Updating website/web/documentation/reference-manual.php"
     vim -e website/web/documentation/reference-manual.php <<EOF
 %s/\(releases\/jastadd2\/\)\d\+\.\d\+\.\d\+\(\/reference-manual.html\)/\1${VERSION}\2/
 w
+EOF
+    echo "Updating website/static/releases/jastadd2/${VERSION}/reference-manual.html"
+    vim -e "website/static/releases/jastadd2/${VERSION}/reference-manual.html" <<EOF
+%s/\(Reference Manual for JastAdd \)\d\+\.\d\+\.\d\+/\1${VERSION}/
+w
 EOF
 
     pushd website
-    echo "Publishing to staging website http://jastadd.org/testweb..."
+    echo "Publishing to staging website http://jastadd.org/testweb"
     ./testpublish.sh
     git add static/releases
     git commit -am "Update for JastAdd release ${VERSION}"
@@ -87,7 +110,7 @@ EOF
     echo "Published to http://jastadd.org/testweb - go check it out!"
 
     while true; do
-      read -p "Push website changes to bitbucket and continue? (yes/no) " yn
+      read -p "Publish live website and push changes to Bitbucket? (yes/no) " yn
       case $yn in
         [Yy]* ) break;;
         [Nn]* ) exit;;
@@ -100,6 +123,27 @@ EOF
     popd
 }
 
+update_tests ()
+{
+    echo "Tagging test repository..."
+    if [ ! -d tests ]; then
+        echo "Cloning jastadd/jastadd-test into ./tests"
+        git clone git@bitbucket.org:jastadd/jastadd-test.git tests
+    else
+        echo "Updating jastadd/jastadd-test clone in ./tests"
+        pushd tests
+        git clean -fd
+        git fetch origin
+        git reset --hard origin/master
+        popd
+    fi
+
+    pushd tests
+    git tag -a "${VERSION}" -m "Tests for JastAdd ${VERSION}"
+    git push origin "${VERSION}"
+    popd
+}
+
 VERSION="${1}"
 
 echo "JastAdd2 Release $VERSION"
@@ -123,15 +167,24 @@ while true; do
   esac
 done
 
-# Show staged changes.
 git add doc/release-notes.md
+
+# Show staged changes.
 git status -sb
 
-echo "NB: All **staged** changes will be added to the release commit!"
-echo "See the above status message for changes that will be committed."
+echo "Building release ${VERSION}..."
+gradle clean release "-PnewVersion=${VERSION}"
+VERSIONFILE='src/res/Version.properties'
+git add "${VERSIONFILE}"
+git commit "${VERSIONFILE}" -m "Release ${VERSION}"
+git tag -a "${VERSION}" -m "Version ${VERSION}"
+
+update_website
+
+update_tests
 
 while true; do
-  read -p "Proceed? (yes/no) " yn
+  read -p "Push the JastAdd release commit to Bitbucket? (yes/no) " yn
   case $yn in
     [Yy]* ) break;;
     [Nn]* ) exit;;
@@ -139,22 +192,8 @@ while true; do
   esac
 done
 
-echo "Building release ${VERSION}..."
-gradle clean release "-PnewVersion=${VERSION}"
-
-update_web
+git push origin master
+git push origin "${VERSION}"
 
-echo
-echo "Post-release checklist"
-echo "----------------------"
-echo
-echo "1. Tag the jastadd-test repository with the new JastAdd2 version:"
-echo "    cd ../jastadd-test"
-echo "    git tag -a ${VERSION} -m \"Tests for JastAdd2 ${VERSION}\""
-echo "    git push origin ${VERSION}"
-echo "2. Push the JastAdd2 release commit:"
-echo "    git push origin master"
-echo "7. Push the release tag:"
-echo "    git push origin ${VERSION}"
-echo "8. Upload artifacts to JastAdd Maven repository:"
+echo "Release finished. To upload artifacts to the Central Repository, use this command:"
 echo "    gradle uploadArchives -PsshUser=username"
diff --git a/tools/Markdown.pl b/tools/Markdown.pl
deleted file mode 100755
index e4c8469d..00000000
--- a/tools/Markdown.pl
+++ /dev/null
@@ -1,1450 +0,0 @@
-#!/usr/bin/perl
-
-#
-# Markdown -- A text-to-HTML conversion tool for web writers
-#
-# Copyright (c) 2004 John Gruber
-# <http://daringfireball.net/projects/markdown/>
-#
-
-
-package Markdown;
-require 5.006_000;
-use strict;
-use warnings;
-
-use Digest::MD5 qw(md5_hex);
-use vars qw($VERSION);
-$VERSION = '1.0.1';
-# Tue 14 Dec 2004
-
-## Disabled; causes problems under Perl 5.6.1:
-# use utf8;
-# binmode( STDOUT, ":utf8" );  # c.f.: http://acis.openlib.org/dev/perl-unicode-struggle.html
-
-
-#
-# Global default settings:
-#
-my $g_empty_element_suffix = " />";     # Change to ">" for HTML output
-my $g_tab_width = 4;
-
-
-#
-# Globals:
-#
-
-# Regex to match balanced [brackets]. See Friedl's
-# "Mastering Regular Expressions", 2nd Ed., pp. 328-331.
-my $g_nested_brackets;
-$g_nested_brackets = qr{
-	(?> 								# Atomic matching
-	   [^\[\]]+							# Anything other than brackets
-	 | 
-	   \[
-		 (??{ $g_nested_brackets })		# Recursive set of nested brackets
-	   \]
-	)*
-}x;
-
-
-# Table of hash values for escaped characters:
-my %g_escape_table;
-foreach my $char (split //, '\\`*_{}[]()>#+-.!') {
-	$g_escape_table{$char} = md5_hex($char);
-}
-
-
-# Global hashes, used by various utility routines
-my %g_urls;
-my %g_titles;
-my %g_html_blocks;
-
-# Used to track when we're inside an ordered or unordered list
-# (see _ProcessListItems() for details):
-my $g_list_level = 0;
-
-
-#### Blosxom plug-in interface ##########################################
-
-# Set $g_blosxom_use_meta to 1 to use Blosxom's meta plug-in to determine
-# which posts Markdown should process, using a "meta-markup: markdown"
-# header. If it's set to 0 (the default), Markdown will process all
-# entries.
-my $g_blosxom_use_meta = 0;
-
-sub start { 1; }
-sub story {
-	my($pkg, $path, $filename, $story_ref, $title_ref, $body_ref) = @_;
-
-	if ( (! $g_blosxom_use_meta) or
-	     (defined($meta::markup) and ($meta::markup =~ /^\s*markdown\s*$/i))
-	     ){
-			$$body_ref  = Markdown($$body_ref);
-     }
-     1;
-}
-
-
-#### Movable Type plug-in interface #####################################
-eval {require MT};  # Test to see if we're running in MT.
-unless ($@) {
-    require MT;
-    import  MT;
-    require MT::Template::Context;
-    import  MT::Template::Context;
-
-	eval {require MT::Plugin};  # Test to see if we're running >= MT 3.0.
-	unless ($@) {
-		require MT::Plugin;
-		import  MT::Plugin;
-		my $plugin = new MT::Plugin({
-			name => "Markdown",
-			description => "A plain-text-to-HTML formatting plugin. (Version: $VERSION)",
-			doc_link => 'http://daringfireball.net/projects/markdown/'
-		});
-		MT->add_plugin( $plugin );
-	}
-
-	MT::Template::Context->add_container_tag(MarkdownOptions => sub {
-		my $ctx	 = shift;
-		my $args = shift;
-		my $builder = $ctx->stash('builder');
-		my $tokens = $ctx->stash('tokens');
-
-		if (defined ($args->{'output'}) ) {
-			$ctx->stash('markdown_output', lc $args->{'output'});
-		}
-
-		defined (my $str = $builder->build($ctx, $tokens) )
-			or return $ctx->error($builder->errstr);
-		$str;		# return value
-	});
-
-	MT->add_text_filter('markdown' => {
-		label     => 'Markdown',
-		docs      => 'http://daringfireball.net/projects/markdown/',
-		on_format => sub {
-			my $text = shift;
-			my $ctx  = shift;
-			my $raw  = 0;
-		    if (defined $ctx) {
-		    	my $output = $ctx->stash('markdown_output'); 
-				if (defined $output  &&  $output =~ m/^html/i) {
-					$g_empty_element_suffix = ">";
-					$ctx->stash('markdown_output', '');
-				}
-				elsif (defined $output  &&  $output eq 'raw') {
-					$raw = 1;
-					$ctx->stash('markdown_output', '');
-				}
-				else {
-					$raw = 0;
-					$g_empty_element_suffix = " />";
-				}
-			}
-			$text = $raw ? $text : Markdown($text);
-			$text;
-		},
-	});
-
-	# If SmartyPants is loaded, add a combo Markdown/SmartyPants text filter:
-	my $smartypants;
-
-	{
-		no warnings "once";
-		$smartypants = $MT::Template::Context::Global_filters{'smarty_pants'};
-	}
-
-	if ($smartypants) {
-		MT->add_text_filter('markdown_with_smartypants' => {
-			label     => 'Markdown With SmartyPants',
-			docs      => 'http://daringfireball.net/projects/markdown/',
-			on_format => sub {
-				my $text = shift;
-				my $ctx  = shift;
-				if (defined $ctx) {
-					my $output = $ctx->stash('markdown_output'); 
-					if (defined $output  &&  $output eq 'html') {
-						$g_empty_element_suffix = ">";
-					}
-					else {
-						$g_empty_element_suffix = " />";
-					}
-				}
-				$text = Markdown($text);
-				$text = $smartypants->($text, '1');
-			},
-		});
-	}
-}
-else {
-#### BBEdit/command-line text filter interface ##########################
-# Needs to be hidden from MT (and Blosxom when running in static mode).
-
-    # We're only using $blosxom::version once; tell Perl not to warn us:
-	no warnings 'once';
-    unless ( defined($blosxom::version) ) {
-		use warnings;
-
-		#### Check for command-line switches: #################
-		my %cli_opts;
-		use Getopt::Long;
-		Getopt::Long::Configure('pass_through');
-		GetOptions(\%cli_opts,
-			'version',
-			'shortversion',
-			'html4tags',
-		);
-		if ($cli_opts{'version'}) {		# Version info
-			print "\nThis is Markdown, version $VERSION.\n";
-			print "Copyright 2004 John Gruber\n";
-			print "http://daringfireball.net/projects/markdown/\n\n";
-			exit 0;
-		}
-		if ($cli_opts{'shortversion'}) {		# Just the version number string.
-			print $VERSION;
-			exit 0;
-		}
-		if ($cli_opts{'html4tags'}) {			# Use HTML tag style instead of XHTML
-			$g_empty_element_suffix = ">";
-		}
-
-
-		#### Process incoming text: ###########################
-		my $text;
-		{
-			local $/;               # Slurp the whole file
-			$text = <>;
-		}
-        print Markdown($text);
-    }
-}
-
-
-
-sub Markdown {
-#
-# Main function. The order in which other subs are called here is
-# essential. Link and image substitutions need to happen before
-# _EscapeSpecialChars(), so that any *'s or _'s in the <a>
-# and <img> tags get encoded.
-#
-	my $text = shift;
-
-	# Clear the global hashes. If we don't clear these, you get conflicts
-	# from other articles when generating a page which contains more than
-	# one article (e.g. an index page that shows the N most recent
-	# articles):
-	%g_urls = ();
-	%g_titles = ();
-	%g_html_blocks = ();
-
-
-	# Standardize line endings:
-	$text =~ s{\r\n}{\n}g; 	# DOS to Unix
-	$text =~ s{\r}{\n}g; 	# Mac to Unix
-
-	# Make sure $text ends with a couple of newlines:
-	$text .= "\n\n";
-
-	# Convert all tabs to spaces.
-	$text = _Detab($text);
-
-	# Strip any lines consisting only of spaces and tabs.
-	# This makes subsequent regexen easier to write, because we can
-	# match consecutive blank lines with /\n+/ instead of something
-	# contorted like /[ \t]*\n+/ .
-	$text =~ s/^[ \t]+$//mg;
-
-	# Turn block-level HTML blocks into hash entries
-	$text = _HashHTMLBlocks($text);
-
-	# Strip link definitions, store in hashes.
-	$text = _StripLinkDefinitions($text);
-
-	$text = _RunBlockGamut($text);
-
-	$text = _UnescapeSpecialChars($text);
-
-	return $text . "\n";
-}
-
-
-sub _StripLinkDefinitions {
-#
-# Strips link definitions from text, stores the URLs and titles in
-# hash references.
-#
-	my $text = shift;
-	my $less_than_tab = $g_tab_width - 1;
-
-	# Link defs are in the form: ^[id]: url "optional title"
-	while ($text =~ s{
-						^[ ]{0,$less_than_tab}\[(.+)\]:	# id = $1
-						  [ \t]*
-						  \n?				# maybe *one* newline
-						  [ \t]*
-						<?(\S+?)>?			# url = $2
-						  [ \t]*
-						  \n?				# maybe one newline
-						  [ \t]*
-						(?:
-							(?<=\s)			# lookbehind for whitespace
-							["(]
-							(.+?)			# title = $3
-							[")]
-							[ \t]*
-						)?	# title is optional
-						(?:\n+|\Z)
-					}
-					{}mx) {
-		$g_urls{lc $1} = _EncodeAmpsAndAngles( $2 );	# Link IDs are case-insensitive
-		if ($3) {
-			$g_titles{lc $1} = $3;
-			$g_titles{lc $1} =~ s/"/&quot;/g;
-		}
-	}
-
-	return $text;
-}
-
-
-sub _HashHTMLBlocks {
-	my $text = shift;
-	my $less_than_tab = $g_tab_width - 1;
-
-	# Hashify HTML blocks:
-	# We only want to do this for block-level HTML tags, such as headers,
-	# lists, and tables. That's because we still want to wrap <p>s around
-	# "paragraphs" that are wrapped in non-block-level tags, such as anchors,
-	# phrase emphasis, and spans. The list of tags we're looking for is
-	# hard-coded:
-	my $block_tags_a = qr/p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del/;
-	my $block_tags_b = qr/p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math/;
-
-	# First, look for nested blocks, e.g.:
-	# 	<div>
-	# 		<div>
-	# 		tags for inner block must be indented.
-	# 		</div>
-	# 	</div>
-	#
-	# The outermost tags must start at the left margin for this to match, and
-	# the inner nested divs must be indented.
-	# We need to do this before the next, more liberal match, because the next
-	# match will start at the first `<div>` and stop at the first `</div>`.
-	$text =~ s{
-				(						# save in $1
-					^					# start of line  (with /m)
-					<($block_tags_a)	# start tag = $2
-					\b					# word break
-					(.*\n)*?			# any number of lines, minimally matching
-					</\2>				# the matching end tag
-					[ \t]*				# trailing spaces/tabs
-					(?=\n+|\Z)	# followed by a newline or end of document
-				)
-			}{
-				my $key = md5_hex($1);
-				$g_html_blocks{$key} = $1;
-				"\n\n" . $key . "\n\n";
-			}egmx;
-
-
-	#
-	# Now match more liberally, simply from `\n<tag>` to `</tag>\n`
-	#
-	$text =~ s{
-				(						# save in $1
-					^					# start of line  (with /m)
-					<($block_tags_b)	# start tag = $2
-					\b					# word break
-					(.*\n)*?			# any number of lines, minimally matching
-					.*</\2>				# the matching end tag
-					[ \t]*				# trailing spaces/tabs
-					(?=\n+|\Z)	# followed by a newline or end of document
-				)
-			}{
-				my $key = md5_hex($1);
-				$g_html_blocks{$key} = $1;
-				"\n\n" . $key . "\n\n";
-			}egmx;
-	# Special case just for <hr />. It was easier to make a special case than
-	# to make the other regex more complicated.	
-	$text =~ s{
-				(?:
-					(?<=\n\n)		# Starting after a blank line
-					|				# or
-					\A\n?			# the beginning of the doc
-				)
-				(						# save in $1
-					[ ]{0,$less_than_tab}
-					<(hr)				# start tag = $2
-					\b					# word break
-					([^<>])*?			# 
-					/?>					# the matching end tag
-					[ \t]*
-					(?=\n{2,}|\Z)		# followed by a blank line or end of document
-				)
-			}{
-				my $key = md5_hex($1);
-				$g_html_blocks{$key} = $1;
-				"\n\n" . $key . "\n\n";
-			}egx;
-
-	# Special case for standalone HTML comments:
-	$text =~ s{
-				(?:
-					(?<=\n\n)		# Starting after a blank line
-					|				# or
-					\A\n?			# the beginning of the doc
-				)
-				(						# save in $1
-					[ ]{0,$less_than_tab}
-					(?s:
-						<!
-						(--.*?--\s*)+
-						>
-					)
-					[ \t]*
-					(?=\n{2,}|\Z)		# followed by a blank line or end of document
-				)
-			}{
-				my $key = md5_hex($1);
-				$g_html_blocks{$key} = $1;
-				"\n\n" . $key . "\n\n";
-			}egx;
-
-
-	return $text;
-}
-
-
-sub _RunBlockGamut {
-#
-# These are all the transformations that form block-level
-# tags like paragraphs, headers, and list items.
-#
-	my $text = shift;
-
-	$text = _DoHeaders($text);
-
-	# Do Horizontal Rules:
-	$text =~ s{^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$}{\n<hr$g_empty_element_suffix\n}gmx;
-	$text =~ s{^[ ]{0,2}([ ]? -[ ]?){3,}[ \t]*$}{\n<hr$g_empty_element_suffix\n}gmx;
-	$text =~ s{^[ ]{0,2}([ ]? _[ ]?){3,}[ \t]*$}{\n<hr$g_empty_element_suffix\n}gmx;
-
-	$text = _DoLists($text);
-
-	$text = _DoCodeBlocks($text);
-
-	$text = _DoBlockQuotes($text);
-
-	# We already ran _HashHTMLBlocks() before, in Markdown(), but that
-	# was to escape raw HTML in the original Markdown source. This time,
-	# we're escaping the markup we've just created, so that we don't wrap
-	# <p> tags around block-level tags.
-	$text = _HashHTMLBlocks($text);
-
-	$text = _FormParagraphs($text);
-
-	return $text;
-}
-
-
-sub _RunSpanGamut {
-#
-# These are all the transformations that occur *within* block-level
-# tags like paragraphs, headers, and list items.
-#
-	my $text = shift;
-
-	$text = _DoCodeSpans($text);
-
-	$text = _EscapeSpecialChars($text);
-
-	# Process anchor and image tags. Images must come first,
-	# because ![foo][f] looks like an anchor.
-	$text = _DoImages($text);
-	$text = _DoAnchors($text);
-
-	# Make links out of things like `<http://example.com/>`
-	# Must come after _DoAnchors(), because you can use < and >
-	# delimiters in inline links like [this](<url>).
-	$text = _DoAutoLinks($text);
-
-	$text = _EncodeAmpsAndAngles($text);
-
-	$text = _DoItalicsAndBold($text);
-
-	# Do hard breaks:
-	$text =~ s/ {2,}\n/ <br$g_empty_element_suffix\n/g;
-
-	return $text;
-}
-
-
-sub _EscapeSpecialChars {
-	my $text = shift;
-	my $tokens ||= _TokenizeHTML($text);
-
-	$text = '';   # rebuild $text from the tokens
-# 	my $in_pre = 0;	 # Keep track of when we're inside <pre> or <code> tags.
-# 	my $tags_to_skip = qr!<(/?)(?:pre|code|kbd|script|math)[\s>]!;
-
-	foreach my $cur_token (@$tokens) {
-		if ($cur_token->[0] eq "tag") {
-			# Within tags, encode * and _ so they don't conflict
-			# with their use in Markdown for italics and strong.
-			# We're replacing each such character with its
-			# corresponding MD5 checksum value; this is likely
-			# overkill, but it should prevent us from colliding
-			# with the escape values by accident.
-			$cur_token->[1] =~  s! \* !$g_escape_table{'*'}!gx;
-			$cur_token->[1] =~  s! _  !$g_escape_table{'_'}!gx;
-			$text .= $cur_token->[1];
-		} else {
-			my $t = $cur_token->[1];
-			$t = _EncodeBackslashEscapes($t);
-			$text .= $t;
-		}
-	}
-	return $text;
-}
-
-
-sub _DoAnchors {
-#
-# Turn Markdown link shortcuts into XHTML <a> tags.
-#
-	my $text = shift;
-
-	#
-	# First, handle reference-style links: [link text] [id]
-	#
-	$text =~ s{
-		(					# wrap whole match in $1
-		  \[
-		    ($g_nested_brackets)	# link text = $2
-		  \]
-
-		  [ ]?				# one optional space
-		  (?:\n[ ]*)?		# one optional newline followed by spaces
-
-		  \[
-		    (.*?)		# id = $3
-		  \]
-		)
-	}{
-		my $result;
-		my $whole_match = $1;
-		my $link_text   = $2;
-		my $link_id     = lc $3;
-
-		if ($link_id eq "") {
-			$link_id = lc $link_text;     # for shortcut links like [this][].
-		}
-
-		if (defined $g_urls{$link_id}) {
-			my $url = $g_urls{$link_id};
-			$url =~ s! \* !$g_escape_table{'*'}!gx;		# We've got to encode these to avoid
-			$url =~ s!  _ !$g_escape_table{'_'}!gx;		# conflicting with italics/bold.
-			$result = "<a href=\"$url\"";
-			if ( defined $g_titles{$link_id} ) {
-				my $title = $g_titles{$link_id};
-				$title =~ s! \* !$g_escape_table{'*'}!gx;
-				$title =~ s!  _ !$g_escape_table{'_'}!gx;
-				$result .=  " title=\"$title\"";
-			}
-			$result .= ">$link_text</a>";
-		}
-		else {
-			$result = $whole_match;
-		}
-		$result;
-	}xsge;
-
-	#
-	# Next, inline-style links: [link text](url "optional title")
-	#
-	$text =~ s{
-		(				# wrap whole match in $1
-		  \[
-		    ($g_nested_brackets)	# link text = $2
-		  \]
-		  \(			# literal paren
-		  	[ \t]*
-			<?(.*?)>?	# href = $3
-		  	[ \t]*
-			(			# $4
-			  (['"])	# quote char = $5
-			  (.*?)		# Title = $6
-			  \5		# matching quote
-			)?			# title is optional
-		  \)
-		)
-	}{
-		my $result;
-		my $whole_match = $1;
-		my $link_text   = $2;
-		my $url	  		= $3;
-		my $title		= $6;
-
-		$url =~ s! \* !$g_escape_table{'*'}!gx;		# We've got to encode these to avoid
-		$url =~ s!  _ !$g_escape_table{'_'}!gx;		# conflicting with italics/bold.
-		$result = "<a href=\"$url\"";
-
-		if (defined $title) {
-			$title =~ s/"/&quot;/g;
-			$title =~ s! \* !$g_escape_table{'*'}!gx;
-			$title =~ s!  _ !$g_escape_table{'_'}!gx;
-			$result .=  " title=\"$title\"";
-		}
-
-		$result .= ">$link_text</a>";
-
-		$result;
-	}xsge;
-
-	return $text;
-}
-
-
-sub _DoImages {
-#
-# Turn Markdown image shortcuts into <img> tags.
-#
-	my $text = shift;
-
-	#
-	# First, handle reference-style labeled images: ![alt text][id]
-	#
-	$text =~ s{
-		(				# wrap whole match in $1
-		  !\[
-		    (.*?)		# alt text = $2
-		  \]
-
-		  [ ]?				# one optional space
-		  (?:\n[ ]*)?		# one optional newline followed by spaces
-
-		  \[
-		    (.*?)		# id = $3
-		  \]
-
-		)
-	}{
-		my $result;
-		my $whole_match = $1;
-		my $alt_text    = $2;
-		my $link_id     = lc $3;
-
-		if ($link_id eq "") {
-			$link_id = lc $alt_text;     # for shortcut links like ![this][].
-		}
-
-		$alt_text =~ s/"/&quot;/g;
-		if (defined $g_urls{$link_id}) {
-			my $url = $g_urls{$link_id};
-			$url =~ s! \* !$g_escape_table{'*'}!gx;		# We've got to encode these to avoid
-			$url =~ s!  _ !$g_escape_table{'_'}!gx;		# conflicting with italics/bold.
-			$result = "<img src=\"$url\" alt=\"$alt_text\"";
-			if (defined $g_titles{$link_id}) {
-				my $title = $g_titles{$link_id};
-				$title =~ s! \* !$g_escape_table{'*'}!gx;
-				$title =~ s!  _ !$g_escape_table{'_'}!gx;
-				$result .=  " title=\"$title\"";
-			}
-			$result .= $g_empty_element_suffix;
-		}
-		else {
-			# If there's no such link ID, leave intact:
-			$result = $whole_match;
-		}
-
-		$result;
-	}xsge;
-
-	#
-	# Next, handle inline images:  ![alt text](url "optional title")
-	# Don't forget: encode * and _
-
-	$text =~ s{
-		(				# wrap whole match in $1
-		  !\[
-		    (.*?)		# alt text = $2
-		  \]
-		  \(			# literal paren
-		  	[ \t]*
-			<?(\S+?)>?	# src url = $3
-		  	[ \t]*
-			(			# $4
-			  (['"])	# quote char = $5
-			  (.*?)		# title = $6
-			  \5		# matching quote
-			  [ \t]*
-			)?			# title is optional
-		  \)
-		)
-	}{
-		my $result;
-		my $whole_match = $1;
-		my $alt_text    = $2;
-		my $url	  		= $3;
-		my $title		= '';
-		if (defined($6)) {
-			$title		= $6;
-		}
-
-		$alt_text =~ s/"/&quot;/g;
-		$title    =~ s/"/&quot;/g;
-		$url =~ s! \* !$g_escape_table{'*'}!gx;		# We've got to encode these to avoid
-		$url =~ s!  _ !$g_escape_table{'_'}!gx;		# conflicting with italics/bold.
-		$result = "<img src=\"$url\" alt=\"$alt_text\"";
-		if (defined $title) {
-			$title =~ s! \* !$g_escape_table{'*'}!gx;
-			$title =~ s!  _ !$g_escape_table{'_'}!gx;
-			$result .=  " title=\"$title\"";
-		}
-		$result .= $g_empty_element_suffix;
-
-		$result;
-	}xsge;
-
-	return $text;
-}
-
-
-sub _DoHeaders {
-	my $text = shift;
-
-	# Setext-style headers:
-	#	  Header 1
-	#	  ========
-	#  
-	#	  Header 2
-	#	  --------
-	#
-	$text =~ s{ ^(.+)[ \t]*\n=+[ \t]*\n+ }{
-		"<h1>"  .  _RunSpanGamut($1)  .  "</h1>\n\n";
-	}egmx;
-
-	$text =~ s{ ^(.+)[ \t]*\n-+[ \t]*\n+ }{
-		"<h2>"  .  _RunSpanGamut($1)  .  "</h2>\n\n";
-	}egmx;
-
-
-	# atx-style headers:
-	#	# Header 1
-	#	## Header 2
-	#	## Header 2 with closing hashes ##
-	#	...
-	#	###### Header 6
-	#
-	$text =~ s{
-			^(\#{1,6})	# $1 = string of #'s
-			[ \t]*
-			(.+?)		# $2 = Header text
-			[ \t]*
-			\#*			# optional closing #'s (not counted)
-			\n+
-		}{
-			my $h_level = length($1);
-			"<h$h_level>"  .  _RunSpanGamut($2)  .  "</h$h_level>\n\n";
-		}egmx;
-
-	return $text;
-}
-
-
-sub _DoLists {
-#
-# Form HTML ordered (numbered) and unordered (bulleted) lists.
-#
-	my $text = shift;
-	my $less_than_tab = $g_tab_width - 1;
-
-	# Re-usable patterns to match list item bullets and number markers:
-	my $marker_ul  = qr/[*+-]/;
-	my $marker_ol  = qr/\d+[.]/;
-	my $marker_any = qr/(?:$marker_ul|$marker_ol)/;
-
-	# Re-usable pattern to match any entirel ul or ol list:
-	my $whole_list = qr{
-		(								# $1 = whole list
-		  (								# $2
-			[ ]{0,$less_than_tab}
-			(${marker_any})				# $3 = first list item marker
-			[ \t]+
-		  )
-		  (?s:.+?)
-		  (								# $4
-			  \z
-			|
-			  \n{2,}
-			  (?=\S)
-			  (?!						# Negative lookahead for another list item marker
-				[ \t]*
-				${marker_any}[ \t]+
-			  )
-		  )
-		)
-	}mx;
-
-	# We use a different prefix before nested lists than top-level lists.
-	# See extended comment in _ProcessListItems().
-	#
-	# Note: There's a bit of duplication here. My original implementation
-	# created a scalar regex pattern as the conditional result of the test on
-	# $g_list_level, and then only ran the $text =~ s{...}{...}egmx
-	# substitution once, using the scalar as the pattern. This worked,
-	# everywhere except when running under MT on my hosting account at Pair
-	# Networks. There, this caused all rebuilds to be killed by the reaper (or
-	# perhaps they crashed, but that seems incredibly unlikely given that the
-	# same script on the same server ran fine *except* under MT. I've spent
-	# more time trying to figure out why this is happening than I'd like to
-	# admit. My only guess, backed up by the fact that this workaround works,
-	# is that Perl optimizes the substition when it can figure out that the
-	# pattern will never change, and when this optimization isn't on, we run
-	# afoul of the reaper. Thus, the slightly redundant code to that uses two
-	# static s/// patterns rather than one conditional pattern.
-
-	if ($g_list_level) {
-		$text =~ s{
-				^
-				$whole_list
-			}{
-				my $list = $1;
-				my $list_type = ($3 =~ m/$marker_ul/) ? "ul" : "ol";
-				# Turn double returns into triple returns, so that we can make a
-				# paragraph for the last item in a list, if necessary:
-				$list =~ s/\n{2,}/\n\n\n/g;
-				my $result = _ProcessListItems($list, $marker_any);
-				$result = "<$list_type>\n" . $result . "</$list_type>\n";
-				$result;
-			}egmx;
-	}
-	else {
-		$text =~ s{
-				(?:(?<=\n\n)|\A\n?)
-				$whole_list
-			}{
-				my $list = $1;
-				my $list_type = ($3 =~ m/$marker_ul/) ? "ul" : "ol";
-				# Turn double returns into triple returns, so that we can make a
-				# paragraph for the last item in a list, if necessary:
-				$list =~ s/\n{2,}/\n\n\n/g;
-				my $result = _ProcessListItems($list, $marker_any);
-				$result = "<$list_type>\n" . $result . "</$list_type>\n";
-				$result;
-			}egmx;
-	}
-
-
-	return $text;
-}
-
-
-sub _ProcessListItems {
-#
-#	Process the contents of a single ordered or unordered list, splitting it
-#	into individual list items.
-#
-
-	my $list_str = shift;
-	my $marker_any = shift;
-
-
-	# The $g_list_level global keeps track of when we're inside a list.
-	# Each time we enter a list, we increment it; when we leave a list,
-	# we decrement. If it's zero, we're not in a list anymore.
-	#
-	# We do this because when we're not inside a list, we want to treat
-	# something like this:
-	#
-	#		I recommend upgrading to version
-	#		8. Oops, now this line is treated
-	#		as a sub-list.
-	#
-	# As a single paragraph, despite the fact that the second line starts
-	# with a digit-period-space sequence.
-	#
-	# Whereas when we're inside a list (or sub-list), that line will be
-	# treated as the start of a sub-list. What a kludge, huh? This is
-	# an aspect of Markdown's syntax that's hard to parse perfectly
-	# without resorting to mind-reading. Perhaps the solution is to
-	# change the syntax rules such that sub-lists must start with a
-	# starting cardinal number; e.g. "1." or "a.".
-
-	$g_list_level++;
-
-	# trim trailing blank lines:
-	$list_str =~ s/\n{2,}\z/\n/;
-
-
-	$list_str =~ s{
-		(\n)?							# leading line = $1
-		(^[ \t]*)						# leading whitespace = $2
-		($marker_any) [ \t]+			# list marker = $3
-		((?s:.+?)						# list item text   = $4
-		(\n{1,2}))
-		(?= \n* (\z | \2 ($marker_any) [ \t]+))
-	}{
-		my $item = $4;
-		my $leading_line = $1;
-		my $leading_space = $2;
-
-		if ($leading_line or ($item =~ m/\n{2,}/)) {
-			$item = _RunBlockGamut(_Outdent($item));
-		}
-		else {
-			# Recursion for sub-lists:
-			$item = _DoLists(_Outdent($item));
-			chomp $item;
-			$item = _RunSpanGamut($item);
-		}
-
-		"<li>" . $item . "</li>\n";
-	}egmx;
-
-	$g_list_level--;
-	return $list_str;
-}
-
-
-
-sub _DoCodeBlocks {
-#
-#	Process Markdown `<pre><code>` blocks.
-#	
-
-	my $text = shift;
-
-	$text =~ s{
-			(?:\n\n|\A)
-			(	            # $1 = the code block -- one or more lines, starting with a space/tab
-			  (?:
-			    (?:[ ]{$g_tab_width} | \t)  # Lines must start with a tab or a tab-width of spaces
-			    .*\n+
-			  )+
-			)
-			((?=^[ ]{0,$g_tab_width}\S)|\Z)	# Lookahead for non-space at line-start, or end of doc
-		}{
-			my $codeblock = $1;
-			my $result; # return value
-
-			$codeblock = _EncodeCode(_Outdent($codeblock));
-			$codeblock = _Detab($codeblock);
-			$codeblock =~ s/\A\n+//; # trim leading newlines
-			$codeblock =~ s/\s+\z//; # trim trailing whitespace
-
-			$result = "\n\n<pre><code>" . $codeblock . "\n</code></pre>\n\n";
-
-			$result;
-		}egmx;
-
-	return $text;
-}
-
-
-sub _DoCodeSpans {
-#
-# 	*	Backtick quotes are used for <code></code> spans.
-# 
-# 	*	You can use multiple backticks as the delimiters if you want to
-# 		include literal backticks in the code span. So, this input:
-#     
-#         Just type ``foo `bar` baz`` at the prompt.
-#     
-#     	Will translate to:
-#     
-#         <p>Just type <code>foo `bar` baz</code> at the prompt.</p>
-#     
-#		There's no arbitrary limit to the number of backticks you
-#		can use as delimters. If you need three consecutive backticks
-#		in your code, use four for delimiters, etc.
-#
-#	*	You can use spaces to get literal backticks at the edges:
-#     
-#         ... type `` `bar` `` ...
-#     
-#     	Turns to:
-#     
-#         ... type <code>`bar`</code> ...
-#
-
-	my $text = shift;
-
-	$text =~ s@
-			(`+)		# $1 = Opening run of `
-			(.+?)		# $2 = The code block
-			(?<!`)
-			\1			# Matching closer
-			(?!`)
-		@
- 			my $c = "$2";
- 			$c =~ s/^[ \t]*//g; # leading whitespace
- 			$c =~ s/[ \t]*$//g; # trailing whitespace
- 			$c = _EncodeCode($c);
-			"<code>$c</code>";
-		@egsx;
-
-	return $text;
-}
-
-
-sub _EncodeCode {
-#
-# Encode/escape certain characters inside Markdown code runs.
-# The point is that in code, these characters are literals,
-# and lose their special Markdown meanings.
-#
-    local $_ = shift;
-
-	# Encode all ampersands; HTML entities are not
-	# entities within a Markdown code span.
-	s/&/&amp;/g;
-
-	# Encode $'s, but only if we're running under Blosxom.
-	# (Blosxom interpolates Perl variables in article bodies.)
-	{
-		no warnings 'once';
-    	if (defined($blosxom::version)) {
-    		s/\$/&#036;/g;	
-    	}
-    }
-
-
-	# Do the angle bracket song and dance:
-	s! <  !&lt;!gx;
-	s! >  !&gt;!gx;
-
-	# Now, escape characters that are magic in Markdown:
-	s! \* !$g_escape_table{'*'}!gx;
-	s! _  !$g_escape_table{'_'}!gx;
-	s! {  !$g_escape_table{'{'}!gx;
-	s! }  !$g_escape_table{'}'}!gx;
-	s! \[ !$g_escape_table{'['}!gx;
-	s! \] !$g_escape_table{']'}!gx;
-	s! \\ !$g_escape_table{'\\'}!gx;
-
-	return $_;
-}
-
-
-sub _DoItalicsAndBold {
-	my $text = shift;
-
-	# <strong> must go first:
-	$text =~ s{ (\*\*|__) (?=\S) (.+?[*_]*) (?<=\S) \1 }
-		{<strong>$2</strong>}gsx;
-
-	$text =~ s{ (\*|_) (?=\S) (.+?) (?<=\S) \1 }
-		{<em>$2</em>}gsx;
-
-	return $text;
-}
-
-
-sub _DoBlockQuotes {
-	my $text = shift;
-
-	$text =~ s{
-		  (								# Wrap whole match in $1
-			(
-			  ^[ \t]*>[ \t]?			# '>' at the start of a line
-			    .+\n					# rest of the first line
-			  (.+\n)*					# subsequent consecutive lines
-			  \n*						# blanks
-			)+
-		  )
-		}{
-			my $bq = $1;
-			$bq =~ s/^[ \t]*>[ \t]?//gm;	# trim one level of quoting
-			$bq =~ s/^[ \t]+$//mg;			# trim whitespace-only lines
-			$bq = _RunBlockGamut($bq);		# recurse
-
-			$bq =~ s/^/  /g;
-			# These leading spaces screw with <pre> content, so we need to fix that:
-			$bq =~ s{
-					(\s*<pre>.+?</pre>)
-				}{
-					my $pre = $1;
-					$pre =~ s/^  //mg;
-					$pre;
-				}egsx;
-
-			"<blockquote>\n$bq\n</blockquote>\n\n";
-		}egmx;
-
-
-	return $text;
-}
-
-
-sub _FormParagraphs {
-#
-#	Params:
-#		$text - string to process with html <p> tags
-#
-	my $text = shift;
-
-	# Strip leading and trailing lines:
-	$text =~ s/\A\n+//;
-	$text =~ s/\n+\z//;
-
-	my @grafs = split(/\n{2,}/, $text);
-
-	#
-	# Wrap <p> tags.
-	#
-	foreach (@grafs) {
-		unless (defined( $g_html_blocks{$_} )) {
-			$_ = _RunSpanGamut($_);
-			s/^([ \t]*)/<p>/;
-			$_ .= "</p>";
-		}
-	}
-
-	#
-	# Unhashify HTML blocks
-	#
-	foreach (@grafs) {
-		if (defined( $g_html_blocks{$_} )) {
-			$_ = $g_html_blocks{$_};
-		}
-	}
-
-	return join "\n\n", @grafs;
-}
-
-
-sub _EncodeAmpsAndAngles {
-# Smart processing for ampersands and angle brackets that need to be encoded.
-
-	my $text = shift;
-
-	# Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin:
-	#   http://bumppo.net/projects/amputator/
- 	$text =~ s/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/&amp;/g;
-
-	# Encode naked <'s
- 	$text =~ s{<(?![a-z/?\$!])}{&lt;}gi;
-
-	return $text;
-}
-
-
-sub _EncodeBackslashEscapes {
-#
-#   Parameter:  String.
-#   Returns:    The string, with after processing the following backslash
-#               escape sequences.
-#
-    local $_ = shift;
-
-    s! \\\\  !$g_escape_table{'\\'}!gx;		# Must process escaped backslashes first.
-    s! \\`   !$g_escape_table{'`'}!gx;
-    s! \\\*  !$g_escape_table{'*'}!gx;
-    s! \\_   !$g_escape_table{'_'}!gx;
-    s! \\\{  !$g_escape_table{'{'}!gx;
-    s! \\\}  !$g_escape_table{'}'}!gx;
-    s! \\\[  !$g_escape_table{'['}!gx;
-    s! \\\]  !$g_escape_table{']'}!gx;
-    s! \\\(  !$g_escape_table{'('}!gx;
-    s! \\\)  !$g_escape_table{')'}!gx;
-    s! \\>   !$g_escape_table{'>'}!gx;
-    s! \\\#  !$g_escape_table{'#'}!gx;
-    s! \\\+  !$g_escape_table{'+'}!gx;
-    s! \\\-  !$g_escape_table{'-'}!gx;
-    s! \\\.  !$g_escape_table{'.'}!gx;
-    s{ \\!  }{$g_escape_table{'!'}}gx;
-
-    return $_;
-}
-
-
-sub _DoAutoLinks {
-	my $text = shift;
-
-	$text =~ s{<((https?|ftp):[^'">\s]+)>}{<a href="$1">$1</a>}gi;
-
-	# Email addresses: <address@domain.foo>
-	$text =~ s{
-		<
-        (?:mailto:)?
-		(
-			[-.\w]+
-			\@
-			[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+
-		)
-		>
-	}{
-		_EncodeEmailAddress( _UnescapeSpecialChars($1) );
-	}egix;
-
-	return $text;
-}
-
-
-sub _EncodeEmailAddress {
-#
-#	Input: an email address, e.g. "foo@example.com"
-#
-#	Output: the email address as a mailto link, with each character
-#		of the address encoded as either a decimal or hex entity, in
-#		the hopes of foiling most address harvesting spam bots. E.g.:
-#
-#	  <a href="&#x6D;&#97;&#105;&#108;&#x74;&#111;:&#102;&#111;&#111;&#64;&#101;
-#       x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;">&#102;&#111;&#111;
-#       &#64;&#101;x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;</a>
-#
-#	Based on a filter by Matthew Wickline, posted to the BBEdit-Talk
-#	mailing list: <http://tinyurl.com/yu7ue>
-#
-
-	my $addr = shift;
-
-	srand;
-	my @encode = (
-		sub { '&#' .                 ord(shift)   . ';' },
-		sub { '&#x' . sprintf( "%X", ord(shift) ) . ';' },
-		sub {                            shift          },
-	);
-
-	$addr = "mailto:" . $addr;
-
-	$addr =~ s{(.)}{
-		my $char = $1;
-		if ( $char eq '@' ) {
-			# this *must* be encoded. I insist.
-			$char = $encode[int rand 1]->($char);
-		} elsif ( $char ne ':' ) {
-			# leave ':' alone (to spot mailto: later)
-			my $r = rand;
-			# roughly 10% raw, 45% hex, 45% dec
-			$char = (
-				$r > .9   ?  $encode[2]->($char)  :
-				$r < .45  ?  $encode[1]->($char)  :
-							 $encode[0]->($char)
-			);
-		}
-		$char;
-	}gex;
-
-	$addr = qq{<a href="$addr">$addr</a>};
-	$addr =~ s{">.+?:}{">}; # strip the mailto: from the visible part
-
-	return $addr;
-}
-
-
-sub _UnescapeSpecialChars {
-#
-# Swap back in all the special characters we've hidden.
-#
-	my $text = shift;
-
-	while( my($char, $hash) = each(%g_escape_table) ) {
-		$text =~ s/$hash/$char/g;
-	}
-    return $text;
-}
-
-
-sub _TokenizeHTML {
-#
-#   Parameter:  String containing HTML markup.
-#   Returns:    Reference to an array of the tokens comprising the input
-#               string. Each token is either a tag (possibly with nested,
-#               tags contained therein, such as <a href="<MTFoo>">, or a
-#               run of text between tags. Each element of the array is a
-#               two-element array; the first is either 'tag' or 'text';
-#               the second is the actual value.
-#
-#
-#   Derived from the _tokenize() subroutine from Brad Choate's MTRegex plugin.
-#       <http://www.bradchoate.com/past/mtregex.php>
-#
-
-    my $str = shift;
-    my $pos = 0;
-    my $len = length $str;
-    my @tokens;
-
-    my $depth = 6;
-    my $nested_tags = join('|', ('(?:<[a-z/!$](?:[^<>]') x $depth) . (')*>)' x  $depth);
-    my $match = qr/(?s: <! ( -- .*? -- \s* )+ > ) |  # comment
-                   (?s: <\? .*? \?> ) |              # processing instruction
-                   $nested_tags/ix;                   # nested tags
-
-    while ($str =~ m/($match)/g) {
-        my $whole_tag = $1;
-        my $sec_start = pos $str;
-        my $tag_start = $sec_start - length $whole_tag;
-        if ($pos < $tag_start) {
-            push @tokens, ['text', substr($str, $pos, $tag_start - $pos)];
-        }
-        push @tokens, ['tag', $whole_tag];
-        $pos = pos $str;
-    }
-    push @tokens, ['text', substr($str, $pos, $len - $pos)] if $pos < $len;
-    \@tokens;
-}
-
-
-sub _Outdent {
-#
-# Remove one level of line-leading tabs or spaces
-#
-	my $text = shift;
-
-	$text =~ s/^(\t|[ ]{1,$g_tab_width})//gm;
-	return $text;
-}
-
-
-sub _Detab {
-#
-# Cribbed from a post by Bart Lateur:
-# <http://www.nntp.perl.org/group/perl.macperl.anyperl/154>
-#
-	my $text = shift;
-
-	$text =~ s{(.*?)\t}{$1.(' ' x ($g_tab_width - length($1) % $g_tab_width))}ge;
-	return $text;
-}
-
-
-1;
-
-__END__
-
-
-=pod
-
-=head1 NAME
-
-B<Markdown>
-
-
-=head1 SYNOPSIS
-
-B<Markdown.pl> [ B<--html4tags> ] [ B<--version> ] [ B<-shortversion> ]
-    [ I<file> ... ]
-
-
-=head1 DESCRIPTION
-
-Markdown is a text-to-HTML filter; it translates an easy-to-read /
-easy-to-write structured text format into HTML. Markdown's text format
-is most similar to that of plain text email, and supports features such
-as headers, *emphasis*, code blocks, blockquotes, and links.
-
-Markdown's syntax is designed not as a generic markup language, but
-specifically to serve as a front-end to (X)HTML. You can  use span-level
-HTML tags anywhere in a Markdown document, and you can use block level
-HTML tags (like <div> and <table> as well).
-
-For more information about Markdown's syntax, see:
-
-    http://daringfireball.net/projects/markdown/
-
-
-=head1 OPTIONS
-
-Use "--" to end switch parsing. For example, to open a file named "-z", use:
-
-	Markdown.pl -- -z
-
-=over 4
-
-
-=item B<--html4tags>
-
-Use HTML 4 style for empty element tags, e.g.:
-
-    <br>
-
-instead of Markdown's default XHTML style tags, e.g.:
-
-    <br />
-
-
-=item B<-v>, B<--version>
-
-Display Markdown's version number and copyright information.
-
-
-=item B<-s>, B<--shortversion>
-
-Display the short-form version number.
-
-
-=back
-
-
-
-=head1 BUGS
-
-To file bug reports or feature requests (other than topics listed in the
-Caveats section above) please send email to:
-
-    support@daringfireball.net
-
-Please include with your report: (1) the example input; (2) the output
-you expected; (3) the output Markdown actually produced.
-
-
-=head1 VERSION HISTORY
-
-See the readme file for detailed release notes for this version.
-
-1.0.1 - 14 Dec 2004
-
-1.0 - 28 Aug 2004
-
-
-=head1 AUTHOR
-
-    John Gruber
-    http://daringfireball.net
-
-    PHP port and other contributions by Michel Fortin
-    http://michelf.com
-
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright (c) 2003-2004 John Gruber   
-<http://daringfireball.net/>   
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-* Redistributions of source code must retain the above copyright notice,
-  this list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright
-  notice, this list of conditions and the following disclaimer in the
-  documentation and/or other materials provided with the distribution.
-
-* Neither the name "Markdown" nor the names of its contributors may
-  be used to endorse or promote products derived from this software
-  without specific prior written permission.
-
-This software is provided by the copyright holders and contributors "as
-is" and any express or implied warranties, including, but not limited
-to, the implied warranties of merchantability and fitness for a
-particular purpose are disclaimed. In no event shall the copyright owner
-or contributors be liable for any direct, indirect, incidental, special,
-exemplary, or consequential damages (including, but not limited to,
-procurement of substitute goods or services; loss of use, data, or
-profits; or business interruption) however caused and on any theory of
-liability, whether in contract, strict liability, or tort (including
-negligence or otherwise) arising in any way out of the use of this
-software, even if advised of the possibility of such damage.
-
-=cut
diff --git a/tools/pymarkdown.py b/tools/pymarkdown.py
new file mode 100644
index 00000000..7b8a77fd
--- /dev/null
+++ b/tools/pymarkdown.py
@@ -0,0 +1,44 @@
+# coding=utf-8
+# Copyright (c) 2016, Jesper Öqvist <jesper.oqvist@cs.lth.se>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+#     * Redistributions of source code must retain the above copyright notice,
+#       this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright notice,
+#       this list of conditions and the following disclaimer in the documentation
+#       and/or other materials provided with the distribution.
+#     * Neither the name of the Lund University nor the names of its contributors
+#       may be used to endorse or promote products derived from this software
+#       without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Simple script to run Python-Markdown on a file. Requires Python-Markdown.
+# Install with pip install markdown.
+
+import sys
+import markdown
+import codecs
+
+if __name__ == '__main__':
+    if len(sys.argv) is not 2:
+        sys.stderr.write("Usage: markdown.py <FILE>\n")
+        sys.stderr.flush()
+    else:
+        with codecs.open(sys.argv[1], mode='r', encoding='utf-8') as f:
+            text = f.read()
+        sys.stdout.write(markdown.markdown(text, ['extra']))
+        sys.stdout.flush()
+
-- 
GitLab