changeset 806:bcb74c9b895c

Moved out files in the trunk folder to the root.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Sun, 09 Mar 2008 00:12:19 +0100
parents a3fab8b74a7d
children a2880c95eda3
files AUTHORS COPYING README dsss.conf i18n/build.py i18n/de.cat i18n/dil.tproj i18n/en.cat i18n/fi.cat i18n/tr.cat release.py release.sh src/Settings.d src/SettingsLoader.d src/TypeRules.d src/TypeRulesData.d src/TypeRulesGenerator.d src/cmd/ASTStats.d src/cmd/DDoc.d src/cmd/DDocXML.d src/cmd/Generate.d src/cmd/ImportGraph.d src/cmd/Statistics.d src/common.d src/config.d src/dil/Compilation.d src/dil/CompilerInfo.d src/dil/Converter.d src/dil/Enums.d src/dil/FileBOM.d src/dil/HtmlEntities.d src/dil/Information.d src/dil/Location.d src/dil/Messages.d src/dil/SourceText.d src/dil/Time.d src/dil/Unicode.d src/dil/ast/Declaration.d src/dil/ast/Declarations.d src/dil/ast/DefaultVisitor.d src/dil/ast/Expression.d src/dil/ast/Expressions.d src/dil/ast/Node.d src/dil/ast/NodeCopier.d src/dil/ast/NodesEnum.d src/dil/ast/Parameters.d src/dil/ast/Statement.d src/dil/ast/Statements.d src/dil/ast/Type.d src/dil/ast/Types.d src/dil/ast/Visitor.d src/dil/doc/Doc.d src/dil/doc/Macro.d src/dil/doc/Parser.d src/dil/lexer/Funcs.d src/dil/lexer/IdTable.d src/dil/lexer/Identifier.d src/dil/lexer/IdentsEnum.d src/dil/lexer/IdentsGenerator.d src/dil/lexer/Keywords.d src/dil/lexer/Lexer.d src/dil/lexer/Token.d src/dil/lexer/TokensEnum.d src/dil/parser/ImportParser.d src/dil/parser/Parser.d src/dil/semantic/Analysis.d src/dil/semantic/Interpreter.d src/dil/semantic/Module.d src/dil/semantic/Package.d src/dil/semantic/Pass1.d src/dil/semantic/Pass2.d src/dil/semantic/Scope.d src/dil/semantic/Symbol.d src/dil/semantic/SymbolTable.d src/dil/semantic/Symbols.d src/dil/semantic/Types.d src/dil/semantic/TypesEnum.d src/dil/translator/German.d src/docgen/archdoc.xmi src/docgen/config/configurator.d src/docgen/config/default.cfg src/docgen/config/reader.d src/docgen/config/reflection.d src/docgen/docgen.d src/docgen/document/generator.d src/docgen/document/htmlgenerator.d src/docgen/document/latexgenerator.d src/docgen/document/plaintextgenerator.d src/docgen/document/xmlgenerator.d src/docgen/graphutils/dotwriter.d src/docgen/graphutils/modulenamewriter.d src/docgen/graphutils/modulepathwriter.d src/docgen/graphutils/primitives.d src/docgen/graphutils/writer.d src/docgen/graphutils/writers.d src/docgen/lstlang0.sty src/docgen/misc/meta.d src/docgen/misc/misc.d src/docgen/misc/options.d src/docgen/misc/parser.d src/docgen/misc/textutils.d src/docgen/moduledoc/htmlwriter.d src/docgen/moduledoc/writer.d src/docgen/moduledoc/writers.d src/docgen/page/htmlwriter.d src/docgen/page/latexwriter.d src/docgen/page/plaintextwriter.d src/docgen/page/writer.d src/docgen/page/writers.d src/docgen/page/xmlwriter.d src/docgen/sourcelisting/htmlwriter.d src/docgen/sourcelisting/latexwriter.d src/docgen/sourcelisting/writer.d src/docgen/sourcelisting/writers.d src/docgen/sourcelisting/xmlwriter.d src/docgen/templates/README src/docgen/templates/default/html/classes.tpl src/docgen/templates/default/html/dependencies.tpl src/docgen/templates/default/html/firstpage.tpl src/docgen/templates/default/html/graphics.tpl src/docgen/templates/default/html/listing.tpl src/docgen/templates/default/html/listings.tpl src/docgen/templates/default/html/makefile.tpl src/docgen/templates/default/html/modules.tpl src/docgen/templates/default/html/pagetemplate.tpl src/docgen/templates/default/html/pagetemplate2.tpl src/docgen/templates/default/html/static/tab_b.gif src/docgen/templates/default/html/static/tab_l.gif src/docgen/templates/default/html/static/tab_r.gif src/docgen/templates/default/html/static/tabs.css src/docgen/templates/default/html/stylesheet.tpl src/docgen/templates/default/html/toc.tpl src/docgen/templates/default/latex/classes.tpl src/docgen/templates/default/latex/dependencies.tpl src/docgen/templates/default/latex/firstpage.tpl src/docgen/templates/default/latex/graphics.tpl src/docgen/templates/default/latex/index.tpl src/docgen/templates/default/latex/lastpage.tpl src/docgen/templates/default/latex/listing.tpl src/docgen/templates/default/latex/listings.tpl src/docgen/templates/default/latex/makefile.tpl src/docgen/templates/default/latex/modules.tpl src/docgen/templates/default/latex/static/lstlang0.sty src/docgen/templates/default/latex/toc.tpl src/docgen/templates/default/plaintext/classes.tpl src/docgen/templates/default/plaintext/dependencies.tpl src/docgen/templates/default/plaintext/firstpage.tpl src/docgen/templates/default/plaintext/graphics.tpl src/docgen/templates/default/plaintext/listing.tpl src/docgen/templates/default/plaintext/listings.tpl src/docgen/templates/default/plaintext/makefile.tpl src/docgen/templates/default/plaintext/modules.tpl src/docgen/templates/default/plaintext/toc.tpl src/docgen/tests/common.d src/docgen/tests/doctemplate.d src/docgen/tests/graphs.d src/docgen/tests/listing.d src/docgen/tests/parse.d src/docgen/teststuff/a.d src/docgen/teststuff/b.d src/docgen/teststuff/c.d src/docgen/teststuff/clean.sh src/docgen/teststuff/lstlang0.sty src/docgen/teststuff/modules.tex src/docgen/testsuite.d src/html.css src/html_map.d src/lang_de.d src/lang_en.d src/lang_fi.d src/lang_tr.d src/macros_dil.ddoc src/main.d src/predefined.ddoc src/predefined_xml.ddoc src/tests/forward01.d src/tests/forward02.d src/tests/forward03.d src/tests/forward04.d src/tests/forward05.d src/translator/about.ui src/translator/closing_project.ui src/translator/errors.py src/translator/langfile.py src/translator/langfile_properties.ui src/translator/make_ui.sh src/translator/make_uis.sh src/translator/msg_form.ui src/translator/new_project.ui src/translator/project.py src/translator/project_properties.ui src/translator/translator.py src/translator/translator.ui src/translator/ui_about.py src/translator/ui_closing_project.py src/translator/ui_langfile_properties.py src/translator/ui_msg_form.py src/translator/ui_new_project.py src/translator/ui_project_properties.py src/translator/ui_translator.py src/util/uni.d src/xml.css src/xml_map.d trunk/AUTHORS trunk/COPYING trunk/README trunk/dsss.conf trunk/i18n/build.py trunk/i18n/de.cat trunk/i18n/dil.tproj trunk/i18n/en.cat trunk/i18n/fi.cat trunk/i18n/tr.cat trunk/release.py trunk/release.sh trunk/src/Settings.d trunk/src/SettingsLoader.d trunk/src/TypeRules.d trunk/src/TypeRulesData.d trunk/src/TypeRulesGenerator.d trunk/src/cmd/ASTStats.d trunk/src/cmd/DDoc.d trunk/src/cmd/DDocXML.d trunk/src/cmd/Generate.d trunk/src/cmd/ImportGraph.d trunk/src/cmd/Statistics.d trunk/src/common.d trunk/src/config.d trunk/src/dil/Compilation.d trunk/src/dil/CompilerInfo.d trunk/src/dil/Converter.d trunk/src/dil/Enums.d trunk/src/dil/FileBOM.d trunk/src/dil/HtmlEntities.d trunk/src/dil/Information.d trunk/src/dil/Location.d trunk/src/dil/Messages.d trunk/src/dil/SourceText.d trunk/src/dil/Time.d trunk/src/dil/Unicode.d trunk/src/dil/ast/Declaration.d trunk/src/dil/ast/Declarations.d trunk/src/dil/ast/DefaultVisitor.d trunk/src/dil/ast/Expression.d trunk/src/dil/ast/Expressions.d trunk/src/dil/ast/Node.d trunk/src/dil/ast/NodeCopier.d trunk/src/dil/ast/NodesEnum.d trunk/src/dil/ast/Parameters.d trunk/src/dil/ast/Statement.d trunk/src/dil/ast/Statements.d trunk/src/dil/ast/Type.d trunk/src/dil/ast/Types.d trunk/src/dil/ast/Visitor.d trunk/src/dil/doc/Doc.d trunk/src/dil/doc/Macro.d trunk/src/dil/doc/Parser.d trunk/src/dil/lexer/Funcs.d trunk/src/dil/lexer/IdTable.d trunk/src/dil/lexer/Identifier.d trunk/src/dil/lexer/IdentsEnum.d trunk/src/dil/lexer/IdentsGenerator.d trunk/src/dil/lexer/Keywords.d trunk/src/dil/lexer/Lexer.d trunk/src/dil/lexer/Token.d trunk/src/dil/lexer/TokensEnum.d trunk/src/dil/parser/ImportParser.d trunk/src/dil/parser/Parser.d trunk/src/dil/semantic/Analysis.d trunk/src/dil/semantic/Interpreter.d trunk/src/dil/semantic/Module.d trunk/src/dil/semantic/Package.d trunk/src/dil/semantic/Pass1.d trunk/src/dil/semantic/Pass2.d trunk/src/dil/semantic/Scope.d trunk/src/dil/semantic/Symbol.d trunk/src/dil/semantic/SymbolTable.d trunk/src/dil/semantic/Symbols.d trunk/src/dil/semantic/Types.d trunk/src/dil/semantic/TypesEnum.d trunk/src/dil/translator/German.d trunk/src/docgen/archdoc.xmi trunk/src/docgen/config/configurator.d trunk/src/docgen/config/default.cfg trunk/src/docgen/config/reader.d trunk/src/docgen/config/reflection.d trunk/src/docgen/docgen.d trunk/src/docgen/document/generator.d trunk/src/docgen/document/htmlgenerator.d trunk/src/docgen/document/latexgenerator.d trunk/src/docgen/document/plaintextgenerator.d trunk/src/docgen/document/xmlgenerator.d trunk/src/docgen/graphutils/dotwriter.d trunk/src/docgen/graphutils/modulenamewriter.d trunk/src/docgen/graphutils/modulepathwriter.d trunk/src/docgen/graphutils/primitives.d trunk/src/docgen/graphutils/writer.d trunk/src/docgen/graphutils/writers.d trunk/src/docgen/lstlang0.sty trunk/src/docgen/misc/meta.d trunk/src/docgen/misc/misc.d trunk/src/docgen/misc/options.d trunk/src/docgen/misc/parser.d trunk/src/docgen/misc/textutils.d trunk/src/docgen/moduledoc/htmlwriter.d trunk/src/docgen/moduledoc/writer.d trunk/src/docgen/moduledoc/writers.d trunk/src/docgen/page/htmlwriter.d trunk/src/docgen/page/latexwriter.d trunk/src/docgen/page/plaintextwriter.d trunk/src/docgen/page/writer.d trunk/src/docgen/page/writers.d trunk/src/docgen/page/xmlwriter.d trunk/src/docgen/sourcelisting/htmlwriter.d trunk/src/docgen/sourcelisting/latexwriter.d trunk/src/docgen/sourcelisting/writer.d trunk/src/docgen/sourcelisting/writers.d trunk/src/docgen/sourcelisting/xmlwriter.d trunk/src/docgen/templates/README trunk/src/docgen/templates/default/html/classes.tpl trunk/src/docgen/templates/default/html/dependencies.tpl trunk/src/docgen/templates/default/html/firstpage.tpl trunk/src/docgen/templates/default/html/graphics.tpl trunk/src/docgen/templates/default/html/listing.tpl trunk/src/docgen/templates/default/html/listings.tpl trunk/src/docgen/templates/default/html/makefile.tpl trunk/src/docgen/templates/default/html/modules.tpl trunk/src/docgen/templates/default/html/pagetemplate.tpl trunk/src/docgen/templates/default/html/pagetemplate2.tpl trunk/src/docgen/templates/default/html/static/tab_b.gif trunk/src/docgen/templates/default/html/static/tab_l.gif trunk/src/docgen/templates/default/html/static/tab_r.gif trunk/src/docgen/templates/default/html/static/tabs.css trunk/src/docgen/templates/default/html/stylesheet.tpl trunk/src/docgen/templates/default/html/toc.tpl trunk/src/docgen/templates/default/latex/classes.tpl trunk/src/docgen/templates/default/latex/dependencies.tpl trunk/src/docgen/templates/default/latex/firstpage.tpl trunk/src/docgen/templates/default/latex/graphics.tpl trunk/src/docgen/templates/default/latex/index.tpl trunk/src/docgen/templates/default/latex/lastpage.tpl trunk/src/docgen/templates/default/latex/listing.tpl trunk/src/docgen/templates/default/latex/listings.tpl trunk/src/docgen/templates/default/latex/makefile.tpl trunk/src/docgen/templates/default/latex/modules.tpl trunk/src/docgen/templates/default/latex/static/lstlang0.sty trunk/src/docgen/templates/default/latex/toc.tpl trunk/src/docgen/templates/default/plaintext/classes.tpl trunk/src/docgen/templates/default/plaintext/dependencies.tpl trunk/src/docgen/templates/default/plaintext/firstpage.tpl trunk/src/docgen/templates/default/plaintext/graphics.tpl trunk/src/docgen/templates/default/plaintext/listing.tpl trunk/src/docgen/templates/default/plaintext/listings.tpl trunk/src/docgen/templates/default/plaintext/makefile.tpl trunk/src/docgen/templates/default/plaintext/modules.tpl trunk/src/docgen/templates/default/plaintext/toc.tpl trunk/src/docgen/tests/common.d trunk/src/docgen/tests/doctemplate.d trunk/src/docgen/tests/graphs.d trunk/src/docgen/tests/listing.d trunk/src/docgen/tests/parse.d trunk/src/docgen/teststuff/a.d trunk/src/docgen/teststuff/b.d trunk/src/docgen/teststuff/c.d trunk/src/docgen/teststuff/clean.sh trunk/src/docgen/teststuff/lstlang0.sty trunk/src/docgen/teststuff/modules.tex trunk/src/docgen/testsuite.d trunk/src/html.css trunk/src/html_map.d trunk/src/lang_de.d trunk/src/lang_en.d trunk/src/lang_fi.d trunk/src/lang_tr.d trunk/src/macros_dil.ddoc trunk/src/main.d trunk/src/predefined.ddoc trunk/src/predefined_xml.ddoc trunk/src/tests/forward01.d trunk/src/tests/forward02.d trunk/src/tests/forward03.d trunk/src/tests/forward04.d trunk/src/tests/forward05.d trunk/src/translator/about.ui trunk/src/translator/closing_project.ui trunk/src/translator/errors.py trunk/src/translator/langfile.py trunk/src/translator/langfile_properties.ui trunk/src/translator/make_ui.sh trunk/src/translator/make_uis.sh trunk/src/translator/msg_form.ui trunk/src/translator/new_project.ui trunk/src/translator/project.py trunk/src/translator/project_properties.ui trunk/src/translator/translator.py trunk/src/translator/translator.ui trunk/src/translator/ui_about.py trunk/src/translator/ui_closing_project.py trunk/src/translator/ui_langfile_properties.py trunk/src/translator/ui_msg_form.py trunk/src/translator/ui_new_project.py trunk/src/translator/ui_project_properties.py trunk/src/translator/ui_translator.py trunk/src/util/uni.d trunk/src/xml.css trunk/src/xml_map.d
diffstat 404 files changed, 32049 insertions(+), 32049 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AUTHORS	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,13 @@
+Founder:
+  Aziz Köksal <aziz.koeksal@gmail.com>
+  "All rights to the code I've written will pass over to Jari-Matti Mäkelä,
+  in case I catch the bus or the bus catches me.
+  My death will probably not be made known anywhere on the internet,
+  therefore my testament will become effective if I don't
+  show any signs of life for 6 months on the internet.
+  Within this time limit I may always revoke or edit this testament,
+  by committing to the hg repository at http://hg.sharesource.org/dil/
+  Only the latest revision of this file is to be considered valid."
+    - Aziz Köksal
+Contributors:
+  Jari-Matti Mäkelä <jmjmak@utu.fi>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/COPYING	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,32 @@
+dil
+===
+Copyright (c) 2008 by Aziz Köksal <aziz.koeksal@gmail.com>
+This program is free software, licensed under the GPL3.
+Please, read the license file, COPYING, for further information.
+
+Description
+===========
+This software is a compiler written in D for the D programming language.
+
+How To Compile dil
+==================
+In order to compile dil you need to have:
+ *) DMD 1.028 (http://www.digitalmars.com/d/1.0/changelog.html)
+ *) Tango 0.99.5 (http://dsource.org/projects/tango/)
+ *) DSSS 0.71 (http://dsource.org/projects/dsss/)
+
+If you can't compile dil because you have a newer version of these programs
+then please report the problem to me (see Bugs section.)
+
+Before you run dil, make sure that the executable can find config.d and
+lang_en.d (which are located in trunk/src/.)
+The language can be configured in config.d.
+
+Bugs And Patches
+================
+"errare humanum est, ignoscere divinum" - to err is human, to forgive divine.
+ - Cicero
+
+Users can report problems with this software or submit patches by:
+ *) contacting me: aziz.koeksal@gmail.com
+ *) filing a bug report here: http://code.google.com/p/dil/issues/list
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dsss.conf	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,10 @@
+name = dil
+version = 0.1
+[src/main.d]
+type = binary
+target = dil
+version(GNU) {
+  buildflags = -Isrc/ -Ldsss_objs/G/cmd.DDoc.o -Ldsss_objs/G/cmd.DDocXML.o
+} else {
+  buildflags = -Isrc/
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/i18n/build.py	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+# Author: Aziz Köksal
+# License: GPL2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/i18n/de.cat	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,86 @@
+Authors:
+- {EMail: aziz.koeksal@gmail.com, Name: Aziz Köksal}
+LangCode: de
+License: GPL3
+Messages:
+- {Annot: '', ID: 0, LastEd: 0, Text: 'illegales Zeichen gefunden: ''{0}'''}
+- {Annot: '', ID: 1, LastEd: 0, Text: ungültiges Unicodezeichen.}
+- {Annot: '', ID: 2, LastEd: 0, Text: ungültige UTF-8-Sequenz.}
+- {Annot: '', ID: 3, LastEd: 0, Text: unterminiertes Zeichenliteral.}
+- {Annot: '', ID: 4, LastEd: 0, Text: leeres Zeichenliteral.}
+- {Annot: '', ID: 5, LastEd: 0, Text: erwartete 'line' nach '#'.}
+- {Annot: '', ID: 6, LastEd: 0, Text: 'Ganzzahl nach #line erwartet.'}
+- {Annot: '', ID: 7, LastEd: 0, Text: erwartete Dateispezifikation (z.B. "pfad\zur\datei".)}
+- {Annot: '', ID: 8, LastEd: 0, Text: unterminierte Dateispezifikation (filespec.)}
+- {Annot: '', ID: 9, LastEd: 0, Text: ein Special Token muss mit einem Zeilenumbruch
+    abgeschlossen werden.}
+- {Annot: '', ID: 10, LastEd: 0, Text: unterminiertes Zeichenkettenliteral.}
+- {Annot: '', ID: 11, LastEd: 0, Text: 'Nicht-Hexzeichen ''{0}'' in Hexzeichenkette
+    gefunden.'}
+- {Annot: '', ID: 12, LastEd: 0, Text: ungerade Anzahl von Hexziffern in Hexzeichenkette.}
+- {Annot: '', ID: 13, LastEd: 0, Text: unterminierte Hexzeichenkette.}
+- {Annot: '', ID: 14, LastEd: 0, Text: unterminierter Blockkommentar (/* */).}
+- {Annot: '', ID: 15, LastEd: 0, Text: unterminierter verschachtelter Kommentar (/+
+    +/).}
+- {Annot: '', ID: 16, LastEd: 0, Text: unterminierte rohe Zeichenkette.}
+- {Annot: '', ID: 17, LastEd: 0, Text: unterminierte Backquote-Zeichenkette.}
+- {Annot: '', ID: 18, LastEd: 0, Text: 'undefinierte Escapesequenz ''{0}'' gefunden.'}
+- {Annot: '', ID: 19, LastEd: 0, Text: 'ungültige Unicode-Escapesequenz ''{0}'' gefunden.'}
+- {Annot: '', ID: 20, LastEd: 0, Text: unzureichende Anzahl von Hexziffern in Escapesequenz.}
+- {Annot: '', ID: 21, LastEd: 0, Text: 'undefinierte HTML-Entität ''{0}'''}
+- {Annot: '', ID: 22, LastEd: 0, Text: 'unterminierte HTML-Entität ''{0}''.'}
+- {Annot: '', ID: 23, LastEd: 0, Text: HTML-Entitäten müssen mit einem Buchstaben
+    beginnen.}
+- {Annot: '', ID: 24, LastEd: 0, Text: Dezimalzahl überläuft im Vorzeichenbit.}
+- {Annot: '', ID: 25, LastEd: 0, Text: Überlauf in Dezimalzahl.}
+- {Annot: '', ID: 26, LastEd: 0, Text: Überlauf in Hexadezimalzahl.}
+- {Annot: '', ID: 27, LastEd: 0, Text: Überlauf in Binärzahl.}
+- {Annot: '', ID: 28, LastEd: 0, Text: Überlauf in Oktalzahl.}
+- {Annot: '', ID: 29, LastEd: 0, Text: Überlauf in Fließkommazahl.}
+- {Annot: '', ID: 30, LastEd: 0, Text: die Ziffern 8 und 9 sind in Oktalzahlen unzulässig.}
+- {Annot: '', ID: 31, LastEd: 0, Text: ungültige Hexzahl; mindestens eine Hexziffer
+    erforderlich.}
+- {Annot: '', ID: 32, LastEd: 0, Text: ungültige Binärzahl; mindestens eine Binärziffer
+    erforderlich.}
+- {Annot: '', ID: 33, LastEd: 0, Text: der Exponent einer hexadezimalen Fließkommazahl
+    ist erforderlich.}
+- {Annot: '', ID: 34, LastEd: 0, Text: Hexadezimal-Exponenten müssen mit einer Dezimalziffer
+    anfangen.}
+- {Annot: '', ID: 35, LastEd: 0, Text: Exponenten müssen mit einer Dezimalziffer anfangen.}
+- {Annot: '', ID: 36, LastEd: 0, Text: 'erwartete ''{0}'', fand aber ''{1}''.'}
+- {Annot: '', ID: 37, LastEd: 0, Text: '''{0}'' ist redundant.'}
+- {Annot: '', ID: 38, LastEd: 0, Text: Template-Tupel-Parameter dürfen nur am Ende
+    auftreten.}
+- {Annot: '', ID: 39, LastEd: 0, Text: der 'in'-Vertrag der Funktion wurde bereits
+    geparsed.}
+- {Annot: '', ID: 40, LastEd: 0, Text: der 'out'-Vertrag der Funktion wurde bereits
+    geparsed.}
+- {Annot: '', ID: 41, LastEd: 0, Text: es wurde kein Verbindungstyp angegeben.}
+- {Annot: '', ID: 42, LastEd: 0, Text: 'unbekannter Verbindungstyp ''{0}''; gültig
+    sind C, C++, D, Windows, Pascal und System.'}
+- {Annot: '', ID: 43, LastEd: 0, Text: 'erwartete eine oder mehrere Basisklassen,
+    nicht ''{0}''.'}
+- {Annot: '', ID: 44, LastEd: 0, Text: Basisklassen sind in Vorwärtsdeklarationen
+    nicht erlaubt.}
+- {Annot: '', ID: 45, LastEd: 0, Text: 'dil v{0}
+
+    Copyright (c) 2007, Aziz Köksal. Lizensiert unter der GPL3.
+
+
+    Befehle:
+
+    {1}
+
+    Geben Sie ''dil help <Befehl>'' ein, um mehr Hilfe zu einem bestimmten Befehl
+    zu
+
+    erhalten.
+
+
+    Kompiliert mit {2} v{3} am {4}.'}
+- {Annot: '', ID: 46, LastEd: 0, Text: "Generiere ein XML- oder HTML-Dokument aus\
+    \ einer D-Quelltextdatei.\nVerwendung:\n  dil gen datei.d [Optionen]\n\nOptionen:\n\
+    \  --syntax         : generiere Elemente für den Syntaxbaum\n  --xml         \
+    \   : verwende XML-Format (voreingestellt)\n  --html           : verwende HTML-Format\n\
+    \nBeispiel:\n  dil gen Parser.d --html --syntax > Parser.html"}
+- {Annot: '', ID: 47, LastEd: 0, Text: ''}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/i18n/dil.tproj	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,54 @@
+BuildScript: build.py
+CreationDate: '2007-10-12 09:41:17.868084'
+LangFiles: [de.cat, tr.cat, fi.cat]
+MsgIDs:
+- {ID: 0, Name: IllegalCharacter, Order: 0}
+- {ID: 1, Name: InvalidUnicodeCharacter, Order: 1}
+- {ID: 2, Name: InvalidUTF8Sequence, Order: 2}
+- {ID: 3, Name: UnterminatedCharacterLiteral, Order: 3}
+- {ID: 4, Name: EmptyCharacterLiteral, Order: 4}
+- {ID: 5, Name: ExpectedIdentifierSTLine, Order: 5}
+- {ID: 6, Name: ExpectedIntegerAfterSTLine, Order: 6}
+- {ID: 7, Name: ExpectedFilespec, Order: 7}
+- {ID: 8, Name: UnterminatedFilespec, Order: 8}
+- {ID: 9, Name: UnterminatedSpecialToken, Order: 9}
+- {ID: 10, Name: UnterminatedString, Order: 10}
+- {ID: 11, Name: NonHexCharInHexString, Order: 11}
+- {ID: 12, Name: OddNumberOfDigitsInHexString, Order: 12}
+- {ID: 13, Name: UnterminatedHexString, Order: 13}
+- {ID: 14, Name: UnterminatedBlockComment, Order: 14}
+- {ID: 15, Name: UnterminatedNestedComment, Order: 15}
+- {ID: 16, Name: UnterminatedRawString, Order: 16}
+- {ID: 17, Name: UnterminatedBackQuoteString, Order: 17}
+- {ID: 18, Name: UndefinedEscapeSequence, Order: 18}
+- {ID: 19, Name: InvalidUnicodeEscapeSequence, Order: 19}
+- {ID: 20, Name: InsufficientHexDigits, Order: 20}
+- {ID: 21, Name: UndefinedHTMLEntity, Order: 21}
+- {ID: 22, Name: UnterminatedHTMLEntity, Order: 22}
+- {ID: 23, Name: InvalidBeginHTMLEntity, Order: 23}
+- {ID: 24, Name: OverflowDecimalSign, Order: 24}
+- {ID: 25, Name: OverflowDecimalNumber, Order: 25}
+- {ID: 26, Name: OverflowHexNumber, Order: 26}
+- {ID: 27, Name: OverflowBinaryNumber, Order: 27}
+- {ID: 28, Name: OverflowOctalNumber, Order: 28}
+- {ID: 29, Name: OverflowFloatNumber, Order: 29}
+- {ID: 30, Name: OctalNumberHasDecimals, Order: 30}
+- {ID: 31, Name: NoDigitsInHexNumber, Order: 31}
+- {ID: 32, Name: NoDigitsInBinNumber, Order: 32}
+- {ID: 33, Name: HexFloatExponentRequired, Order: 33}
+- {ID: 34, Name: HexFloatExpMustStartWithDigit, Order: 34}
+- {ID: 35, Name: FloatExpMustStartWithDigit, Order: 35}
+- {ID: 36, Name: ExpectedButFound, Order: 36}
+- {ID: 37, Name: RedundantStorageClass, Order: 37}
+- {ID: 38, Name: TemplateTupleParameter, Order: 38}
+- {ID: 39, Name: InContract, Order: 39}
+- {ID: 40, Name: OutContract, Order: 40}
+- {ID: 41, Name: MissingLinkageType, Order: 41}
+- {ID: 42, Name: UnrecognizedLinkageType, Order: 42}
+- {ID: 43, Name: ExpectedBaseClasses, Order: 43}
+- {ID: 44, Name: BaseClassInForwardDeclaration, Order: 44}
+- {ID: 45, Name: HelpMain, Order: 45}
+- {ID: 46, Name: HelpGenerate, Order: 46}
+- {ID: 47, Name: HelpImportGraph, Order: 47}
+Name: dil
+SourceLangFile: en.cat
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/i18n/en.cat	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,90 @@
+Authors:
+- {EMail: aziz.koeksal@gmail.com, Name: Aziz Köksal}
+LangCode: en
+License: GPL3
+Messages:
+- {Annot: '', ID: 0, LastEd: 0, Text: 'illegal character found: ''{0}'''}
+- {Annot: '', ID: 1, LastEd: 0, Text: invalid Unicode character.}
+- {Annot: '', ID: 2, LastEd: 0, Text: invalid UTF-8 sequence.}
+- {Annot: '', ID: 3, LastEd: 0, Text: unterminated character literal.}
+- {Annot: '', ID: 4, LastEd: 0, Text: empty character literal.}
+- {Annot: '', ID: 5, LastEd: 0, Text: expected 'line' after '#'.}
+- {Annot: '', ID: 6, LastEd: 0, Text: 'integer expected after #line'}
+- {Annot: '', ID: 7, LastEd: 0, Text: expected filespec string (e.g. "path\to\file".)}
+- {Annot: '', ID: 8, LastEd: 0, Text: unterminated filespec string.}
+- {Annot: '', ID: 9, LastEd: 0, Text: expected a terminating newline after special
+    token.}
+- {Annot: '', ID: 10, LastEd: 0, Text: unterminated string literal.}
+- {Annot: '', ID: 11, LastEd: 0, Text: 'non-hex character ''{0}'' found in hex string.'}
+- {Annot: '', ID: 12, LastEd: 0, Text: odd number of hex digits in hex string.}
+- {Annot: '', ID: 13, LastEd: 0, Text: unterminated hex string.}
+- {Annot: '', ID: 14, LastEd: 0, Text: unterminated block comment (/* */).}
+- {Annot: '', ID: 15, LastEd: 0, Text: unterminated nested comment (/+ +/).}
+- {Annot: '', ID: 16, LastEd: 0, Text: unterminated raw string.}
+- {Annot: '', ID: 17, LastEd: 0, Text: unterminated back quote string.}
+- {Annot: '', ID: 18, LastEd: 0, Text: 'found undefined escape sequence ''{0}''.'}
+- {Annot: '', ID: 19, LastEd: 0, Text: 'found invalid Unicode escape sequence ''{0}''.'}
+- {Annot: '', ID: 20, LastEd: 0, Text: insufficient number of hex digits in escape
+    sequence.}
+- {Annot: '', ID: 21, LastEd: 0, Text: 'undefined HTML entity ''{0}'''}
+- {Annot: '', ID: 22, LastEd: 0, Text: 'unterminated HTML entity ''{0}''.'}
+- {Annot: '', ID: 23, LastEd: 0, Text: HTML entities must begin with a letter.}
+- {Annot: '', ID: 24, LastEd: 0, Text: decimal number overflows sign bit.}
+- {Annot: '', ID: 25, LastEd: 0, Text: overflow in decimal number.}
+- {Annot: '', ID: 26, LastEd: 0, Text: overflow in hexadecimal number.}
+- {Annot: '', ID: 27, LastEd: 0, Text: overflow in binary number.}
+- {Annot: '', ID: 28, LastEd: 0, Text: overflow in octal number.}
+- {Annot: '', ID: 29, LastEd: 0, Text: overflow in float number.}
+- {Annot: '', ID: 30, LastEd: 0, Text: digits 8 and 9 are not allowed in octal numbers.}
+- {Annot: '', ID: 31, LastEd: 0, Text: invalid hex number; at least one hex digit
+    expected.}
+- {Annot: '', ID: 32, LastEd: 0, Text: invalid binary number; at least one binary
+    digit expected.}
+- {Annot: '', ID: 33, LastEd: 0, Text: the exponent of a hexadecimal float number
+    is required.}
+- {Annot: '', ID: 34, LastEd: 0, Text: hexadecimal float exponents must start with
+    a digit.}
+- {Annot: '', ID: 35, LastEd: 0, Text: exponents must start with a digit.}
+- {Annot: '', ID: 36, LastEd: 0, Text: 'expected ''{0}'', but found ''{1}''.'}
+- {Annot: '', ID: 37, LastEd: 0, Text: '''{0}'' is redundant.'}
+- {Annot: '', ID: 38, LastEd: 0, Text: template tuple parameters can only be last.}
+- {Annot: '', ID: 39, LastEd: 0, Text: the functions 'in' contract was already parsed.}
+- {Annot: '', ID: 40, LastEd: 0, Text: the functions 'out' contract was already parsed.}
+- {Annot: '', ID: 41, LastEd: 0, Text: no linkage type was specified.}
+- {Annot: '', ID: 42, LastEd: 0, Text: 'unrecognized linkage type ''{0}''; valid types
+    are C, C++, D, Windows, Pascal und System.'}
+- {Annot: '', ID: 43, LastEd: 0, Text: 'expected one or more base classes, not ''{0}''.'}
+- {Annot: '', ID: 44, LastEd: 0, Text: base classes are not allowed in forward declarations.}
+- {Annot: '', ID: 45, LastEd: 0, Text: 'dil v{0}
+
+    Copyright (c) 2007 by Aziz Köksal. Licensed under the GPL3.
+
+
+    Subcommands:
+
+    {1}
+
+    Type ''dil help <subcommand>'' for more help on a particular subcommand.
+
+
+    Compiled with {2} v{3} on {4}.'}
+- {Annot: '', ID: 46, LastEd: 0, Text: "Generate an XML or HTML document from a D\
+    \ source file.\nUsage:\n  dil gen file.d [Options]\n\nOptions:\n  --syntax   \
+    \      : generate tags for the syntax tree\n  --xml            : use XML format\
+    \ (default)\n  --html           : use HTML format\n\nExample:\n  dil gen Parser.d\
+    \ --html --syntax > Parser.html"}
+- {Annot: '', ID: 47, LastEd: 0, Text: "Parse a module and extract information from\
+    \ the resulting module dependency graph.\nUsage:\n  dil igraph file.d Format [Options]\n\
+    \n  The directory of file.d is implicitly added to the list of import paths.\n\
+    \nFormat:\n  --dot            : generate a dot document\n  Further options for\
+    \ --dot:\n  -gbp             : Group modules by package names\n  -gbf        \
+    \     : Group modules by full package name\n  -hle             : highlight cyclic\
+    \ edges in the graph\n  -hlv             : highlight modules in cyclic relationship\n\
+    \n  --paths          : print a list of paths to the modules imported by file.d\n\
+    \  --list           : print a list of the module names imported by file.d\n  Options\
+    \ common to --paths and --list:\n  -lN              : print N levels.\n  -m  \
+    \             : mark modules in cyclic relationships with a star.\n\nOptions:\n\
+    \  -Ipath           : add 'path' to the list of import paths where modules are\n\
+    \                     looked for\n  -rREGEXP         : exclude modules whose names\
+    \ match the regular expression\n                     REGEXP\n  -i            \
+    \   : include unlocatable modules\n\nExample:\n  dil igraph src/main.d"}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/i18n/fi.cat	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,76 @@
+Authors:
+- {EMail: jmjm@iki.fi, Name: Jari-Matti Mäkelä}
+LangCode: fi
+License: GPL3
+Messages:
+- {Annot: '', ID: 0, LastEd: 0, Text: ''}
+- {Annot: '', ID: 1, LastEd: 0, Text: virheellinen Unicode-merkki.}
+- {Annot: '', ID: 2, LastEd: 0, Text: virheellinen UTF-8-merkkijono.}
+- {Annot: '', ID: 3, LastEd: 0, Text: päättämätön merkkiliteraali.}
+- {Annot: '', ID: 4, LastEd: 0, Text: tyhjä merkkiliteraali.}
+- {Annot: '', ID: 5, LastEd: 0, Text: 'odotettiin rivinumeroa ''#'':n jälkeen.'}
+- {Annot: '', ID: 6, LastEd: 0, Text: 'odotettiin kokonaislukua #line:n jälkeen'}
+- {Annot: '', ID: 7, LastEd: 0, Text: odotettiin tiedostomäärittelyn merkkijonoa (esim.
+    "polku\tiedostoon")}
+- {Annot: '', ID: 8, LastEd: 0, Text: päättämätön tiedostomäärittely.}
+- {Annot: '', ID: 9, LastEd: 0, Text: odotettiin päättävää rivinvaihtoa erikoismerkin
+    jälkeen.}
+- {Annot: '', ID: 10, LastEd: 0, Text: päättämätön merkkijonoliteraali.}
+- {Annot: '', ID: 11, LastEd: 0, Text: 'ei-heksamerkki ''{0}'' löytyi heksajonossa.'}
+- {Annot: '', ID: 12, LastEd: 0, Text: pariton määrä heksanumeroita heksajonossa.}
+- {Annot: '', ID: 13, LastEd: 0, Text: päättämätön heksajono.}
+- {Annot: '', ID: 14, LastEd: 0, Text: päättämätön lohkokommentti (/* */).}
+- {Annot: '', ID: 15, LastEd: 0, Text: päättämätön sisäkkäinen kommentti (/+ +/).}
+- {Annot: '', ID: 16, LastEd: 0, Text: päättämätön raakamerkkijono.}
+- {Annot: '', ID: 17, LastEd: 0, Text: päättämätön gravisaksenttimerkkijono.}
+- {Annot: '', ID: 18, LastEd: 0, Text: löydettiin määrittelemätön escape-sekvenssi.}
+- {Annot: '', ID: 19, LastEd: 0, Text: 'found invalid Unicode escape sequence ''{0}''.'}
+- {Annot: '', ID: 20, LastEd: 0, Text: riittämätön määrä heksanumeroita escape-sekvenssissä.}
+- {Annot: '', ID: 21, LastEd: 0, Text: 'määrittelemätön HTML-entiteetti ''{0}'''}
+- {Annot: '', ID: 22, LastEd: 0, Text: päättämätön HTML-entiteetti.}
+- {Annot: '', ID: 23, LastEd: 0, Text: HTML-entiteettien tulee alkaa kirjaimella.}
+- {Annot: '', ID: 24, LastEd: 0, Text: desimaaliluku ylivuotaa etumerkin.}
+- {Annot: '', ID: 25, LastEd: 0, Text: desimaaliluvun ylivuoto.}
+- {Annot: '', ID: 26, LastEd: 0, Text: heksadesimaaliluvun ylivuoto.}
+- {Annot: '', ID: 27, LastEd: 0, Text: binääriluvun ylivuoto.}
+- {Annot: '', ID: 28, LastEd: 0, Text: oktaaliluvun ylivuoto.}
+- {Annot: '', ID: 29, LastEd: 0, Text: liukuluvun ylivuoto.}
+- {Annot: '', ID: 30, LastEd: 0, Text: numerot 8 ja 9 eivät ole sallittuja oktaaliluvuissa.}
+- {Annot: '', ID: 31, LastEd: 0, Text: virheellinen heksaluku; odotettiin vähintään
+    yhtä heksanumeroa.}
+- {Annot: '', ID: 32, LastEd: 0, Text: virheellinen binääriluku; odotettiin vähintään
+    yhtä binäärinumeroa.}
+- {Annot: '', ID: 33, LastEd: 0, Text: heksadesimaalisen liukuluvun eksponentti vaaditaan.}
+- {Annot: '', ID: 34, LastEd: 0, Text: heksadesimaalisen liukuluvun eksponentista
+    puuttui numeroita.}
+- {Annot: '', ID: 35, LastEd: 0, Text: eksponenttien tulee alkaa numerolla.}
+- {Annot: '', ID: 36, LastEd: 0, Text: 'odotettiin ''{0}'':a, mutta löydettiin ''{1}''.'}
+- {Annot: '', ID: 37, LastEd: 0, Text: '''{0}'' on redundantti.'}
+- {Annot: '', ID: 38, LastEd: 0, Text: tupla voi esiintyä ainoastaan mallin viimeisenä
+    parametrina.}
+- {Annot: '', ID: 39, LastEd: 0, Text: funktion alkuehto jäsennettiin jo.}
+- {Annot: '', ID: 40, LastEd: 0, Text: funktion loppuehto jäsennettiin jo.}
+- {Annot: '', ID: 41, LastEd: 0, Text: linkitystyyppiä ei määritelty.}
+- {Annot: '', ID: 42, LastEd: 0, Text: 'tunnistamaton linkitystyyppi ''{0}''; sallittuja
+    tyyppejä ovat C, C++, D, Windows, Pascal ja System.'}
+- {Annot: '', ID: 43, LastEd: 0, Text: 'expected one or more base classes, not ''{0}''.'}
+- {Annot: '', ID: 44, LastEd: 0, Text: base classes are not allowed in forward declarations.}
+- {Annot: '', ID: 45, LastEd: 0, Text: 'dil v{0}
+
+    Copyright (c) 2007, Aziz Köksal. GPL3-lisensöity.
+
+
+    Alikomennot:
+
+    {1}
+
+    Lisäohjeita tietystä alitoiminnosta saa kirjoittamalla ''dil help <toiminto>''.
+
+
+    Käännetty {2}:n versiolla {3} {4}.'}
+- {Annot: '', ID: 46, LastEd: 0, Text: "Luo XML- tai HTML-dokumentti D-lähdekoodista.\n\
+    Käyttö:\n  dil gen tiedosto.d [Valinnat]\n\nValinnat:\n  --syntax         : luo\
+    \ elementtejä syntaksipuun mukaisesti\n  --xml            : käytä XML-muotoa (oletus)\n\
+    \  --html           : käytä HTML-muotoa\n\nEsimerkki:\n  dil gen Parser.d --html\
+    \ --syntax > Parser.html"}
+- {Annot: '', ID: 47, LastEd: 0, Text: ''}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/i18n/tr.cat	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,73 @@
+Authors:
+- {EMail: aziz.koeksal@gmail.com, Name: Aziz Köksal}
+LangCode: tr
+License: GPL3
+Messages:
+- {Annot: '', ID: 0, LastEd: 0, Text: 'illegal karakter bulundu: ''{0}'''}
+- {Annot: '', ID: 1, LastEd: 0, Text: geçersiz Unikod karakteri.}
+- {Annot: '', ID: 2, LastEd: 0, Text: geçersiz UTF-8 serisi.}
+- {Annot: '', ID: 3, LastEd: 0, Text: kapanmamış karakter sabiti.}
+- {Annot: '', ID: 4, LastEd: 0, Text: boş karakter sabiti.}
+- {Annot: '', ID: 5, LastEd: 0, Text: '''#'' karakter''den sonra ''line'' beklendi.'}
+- {Annot: '', ID: 6, LastEd: 0, Text: '''#line''''den sonra rakam beklendi.'}
+- {Annot: '', ID: 7, LastEd: 0, Text: filespec dizgisi beklendi (e.g. "yol\dosya".)}
+- {Annot: '', ID: 8, LastEd: 0, Text: kapanmamış filespec dizgisi.}
+- {Annot: '', ID: 9, LastEd: 0, Text: özel belirtici'den (special token) sonra yeni
+    bir satır beklendi.}
+- {Annot: '', ID: 10, LastEd: 0, Text: kapanmamış çift tırnak dizgisi.}
+- {Annot: '', ID: 11, LastEd: 0, Text: 'heks sayı olmayan karakter ''{0}'' heks dizgisi
+    içinde bulundu.'}
+- {Annot: '', ID: 12, LastEd: 0, Text: heks dizginin içindeki sayılar çifter çifter
+    olmalıdır.}
+- {Annot: '', ID: 13, LastEd: 0, Text: kapanmamış heks dizgisi.}
+- {Annot: '', ID: 14, LastEd: 0, Text: kapanmamış blok açıklaması (/* */).}
+- {Annot: '', ID: 15, LastEd: 0, Text: kapanmamış iç içe koyulabilen açıklaması (/+
+    +/).}
+- {Annot: '', ID: 16, LastEd: 0, Text: kapanmamış çiğ dizgisi.}
+- {Annot: '', ID: 17, LastEd: 0, Text: kapanmamış ters tırnak dizgisi.}
+- {Annot: '', ID: 18, LastEd: 0, Text: 'tanımlanmamış çıkış serisi ''{0}'' bulundu.'}
+- {Annot: '', ID: 19, LastEd: 0, Text: 'geçersiz Unikod çıkış serisi ''{0}'' bulundu.'}
+- {Annot: '', ID: 20, LastEd: 0, Text: heksadesimal çıkış serisi sayıları yeterli
+    değil.}
+- {Annot: '', ID: 21, LastEd: 0, Text: 'tanımlanmamış HTML varlık ''{0}'''}
+- {Annot: '', ID: 22, LastEd: 0, Text: 'kapanmamış HTML varlık ''{0}''.'}
+- {Annot: '', ID: 23, LastEd: 0, Text: HTML varlık bir harf ile başlamalı.}
+- {Annot: '', ID: 24, LastEd: 0, Text: desimal rakamın bit işareti taşdı.}
+- {Annot: '', ID: 25, LastEd: 0, Text: desimal rakam taşması.}
+- {Annot: '', ID: 26, LastEd: 0, Text: heksadesimal rakam taşması.}
+- {Annot: '', ID: 27, LastEd: 0, Text: binari rakam taşması.}
+- {Annot: '', ID: 28, LastEd: 0, Text: oktal rakam taşması.}
+- {Annot: '', ID: 29, LastEd: 0, Text: float rakam taşması.}
+- {Annot: '', ID: 30, LastEd: 0, Text: 8 ve 9 sayılar oktal rakamlar'da geçersizdir.}
+- {Annot: '', ID: 31, LastEd: 0, Text: geçersiz heks rakam; minimum bir heks sayı
+    gereklidir.}
+- {Annot: '', ID: 32, LastEd: 0, Text: geçersiz binari rakam; minimum bir binari sayı
+    gereklidir.}
+- {Annot: '', ID: 33, LastEd: 0, Text: bir heksadesimal float rakamın üsü gereklidir.}
+- {Annot: '', ID: 34, LastEd: 0, Text: heksadesimal float üsler desimal sayı ile başlamalı.}
+- {Annot: '', ID: 35, LastEd: 0, Text: üsler desimal sayı ile başlamalı.}
+- {Annot: '', ID: 36, LastEd: 0, Text: '''{0}'' beklendi, ama ''{1}'' bulundu.'}
+- {Annot: '', ID: 37, LastEd: 0, Text: '''{0}'' lüzumsuz.'}
+- {Annot: '', ID: 38, LastEd: 0, Text: şablon tuple parametre son sırada olmalı.}
+- {Annot: '', ID: 39, LastEd: 0, Text: fonksiyonun 'in' kontratı daha önceden ayrıştırılmış.}
+- {Annot: '', ID: 40, LastEd: 0, Text: fonksiyonun 'out' kontratı daha önceden ayrıştırılmış.}
+- {Annot: '', ID: 41, LastEd: 0, Text: bağlantı tüp (linkage type) belirtilmedi.}
+- {Annot: '', ID: 42, LastEd: 0, Text: 'bilinmeyen bağlantı tüpü (linkage type) ''{0}'';
+    geçerli olanlar C, C++, D, Windows, Pascal ve System.'}
+- {Annot: '', ID: 43, LastEd: 0, Text: ''}
+- {Annot: '', ID: 44, LastEd: 0, Text: ''}
+- {Annot: '', ID: 45, LastEd: 0, Text: 'dil v{0}
+
+    Copyright (c) 2007, Aziz Köksal. Lisans GPL3.
+
+
+    Komutlar: {1} Belirli komut''a yardım edinmek için ''dil help <komut>'' yazınız.
+
+
+    Bu yazılım {2} v{3} ile {4} tarihinde derletilmiş.'}
+- {Annot: '', ID: 46, LastEd: 0, Text: "Bir D kaynak kodundan XML veya HTML dosyası\
+    \ oluştur.\nKullanım:\n  dil gen dosya.d [Seçenekler]\n\nSeçenekler:\n  --syntax\
+    \         : söz dizimi için etiketler yazdır\n  --xml            : XML biçimi\
+    \ kullan (varsayılır)\n  --html           : HTML biçimi kullan\n\nÖrnek:\n  dil\
+    \ gen Parser.d --html --syntax > Parser.html"}
+- {Annot: '', ID: 47, LastEd: 0, Text: ''}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/release.py	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+# Author: Aziz Köksal
+
+# TODO: port release.sh to Python
+
+# TODO: write subcommand that creates a Makefile
+def writeMakefile():
+  pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/release.sh	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,96 @@
+#!/bin/bash
+
+if [[ $1 != [0-9].[0-9][0-9][0-9] ]]; then
+  echo Wrong version format. Expected: d.ddd
+  exit;
+fi
+
+BUILD="./build"
+DIR="dil.$1"
+DEST="$BUILD/$DIR"
+FRESH_REPOS="$BUILD/fresh_repos"
+
+# Create build directory if it doesn't exist.
+[ ! -e $BUILD ] && mkdir $BUILD
+
+# Convert Unix newlines to Windows newlines
+# function unix2win
+# {
+#   sed {s/$/\\r/} $*
+# }
+
+# We need dil to get a list of all modules to be compiled.
+if [ ! -s ./dil ]; then
+  dsss build -full &> /dev/null
+fi
+
+if [ ! -s ./dil ]; then
+  echo "Couldn't build DIL. Can't get list of modules to be built."
+  exit;
+fi
+
+# Used by doc generation and winbuild function.
+SRC_FILES=`./dil igraph src/main.d --paths`
+
+# Recreate destination directory.
+rm -rf $DEST
+mkdir -p $DEST/{bin,doc/htmlsrc,src}
+
+# Create documentation.
+./dil ddoc $DEST/doc/ -v src/macros_dil.ddoc -version=DDoc src/config.d $SRC_FILES
+# Generate syntax highlighted HTML files.
+HTMLSRC="$DEST/doc/htmlsrc"
+for filepath in $SRC_FILES;
+do
+  htmlfile=`echo $filepath | sed -e 's@^src/@@' -e 's@/@.@g' -e 's@.d$@@'`.html
+  echo "FILE: $filepath > $HTMLSRC/$htmlfile";
+  ./dil gen --lines --syntax --html $filepath > "$HTMLSRC/$htmlfile";
+done
+
+# Linux Debug
+echo "***** Building Linux binaries *****"
+dsss build -clean -full -version=D2
+cp dil $DEST/bin/dil2_d
+dsss build -clean -full
+cp dil $DEST/bin/dil_d
+# Linux Release
+dsss build -clean -full -release -O -inline -version=D2
+cp dil $DEST/bin/dil2
+dsss build -clean -full -release -O -inline
+cp dil $DEST/bin/dil
+
+if [ -s ~/bin/dmd.exe ]; then
+  echo "***** Building Windows binaries *****"
+  function winbuild
+  { # obj dir is winobj. -op = don't strip paths from obj files.
+    wine ~/bin/dmd.exe -odwinobj -op -ofdil $* $SRC_FILES
+  }
+  # Windows Debug
+  winbuild -version=D2
+  cp dil.exe $DEST/bin/dil2_d.exe
+  winbuild
+  cp dil.exe $DEST/bin/dil_d.exe
+  # Windows Release
+  winbuild -release -O -inline -version=D2
+  cp dil.exe $DEST/bin/dil2.exe
+  winbuild -release -O -inline
+  cp dil.exe $DEST/bin/dil.exe
+fi
+
+# Copy source and other files.
+rm -rf $FRESH_REPOS
+hg archive -r tip -t files $FRESH_REPOS
+cp -r $FRESH_REPOS/trunk/* $DEST
+
+cp $FRESH_REPOS/trunk/src/config.d $DEST/bin/
+cp $FRESH_REPOS/trunk/src/lang_*.d $DEST/bin/
+cp $FRESH_REPOS/trunk/src/*_map.d $DEST/bin/
+cp $FRESH_REPOS/trunk/src/*.css $DEST/bin/
+cp $FRESH_REPOS/trunk/src/predefined.ddoc $DEST/bin/
+cp $FRESH_REPOS/trunk/src/html.css $HTMLSRC
+
+# Build archives
+# tar.gz doesn't compress well
+tar --owner root --group root -czf $DEST.tar.gz $DEST
+tar --owner root --group root --bzip2 -cf $DEST.tar.bz2 $DEST
+zip -q -9 -r $DEST.zip $DEST
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Settings.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,29 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module Settings;
+import common;
+
+/// Global application settings.
+struct GlobalSettings
+{
+static:
+  /// Predefined version identifiers.
+  string[] versionIds;
+  /// Path to the language file.
+  string langFile = "lang_en.d";
+  /// Language code of loaded messages catalogue.
+  string langCode = "en";
+  /// Table of localized compiler messages.
+  string[] messages;
+  /// Array of import paths to look for modules.
+  string[] importPaths;
+  /// Array of DDoc macro file paths.
+  string[] ddocFilePaths;
+  string xmlMapFile = "xml_map.d"; /// XML map file.
+  string htmlMapFile = "html_map.d"; /// HTML map file.
+  string lexerErrorFormat = "{0}({1},{2})L: {3}"; /// Lexer error.
+  string parserErrorFormat = "{0}({1},{2})P: {3}"; /// Parser error.
+  string semanticErrorFormat = "{0}({1},{2})S: {3}"; /// Semantic error.
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/SettingsLoader.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,252 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module SettingsLoader;
+
+import Settings;
+import dil.Messages;
+import dil.ast.Node, dil.ast.Declarations, dil.ast.Expressions;
+import dil.semantic.Module;
+import dil.semantic.Pass1;
+import dil.semantic.Symbol;
+import dil.semantic.Symbols;
+import dil.Information;
+import dil.Compilation;
+import common;
+
+import tango.io.FilePath;
+
+/// Loads settings from a D module file.
+class SettingsLoader
+{
+  InfoManager infoMan; /// Collects error messages.
+  Module mod; /// Current module.
+
+  this(InfoManager infoMan)
+  {
+    this.infoMan = infoMan;
+  }
+
+  static SettingsLoader opCall(InfoManager infoMan)
+  {
+    return new SettingsLoader(infoMan);
+  }
+
+  /// Creates an error report.
+  /// Params:
+  ///   token = where the error occurred.
+  ///   formatMsg = error message.
+  void error(Token* token, char[] formatMsg, ...)
+  {
+    auto location = token.getErrorLocation();
+    auto msg = Format(_arguments, _argptr, formatMsg);
+    infoMan ~= new SemanticError(location, msg);
+  }
+
+  T getValue(T)(char[] name)
+  {
+    auto var = mod.lookup(name);
+    if (!var) // Returning T.init instead of null, because dmd gives an error.
+      return error(mod.firstToken, "variable '{}' is not defined", name), T.init;
+    auto t = var.node.begin;
+    if (!var.isVariable)
+      return error(t, "'{}' is not a variable declaration", name), T.init;
+    auto value = var.to!(Variable).value;
+    if (!value)
+      return error(t, "'{}' variable has no value set", name), T.init;
+    T val = value.Is!(T); // Try casting to T.
+    if (!val)
+      error(value.begin, "the value of '{}' is not of type {}", name, typeof(T).stringof);
+    return val;
+  }
+
+  T castTo(T)(Node n)
+  {
+    char[] type;
+    is(T == StringExpression) && (type = "char[]");
+    if (!n.Is!(T))
+      error(n.begin, "expression is not of type {}", type);
+    return n.Is!(T);
+  }
+
+  void load()
+  {
+    scope execPath = new FilePath(GetExecutableFilePath());
+    execPath = new FilePath(execPath.folder());
+
+    // Load config.d
+    auto filePath = resolvePath(execPath, "config.d");
+    mod = new Module(filePath, infoMan);
+    mod.parse();
+
+    if (mod.hasErrors)
+      return;
+
+    auto context = new CompilationContext;
+    auto pass1 = new SemanticPass1(mod, context);
+    pass1.start();
+
+    if (auto array = getValue!(ArrayInitExpression)("version_ids"))
+      foreach (value; array.values)
+        if (auto str = castTo!(StringExpression)(value))
+          GlobalSettings.versionIds ~= str.getString();
+    if (auto val = getValue!(StringExpression)("langfile"))
+      GlobalSettings.langFile = val.getString();
+    if (auto array = getValue!(ArrayInitExpression)("import_paths"))
+      foreach (value; array.values)
+        if (auto str = castTo!(StringExpression)(value))
+          GlobalSettings.importPaths ~= str.getString();
+    if (auto array = getValue!(ArrayInitExpression)("ddoc_files"))
+      foreach (value; array.values)
+        if (auto str = castTo!(StringExpression)(value))
+          GlobalSettings.ddocFilePaths ~= resolvePath(execPath, str.getString());
+    if (auto val = getValue!(StringExpression)("xml_map"))
+      GlobalSettings.xmlMapFile = val.getString();
+    if (auto val = getValue!(StringExpression)("html_map"))
+      GlobalSettings.htmlMapFile = val.getString();
+    if (auto val = getValue!(StringExpression)("lexer_error"))
+      GlobalSettings.lexerErrorFormat = val.getString();
+    if (auto val = getValue!(StringExpression)("parser_error"))
+      GlobalSettings.parserErrorFormat = val.getString();
+    if (auto val = getValue!(StringExpression)("semantic_error"))
+      GlobalSettings.semanticErrorFormat = val.getString();
+
+    // Load language file.
+    filePath = resolvePath(execPath, GlobalSettings.langFile);
+    mod = new Module(filePath);
+    mod.parse();
+
+    if (mod.hasErrors)
+      return;
+
+    pass1 = new SemanticPass1(mod, context);
+    pass1.start();
+
+    if (auto array = getValue!(ArrayInitExpression)("messages"))
+    {
+      char[][] messages;
+      foreach (value; array.values)
+        if (auto str = castTo!(StringExpression)(value))
+          messages ~= str.getString();
+      if (messages.length != MID.max+1)
+        error(mod.firstToken,
+              "messages table in {} must exactly have {} entries, but not {}.",
+              filePath, MID.max+1, messages.length);
+      GlobalSettings.messages = messages;
+      dil.Messages.SetMessages(messages);
+    }
+    if (auto val = getValue!(StringExpression)("lang_code"))
+      GlobalSettings.langCode = val.getString();
+  }
+}
+
+/// Loads an associative array from a D module file.
+class TagMapLoader : SettingsLoader
+{
+  this(InfoManager infoMan)
+  {
+    super(infoMan);
+  }
+
+  static TagMapLoader opCall(InfoManager infoMan)
+  {
+    return new TagMapLoader(infoMan);
+  }
+
+  string[string] load(string filePath)
+  {
+    mod = new Module(filePath, infoMan);
+    mod.parse();
+    if (mod.hasErrors)
+      return null;
+
+    auto context = new CompilationContext;
+    auto pass1 = new SemanticPass1(mod, context);
+    pass1.start();
+
+    string[string] map;
+    if (auto array = getValue!(ArrayInitExpression)("map"))
+      foreach (i, value; array.values)
+      {
+        auto key = array.keys[i];
+        if (auto valExp = castTo!(StringExpression)(value))
+          if (!key)
+            error(value.begin, "expected key : value");
+          else if (auto keyExp = castTo!(StringExpression)(key))
+            map[keyExp.getString()] = valExp.getString();
+      }
+    return map;
+  }
+}
+
+/// Resolves the path to a file from the executable's dir path
+/// if it is relative.
+/// Returns: filePath if it is absolute or execPath + filePath.
+string resolvePath(FilePath execPath, string filePath)
+{
+  if ((new FilePath(filePath)).isAbsolute())
+    return filePath;
+  return execPath.dup.append(filePath).toString();
+}
+
+version(DDoc)
+{
+  /// Returns the fully qualified path to this executable.
+  char[] GetExecutableFilePath();
+}
+else version(Windows)
+{
+private extern(Windows) uint GetModuleFileNameA(void*, char*, uint);
+
+char[] GetExecutableFilePath()
+{
+  alias GetModuleFileNameA GetModuleFileName;
+  char[] buffer = new char[256];
+  uint count;
+
+  while (1)
+  {
+    if (buffer is null)
+      return null;
+
+    count = GetModuleFileName(null, buffer.ptr, buffer.length);
+    if (count == 0)
+      return null;
+    if (buffer.length != count && buffer[count] == 0)
+      break;
+    // Increase size of buffer
+    buffer.length = buffer.length * 2;
+  }
+  assert(buffer[count] == 0);
+  // Reduce buffer to the actual length of the string (excluding '\0'.)
+  if (count < buffer.length)
+    buffer.length = count;
+  return buffer;
+}
+}
+else version(linux)
+{
+private extern(C) size_t readlink(char* path, char* buf, size_t bufsize);
+
+char[] GetExecutableFilePath()
+{
+  char[] buffer = new char[256];
+  size_t count;
+
+  while (1)
+  {
+    // This won't work on very old Linux systems.
+    count = readlink("/proc/self/exe".ptr, buffer.ptr, buffer.length);
+    if (count == -1)
+      return null;
+    if (count < buffer.length)
+      break;
+    buffer.length = buffer.length * 2;
+  }
+  buffer.length = count;
+  return buffer;
+}
+}
+else
+  static assert(0, "GetExecutableFilePath() is not implemented on this platform.");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/TypeRules.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,129 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module TypeRules;
+
+import cmd.Generate : xml_escape;
+
+import TypeRulesData;
+import common;
+
+static const string[] basicTypes = [
+  "char"[],   "wchar",   "dchar", "bool",
+  "byte",   "ubyte",   "short", "ushort",
+  "int",    "uint",    "long",  "ulong",
+  /+"cent",   "ucent",+/
+  "float",  "double",  "real",
+  "ifloat", "idouble", "ireal",
+  "cfloat", "cdouble", "creal"/+, "void"+/
+];
+
+static const string[] unaryExpressions = [
+  "!x",
+  "&x",
+  "~x",
+  "+x",
+  "-x",
+  "++x",
+  "--x",
+  "x++",
+  "x--",
+];
+
+static const string[] binaryExpressions = [
+  "x!<>=y",
+  "x!<>y",
+  "x!<=y",
+  "x!<y",
+  "x!>=y",
+  "x!>y",
+  "x<>=y",
+  "x<>y",
+
+  "x=y", "x==y", "x!=y",
+  "x<=y", "x<y",
+  "x>=y", "x>y",
+  "x<<=y", "x<<y",
+  "x>>=y","x>>y",
+  "x>>>=y", "x>>>y",
+  "x|=y", "x||y", "x|y",
+  "x&=y", "x&&y", "x&y",
+  "x+=y", "x+y",
+  "x-=y", "x-y",
+  "x/=y", "x/y",
+  "x*=y", "x*y",
+  "x%=y", "x%y",
+  "x^=y", "x^y",
+  "x~=y",
+  "x~y",
+  "x,y"
+];
+
+void genHTMLTypeRulesTables()
+{
+  Stdout(
+    `<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">`\n
+    `<html>`\n
+    `<head>`\n
+    `  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">`\n
+    `  <link href="" rel="stylesheet" type="text/css">`\n
+    `  <style type="text/css">`\n
+    `    .E { color: darkred; } /* Error */`\n
+    `    .R { font-size: 0.8em; } /* Result */`\n
+    `    .X { color: darkorange; }`\n
+    `    .Y { color: darkblue; }`\n
+    `  </style>`\n
+    `</head>`\n
+    `<body>`\n
+    `<p>These tables show what the type results of certain expressions are.</p>`\n
+  );
+
+  Stdout.format("<table>\n<tr><th colspan=\"{}\">Unary Expressions</th></tr>\n", unaryExpressions.length);
+  Stdout("<tr><td><!--typecol--></td>");
+  foreach (unaryExpression; unaryExpressions)
+    Stdout.format("<td>{}</td>", {
+      if (unaryExpression[0] == 'x')
+        return `<span class="X">x</span>` ~ xml_escape(unaryExpression[1..$]);
+      else
+        return xml_escape(unaryExpression[0..$-1]) ~ `<span class="X">x</span>`;
+    }());
+  Stdout("</tr>\n");
+  foreach (i, basicType; basicTypes)
+  {
+    Stdout.format("<tr>\n"`<td class="X">{}</td>`, basicType);
+    foreach (expResults; unaryExpsResults)
+    {
+      auto result =  expResults[i];
+      Stdout.format(`<td class="R">{}</td>`, result[0] == 'E' ? `<span class="E">Error</span>`[] : result);
+    }
+    Stdout("\n<tr>\n");
+  }
+  Stdout("</table>\n");
+
+  foreach (i, expResults; binaryExpsResults)
+  {
+    auto binaryExpression = binaryExpressions[i];
+    binaryExpression = `<span class="X">x</span> ` ~
+                       xml_escape(binaryExpression[1..$-1]) ~
+                       ` <span class="Y">y</span>`;
+    Stdout.format("<table>\n<tr><th colspan=\"{}\">{}</th></tr>\n", basicTypes.length, binaryExpression);
+    Stdout.format("<tr><td><!--typecol--></td>");
+    foreach (basicType; basicTypes)
+      Stdout.format(`<td class="Y">{}</td>`, basicType);
+    Stdout("\n<tr>\n");
+    foreach (j, results; expResults)
+    {
+      Stdout.format("<tr>\n"`<td class="X">{}</td>`, basicTypes[j]);
+      foreach (result; results)
+        Stdout.format(`<td class="R">{}</td>`, result[0] == 'E' ? `<span class="E">Error</span>`[] : result);
+      Stdout("\n<tr>\n");
+    }
+    Stdout("</table>\n");
+  }
+
+  Stdout(
+    "\n</body>"
+    "\n</html>"
+  );
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/TypeRulesData.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,1 @@
+// Run TypeRulesGenerator.d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/TypeRulesGenerator.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,174 @@
+#! /usr/bin/rdmd
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module TypeRulesGenerator;
+
+import tango.io.File;
+import tango.io.FilePath;
+
+alias char[] string;
+
+void main(char[][] args)
+{
+  char[] text = "// Generated by TypeRulesGenerator.d\n"
+                "module TypeRules.d;\n\n";
+  text ~= "char[][][] unaryExpsResults = [\n";
+  foreach (results; unaryExpsResults)
+  {
+    text ~= "  [";
+    foreach (result; results)
+      text ~= '"' ~ result ~ '"' ~ ", ";
+    text[$-2] = ']';
+    text[$-1] = ',';
+    text ~= \n;
+  }
+  text[$-2] = '\n';
+  text[$-1] = ']';
+  text ~= ";\n\n";
+
+  text ~= "char[][][][] binaryExpsResults = [\n";
+  foreach (expResults; binaryExpsResults)
+  {
+    text ~= "  [\n";
+    foreach (results; expResults)
+    {
+      text ~= "    [";
+      foreach (result; results)
+        text ~= '"' ~ result ~ '"' ~ ", ";
+      text[$-2] = ']';
+      text[$-1] = ',';
+      text ~= \n;
+    }
+    text[$-2] = '\n';
+    text[$-1] = ' ';
+    text ~= " ],\n";
+  }
+  text[$-2] = '\n';
+  text[$-1] = ']';
+  text ~= ";\n";
+
+  // Write the text to a D module.
+  auto file = new File("TypeRulesData.d");
+  file.write(text);
+}
+
+template ExpressionType(char[] T1, char[] T2, char[] expression)
+{
+  mixin("alias "~T1~" X;");
+  mixin("alias "~T2~" Y;");
+  X x;
+  Y y;
+  static if(is(typeof(mixin(expression)) ResultType))
+    const char[] result = ResultType.stringof;
+  else
+    const char[] result = "Error";
+}
+alias ExpressionType EType;
+
+// pragma(msg, EType!("char", "int", "&x").result);
+
+static const string[] basicTypes = [
+  "char"[],   "wchar",   "dchar", "bool",
+  "byte",   "ubyte",   "short", "ushort",
+  "int",    "uint",    "long",  "ulong",
+  /+"cent",   "ucent",+/
+  "float",  "double",  "real",
+  "ifloat", "idouble", "ireal",
+  "cfloat", "cdouble", "creal"/+, "void"+/
+];
+
+static const string[] unaryExpressions = [
+  "!x",
+  "&x",
+  "~x",
+  "+x",
+  "-x",
+  "++x",
+  "--x",
+  "x++",
+  "x--",
+];
+
+static const string[] binaryExpressions = [
+  "x!<>=y",
+  "x!<>y",
+  "x!<=y",
+  "x!<y",
+  "x!>=y",
+  "x!>y",
+  "x<>=y",
+  "x<>y",
+
+  "x=y", "x==y", "x!=y",
+  "x<=y", "x<y",
+  "x>=y", "x>y",
+  "x<<=y", "x<<y",
+  "x>>=y","x>>y",
+  "x>>>=y", "x>>>y",
+  "x|=y", "x||y", "x|y",
+  "x&=y", "x&&y", "x&y",
+  "x+=y", "x+y",
+  "x-=y", "x-y",
+  "x/=y", "x/y",
+  "x*=y", "x*y",
+  "x%=y", "x%y",
+  "x^=y", "x^y",
+  "x~=y",
+  "x~y",
+  "x,y"
+];
+
+char[] genBinaryExpArray(char[] expression)
+{
+  char[] result = "[\n";
+  foreach (t1; basicTypes)
+  {
+    result ~= "[\n";
+    foreach (t2; basicTypes)
+      result ~= `EType!("`~t1~`", "`~t2~`", "`~expression~`").result,`\n;
+    result[result.length-2] = ']'; // Overwrite last comma.
+    result[result.length-1] = ','; // Overwrite last \n.
+  }
+  result[result.length-1] = ']'; // Overwrite last comma.
+  return result;
+}
+// pragma(msg, mixin(genBinaryExpArray("x%y")).stringof);
+
+char[] genBinaryExpsArray()
+{
+  char[] result = "[\n";
+  foreach (expression; binaryExpressions)
+  {
+    result ~= genBinaryExpArray(expression);
+    result ~= ",\n";
+  }
+  result[result.length-2] = ']';
+  return result;
+}
+
+// pragma(msg, mixin(genBinaryExpsArray()).stringof);
+
+char[] genUnaryExpArray(char[] expression)
+{
+  char[] result = "[\n";
+  foreach (t1; basicTypes)
+    result ~= `EType!("`~t1~`", "int", "`~expression~`").result,`\n;
+  result[result.length-2] = ']'; // Overwrite last comma.
+  return result;
+}
+
+char[] genUnaryExpsArray()
+{
+  char[] result = "[\n";
+  foreach (expression; unaryExpressions)
+    result ~= genUnaryExpArray(expression) ~ ",\n";
+  result[result.length-2] = ']';
+  return result;
+}
+
+// pragma(msg, mixin(genUnaryExpsArray()).stringof);
+
+auto unaryExpsResults = mixin(genUnaryExpsArray());
+auto binaryExpsResults = mixin(genBinaryExpsArray());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cmd/ASTStats.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,33 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module cmd.ASTStats;
+
+import dil.ast.DefaultVisitor;
+import dil.ast.Node,
+       dil.ast.Declaration,
+       dil.ast.Statement,
+       dil.ast.Expression,
+       dil.ast.Types;
+
+/// Counts the nodes in a syntax tree.
+class ASTStats : DefaultVisitor
+{
+  uint[] table; /// Table for counting nodes.
+
+  /// Starts counting.
+  uint[] count(Node root)
+  {
+    table = new uint[g_classNames.length];
+    super.visitN(root);
+    return table;
+  }
+
+  // Override dispatch function.
+  override Node dispatch(Node n)
+  {
+    table[n.kind]++;
+    return super.dispatch(n);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cmd/DDoc.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,849 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module cmd.DDoc;
+
+import cmd.DDocXML;
+import cmd.Generate;
+import dil.doc.Parser;
+import dil.doc.Macro;
+import dil.doc.Doc;
+import dil.ast.Node;
+import dil.ast.Declarations,
+       dil.ast.Statements,
+       dil.ast.Expression,
+       dil.ast.Parameters,
+       dil.ast.Types;
+import dil.ast.DefaultVisitor;
+import dil.lexer.Token;
+import dil.lexer.Funcs;
+import dil.semantic.Module;
+import dil.semantic.Pass1;
+import dil.semantic.Symbol;
+import dil.semantic.Symbols;
+import dil.Compilation;
+import dil.Information;
+import dil.Converter;
+import dil.SourceText;
+import dil.Enums;
+import dil.Time;
+import common;
+
+import tango.text.Ascii : toUpper;
+import tango.io.File;
+import tango.io.FilePath;
+
+/// Executes the doc generation command.
+void execute(string[] filePaths, string destDir, string[] macroPaths,
+             bool writeXML, bool incUndoc, bool verbose,
+             CompilationContext context, InfoManager infoMan)
+{
+  // Parse macro files.
+  MacroTable mtable;
+  MacroParser mparser;
+  foreach (macroPath; macroPaths)
+  {
+    auto macros = mparser.parse(loadMacroFile(macroPath, infoMan));
+    mtable = new MacroTable(mtable);
+    mtable.insert(macros);
+  }
+
+//   foreach (k, v; mtable.table)
+//     Stdout(k)("=")(v.text);
+
+  // For DDoc code sections.
+  auto tokenHL = new TokenHighlighter(infoMan, writeXML == false);
+
+  // Process D files.
+  foreach (filePath; filePaths)
+  {
+    auto mod = new Module(filePath, infoMan);
+    // Parse the file.
+    mod.parse();
+    if (mod.hasErrors)
+      continue;
+
+    // Start semantic analysis.
+    auto pass1 = new SemanticPass1(mod, context);
+    pass1.start();
+
+    // Generate documentation.
+    auto dest = new FilePath(destDir);
+    dest.append(mod.getFQN() ~ (writeXML ? ".xml" : ".html"));
+
+    InfoManager infoMan2; // Collects warnings from the macro expander.
+    if (verbose)
+    {
+      Stdout.formatln("{} > {}", mod.filePath, dest);
+      infoMan2 = new InfoManager();
+    }
+
+    writeDocFile(dest.toString(), mod, mtable, writeXML, incUndoc, tokenHL, infoMan2);
+
+    if (infoMan2)
+      infoMan ~= infoMan2.info;
+  }
+}
+
+void writeDocFile(string dest, Module mod, MacroTable mtable,
+                  bool writeXML, bool incUndoc,
+                  TokenHighlighter tokenHL, InfoManager infoMan)
+{
+  // Create a macro environment for this module.
+  mtable = new MacroTable(mtable);
+  // Define runtime macros.
+  // MODPATH is not in the specs.
+  mtable.insert("MODPATH", mod.getFQNPath() ~ "." ~ mod.fileExtension());
+  mtable.insert("TITLE", mod.getFQN());
+  mtable.insert("DOCFILENAME", mod.getFQN() ~ (writeXML ? ".xml" : ".html"));
+  auto timeStr = Time.toString();
+  mtable.insert("DATETIME", timeStr);
+  mtable.insert("YEAR", Time.year(timeStr));
+
+  DDocEmitter docEmitter;
+  if (writeXML)
+    docEmitter = new DDocXMLEmitter(mod, mtable, incUndoc, tokenHL);
+  else
+    docEmitter = new DDocEmitter(mod, mtable, incUndoc, tokenHL);
+  docEmitter.emit();
+  // Set BODY macro to the text produced by the DDocEmitter.
+  mtable.insert("BODY", docEmitter.text);
+  // Do the macro expansion pass.
+  auto fileText = MacroExpander.expand(mtable, "$(DDOC)", mod.filePath, infoMan);
+// fileText ~= "\n<pre>\n" ~ doc.text ~ "\n</pre>";
+  // Finally write the file out to the harddisk.
+  auto file = new File(dest);
+  file.write(fileText);
+}
+
+/// Loads a macro file. Converts any Unicode encoding to UTF-8.
+string loadMacroFile(string filePath, InfoManager infoMan)
+{
+  auto src = new SourceText(filePath);
+  src.load(infoMan);
+  auto text = src.data[0..$-1]; // Exclude '\0'.
+  return sanitizeText(text);
+}
+
+/// Traverses the syntax tree and writes DDoc macros to a string buffer.
+class DDocEmitter : DefaultVisitor
+{
+  char[] text; /// The buffer that is written to.
+  bool includeUndocumented;
+  MacroTable mtable;
+  Module modul;
+  TokenHighlighter tokenHL;
+
+  /// Constructs a DDocEmitter object.
+  /// Params:
+  ///   modul = the module to generate text for.
+  ///   mtable = the macro table.
+  ///   includeUndocumented = whether to include undocumented symbols.
+  ///   tokenHL = used to highlight code sections.
+  this(Module modul, MacroTable mtable, bool includeUndocumented,
+       TokenHighlighter tokenHL)
+  {
+    this.mtable = mtable;
+    this.includeUndocumented = includeUndocumented;
+    this.modul = modul;
+    this.tokenHL = tokenHL;
+  }
+
+  /// Entry method.
+  char[] emit()
+  {
+    if (auto d = modul.moduleDecl)
+    {
+      if (ddoc(d))
+      {
+        if (auto copyright = cmnt.takeCopyright())
+          mtable.insert(new Macro("COPYRIGHT", copyright.text));
+        writeComment();
+      }
+    }
+    MEMBERS("MODULE", { visitD(modul.root); });
+    return text;
+  }
+
+  char[] textSpan(Token* left, Token* right)
+  {
+    //assert(left && right && (left.end <= right.start || left is right));
+    //char[] result;
+    //TODO: filter out whitespace tokens.
+    return Token.textSpan(left, right);
+  }
+
+  TemplateParameters tparams; /// The template parameters of the current declaration.
+
+  DDocComment cmnt; /// Current comment.
+  DDocComment prevCmnt; /// Previous comment in scope.
+  /// An empty comment. Used for undocumented symbols.
+  static const DDocComment emptyCmnt;
+
+  /// Initializes the empty comment.
+  static this()
+  {
+    this.emptyCmnt = new DDocComment(null, null, null);
+  }
+
+  /// Keeps track of previous comments in each scope.
+  scope class Scope
+  {
+    DDocComment saved_prevCmnt;
+    bool saved_cmntIsDitto;
+    uint saved_prevDeclOffset;
+    this()
+    { // Save the previous comment of the parent scope.
+      saved_prevCmnt = this.outer.prevCmnt;
+      saved_cmntIsDitto = this.outer.cmntIsDitto;
+      saved_prevDeclOffset = this.outer.prevDeclOffset; 
+      // Entering a new scope. Clear variables.
+      this.outer.prevCmnt = null;
+      this.outer.cmntIsDitto = false;
+      this.outer.prevDeclOffset = 0;
+    }
+
+    ~this()
+    { // Restore the previous comment of the parent scope.
+      this.outer.prevCmnt = saved_prevCmnt;
+      this.outer.cmntIsDitto = saved_cmntIsDitto;
+      this.outer.prevDeclOffset = saved_prevDeclOffset;
+    }
+  }
+
+  bool cmntIsDitto; /// True if current comment is "ditto".
+
+  /// Returns the DDocComment for node.
+  DDocComment ddoc(Node node)
+  {
+    auto c = getDDocComment(node);
+    this.cmnt = null;
+    if (c)
+    {
+      if (c.isDitto)
+      {
+        this.cmnt = this.prevCmnt;
+        this.cmntIsDitto = true;
+      }
+      else
+      {
+        this.cmntIsDitto = false;
+        this.cmnt = c;
+        this.prevCmnt = c;
+      }
+    }
+    else if (includeUndocumented)
+      this.cmnt = this.emptyCmnt;
+    return this.cmnt;
+  }
+
+  /// List of predefined, special sections.
+  static char[][char[]] specialSections;
+  static this()
+  {
+    foreach (name; ["AUTHORS", "BUGS", "COPYRIGHT", "DATE", "DEPRECATED",
+                    "EXAMPLES", "HISTORY", "LICENSE", "RETURNS", "SEE_ALSO",
+                    "STANDARDS", "THROWS", "VERSION"])
+      specialSections[name] = name;
+  }
+
+  /// Writes the DDoc comment to the text buffer.
+  void writeComment()
+  {
+    auto c = this.cmnt;
+    assert(c !is null);
+    if (c.sections.length == 0)
+      return;
+    write("$(DDOC_SECTIONS ");
+      foreach (s; c.sections)
+      {
+        if (s is c.summary)
+          write("\n$(DDOC_SUMMARY ");
+        else if (s is c.description)
+          write("\n$(DDOC_DESCRIPTION ");
+        else if (auto name = toUpper(s.name.dup) in specialSections)
+          write("\n$(DDOC_" ~ *name ~ " ");
+        else if (s.Is("params"))
+        { // Process parameters section.
+          auto ps = new ParamsSection(s.name, s.text);
+          write("\n$(DDOC_PARAMS ");
+          foreach (i, paramName; ps.paramNames)
+            write("\n$(DDOC_PARAM_ROW ",
+                    "$(DDOC_PARAM_ID $(DDOC_PARAM ", paramName, "))",
+                    "$(DDOC_PARAM_DESC ", ps.paramDescs[i], ")",
+                  ")");
+          write(")");
+          continue;
+        }
+        else if (s.Is("macros"))
+        { // Declare the macros in this section.
+          auto ms = new MacrosSection(s.name, s.text);
+          mtable.insert(ms.macroNames, ms.macroTexts);
+          continue;
+        }
+        else
+          write("\n$(DDOC_SECTION $(DDOC_SECTION_H " ~ s.name ~ ":)");
+        write(scanCommentText(s.text), ")");
+      }
+    write(")");
+  }
+
+  /// Scans the comment text and:
+  /// $(UL
+  /// $(LI skips and leaves macro invocations unchanged)
+  /// $(LI skips HTML tags)
+  /// $(LI escapes '(', ')', '<', '>' and '&')
+  /// $(LI inserts $&#40;DDOC_BLANKLINE&#41; in place of \n\n)
+  /// $(LI highlights code in code sections)
+  /// )
+  char[] scanCommentText(char[] text)
+  {
+    char* p = text.ptr;
+    char* end = p + text.length;
+    char[] result = new char[text.length]; // Reserve space.
+    result.length = 0;
+
+    while (p < end)
+    {
+      switch (*p)
+      {
+      case '$':
+        if (auto macroEnd = MacroParser.scanMacro(p, end))
+        {
+          result ~= makeString(p, macroEnd); // Copy macro invocation as is.
+          p = macroEnd;
+          continue;
+        }
+        goto default;
+      case '<':
+        auto begin = p;
+        p++;
+        if (p+2 < end && *p == '!' && p[1] == '-' && p[2] == '-') // <!--
+        {
+          p += 2; // Point to 2nd '-'.
+          // Scan to closing "-->".
+          while (++p < end)
+            if (p+2 < end && *p == '-' && p[1] == '-' && p[2] == '>')
+            {
+              p += 3; // Point one past '>'.
+              break;
+            }
+          result ~= makeString(begin, p);
+        } // <tag ...> or </tag>
+        else if (p < end && (isalpha(*p) || *p == '/'))
+        {
+          while (++p < end && *p != '>') // Skip to closing '>'.
+          {}
+          if (p == end)
+          { // No closing '>' found.
+            p = begin + 1;
+            result ~= "&lt;";
+            continue;
+          }
+          p++; // Skip '>'.
+          result ~= makeString(begin, p);
+        }
+        else
+          result ~= "&lt;";
+        continue;
+      case '(': result ~= "&#40;"; break;
+      case ')': result ~= "&#41;"; break;
+      // case '\'': result ~= "&apos;"; break; // &#39;
+      // case '"': result ~= "&quot;"; break;
+      case '>': result ~= "&gt;"; break;
+      case '&':
+        if (p+1 < end && (isalpha(p[1]) || p[1] == '#'))
+          goto default;
+        result ~= "&amp;";
+        break;
+      case '\n':
+        if (!(p+1 < end && p[1] == '\n'))
+          goto default;
+        ++p;
+        result ~= "$(DDOC_BLANKLINE)";
+        break;
+      case '-':
+        if (p+2 < end && p[1] == '-' && p[2] == '-')
+        {
+          while (p < end && *p == '-')
+            p++;
+          auto codeBegin = p;
+          p--;
+          while (++p < end)
+            if (p+2 < end && *p == '-' && p[1] == '-' && p[2] == '-')
+              break;
+          auto codeText = makeString(codeBegin, p);
+          result ~= tokenHL.highlight(codeText, modul.filePath);
+          while (p < end && *p == '-')
+            p++;
+          continue;
+        }
+        //goto default;
+      default:
+        result ~= *p;
+      }
+      p++;
+    }
+    return result;
+  }
+
+  /// Escapes '<', '>' and '&' with named HTML entities.
+  char[] escape(char[] text)
+  {
+    char[] result = new char[text.length]; // Reserve space.
+    result.length = 0;
+    foreach(c; text)
+      switch(c)
+      {
+        case '<': result ~= "&lt;";  break;
+        case '>': result ~= "&gt;";  break;
+        case '&': result ~= "&amp;"; break;
+        default:  result ~= c;
+      }
+    if (result.length != text.length)
+      return result;
+    // Nothing escaped. Return original text.
+    delete result;
+    return text;
+  }
+
+  /// Writes an array of strings to the text buffer.
+  void write(char[][] strings...)
+  {
+    foreach (s; strings)
+      text ~= s;
+  }
+
+  /// Writes params to the text buffer.
+  void writeParams(Parameters params)
+  {
+    if (!params.items.length)
+      return write("()");
+    write("(");
+    auto lastParam = params.items[$-1];
+    foreach (param; params.items)
+    {
+      if (param.isCVariadic)
+        write("...");
+      else
+      {
+        assert(param.type);
+        // Write storage classes.
+        auto typeBegin = param.type.baseType.begin;
+        if (typeBegin !is param.begin) // Write storage classes.
+          write(textSpan(param.begin, typeBegin.prevNWS), " ");
+        write(escape(textSpan(typeBegin, param.type.end))); // Write type.
+        if (param.name)
+          write(" $(DDOC_PARAM ", param.name.str, ")");
+        if (param.isDVariadic)
+          write("...");
+        if (param.defValue)
+          write(" = ", escape(textSpan(param.defValue.begin, param.defValue.end)));
+      }
+      if (param !is lastParam)
+        write(", ");
+    }
+    write(")");
+  }
+
+  /// Writes the current template parameters to the text buffer.
+  void writeTemplateParams()
+  {
+    if (!tparams)
+      return;
+    write(escape(textSpan(tparams.begin, tparams.end)));
+    tparams = null;
+  }
+
+  /// Writes bases to the text buffer.
+  void writeInheritanceList(BaseClassType[] bases)
+  {
+    if (bases.length == 0)
+      return;
+    auto basesBegin = bases[0].begin.prevNWS;
+    if (basesBegin.kind == TOK.Colon)
+      basesBegin = bases[0].begin;
+    write(" : ", escape(textSpan(basesBegin, bases[$-1].end)));
+  }
+
+  /// Writes a symbol to the text buffer. E.g: $&#40;SYMBOL Buffer, 123&#41;
+  void SYMBOL(char[] name, Declaration d)
+  {
+    auto loc = d.begin.getRealLocation();
+    auto str = Format("$(SYMBOL {}, {})", name, loc.lineNum);
+    write(str);
+    // write("$(DDOC_PSYMBOL ", name, ")");
+  }
+
+  /// Offset at which to insert a declaration which have a "ditto" comment.
+  uint prevDeclOffset;
+
+  /// Writes a declaration to the text buffer.
+  void DECL(void delegate() dg, Declaration d, bool writeSemicolon = true)
+  {
+    if (cmntIsDitto)
+    { alias prevDeclOffset offs;
+      assert(offs != 0);
+      auto savedText = text;
+      text = "";
+      write("\n$(DDOC_DECL ");
+      dg();
+      writeSemicolon && write(";");
+      writeAttributes(d);
+      write(")");
+      // Insert text at offset.
+      auto len = text.length;
+      text = savedText[0..offs] ~ text ~ savedText[offs..$];
+      offs += len; // Add length of the inserted text to the offset.
+      return;
+    }
+    write("\n$(DDOC_DECL ");
+    dg();
+    writeSemicolon && write(";");
+    writeAttributes(d);
+    write(")");
+    prevDeclOffset = text.length;
+  }
+
+  /// Wraps the DDOC_DECL_DD macro around the text written by dg().
+  void DESC(void delegate() dg)
+  {
+    if (cmntIsDitto)
+      return;
+    write("\n$(DDOC_DECL_DD ");
+    dg();
+    write(")");
+  }
+
+  /// Wraps the DDOC_kind_MEMBERS macro around the text written by dg().
+  void MEMBERS(char[] kind, void delegate() dg)
+  {
+    write("\n$(DDOC_"~kind~"_MEMBERS ");
+    dg();
+    write(")");
+  }
+
+  /// Writes a class or interface declaration.
+  void writeClassOrInterface(T)(T d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({
+      write(d.begin.srcText, " ");
+      SYMBOL(d.name.str, d);
+      writeTemplateParams();
+      writeInheritanceList(d.bases);
+    }, d);
+    DESC({
+      writeComment();
+      MEMBERS(is(T == ClassDeclaration) ? "CLASS" : "INTERFACE", {
+        scope s = new Scope();
+        d.decls && super.visit(d.decls);
+      });
+    });
+  }
+
+  // templated decls are not virtual so we need these:
+
+  /// Writes a class declaration.
+  void writeClass(ClassDeclaration d) {
+    writeClassOrInterface(d);
+  }
+
+  /// Writes an interface declaration.
+  void writeInterface(InterfaceDeclaration d) {
+    writeClassOrInterface(d);
+  }
+
+  /// Writes a struct or union declaration.
+  void writeStructOrUnion(T)(T d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({
+      write(d.begin.srcText, d.name ? " " : "");
+      if (d.name)
+        SYMBOL(d.name.str, d);
+      writeTemplateParams();
+    }, d);
+    DESC({
+      writeComment();
+      MEMBERS(is(T == StructDeclaration) ? "STRUCT" : "UNION", {
+        scope s = new Scope();
+        d.decls && super.visit(d.decls);
+      });
+    });
+  }
+
+  // templated decls are not virtual so we need these:
+
+  /// Writes a struct declaration.
+  void writeStruct(StructDeclaration d) {
+    writeStructOrUnion(d);
+  }
+
+  /// Writes an union declaration.
+  void writeUnion(UnionDeclaration d) {
+    writeStructOrUnion(d);
+  }
+
+  /// Writes an alias or typedef declaration.
+  void writeAliasOrTypedef(T)(T d)
+  {
+    auto prefix = is(T == AliasDeclaration) ? "alias " : "typedef ";
+    if (auto vd = d.decl.Is!(VariablesDeclaration))
+    {
+      auto type = textSpan(vd.typeNode.baseType.begin, vd.typeNode.end);
+      foreach (name; vd.names)
+        DECL({ write(prefix); write(escape(type), " "); SYMBOL(name.str, d); }, d);
+    }
+    else if (auto fd = d.decl.Is!(FunctionDeclaration))
+    {}
+    // DECL({ write(textSpan(d.begin, d.end)); }, false);
+    DESC({ writeComment(); });
+  }
+
+  /// Writes the attributes of a declaration in brackets.
+  void writeAttributes(Declaration d)
+  {
+    char[][] attributes;
+
+    if (d.prot != Protection.None)
+      attributes ~= "$(PROT " ~ .toString(d.prot) ~ ")";
+
+    auto stc = d.stc;
+    stc &= ~StorageClass.Auto; // Ignore auto.
+    foreach (stcStr; .toStrings(stc))
+      attributes ~= "$(STC " ~ stcStr ~ ")";
+
+    LinkageType ltype;
+    if (auto vd = d.Is!(VariablesDeclaration))
+      ltype = vd.linkageType;
+    else if (auto fd = d.Is!(FunctionDeclaration))
+      ltype = fd.linkageType;
+
+    if (ltype != LinkageType.None)
+      attributes ~= "$(LINKAGE extern(" ~ .toString(ltype) ~ "))";
+
+    if (!attributes.length)
+      return;
+
+    write(" $(ATTRIBUTES ");
+    write(attributes[0]);
+    foreach (attribute; attributes[1..$])
+      write(", ", attribute);
+    write(")");
+  }
+
+  alias Declaration D;
+
+override:
+  D visit(AliasDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    writeAliasOrTypedef(d);
+    return d;
+  }
+
+  D visit(TypedefDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    writeAliasOrTypedef(d);
+    return d;
+  }
+
+  D visit(EnumDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({
+      write("enum", d.name ? " " : "");
+      d.name && SYMBOL(d.name.str, d);
+    }, d);
+    DESC({
+      writeComment();
+      MEMBERS("ENUM", { scope s = new Scope(); super.visit(d); });
+    });
+    return d;
+  }
+
+  D visit(EnumMemberDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ SYMBOL(d.name.str, d); }, d, false);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(TemplateDeclaration d)
+  {
+    this.tparams = d.tparams;
+    if (d.begin.kind != TOK.Template)
+    { // This is a templatized class/interface/struct/union/function.
+      super.visit(d.decls);
+      this.tparams = null;
+      return d;
+    }
+    if (!ddoc(d))
+      return d;
+    DECL({
+      write("template ");
+      SYMBOL(d.name.str, d);
+      writeTemplateParams();
+    }, d);
+    DESC({
+      writeComment();
+      MEMBERS("TEMPLATE", {
+        scope s = new Scope();
+        super.visit(d.decls);
+      });
+    });
+    return d;
+  }
+
+  D visit(ClassDeclaration d)
+  {
+    writeClass(d);
+    return d;
+  }
+
+  D visit(InterfaceDeclaration d)
+  {
+    writeInterface(d);
+    return d;
+  }
+
+  D visit(StructDeclaration d)
+  {
+    writeStruct(d);
+    return d;
+  }
+
+  D visit(UnionDeclaration d)
+  {
+    writeUnion(d);
+    return d;
+  }
+
+  D visit(ConstructorDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ SYMBOL("this", d); writeParams(d.params); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(StaticConstructorDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("static "); SYMBOL("this", d); write("()"); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(DestructorDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("~"); SYMBOL("this", d); write("()"); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(StaticDestructorDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("static ~"); SYMBOL("this", d); write("()"); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(FunctionDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    auto type = textSpan(d.returnType.baseType.begin, d.returnType.end);
+    DECL({
+      write(escape(type), " ");
+      SYMBOL(d.name.str, d);
+      writeTemplateParams();
+      writeParams(d.params);
+    }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(NewDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ SYMBOL("new", d); writeParams(d.params); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(DeleteDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ SYMBOL("delete", d); writeParams(d.params); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(VariablesDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    char[] type = "auto";
+    if (d.typeNode)
+      type = textSpan(d.typeNode.baseType.begin, d.typeNode.end);
+    foreach (name; d.names)
+      DECL({ write(escape(type), " "); SYMBOL(name.str, d); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(InvariantDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ SYMBOL("invariant", d); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(UnittestDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ SYMBOL("unittest", d); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(DebugDeclaration d)
+  {
+    d.compiledDecls && visitD(d.compiledDecls);
+    return d;
+  }
+
+  D visit(VersionDeclaration d)
+  {
+    d.compiledDecls && visitD(d.compiledDecls);
+    return d;
+  }
+
+  D visit(StaticIfDeclaration d)
+  {
+    d.ifDecls && visitD(d.ifDecls);
+    return d;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cmd/DDocXML.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,406 @@
+/++
+  Authors: Aziz Köksal & Jari-Matti Mäkelä
+  License: GPL3
++/
+module cmd.DDocXML;
+
+import cmd.DDoc;
+import cmd.Generate;
+import dil.doc.Parser;
+import dil.doc.Macro;
+import dil.doc.Doc;
+import dil.ast.Node;
+import dil.ast.Declarations,
+       dil.ast.Statements,
+       dil.ast.Expression,
+       dil.ast.Parameters,
+       dil.ast.Types;
+import dil.ast.DefaultVisitor;
+import dil.lexer.Token;
+import dil.lexer.Funcs;
+import dil.semantic.Module;
+import dil.semantic.Pass1;
+import dil.semantic.Symbol;
+import dil.semantic.Symbols;
+import dil.Compilation;
+import dil.Information;
+import dil.Converter;
+import dil.SourceText;
+import dil.Enums;
+import dil.Time;
+import common;
+
+import tango.text.Ascii : toUpper;
+import tango.io.File;
+import tango.io.FilePath;
+
+/// Traverses the syntax tree and writes DDoc macros to a string buffer.
+class DDocXMLEmitter : DDocEmitter
+{
+  this(Module modul, MacroTable mtable, bool includeUndocumented,
+       TokenHighlighter tokenHL)
+  {
+    super(modul, mtable, includeUndocumented, tokenHL);
+  }
+
+  /// Writes params to the text buffer.
+  void writeParams(Parameters params)
+  {
+    if (!params.items.length)
+      return;
+
+    write("$(PARAMS ");
+    auto lastParam = params.items[$-1];
+    foreach (param; params.items)
+    {
+      if (param.isCVariadic)
+        write("...");
+      else
+      {
+        assert(param.type);
+        // Write storage classes.
+        auto typeBegin = param.type.baseType.begin;
+        if (typeBegin !is param.begin) // Write storage classes.
+          write(textSpan(param.begin, typeBegin.prevNWS), " ");
+        write(escape(textSpan(typeBegin, param.type.end))); // Write type.
+        if (param.name)
+          write(" $(DDOC_PARAM ", param.name.str, ")");
+        if (param.isDVariadic)
+          write("...");
+        if (param.defValue)
+          write(" = ", escape(textSpan(param.defValue.begin, param.defValue.end)));
+      }
+      if (param !is lastParam)
+        write(", ");
+    }
+    write(")");
+  }
+
+  /// Writes the current template parameters to the text buffer.
+  void writeTemplateParams()
+  {
+    if (!tparams)
+      return;
+    write("$(TEMPLATE_PARAMS ", escape(textSpan(tparams.begin, tparams.end))[1..$-1], ")");
+    tparams = null;
+  }
+
+  /// Writes bases to the text buffer.
+  void writeInheritanceList(BaseClassType[] bases)
+  {
+    if (bases.length == 0)
+      return;
+    auto basesBegin = bases[0].begin.prevNWS;
+    if (basesBegin.kind == TOK.Colon)
+      basesBegin = bases[0].begin;
+    write("$(PARENTS ", escape(textSpan(basesBegin, bases[$-1].end)), ")");
+  }
+
+  /// Writes a symbol to the text buffer. E.g: $&#40;SYMBOL Buffer, 123&#41;
+  void SYMBOL(char[] name, Declaration d)
+  {
+    auto loc = d.begin.getRealLocation();
+    auto str = Format("$(SYMBOL {}, {})", name, loc.lineNum);
+    write(str);
+    // write("$(DDOC_PSYMBOL ", name, ")");
+  }
+
+  /// Writes a declaration to the text buffer.
+  void DECL(void delegate() dg, Declaration d, bool writeSemicolon = true)
+  {
+    if (cmntIsDitto)
+    { alias prevDeclOffset offs;
+      assert(offs != 0);
+      auto savedText = text;
+      text = "";
+      write("\n$(DDOC_DECL ");
+      dg();
+      writeAttributes(d);
+      write(")");
+      // Insert text at offset.
+      auto len = text.length;
+      text = savedText[0..offs] ~ text ~ savedText[offs..$];
+      offs += len; // Add length of the inserted text to the offset.
+      return;
+    }
+    write("\n$(DDOC_DECL ");
+    dg();
+    writeAttributes(d);
+    write(")");
+    prevDeclOffset = text.length;
+  }
+
+
+  /// Writes a class or interface declaration.
+  void writeClassOrInterface(T)(T d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({
+      write(d.begin.srcText, ", ");
+      SYMBOL(d.name.str, d);
+      writeTemplateParams();
+      writeInheritanceList(d.bases);
+    }, d);
+    DESC({
+      writeComment();
+      MEMBERS(is(T == ClassDeclaration) ? "CLASS" : "INTERFACE", {
+        scope s = new Scope();
+        d.decls && DefaultVisitor.visit(d.decls);
+      });
+    });
+  }
+
+  // templated decls are not virtual so we need these:
+
+  /// Writes a class declaration.
+  void writeClass(ClassDeclaration d) {
+    writeClassOrInterface(d);
+  }
+
+  /// Writes an interface declaration.
+  void writeInterface(InterfaceDeclaration d) {
+    writeClassOrInterface(d);
+  }
+
+  /// Writes a struct or union declaration.
+  void writeStructOrUnion(T)(T d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({
+      write(d.begin.srcText, d.name ? ", " : "");
+      if (d.name)
+        SYMBOL(d.name.str, d);
+      writeTemplateParams();
+    }, d);
+    DESC({
+      writeComment();
+      MEMBERS(is(T == StructDeclaration) ? "STRUCT" : "UNION", {
+        scope s = new Scope();
+        d.decls && DefaultVisitor.visit(d.decls);
+      });
+    });
+  }
+
+  // templated decls are not virtual so we need these:
+
+  /// Writes a struct declaration.
+  void writeStruct(StructDeclaration d) {
+    writeStructOrUnion(d);
+  }
+
+  /// Writes an union declaration.
+  void writeUnion(UnionDeclaration d) {
+    writeStructOrUnion(d);
+  }
+
+  /// Writes an alias or typedef declaration.
+  void writeAliasOrTypedef(T)(T d)
+  {
+    auto prefix = is(T == AliasDeclaration) ? "alias " : "typedef ";
+    if (auto vd = d.decl.Is!(VariablesDeclaration))
+    {
+      auto type = textSpan(vd.typeNode.baseType.begin, vd.typeNode.end);
+      foreach (name; vd.names)
+        DECL({ write(prefix, ", "); write(escape(type), " "); SYMBOL(name.str, d); }, d);
+    }
+    else if (auto fd = d.decl.Is!(FunctionDeclaration))
+    {}
+    // DECL({ write(textSpan(d.begin, d.end)); }, false);
+    DESC({ writeComment(); });
+  }
+
+
+  /// Writes the attributes of a declaration in brackets.
+  void writeAttributes(Declaration d)
+  {
+    char[][] attributes;
+
+    if (d.prot != Protection.None)
+      attributes ~= "$(PROT " ~ .toString(d.prot) ~ ")";
+
+    auto stc = d.stc;
+    stc &= ~StorageClass.Auto; // Ignore auto.
+    foreach (stcStr; .toStrings(stc))
+      attributes ~= "$(STC " ~ stcStr ~ ")";
+
+    LinkageType ltype;
+    if (auto vd = d.Is!(VariablesDeclaration))
+      ltype = vd.linkageType;
+    else if (auto fd = d.Is!(FunctionDeclaration))
+      ltype = fd.linkageType;
+
+    if (ltype != LinkageType.None)
+      attributes ~= "$(LINKAGE extern(" ~ .toString(ltype) ~ "))";
+
+    if (!attributes.length)
+      return;
+
+    write("$(ATTRIBUTES ");
+    foreach (attribute; attributes)
+      write(attribute);
+    write(")");
+  }
+
+  alias Declaration D;
+
+  alias DDocEmitter.visit visit;
+
+  D visit(EnumDeclaration d)
+  {
+      /+ FIXME: broken, infinite recursion :/
+    if (!ddoc(d))
+      return d;
+    DECL({
+      write("enum, ", d.name ? " " : "");
+      d.name && SYMBOL(d.name.str, d);
+    }, d);
+    DESC({
+      writeComment();
+      Stdout("help\n");
+///*FIXME*/      MEMBERS("ENUM", { scope s = new Scope(); DDocEmitter.visit(d); });
+    });
+    +/
+    return d;
+  }
+
+  D visit(EnumMemberDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("member, "); SYMBOL(d.name.str, d); }, d, false);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(TemplateDeclaration d)
+  {
+    this.tparams = d.tparams;
+    if (d.begin.kind != TOK.Template)
+    { // This is a templatized class/interface/struct/union/function.
+      DefaultVisitor.visit(d.decls);
+      this.tparams = null;
+      return d;
+    }
+    if (!ddoc(d))
+      return d;
+    DECL({
+      write("template, ");
+      SYMBOL(d.name.str, d);
+      writeTemplateParams();
+    }, d);
+    DESC({
+      writeComment();
+      MEMBERS("TEMPLATE", {
+        scope s = new Scope();
+        DefaultVisitor.visit(d.decls);
+      });
+    });
+    return d;
+  }
+
+  D visit(ConstructorDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("constructor, "); SYMBOL("this", d); writeParams(d.params); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(StaticConstructorDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("static constructor, "); SYMBOL("this", d); write("()"); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(DestructorDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("destructor, ~"); SYMBOL("this", d); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(StaticDestructorDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("static destructor, ~"); SYMBOL("this", d); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(FunctionDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    auto type = textSpan(d.returnType.baseType.begin, d.returnType.end);
+    DECL({
+      write("function, ");
+      write("$(TYPE ");
+      write("$(RETURNS ", escape(type), ")");
+      writeTemplateParams();
+      writeParams(d.params);
+      write(")");
+      SYMBOL(d.name.str, d);
+    }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(NewDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("new, "); SYMBOL("new", d); writeParams(d.params); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(DeleteDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("delete, "); SYMBOL("delete", d); writeParams(d.params); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(VariablesDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    char[] type = "auto";
+    if (d.typeNode)
+      type = textSpan(d.typeNode.baseType.begin, d.typeNode.end);
+    foreach (name; d.names)
+      DECL({ write("variable, "); write("$(TYPE ", escape(type), ")"); SYMBOL(name.str, d); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(InvariantDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("invariant, "); SYMBOL("invariant", d); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+  D visit(UnittestDeclaration d)
+  {
+    if (!ddoc(d))
+      return d;
+    DECL({ write("unittest, "); SYMBOL("unittest", d); }, d);
+    DESC({ writeComment(); });
+    return d;
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cmd/Generate.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,489 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module cmd.Generate;
+
+import dil.ast.DefaultVisitor;
+import dil.ast.Node,
+       dil.ast.Declaration,
+       dil.ast.Statement,
+       dil.ast.Expression,
+       dil.ast.Types;
+import dil.lexer.Lexer;
+import dil.parser.Parser;
+import dil.semantic.Module;
+import dil.SourceText;
+import dil.Information;
+import SettingsLoader;
+import Settings;
+import common;
+
+import tango.io.GrowBuffer;
+import tango.io.Print;
+
+/// Options for the generate command.
+enum GenOption
+{
+  Empty,
+  Tokens = 1,
+  Syntax = 1<<1,
+  HTML   = 1<<2,
+  XML    = 1<<3,
+  PrintLines  = 1<<4
+}
+
+/// Executes the generate command.
+void execute(string filePath, GenOption options, InfoManager infoMan)
+{
+  assert(options != GenOption.Empty);
+  auto mapFilePath = options & GenOption.HTML ? GlobalSettings.htmlMapFile
+                                              : GlobalSettings.xmlMapFile;
+  auto map = TagMapLoader(infoMan).load(mapFilePath);
+  auto tags = new TagMap(map);
+
+  if (infoMan.hasInfo)
+    return;
+
+  if (options & GenOption.Syntax)
+    highlightSyntax(filePath, tags, Stdout, options);
+  else
+    highlightTokens(filePath, tags, Stdout, options);
+}
+
+/// Escapes the characters '<', '>' and '&' with named character entities.
+char[] xml_escape(char[] text)
+{
+  char[] result;
+  foreach(c; text)
+    switch(c)
+    {
+      case '<': result ~= "&lt;";  break;
+      case '>': result ~= "&gt;";  break;
+      case '&': result ~= "&amp;"; break;
+      default:  result ~= c;
+    }
+  if (result.length != text.length)
+    return result;
+  // Nothing escaped. Return original text.
+  delete result;
+  return text;
+}
+
+/// Maps tokens to (format) strings.
+class TagMap
+{
+  string[string] table;
+  string[TOK.MAX] tokenTable;
+
+  this(string[string] table)
+  {
+    this.table = table;
+    Identifier   = this["Identifier", "{0}"];
+    String       = this["String", "{0}"];
+    Char         = this["Char", "{0}"];
+    Number       = this["Number", "{0}"];
+    Keyword      = this["Keyword", "{0}"];
+    LineC        = this["LineC", "{0}"];
+    BlockC       = this["BlockC", "{0}"];
+    NestedC      = this["NestedC", "{0}"];
+    Shebang      = this["Shebang", "{0}"];
+    HLine        = this["HLine", "{0}"];
+    Filespec     = this["Filespec", "{0}"];
+    Illegal      = this["Illegal", "{0}"];
+    Newline      = this["Newline", "{0}"];
+    SpecialToken = this["SpecialToken", "{0}"];
+    Declaration  = this["Declaration", "d"];
+    Statement    = this["Statement", "s"];
+    Expression   = this["Expression", "e"];
+    Type         = this["Type", "t"];
+    Other        = this["Other", "o"];
+    EOF          = this["EOF", ""];
+
+    foreach (i, tokStr; tokToString)
+      if (auto pStr = tokStr in this.table)
+        tokenTable[i] = *pStr;
+  }
+
+  /// Returns the value for str, or 'fallback' if str is not in the table.
+  string opIndex(string str, string fallback = "")
+  {
+    auto p = str in table;
+    if (p)
+      return *p;
+    return fallback;
+  }
+
+  /// Returns the value for tok in O(1) time.
+  string opIndex(TOK tok)
+  {
+    return tokenTable[tok];
+  }
+
+  /// Shortcuts for quick access.
+  string Identifier, String, Char, Number, Keyword, LineC, BlockC,
+         NestedC, Shebang, HLine, Filespec, Illegal, Newline, SpecialToken,
+         Declaration, Statement, Expression, Type, Other, EOF;
+
+  /// Returns the tag for the category 'nc'.
+  string getTag(NodeCategory nc)
+  {
+    string tag;
+    switch (nc)
+    { alias NodeCategory NC;
+    case NC.Declaration: tag = Declaration; break;
+    case NC.Statement:   tag = Statement; break;
+    case NC.Expression:  tag = Expression; break;
+    case NC.Type:        tag = Type; break;
+    case NC.Other:       tag = Other; break;
+    default: assert(0);
+    }
+    return tag;
+  }
+}
+
+/// Find the last occurrence of object in subject.
+/// Returns: the index if found, or -1 if not.
+int rfind(char[] subject, char object)
+{
+  foreach_reverse(i, c; subject)
+    if (c == object)
+      return i;
+  return -1;
+}
+
+/// Returns the short class name of a class descending from Node.$(BR)
+/// E.g.: dil.ast.Declarations.ClassDeclaration -> Class
+char[] getShortClassName(Node node)
+{
+  static char[][] name_table;
+  if (name_table is null)
+    name_table = new char[][NodeKind.max+1]; // Create a new table.
+  // Look up in table.
+  char[] name = name_table[node.kind];
+  if (name !is null)
+    return name; // Return cached name.
+
+  name = node.classinfo.name; // Get the fully qualified name of the class.
+  name = name[rfind(name, '.')+1 .. $]; // Remove package and module name.
+
+  uint suffixLength;
+  switch (node.category)
+  {
+  alias NodeCategory NC;
+  case NC.Declaration:
+    suffixLength = "Declaration".length;
+    break;
+  case NC.Statement:
+    suffixLength = "Statement".length;
+    break;
+  case NC.Expression:
+    suffixLength = "Expression".length;
+    break;
+  case NC.Type:
+    suffixLength = "Type".length;
+    break;
+  case NC.Other:
+    break;
+  default:
+    assert(0);
+  }
+  // Remove common suffix.
+  name = name[0 .. $ - suffixLength];
+  // Store the name in the table.
+  name_table[node.kind] = name;
+  return name;
+}
+
+/// Extended token structure.
+struct TokenEx
+{
+  Token* token; /// The lexer token.
+  Node[] beginNodes; /// beginNodes[n].begin == token
+  Node[] endNodes; /// endNodes[n].end == token
+}
+
+/// Builds an array of TokenEx items.
+class TokenExBuilder : DefaultVisitor
+{
+  private TokenEx*[Token*] tokenTable;
+
+  TokenEx[] build(Node root, Token* first)
+  {
+    auto token = first;
+
+    uint count; // Count tokens.
+    for (; token; token = token.next)
+      count++;
+    // Creat the exact number of TokenEx instances.
+    auto toks = new TokenEx[count];
+    token = first;
+    foreach (ref tokEx; toks)
+    {
+      tokEx.token = token;
+      if (!token.isWhitespace)
+        tokenTable[token] = &tokEx;
+      token = token.next;
+    }
+
+    super.visitN(root);
+    tokenTable = null;
+    return toks;
+  }
+
+  TokenEx* getTokenEx()(Token* t)
+  {
+    auto p = t in tokenTable;
+    assert(p, t.srcText~" is not in tokenTable");
+    return *p;
+  }
+
+  // Override dispatch function.
+  override Node dispatch(Node n)
+  {
+    auto begin = n.begin;
+    if (begin)
+    { assert(n.end);
+      auto txbegin = getTokenEx(begin);
+      auto txend = getTokenEx(n.end);
+      txbegin.beginNodes ~= n;
+      txend.endNodes ~= n;
+    }
+    return super.dispatch(n);
+  }
+}
+
+void printErrors(Lexer lx, TagMap tags, Print!(char) print)
+{
+  foreach (e; lx.errors)
+    print.format(tags["LexerError"], e.filePath, e.loc, e.col, xml_escape(e.getMsg));
+}
+
+void printErrors(Parser parser, TagMap tags, Print!(char) print)
+{
+  foreach (e; parser.errors)
+    print.format(tags["ParserError"], e.filePath, e.loc, e.col, xml_escape(e.getMsg));
+}
+
+void printLines(uint lines, TagMap tags, Print!(char) print)
+{
+  auto lineNumberFormat = tags["LineNumber"];
+  for (auto lineNum = 1; lineNum <= lines; lineNum++)
+    print.format(lineNumberFormat, lineNum);
+}
+
+// void printMultiline(Token* token, TagMap tags, Print!(char) print)
+// {
+// }
+
+/// Highlights the syntax in a source file.
+void highlightSyntax(string filePath, TagMap tags, Print!(char) print, GenOption options)
+{
+  auto parser = new Parser(new SourceText(filePath, true));
+  auto root = parser.start();
+  auto lx = parser.lexer;
+
+  auto builder = new TokenExBuilder();
+  auto tokenExList = builder.build(root, lx.firstToken());
+
+  print(tags["DocHead"]);
+  if (lx.errors.length || parser.errors.length)
+  { // Output error messages.
+    print(tags["CompBegin"]);
+    printErrors(lx, tags, print);
+    printErrors(parser, tags, print);
+    print(tags["CompEnd"]);
+  }
+
+  if (options & GenOption.PrintLines)
+  {
+    print(tags["LineNumberBegin"]);
+    printLines(lx.lineNum, tags, print);
+    print(tags["LineNumberEnd"]);
+  }
+
+  print(tags["SourceBegin"]);
+
+  auto tagNodeBegin = tags["NodeBegin"];
+  auto tagNodeEnd = tags["NodeEnd"];
+
+  // Iterate over list of tokens.
+  foreach (ref tokenEx; tokenExList)
+  {
+    auto token = tokenEx.token;
+
+    token.ws && print(token.wsChars); // Print preceding whitespace.
+    if (token.isWhitespace) {
+      printToken(token, tags, print);
+      continue;
+    }
+    // <node>
+    foreach (node; tokenEx.beginNodes)
+      print.format(tagNodeBegin, tags.getTag(node.category), getShortClassName(node));
+    // Token text.
+    printToken(token, tags, print);
+    // </node>
+    if (options & GenOption.HTML)
+      foreach_reverse (node; tokenEx.endNodes)
+        print(tagNodeEnd);
+    else
+      foreach_reverse (node; tokenEx.endNodes)
+        print.format(tagNodeEnd, tags.getTag(node.category));
+  }
+  print(tags["SourceEnd"]);
+  print(tags["DocEnd"]);
+}
+
+/// Highlights all tokens of a source file.
+void highlightTokens(string filePath, TagMap tags, Print!(char) print, GenOption options)
+{
+  auto lx = new Lexer(new SourceText(filePath, true));
+  lx.scanAll();
+
+  print(tags["DocHead"]);
+  if (lx.errors.length)
+  {
+    print(tags["CompBegin"]);
+    printErrors(lx, tags, print);
+    print(tags["CompEnd"]);
+  }
+
+  if (options & GenOption.PrintLines)
+  {
+    print(tags["LineNumberBegin"]);
+    printLines(lx.lineNum, tags, print);
+    print(tags["LineNumberEnd"]);
+  }
+
+  print(tags["SourceBegin"]);
+  // Traverse linked list and print tokens.
+  for (auto token = lx.firstToken(); token; token = token.next) {
+    token.ws && print(token.wsChars); // Print preceding whitespace.
+    printToken(token, tags, print);
+  }
+  print(tags["SourceEnd"]);
+  print(tags["DocEnd"]);
+}
+
+/// A token highlighter designed for DDoc.
+class TokenHighlighter
+{
+  TagMap tags;
+  this(InfoManager infoMan, bool useHTML = true)
+  {
+    string filePath = GlobalSettings.htmlMapFile;
+    if (!useHTML)
+      filePath = GlobalSettings.xmlMapFile;
+    auto map = TagMapLoader(infoMan).load(filePath);
+    tags = new TagMap(map);
+  }
+
+  /// Highlights tokens in a DDoc code section.
+  /// Returns: a string with the highlighted tokens (in HTML tags.)
+  string highlight(string text, string filePath)
+  {
+    auto buffer = new GrowBuffer(text.length);
+    auto print = new Print!(char)(Format, buffer);
+
+    auto lx = new Lexer(new SourceText(filePath, text));
+    lx.scanAll();
+
+    // Traverse linked list and print tokens.
+    print("$(D_CODE\n");
+    if (lx.errors.length)
+    { // Output error messages.
+      print(tags["CompBegin"]);
+      printErrors(lx, tags, print);
+      print(tags["CompEnd"]);
+    }
+    // Traverse linked list and print tokens.
+    for (auto token = lx.firstToken(); token; token = token.next) {
+      token.ws && print(token.wsChars); // Print preceding whitespace.
+      printToken(token, tags, print);
+    }
+    print("\n)");
+    return cast(char[])buffer.slice();
+  }
+}
+
+/// Prints a token to the stream print.
+void printToken(Token* token, TagMap tags, Print!(char) print)
+{
+  switch(token.kind)
+  {
+  case TOK.Identifier:
+    print.format(tags.Identifier, token.srcText);
+    break;
+  case TOK.Comment:
+    string formatStr;
+    switch (token.start[1])
+    {
+    case '/': formatStr = tags.LineC; break;
+    case '*': formatStr = tags.BlockC; break;
+    case '+': formatStr = tags.NestedC; break;
+    default: assert(0);
+    }
+    print.format(formatStr, xml_escape(token.srcText));
+    break;
+  case TOK.String:
+    print.format(tags.String, xml_escape(token.srcText));
+    break;
+  case TOK.CharLiteral:
+    print.format(tags.Char, xml_escape(token.srcText));
+    break;
+  case TOK.Int32, TOK.Int64, TOK.Uint32, TOK.Uint64,
+       TOK.Float32, TOK.Float64, TOK.Float80,
+       TOK.Imaginary32, TOK.Imaginary64, TOK.Imaginary80:
+    print.format(tags.Number, token.srcText);
+    break;
+  case TOK.Shebang:
+    print.format(tags.Shebang, xml_escape(token.srcText));
+    break;
+  case TOK.HashLine:
+    auto formatStr = tags.HLine;
+    // The text to be inserted into formatStr.
+    auto buffer = new GrowBuffer;
+    auto print2 = new Print!(char)(Format, buffer);
+
+    void printWS(char* start, char* end)
+    {
+      start != end && print2(start[0 .. end - start]);
+    }
+
+    auto num = token.tokLineNum;
+    if (num is null)
+    { // Malformed #line
+      print.format(formatStr, token.srcText);
+      break;
+    }
+
+    // Print whitespace between #line and number.
+    printWS(token.start, num.start); // Prints "#line" as well.
+    printToken(num, tags, print2); // Print the number.
+
+    if (auto filespec = token.tokLineFilespec)
+    { // Print whitespace between number and filespec.
+      printWS(num.end, filespec.start);
+      print2.format(tags.Filespec, xml_escape(filespec.srcText));
+    }
+    // Finally print the whole token.
+    print.format(formatStr, cast(char[])buffer.slice());
+    break;
+  case TOK.Illegal:
+    print.format(tags.Illegal, token.srcText());
+    break;
+  case TOK.Newline:
+    print.format(tags.Newline, token.srcText());
+    break;
+  case TOK.EOF:
+    print(tags.EOF);
+    break;
+  default:
+    if (token.isKeyword())
+      print.format(tags.Keyword, token.srcText);
+    else if (token.isSpecialToken)
+      print.format(tags.SpecialToken, token.srcText);
+    else
+      print(tags[token.kind]);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cmd/ImportGraph.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,424 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module cmd.ImportGraph;
+
+import dil.ast.Node;
+import dil.ast.Declarations;
+import dil.semantic.Module;
+import dil.parser.ImportParser;
+import dil.SourceText;
+import dil.Compilation;
+import Settings;
+import common;
+
+import tango.text.Regex : RegExp = Regex;
+import tango.io.FilePath;
+import tango.io.FileConst;
+import tango.text.Util;
+
+alias FileConst.PathSeparatorChar dirSep;
+
+/// Options for the importgraph command.
+enum IGraphOption
+{
+  None,
+  IncludeUnlocatableModules = 1,
+  PrintDot                  = 1<<1,
+  HighlightCyclicEdges      = 1<<2,
+  HighlightCyclicVertices   = 1<<3,
+  GroupByPackageNames       = 1<<4,
+  GroupByFullPackageName    = 1<<5,
+  PrintPaths                = 1<<6,
+  PrintList                 = 1<<7,
+  MarkCyclicModules         = 1<<8,
+}
+
+/// Represents a module dependency graph.
+class Graph
+{
+  Vertex[] vertices; /// The vertices or modules.
+  Edge[] edges; /// The edges or import statements.
+
+  void addVertex(Vertex vertex)
+  {
+    vertex.id = vertices.length;
+    vertices ~= vertex;
+  }
+
+  Edge addEdge(Vertex from, Vertex to)
+  {
+    auto edge = new Edge(from, to);
+    edges ~= edge;
+    from.outgoing ~= to;
+    to.incoming ~= from;
+    return edge;
+  }
+
+  /// Walks the graph and marks cyclic vertices and edges.
+  void detectCycles()
+  { // Cycles could also be detected in the GraphBuilder,
+    // but having the code here makes things much clearer.
+
+    // Commented out because this algorithm doesn't work.
+    // Returns true if the vertex is in status Visiting.
+    /+bool visit(Vertex vertex)
+    {
+      switch (vertex.status)
+      {
+      case Vertex.Status.Visiting:
+        vertex.isCyclic = true;
+        return true;
+      case Vertex.Status.None:
+        vertex.status = Vertex.Status.Visiting; // Flag as visiting.
+        foreach (outVertex; vertex.outgoing)    // Visit successors.
+          vertex.isCyclic |= visit(outVertex);
+        vertex.status = Vertex.Status.Visited;  // Flag as visited.
+        break;
+      case Vertex.Status.Visited:
+        break;
+      default:
+        assert(0, "unknown vertex status");
+      }
+      return false; // return (vertex.status == Vertex.Status.Visiting);
+    }
+    // Start visiting vertices.
+    visit(vertices[0]);+/
+
+    //foreach (edge; edges)
+    //  if (edge.from.isCyclic && edge.to.isCyclic)
+    //    edge.isCyclic = true;
+
+    // Use functioning algorithm.
+    analyzeGraph(vertices, edges);
+  }
+}
+
+/// Represents a directed connection between two vertices.
+class Edge
+{
+  Vertex from;   /// Coming from vertex.
+  Vertex to;     /// Going to vertex.
+  bool isCyclic; /// Edge connects cyclic vertices.
+  bool isPublic; /// Public import.
+  bool isStatic; /// Static import.
+
+  this(Vertex from, Vertex to)
+  {
+    this.from = from;
+    this.to = to;
+  }
+}
+
+/// Represents a module in the graph.
+class Vertex
+{
+  Module modul;      /// The module represented by this vertex.
+  uint id;           /// The nth vertex in the graph.
+  Vertex[] incoming; /// Also called predecessors.
+  Vertex[] outgoing; /// Also called successors.
+  bool isCyclic;     /// Whether this vertex is in a cyclic relationship with other vertices.
+
+  enum Status : ubyte
+  { None, Visiting, Visited }
+  Status status; /// Used by the cycle detection algorithm.
+}
+
+/// Searches for a module in the file system looking in importPaths.
+/// Returns: the file path to the module, or null if it wasn't found.
+string findModuleFilePath(string moduleFQNPath, string[] importPaths)
+{
+  auto filePath = new FilePath();
+  foreach (importPath; importPaths)
+  {
+    filePath.set(importPath);
+    filePath.append(moduleFQNPath);
+    foreach (moduleSuffix; [".d", ".di"/*interface file*/])
+    {
+      filePath.suffix(moduleSuffix);
+      if (filePath.exists())
+        return filePath.toString();
+    }
+  }
+  return null;
+}
+
+/// Builds a module dependency graph.
+class GraphBuilder
+{
+  Graph graph;
+  IGraphOption options;
+  string[] importPaths; /// Where to look for modules.
+  Vertex[string] loadedModulesTable; /// Maps FQN paths to modules.
+  bool delegate(string) filterPredicate;
+
+  this()
+  {
+    this.graph = new Graph;
+  }
+
+  /// Start building the graph and return that.
+  /// Params:
+  ///   fileName = the file name of the root module.
+  Graph start(string fileName)
+  {
+    loadModule(fileName);
+    return graph;
+  }
+
+  /// Loads all modules recursively and builds the graph at the same time.
+  /// Params:
+  ///   moduleFQNPath = the path version of the module FQN.$(BR)
+  ///                   E.g.: FQN = dil.ast.Node -> FQNPath = dil/ast/Node
+  Vertex loadModule(string moduleFQNPath)
+  {
+    // Look up in table if the module is already loaded.
+    auto pVertex = moduleFQNPath in loadedModulesTable;
+    if (pVertex !is null)
+      return *pVertex; // Returns null for filtered or unlocatable modules.
+
+    // Filter out modules.
+    if (filterPredicate && filterPredicate(moduleFQNPath))
+    { // Store null for filtered modules.
+      loadedModulesTable[moduleFQNPath] = null;
+      return null;
+    }
+
+    // Locate the module in the file system.
+    auto moduleFilePath = findModuleFilePath(moduleFQNPath, importPaths);
+
+    Vertex vertex;
+
+    if (moduleFilePath is null)
+    { // Module not found.
+      if (options & IGraphOption.IncludeUnlocatableModules)
+      { // Include module nevertheless.
+        vertex = new Vertex;
+        vertex.modul = new Module("");
+        vertex.modul.setFQN(replace(moduleFQNPath, dirSep, '.'));
+        graph.addVertex(vertex);
+      }
+      // Store vertex in the table (vertex may be null.)
+      loadedModulesTable[moduleFQNPath] = vertex;
+    }
+    else
+    {
+      auto modul = new Module(moduleFilePath);
+      // Use lightweight ImportParser.
+      modul.setParser(new ImportParser(modul.sourceText));
+      modul.parse();
+
+      vertex = new Vertex;
+      vertex.modul = modul;
+
+      graph.addVertex(vertex);
+      loadedModulesTable[modul.getFQNPath()] = vertex;
+
+      // Load the modules which this module depends on.
+      foreach (importDecl; modul.imports)
+      {
+        foreach (moduleFQNPath2; importDecl.getModuleFQNs(dirSep))
+        {
+          auto loaded = loadModule(moduleFQNPath2);
+          if (loaded !is null)
+          {
+            auto edge = graph.addEdge(vertex, loaded);
+            edge.isPublic = importDecl.isPublic();
+            edge.isStatic = importDecl.isStatic();
+          }
+        }
+      }
+    }
+    return vertex;
+  }
+}
+
+/// Executes the importgraph command.
+void execute(string filePathString, CompilationContext context, string[] strRegexps,
+             uint levels, string siStyle, string piStyle, IGraphOption options)
+{
+  // Init regular expressions.
+  RegExp[] regexps;
+  foreach (strRegexp; strRegexps)
+    regexps ~= new RegExp(strRegexp);
+
+  // Add the directory of the file to the import paths.
+  auto filePath = new FilePath(filePathString);
+  auto fileDir = filePath.folder();
+  context.importPaths ~= fileDir;
+
+  auto gbuilder = new GraphBuilder;
+
+  gbuilder.importPaths = context.importPaths;
+  gbuilder.options = options;
+  gbuilder.filterPredicate = (string moduleFQNPath) {
+    foreach (rx; regexps)
+      // Replace slashes: dil/ast/Node -> dil.ast.Node
+      if (rx.test(replace(moduleFQNPath.dup, dirSep, '.')))
+        return true;
+    return false;
+  };
+
+  auto graph = gbuilder.start(filePath.name());
+
+  if (options & (IGraphOption.PrintList | IGraphOption.PrintPaths))
+  {
+    if (options & IGraphOption.MarkCyclicModules)
+      graph.detectCycles();
+
+    if (options & IGraphOption.PrintPaths)
+      printModulePaths(graph.vertices, levels+1, "");
+    else
+      printModuleList(graph.vertices, levels+1, "");
+  }
+  else
+    printDotDocument(graph, siStyle, piStyle, options);
+}
+
+/// Prints the file paths to the modules.
+void printModulePaths(Vertex[] vertices, uint level, char[] indent)
+{
+  if (level == 0)
+    return;
+  foreach (vertex; vertices)
+  {
+    Stdout(indent)((vertex.isCyclic?"*":"")~vertex.modul.filePath).newline;
+    if (vertex.outgoing.length)
+      printModulePaths(vertex.outgoing, level-1, indent~"  ");
+  }
+}
+
+/// Prints a list of module FQNs.
+void printModuleList(Vertex[] vertices, uint level, char[] indent)
+{
+  if (level == 0)
+    return;
+  foreach (vertex; vertices)
+  {
+    Stdout(indent)((vertex.isCyclic?"*":"")~vertex.modul.getFQN()).newline;
+    if (vertex.outgoing.length)
+      printModuleList(vertex.outgoing, level-1, indent~"  ");
+  }
+}
+
+/// Prints the graph as a graphviz dot document.
+void printDotDocument(Graph graph, string siStyle, string piStyle,
+                      IGraphOption options)
+{
+  Vertex[][string] verticesByPckgName;
+  if (options & IGraphOption.GroupByFullPackageName)
+    foreach (vertex; graph.vertices)
+      verticesByPckgName[vertex.modul.packageName] ~= vertex;
+
+  if (options & (IGraphOption.HighlightCyclicVertices |
+                 IGraphOption.HighlightCyclicEdges))
+    graph.detectCycles();
+
+  // Output header of the dot document.
+  Stdout("Digraph ImportGraph\n{\n");
+  // Output nodes.
+  // 'i' and vertex.id should be the same.
+  foreach (i, vertex; graph.vertices)
+    Stdout.formatln(`  n{} [label="{}"{}];`, i, vertex.modul.getFQN(), (vertex.isCyclic ? ",style=filled,fillcolor=tomato" : ""));
+
+  // Output edges.
+  foreach (edge; graph.edges)
+  {
+    string edgeStyles = "";
+    if (edge.isStatic || edge.isPublic)
+    {
+      edgeStyles = `[style="`;
+      edge.isStatic && (edgeStyles ~= siStyle ~ ",");
+      edge.isPublic && (edgeStyles ~= piStyle);
+      edgeStyles[$-1] == ',' && (edgeStyles = edgeStyles[0..$-1]); // Remove last comma.
+      edgeStyles ~= `"]`;
+    }
+    edge.isCyclic && (edgeStyles ~= "[color=red]");
+    Stdout.formatln(`  n{} -> n{} {};`, edge.from.id, edge.to.id, edgeStyles);
+  }
+
+  if (options & IGraphOption.GroupByFullPackageName)
+    foreach (packageName, vertices; verticesByPckgName)
+    { // Output nodes in a cluster.
+      Stdout.format(`  subgraph "cluster_{}" {`\n`    label="{}";color=blue;`"\n    ", packageName, packageName);
+      foreach (vertex; vertices)
+        Stdout.format(`n{};`, vertex.id);
+      Stdout("\n  }\n");
+    }
+
+  Stdout("}\n");
+}
+
+// This is the old algorithm that was used to detect cycles in a directed graph.
+void analyzeGraph(Vertex[] vertices_init, Edge[] edges)
+{
+  edges = edges.dup;
+  void recursive(Vertex[] vertices)
+  {
+    foreach (idx, vertex; vertices)
+    {
+      uint outgoing, incoming;
+      foreach (j, edge; edges)
+      {
+        if (edge.from is vertex)
+          outgoing++;
+        if (edge.to is vertex)
+          incoming++;
+      }
+
+      if (outgoing == 0)
+      {
+        if (incoming != 0)
+        {
+          // Vertex is a sink.
+          alias outgoing i; // Reuse
+          alias incoming j; // Reuse
+          // Remove edges.
+          for (i=j=0; i < edges.length; i++)
+            if (edges[i].to !is vertex)
+              edges[j++] = edges[i];
+          edges.length = j;
+          vertices = vertices[0..idx] ~ vertices[idx+1..$];
+          recursive(vertices);
+          return;
+        }
+        else
+        {
+          // Edges to this vertex were removed previously.
+          // Only remove vertex now.
+          vertices = vertices[0..idx] ~ vertices[idx+1..$];
+          recursive(vertices);
+          return;
+        }
+      }
+      else if (incoming == 0)
+      {
+        // Vertex is a source
+        alias outgoing i; // Reuse
+        alias incoming j; // Reuse
+        // Remove edges.
+        for (i=j=0; i < edges.length; i++)
+          if (edges[i].from !is vertex)
+            edges[j++] = edges[i];
+        edges.length = j;
+        vertices = vertices[0..idx] ~ vertices[idx+1..$];
+        recursive(vertices);
+        return;
+      }
+//       else
+//       {
+//         // source && sink
+//         // continue loop.
+//       }
+    }
+
+    // When reaching this point it means only cylic edges and vertices are left.
+    foreach (vertex; vertices)
+      vertex.isCyclic = true;
+    foreach (edge; edges)
+      if (edge)
+        edge.isCyclic = true;
+  }
+  recursive(vertices_init);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cmd/Statistics.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,212 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module cmd.Statistics;
+
+import cmd.ASTStats;
+import dil.lexer.Lexer;
+import dil.lexer.Token;
+import dil.parser.Parser;
+import dil.ast.NodesEnum;
+import dil.SourceText;
+import common;
+
+/// A group of statistics variables.
+struct Statistics
+{
+  uint whitespaceCount; /// Counter for whitespace characters.
+  uint wsTokenCount;    /// Counter for all whitespace tokens.
+  uint keywordCount;    /// Counter for keywords.
+  uint identCount;      /// Counter for identifiers.
+  uint numberCount;     /// Counter for number literals.
+  uint commentCount;    /// Counter for comments.
+  uint tokenCount;      /// Counter for all tokens produced by the Lexer.
+  uint linesOfCode;     /// Number of lines.
+  uint[] tokensTable;   /// Table of counters for all token kinds.
+  uint[] nodesTable;    /// Table of counters for all node kinds.
+
+  static Statistics opCall(bool allocateTokensTable, bool allocateNodesTable = false)
+  {
+    Statistics s;
+    if (allocateTokensTable)
+      s.tokensTable = new uint[TOK.MAX];
+    if (allocateNodesTable)
+      s.nodesTable = new uint[g_classNames.length];
+    return s;
+  }
+
+  void opAddAssign(Statistics s)
+  {
+    this.whitespaceCount += s.whitespaceCount;
+    this.wsTokenCount    += s.wsTokenCount;
+    this.keywordCount    += s.keywordCount;
+    this.identCount      += s.identCount;
+    this.numberCount     += s.numberCount;
+    this.commentCount    += s.commentCount;
+    this.tokenCount      += s.tokenCount;
+    this.linesOfCode     += s.linesOfCode;
+    foreach (i, count; s.tokensTable)
+      this.tokensTable[i] += count;
+    foreach (i, count; s.nodesTable)
+      this.nodesTable[i] += count;
+  }
+}
+
+/// Executes the statistics command.
+void execute(string[] filePaths, bool printTokensTable, bool printNodesTable)
+{
+  Statistics[] stats;
+  foreach (filePath; filePaths)
+    stats ~= getStatistics(filePath, printTokensTable, printNodesTable);
+
+  auto total = Statistics(printTokensTable, printNodesTable);
+
+  foreach (i, ref stat; stats)
+  {
+    total += stat;
+    Stdout.formatln(
+      "----\n"
+      "File: {}\n"
+      "Whitespace character count: {}\n"
+      "Whitespace token count: {}\n"
+      "Keyword count: {}\n"
+      "Identifier count: {}\n"
+      "Number count: {}\n"
+      "Comment count: {}\n"
+      "All tokens count: {}\n"
+      "Lines of code: {}",
+      filePaths[i],
+      stat.whitespaceCount,
+      stat.wsTokenCount,
+      stat.keywordCount,
+      stat.identCount,
+      stat.numberCount,
+      stat.commentCount,
+      stat.tokenCount,
+      stat.linesOfCode
+    );
+  }
+
+  if (filePaths.length > 1)
+  {
+    Stdout.formatln(
+      "--------------------------------------------------------------------------------\n"
+      "Total of {} files:\n"
+      "Whitespace character count: {}\n"
+      "Whitespace token count: {}\n"
+      "Keyword count: {}\n"
+      "Identifier count: {}\n"
+      "Number count: {}\n"
+      "Comment count: {}\n"
+      "All tokens count: {}\n"
+      "Lines of code: {}",
+      filePaths.length,
+      total.whitespaceCount,
+      total.wsTokenCount,
+      total.keywordCount,
+      total.identCount,
+      total.numberCount,
+      total.commentCount,
+      total.tokenCount,
+      total.linesOfCode
+    );
+  }
+
+  if (printTokensTable)
+  {
+    Stdout("Table of tokens:").newline;
+    Stdout.formatln(" {,10} | {}", "Count", "Token kind");
+    Stdout("-----------------------------").newline;
+    foreach (i, count; total.tokensTable)
+      Stdout.formatln(" {,10} | {}", count, Token.toString(cast(TOK)i));
+    Stdout("// End of tokens table.").newline;
+  }
+
+  if(printNodesTable)
+  {
+    Stdout("Table of nodes:").newline;
+    Stdout.formatln(" {,10} | {}", "Count", "Node kind");
+    Stdout("-----------------------------").newline;
+    foreach (i, count; total.nodesTable)
+      Stdout.formatln(" {,10} | {}", count, g_classNames[i]);
+    Stdout("// End of nodes table.").newline;
+  }
+}
+
+/// Returns the statistics for a D source file.
+Statistics getStatistics(string filePath, bool printTokensTable, bool printNodesTable)
+{
+  // Create a new record.
+  auto stats = Statistics(printTokensTable);
+
+  auto sourceText = new SourceText(filePath, true);
+  Parser parser;
+  Lexer lx;
+  if (printNodesTable)
+  {
+    parser = new Parser(sourceText);
+    auto rootNode = parser.start();
+    // Count nodes.
+    stats.nodesTable = (new ASTStats).count(rootNode);
+    lx = parser.lexer;
+  }
+  else
+  {
+    lx = new Lexer(sourceText);
+    lx.scanAll();
+  }
+
+  auto token = lx.firstToken();
+
+  // Count tokens.
+  // Lexer creates HEAD + Newline, which are not in the source text.
+  // No token left behind!
+  stats.tokenCount = 2;
+  stats.linesOfCode = lx.lineNum;
+  if (printTokensTable)
+  {
+    stats.tokensTable[TOK.HEAD] = 1;
+    stats.tokensTable[TOK.Newline] = 1;
+  }
+  // Traverse linked list.
+  while (1)
+  {
+    stats.tokenCount += 1;
+
+    if (printTokensTable)
+      stats.tokensTable[token.kind] += 1;
+
+    // Count whitespace characters
+    if (token.ws !is null)
+      stats.whitespaceCount += token.start - token.ws;
+
+    switch (token.kind)
+    {
+    case TOK.Identifier:
+      stats.identCount++;
+      break;
+    case TOK.Comment:
+      stats.commentCount++;
+      break;
+    case TOK.Int32, TOK.Int64, TOK.Uint32, TOK.Uint64,
+         TOK.Float32, TOK.Float64, TOK.Float80,
+         TOK.Imaginary32, TOK.Imaginary64, TOK.Imaginary80:
+      stats.numberCount++;
+      break;
+    case TOK.Newline:
+      break;
+    default:
+      if (token.isKeyword)
+        stats.keywordCount++;
+      else if (token.isWhitespace)
+        stats.wsTokenCount++;
+    }
+
+    if (token.next is null)
+      break;
+    token = token.next;
+  }
+  assert(token.kind == TOK.EOF);
+  return stats;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,20 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module common;
+
+public import tango.io.Stdout;
+public import tango.text.convert.Layout;
+
+/// String aliases.
+alias char[] string;
+alias wchar[] wstring; /// ditto
+alias dchar[] dstring; /// ditto
+
+/// Global formatter instance.
+static Layout!(char) Format;
+static this()
+{
+  Format = new typeof(Format);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/config.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,34 @@
+/// The configuration file of dil.
+///
+/// Relative paths are resolved from the directory of the executable.
+module config;
+
+/// Predefined version identifiers.
+var version_ids = ["X86", "linux", "LittleEndian"];
+// "X86_64", "Windows", "Win32", "Win64", "BigEndian"
+
+/// Path to the language file.
+var langfile = "lang_en.d";
+
+/// An array of import paths to look for modules.
+var import_paths = []; /// E.g.: ["src/", "import/"]
+
+/// DDoc macro file paths.
+///
+/// Macro definitions in ddoc_files[n] override the ones in ddoc_files[n-1].
+var ddoc_files = ["predefined.ddoc"]; /// E.g.: ["src/mymacros.ddoc", "othermacros.ddoc"]
+
+var xml_map = "xml_map.d";
+var html_map = "html_map.d";
+
+/// Customizable formats for error messages.
+///
+/// <ul>
+///   <li>0: file path to the source text.</li>
+///   <li>1: line number.</li>
+///   <li>2: column number.</li>
+///   <li>3: error message.</li>
+/// </ul>
+var lexer_error = "{0}({1},{2})L: {3}";
+var parser_error = "{0}({1},{2})P: {3}"; /// ditto
+var semantic_error = "{0}({1},{2})S: {3}"; /// ditto
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/Compilation.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,69 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.Compilation;
+
+import common;
+
+/// A group of settings relevant to the compilation process.
+class CompilationContext
+{
+  alias typeof(this) CC;
+  CC parent;
+  string[] importPaths;
+  uint debugLevel;
+  uint versionLevel;
+  bool[string] debugIds;
+  bool[string] versionIds;
+  bool releaseBuild;
+  uint structAlign = 4;
+
+  this(CC parent = null)
+  {
+    this.parent = parent;
+    if (parent)
+    {
+      this.importPaths = parent.importPaths.dup;
+      this.debugLevel = parent.debugLevel;
+      this.versionLevel = parent.versionLevel;
+      this.releaseBuild = parent.releaseBuild;
+      this.structAlign = parent.structAlign;
+    }
+  }
+
+  void addDebugId(string id)
+  {
+    debugIds[id] = true;
+  }
+
+  void addVersionId(string id)
+  {
+    versionIds[id] = true;
+  }
+
+  bool findDebugId(string id)
+  {
+    auto pId = id in debugIds;
+    if (pId)
+      return true;
+    if (!isRoot())
+      return parent.findDebugId(id);
+    return false;
+  }
+
+  bool findVersionId(string id)
+  {
+    auto pId = id in versionIds;
+    if (pId)
+      return true;
+    if (!isRoot())
+      return parent.findVersionId(id);
+    return false;
+  }
+
+  bool isRoot()
+  {
+    return parent is null;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/CompilerInfo.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,50 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.CompilerInfo;
+
+version(D2)
+  /// The major version number of this compiler.
+  const uint VERSION_MAJOR = 2;
+else
+  /// The major version number of this compiler.
+  const uint VERSION_MAJOR = 1;
+
+/// The minor version number of this compiler.
+const uint VERSION_MINOR = 0;
+
+private char[] toString(uint x)
+{
+  char[] str;
+  do
+    str = cast(char)('0' + (x % 10)) ~ str;
+  while (x /= 10)
+  return str;
+}
+
+private char[] toString(uint x, uint pad)
+{
+  char[] str = toString(x);
+  if (pad < str.length)
+    return str;
+  for (uint i = pad-str.length; i; i--)
+    str = "0" ~ str;
+  return str;
+}
+
+/// The compiler version formatted as a string.
+const char[] VERSION = toString(VERSION_MAJOR)~"."~toString(VERSION_MINOR, 3);
+/// The name of the compiler.
+const char[] VENDOR = "dil";
+
+/// The global, default alignment size for struct fields.
+const uint DEFAULT_ALIGN_SIZE = 4;
+
+version(DDoc)
+  const uint PTR_SIZE = 0; /// The pointer size depending on the platform.
+else
+version(X86_64)
+  const uint PTR_SIZE = 8; // Pointer size on 64-bit platforms.
+else
+  const uint PTR_SIZE = 4; // Pointer size on 32-bit platforms.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/Converter.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,334 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.Converter;
+
+import dil.Information;
+import dil.Location;
+import dil.Unicode;
+import dil.FileBOM;
+import dil.lexer.Funcs;
+import dil.Messages;
+import common;
+
+/// Converts various Unicode encoding formats to UTF-8.
+struct Converter
+{
+  char[] filePath; /// For error messages.
+  InfoManager infoMan;
+
+  static Converter opCall(char[] filePath, InfoManager infoMan)
+  {
+    Converter conv;
+    conv.filePath = filePath;
+    conv.infoMan = infoMan;
+    return conv;
+  }
+
+  /// Byte-swaps c.
+  dchar swapBytes(dchar c)
+  {
+    return c = (c << 24) |
+              ((c >> 8) & 0xFF00) |
+              ((c << 8) & 0xFF0000) |
+              (c >> 24);
+  }
+
+  /// Byte-swaps c.
+  wchar swapBytes(wchar c)
+  {
+    return (c << 8) | (c >> 8);
+  }
+
+  /// Swaps the bytes of c on a little-endian machine.
+  dchar BEtoMachineDword(dchar c)
+  {
+    version(LittleEndian)
+      return swapBytes(c);
+    else
+      return c;
+  }
+
+  /// Swaps the bytes of c on a big-endian machine.
+  dchar LEtoMachineDword(dchar c)
+  {
+    version(LittleEndian)
+      return c;
+    else
+      return swapBytes(c);
+  }
+
+  /// Swaps the bytes of c on a little-endian machine.
+  wchar BEtoMachineWord(wchar c)
+  {
+    version(LittleEndian)
+      return swapBytes(c);
+    else
+      return c;
+  }
+
+  /// Swaps the bytes of c on a big-endian machine.
+  wchar LEtoMachineWord(wchar c)
+  {
+    version(LittleEndian)
+      return c;
+    else
+      return swapBytes(c);
+  }
+
+  /// Converts a UTF-32 text to UTF-8.
+  char[] UTF32toUTF8(bool isBigEndian)(ubyte[] data)
+  {
+    if (data.length == 0)
+      return null;
+
+    char[] result;
+    uint lineNum = 1;
+    dchar[] text = cast(dchar[]) data[0 .. $-($%4)]; // Trim to multiple of 4.
+    foreach (dchar c; text)
+    {
+      static if (isBigEndian)
+        c = BEtoMachineDword(c);
+      else
+        c = LEtoMachineDword(c);
+
+      if (!isValidChar(c))
+      {
+        infoMan ~= new LexerError(
+          new Location(filePath, lineNum),
+          Format(MSG.InvalidUTF32Character, c)
+        );
+        c = REPLACEMENT_CHAR;
+      }
+
+      if (isNewline(c))
+        ++lineNum;
+      dil.Unicode.encode(result, c);
+    }
+
+    if (data.length % 4)
+      infoMan ~= new LexerError(
+        new Location(filePath, lineNum),
+        MSG.UTF32FileMustBeDivisibleBy4
+      );
+
+    return result;
+  }
+
+  alias UTF32toUTF8!(true) UTF32BEtoUTF8; /// Instantiation for UTF-32 BE.
+  alias UTF32toUTF8!(false) UTF32LEtoUTF8; /// Instantiation for UTF-32 LE.
+
+  /// Converts a UTF-16 text to UTF-8.
+  char[] UTF16toUTF8(bool isBigEndian)(ubyte[] data)
+  {
+    if (data.length == 0)
+      return null;
+
+    wchar[] text = cast(wchar[]) data[0 .. $-($%2)]; // Trim to multiple of two.
+    wchar* p = text.ptr,
+         end = text.ptr + text.length;
+    char[] result;
+    uint lineNum = 1;
+
+    for (; p < end; p++)
+    {
+      dchar c = *p;
+      static if (isBigEndian)
+        c = BEtoMachineWord(c);
+      else
+        c = LEtoMachineWord(c);
+
+      if (0xD800 > c || c > 0xDFFF)
+      {}
+      else if (c <= 0xDBFF && p+1 < end)
+      { // Decode surrogate pairs.
+        wchar c2 = p[1];
+        static if (isBigEndian)
+          c2 = BEtoMachineWord(c2);
+        else
+          c2 = LEtoMachineWord(c2);
+
+        if (0xDC00 <= c2 && c2 <= 0xDFFF)
+        {
+          c = (c - 0xD7C0) << 10;
+          c |= (c2 & 0x3FF);
+          ++p;
+        }
+      }
+      else
+      {
+        infoMan ~= new LexerError(
+          new Location(filePath, lineNum),
+          Format(MSG.InvalidUTF16Character, c)
+        );
+        c = REPLACEMENT_CHAR;
+      }
+
+      if (isNewline(c))
+        ++lineNum;
+      dil.Unicode.encode(result, c);
+    }
+
+    if (data.length % 2)
+      infoMan ~= new LexerError(
+        new Location(filePath, lineNum),
+        MSG.UTF16FileMustBeDivisibleBy2
+      );
+    return result;
+  }
+
+  alias UTF16toUTF8!(true) UTF16BEtoUTF8; /// Instantiation for UTF-16 BE.
+  alias UTF16toUTF8!(false) UTF16LEtoUTF8; /// Instantiation for UTF-16 LE.
+
+  /// Converts the text in data to UTF-8.
+  /// Leaves data unchanged if it is in UTF-8 already.
+  char[] data2UTF8(ubyte[] data)
+  {
+    if (data.length == 0)
+      return "";
+
+    char[] text;
+    BOM bom = tellBOM(data);
+
+    switch (bom)
+    {
+    case BOM.None:
+      // No BOM found. According to the specs the first character
+      // must be an ASCII character.
+      if (data.length >= 4)
+      {
+        if (data[0..3] == cast(ubyte[3])x"00 00 00")
+        {
+          text = UTF32BEtoUTF8(data); // UTF-32BE: 00 00 00 XX
+          break;
+        }
+        else if (data[1..4] == cast(ubyte[3])x"00 00 00")
+        {
+          text = UTF32LEtoUTF8(data); // UTF-32LE: XX 00 00 00
+          break;
+        }
+      }
+      if (data.length >= 2)
+      {
+        if (data[0] == 0) // UTF-16BE: 00 XX
+        {
+          text = UTF16BEtoUTF8(data);
+          break;
+        }
+        else if (data[1] == 0) // UTF-16LE: XX 00
+        {
+          text = UTF16LEtoUTF8(data);
+          break;
+        }
+      }
+      text = cast(char[])data; // UTF-8
+      break;
+    case BOM.UTF8:
+      text = cast(char[])data[3..$];
+      break;
+    case BOM.UTF16BE:
+      text = UTF16BEtoUTF8(data[2..$]);
+      break;
+    case BOM.UTF16LE:
+      text = UTF16LEtoUTF8(data[2..$]);
+      break;
+    case BOM.UTF32BE:
+      text = UTF32BEtoUTF8(data[4..$]);
+      break;
+    case BOM.UTF32LE:
+      text = UTF32LEtoUTF8(data[4..$]);
+      break;
+    default:
+      assert(0);
+    }
+    return text;
+  }
+}
+
+/// Replaces invalid UTF-8 sequences with U+FFFD (if there's enough space,)
+/// and Newlines with '\n'.
+string sanitizeText(string text)
+{
+  if (!text.length)
+    return null;
+
+  char* p = text.ptr;
+  char* end = p + text.length;
+  char* q = p;
+
+  for (; p < end; p++, q++)
+  {
+    assert(q <= p);
+    switch (*p)
+    {
+    case '\r':
+      if (p+1 < end && p[1] == '\n')
+        p++;
+    case '\n':
+      *q = '\n';
+      continue;
+    default:
+      if (isascii(*p))
+        break;
+      if (p+2 < end && isUnicodeNewline(p))
+      {
+        p += 2;
+        goto case '\n';
+      }
+      auto p2 = p; // Beginning of the UTF-8 sequence.
+      dchar c = decode(p, end);
+      if (c == ERROR_CHAR)
+      { // Skip to next ASCII character or valid UTF-8 sequence.
+        while (++p < end && isTrailByte(*p))
+        {}
+        alias REPLACEMENT_STR R;
+        if (q+2 < p) // Copy replacement char if there is enough space.
+          (*q = R[0]), (*++q = R[1]), (*++q = R[2]);
+        p--;
+      }
+      else
+      { // Copy the valid UTF-8 sequence.
+        while (p2 <= p) // p points to the last trail byte.
+          *q++ = *p2++; // Copy code units.
+        q--;
+      }
+      continue;
+    }
+    assert(isascii(*p));
+    *q = *p;
+  }
+  assert(p == end);
+  text.length = text.length - (p - q);
+  //text = text.ptr[0 .. q - text.ptr]; // Another way.
+  return text;
+}
+
+unittest
+{
+  Stdout("Testing function Converter.\n");
+  struct Data2Text
+  {
+    char[] text;
+    char[] expected = "source";
+    ubyte[] data()
+    { return cast(ubyte[])text; }
+  }
+  const Data2Text[] map = [
+    // Without BOM
+    {"source"},
+    {"s\0o\0u\0r\0c\0e\0"},
+    {"\0s\0o\0u\0r\0c\0e"},
+    {"s\0\0\0o\0\0\0u\0\0\0r\0\0\0c\0\0\0e\0\0\0"},
+    {"\0\0\0s\0\0\0o\0\0\0u\0\0\0r\0\0\0c\0\0\0e"},
+    // With BOM
+    {"\xEF\xBB\xBFsource"},
+    {"\xFE\xFF\0s\0o\0u\0r\0c\0e"},
+    {"\xFF\xFEs\0o\0u\0r\0c\0e\0"},
+    {"\x00\x00\xFE\xFF\0\0\0s\0\0\0o\0\0\0u\0\0\0r\0\0\0c\0\0\0e"},
+    {"\xFF\xFE\x00\x00s\0\0\0o\0\0\0u\0\0\0r\0\0\0c\0\0\0e\0\0\0"},
+  ];
+  auto converter = Converter("", new InfoManager);
+  foreach (i, pair; map)
+    assert(converter.data2UTF8(pair.data) == pair.expected, Format("failed at item {}", i));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/Enums.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,121 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.Enums;
+
+import common;
+
+/// Enumeration of storage classes.
+enum StorageClass
+{
+  None         = 0,
+  Abstract     = 1,
+  Auto         = 1<<2,
+  Const        = 1<<3,
+  Deprecated   = 1<<4,
+  Extern       = 1<<5,
+  Final        = 1<<6,
+  Invariant    = 1<<7,
+  Override     = 1<<8,
+  Scope        = 1<<9,
+  Static       = 1<<10,
+  Synchronized = 1<<11,
+  In           = 1<<12,
+  Out          = 1<<13,
+  Ref          = 1<<14,
+  Lazy         = 1<<15,
+  Variadic     = 1<<16,
+}
+
+/// Enumeration of protection attributes.
+enum Protection
+{
+  None,
+  Private/+   = 1+/,
+  Protected/+ = 1<<1+/,
+  Package/+   = 1<<2+/,
+  Public/+    = 1<<3+/,
+  Export/+    = 1<<4+/
+}
+
+/// Enumeration of linkage types.
+enum LinkageType
+{
+  None,
+  C,
+  Cpp,
+  D,
+  Windows,
+  Pascal,
+  System
+}
+
+/// Returns the string for prot.
+string toString(Protection prot)
+{
+  switch (prot)
+  { alias Protection P;
+  case P.None:      return "";
+  case P.Private:   return "private";
+  case P.Protected: return "protected";
+  case P.Package:   return "package";
+  case P.Public:    return "public";
+  case P.Export:    return "export";
+  default:
+    assert(0);
+  }
+}
+
+/// Returns the string of a storage class. Only one bit may be set.
+string toString(StorageClass stc)
+{
+  switch (stc)
+  { alias StorageClass SC;
+  case SC.Abstract:     return "abstract";
+  case SC.Auto:         return "auto";
+  case SC.Const:        return "const";
+  case SC.Deprecated:   return "deprecated";
+  case SC.Extern:       return "extern";
+  case SC.Final:        return "final";
+  case SC.Invariant:    return "invariant";
+  case SC.Override:     return "override";
+  case SC.Scope:        return "scope";
+  case SC.Static:       return "static";
+  case SC.Synchronized: return "synchronized";
+  case SC.In:           return "in";
+  case SC.Out:          return "out";
+  case SC.Ref:          return "ref";
+  case SC.Lazy:         return "lazy";
+  case SC.Variadic:     return "variadic";
+  default:
+    assert(0);
+  }
+}
+
+/// Returns the strings for stc. Any number of bits may be set.
+string[] toStrings(StorageClass stc)
+{
+  string[] result;
+  for (auto i = StorageClass.max; i; i >>= 1)
+    if (stc & i)
+      result ~= toString(i);
+  return result;
+}
+
+/// Returns the string for ltype.
+string toString(LinkageType ltype)
+{
+  switch (ltype)
+  { alias LinkageType LT;
+  case LT.None:    return "";
+  case LT.C:       return "C";
+  case LT.Cpp:     return "Cpp";
+  case LT.D:       return "D";
+  case LT.Windows: return "Windows";
+  case LT.Pascal:  return "Pascal";
+  case LT.System:  return "System";
+  default:
+    assert(0);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/FileBOM.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,86 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.FileBOM;
+import common;
+
+/// Enumeration of byte order marks.
+enum BOM
+{
+  None,    /// No BOM
+  UTF8,    /// UTF-8: EF BB BF
+  UTF16BE, /// UTF-16 Big Endian: FE FF
+  UTF16LE, /// UTF-16 Little Endian: FF FE
+  UTF32BE, /// UTF-32 Big Endian: 00 00 FE FF
+  UTF32LE  /// UTF-32 Little Endian: FF FE 00 00
+}
+
+/// Looks at the first bytes of data and returns the corresponding BOM.
+BOM tellBOM(ubyte[] data)
+{
+  BOM bom = BOM.None;
+  if (data.length < 2)
+    return bom;
+
+  if (data[0..2] == cast(ubyte[2])x"FE FF")
+  {
+    bom = BOM.UTF16BE; // FE FF
+  }
+  else if (data[0..2] == cast(ubyte[2])x"FF FE")
+  {
+    if (data.length >= 4 && data[2..4] == cast(ubyte[2])x"00 00")
+      bom = BOM.UTF32LE; // FF FE 00 00
+    else
+      bom = BOM.UTF16LE; // FF FE XX XX
+  }
+  else if (data[0..2] == cast(ubyte[2])x"00 00")
+  {
+    if (data.length >= 4 && data[2..4] == cast(ubyte[2])x"FE FF")
+      bom = BOM.UTF32BE; // 00 00 FE FF
+  }
+  else if (data[0..2] ==  cast(ubyte[2])x"EF BB")
+  {
+    if (data.length >= 3 && data[2] == '\xBF')
+      bom =  BOM.UTF8; // EF BB BF
+  }
+  return bom;
+}
+
+unittest
+{
+  Stdout("Testing function tellBOM().\n");
+
+  struct Data2BOM
+  {
+    ubyte[] data;
+    BOM bom;
+  }
+  alias ubyte[] ub;
+  const Data2BOM[] map = [
+    {cast(ub)x"12",          BOM.None},
+    {cast(ub)x"12 34",       BOM.None},
+    {cast(ub)x"00 00 FF FE", BOM.None},
+    {cast(ub)x"EF BB FF",    BOM.None},
+
+    {cast(ub)x"EF",          BOM.None},
+    {cast(ub)x"EF BB",       BOM.None},
+    {cast(ub)x"FE",          BOM.None},
+    {cast(ub)x"FF",          BOM.None},
+    {cast(ub)x"00",          BOM.None},
+    {cast(ub)x"00 00",       BOM.None},
+    {cast(ub)x"00 00 FE",    BOM.None},
+
+    {cast(ub)x"FE FF 00",    BOM.UTF16BE},
+    {cast(ub)x"FE FF 00 FF", BOM.UTF16BE},
+
+    {cast(ub)x"EF BB BF",    BOM.UTF8},
+    {cast(ub)x"FE FF",       BOM.UTF16BE},
+    {cast(ub)x"FF FE",       BOM.UTF16LE},
+    {cast(ub)x"00 00 FE FF", BOM.UTF32BE},
+    {cast(ub)x"FF FE 00 00", BOM.UTF32LE}
+  ];
+
+  foreach (pair; map)
+    assert(tellBOM(pair.data) == pair.bom, Format("Failed at {0}", pair.data));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/HtmlEntities.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,376 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.HtmlEntities;
+
+import common;
+
+/// A named HTML entity.
+struct Entity
+{
+  char[] name;
+  dchar value;
+}
+
+/// The table of named HTML entities.
+static const Entity[] namedEntities = [
+  {"Aacute", '\u00C1'},
+  {"aacute", '\u00E1'},
+  {"Acirc", '\u00C2'},
+  {"acirc", '\u00E2'},
+  {"acute", '\u00B4'},
+  {"AElig", '\u00C6'},
+  {"aelig", '\u00E6'},
+  {"Agrave", '\u00C0'},
+  {"agrave", '\u00E0'},
+  {"alefsym", '\u2135'},
+  {"Alpha", '\u0391'},
+  {"alpha", '\u03B1'},
+  {"amp", '\u0026'},
+  {"and", '\u2227'},
+  {"ang", '\u2220'},
+  {"Aring", '\u00C5'},
+  {"aring", '\u00E5'},
+  {"asymp", '\u2248'},
+  {"Atilde", '\u00C3'},
+  {"atilde", '\u00E3'},
+  {"Auml", '\u00C4'},
+  {"auml", '\u00E4'},
+  {"bdquo", '\u201E'},
+  {"Beta", '\u0392'},
+  {"beta", '\u03B2'},
+  {"brvbar", '\u00A6'},
+  {"bull", '\u2022'},
+  {"cap", '\u2229'},
+  {"Ccedil", '\u00C7'},
+  {"ccedil", '\u00E7'},
+  {"cedil", '\u00B8'},
+  {"cent", '\u00A2'},
+  {"Chi", '\u03A7'},
+  {"chi", '\u03C7'},
+  {"circ", '\u02C6'},
+  {"clubs", '\u2663'},
+  {"cong", '\u2245'},
+  {"copy", '\u00A9'},
+  {"crarr", '\u21B5'},
+  {"cup", '\u222A'},
+  {"curren", '\u00A4'},
+  {"Dagger", '\u2021'},
+  {"dagger", '\u2020'},
+  {"dArr", '\u21D3'},
+  {"darr", '\u2193'},
+  {"deg", '\u00B0'},
+  {"Delta", '\u0394'},
+  {"delta", '\u03B4'},
+  {"diams", '\u2666'},
+  {"divide", '\u00F7'},
+  {"Eacute", '\u00C9'},
+  {"eacute", '\u00E9'},
+  {"Ecirc", '\u00CA'},
+  {"ecirc", '\u00EA'},
+  {"Egrave", '\u00C8'},
+  {"egrave", '\u00E8'},
+  {"empty", '\u2205'},
+  {"emsp", '\u2003'},
+  {"ensp", '\u2002'},
+  {"Epsilon", '\u0395'},
+  {"epsilon", '\u03B5'},
+  {"equiv", '\u2261'},
+  {"Eta", '\u0397'},
+  {"eta", '\u03B7'},
+  {"ETH", '\u00D0'},
+  {"eth", '\u00F0'},
+  {"Euml", '\u00CB'},
+  {"euml", '\u00EB'},
+  {"euro", '\u20AC'},
+  {"exist", '\u2203'},
+  {"fnof", '\u0192'},
+  {"forall", '\u2200'},
+  {"frac12", '\u00BD'},
+  {"frac14", '\u00BC'},
+  {"frac34", '\u00BE'},
+  {"frasl", '\u2044'},
+  {"Gamma", '\u0393'},
+  {"gamma", '\u03B3'},
+  {"ge", '\u2265'},
+  {"gt", '\u003E'},
+  {"hArr", '\u21D4'},
+  {"harr", '\u2194'},
+  {"hearts", '\u2665'},
+  {"hellip", '\u2026'},
+  {"Iacute", '\u00CD'},
+  {"iacute", '\u00ED'},
+  {"Icirc", '\u00CE'},
+  {"icirc", '\u00EE'},
+  {"iexcl", '\u00A1'},
+  {"Igrave", '\u00CC'},
+  {"igrave", '\u00EC'},
+  {"image", '\u2111'},
+  {"infin", '\u221E'},
+  {"int", '\u222B'},
+  {"Iota", '\u0399'},
+  {"iota", '\u03B9'},
+  {"iquest", '\u00BF'},
+  {"isin", '\u2208'},
+  {"Iuml", '\u00CF'},
+  {"iuml", '\u00EF'},
+  {"Kappa", '\u039A'},
+  {"kappa", '\u03BA'},
+  {"Lambda", '\u039B'},
+  {"lambda", '\u03BB'},
+  {"lang", '\u2329'},
+  {"laquo", '\u00AB'},
+  {"lArr", '\u21D0'},
+  {"larr", '\u2190'},
+  {"lceil", '\u2308'},
+  {"ldquo", '\u201C'},
+  {"le", '\u2264'},
+  {"lfloor", '\u230A'},
+  {"lowast", '\u2217'},
+  {"loz", '\u25CA'},
+  {"lrm", '\u200E'},
+  {"lsaquo", '\u2039'},
+  {"lsquo", '\u2018'},
+  {"lt", '\u003C'},
+  {"macr", '\u00AF'},
+  {"mdash", '\u2014'},
+  {"micro", '\u00B5'},
+  {"middot", '\u00B7'},
+  {"minus", '\u2212'},
+  {"Mu", '\u039C'},
+  {"mu", '\u03BC'},
+  {"nabla", '\u2207'},
+  {"nbsp", '\u00A0'},
+  {"ndash", '\u2013'},
+  {"ne", '\u2260'},
+  {"ni", '\u220B'},
+  {"not", '\u00AC'},
+  {"notin", '\u2209'},
+  {"nsub", '\u2284'},
+  {"Ntilde", '\u00D1'},
+  {"ntilde", '\u00F1'},
+  {"Nu", '\u039D'},
+  {"nu", '\u03BD'},
+  {"Oacute", '\u00D3'},
+  {"oacute", '\u00F3'},
+  {"Ocirc", '\u00D4'},
+  {"ocirc", '\u00F4'},
+  {"OElig", '\u0152'},
+  {"oelig", '\u0153'},
+  {"Ograve", '\u00D2'},
+  {"ograve", '\u00F2'},
+  {"oline", '\u203E'},
+  {"Omega", '\u03A9'},
+  {"omega", '\u03C9'},
+  {"Omicron", '\u039F'},
+  {"omicron", '\u03BF'},
+  {"oplus", '\u2295'},
+  {"or", '\u2228'},
+  {"ordf", '\u00AA'},
+  {"ordm", '\u00BA'},
+  {"Oslash", '\u00D8'},
+  {"oslash", '\u00F8'},
+  {"Otilde", '\u00D5'},
+  {"otilde", '\u00F5'},
+  {"otimes", '\u2297'},
+  {"Ouml", '\u00D6'},
+  {"ouml", '\u00F6'},
+  {"para", '\u00B6'},
+  {"part", '\u2202'},
+  {"permil", '\u2030'},
+  {"perp", '\u22A5'},
+  {"Phi", '\u03A6'},
+  {"phi", '\u03C6'},
+  {"Pi", '\u03A0'},
+  {"pi", '\u03C0'},
+  {"piv", '\u03D6'},
+  {"plusmn", '\u00B1'},
+  {"pound", '\u00A3'},
+  {"Prime", '\u2033'},
+  {"prime", '\u2032'},
+  {"prod", '\u220F'},
+  {"prop", '\u221D'},
+  {"Psi", '\u03A8'},
+  {"psi", '\u03C8'},
+  {"quot", '\u0022'},
+  {"radic", '\u221A'},
+  {"rang", '\u232A'},
+  {"raquo", '\u00BB'},
+  {"rArr", '\u21D2'},
+  {"rarr", '\u2192'},
+  {"rceil", '\u2309'},
+  {"rdquo", '\u201D'},
+  {"real", '\u211C'},
+  {"reg", '\u00AE'},
+  {"rfloor", '\u230B'},
+  {"Rho", '\u03A1'},
+  {"rho", '\u03C1'},
+  {"rlm", '\u200F'},
+  {"rsaquo", '\u203A'},
+  {"rsquo", '\u2019'},
+  {"sbquo", '\u201A'},
+  {"Scaron", '\u0160'},
+  {"scaron", '\u0161'},
+  {"sdot", '\u22C5'},
+  {"sect", '\u00A7'},
+  {"shy", '\u00AD'},
+  {"Sigma", '\u03A3'},
+  {"sigma", '\u03C3'},
+  {"sigmaf", '\u03C2'},
+  {"sim", '\u223C'},
+  {"spades", '\u2660'},
+  {"sub", '\u2282'},
+  {"sube", '\u2286'},
+  {"sum", '\u2211'},
+  {"sup", '\u2283'},
+  {"sup1", '\u00B9'},
+  {"sup2", '\u00B2'},
+  {"sup3", '\u00B3'},
+  {"supe", '\u2287'},
+  {"szlig", '\u00DF'},
+  {"Tau", '\u03A4'},
+  {"tau", '\u03C4'},
+  {"there4", '\u2234'},
+  {"Theta", '\u0398'},
+  {"theta", '\u03B8'},
+  {"thetasym", '\u03D1'},
+  {"thinsp", '\u2009'},
+  {"THORN", '\u00DE'},
+  {"thorn", '\u00FE'},
+  {"tilde", '\u02DC'},
+  {"times", '\u00D7'},
+  {"trade", '\u2122'},
+  {"Uacute", '\u00DA'},
+  {"uacute", '\u00FA'},
+  {"uArr", '\u21D1'},
+  {"uarr", '\u2191'},
+  {"Ucirc", '\u00DB'},
+  {"ucirc", '\u00FB'},
+  {"Ugrave", '\u00D9'},
+  {"ugrave", '\u00F9'},
+  {"uml", '\u00A8'},
+  {"upsih", '\u03D2'},
+  {"Upsilon", '\u03A5'},
+  {"upsilon", '\u03C5'},
+  {"Uuml", '\u00DC'},
+  {"uuml", '\u00FC'},
+  {"weierp", '\u2118'},
+  {"Xi", '\u039E'},
+  {"xi", '\u03BE'},
+  {"Yacute", '\u00DD'},
+  {"yacute", '\u00FD'},
+  {"yen", '\u00A5'},
+  {"Yuml", '\u0178'},
+  {"yuml", '\u00FF'},
+  {"Zeta", '\u0396'},
+  {"zeta", '\u03B6'},
+  {"zwj", '\u200D'},
+  {"zwnj", '\u200C'}
+];
+
+uint stringToHash(char[] str)
+{
+  uint hash;
+  foreach(c; str) {
+    hash *= 11;
+    hash += c;
+  }
+  return hash;
+}
+
+char[] toString(uint x)
+{
+  char[] str;
+  do
+    str = cast(char)('0' + (x % 10)) ~ str;
+  while (x /= 10)
+  return str;
+}
+
+char[] generateHashAndValueArrays()
+{
+  uint[] hashes; // String hashes.
+  dchar[] values; // Unicode codepoints.
+  // Build arrays:
+  foreach (entity; namedEntities)
+  {
+    auto hash = stringToHash(entity.name);
+    auto value = entity.value;
+    assert(hash != 0);
+    // Find insertion place.
+    uint i;
+    for (; i < hashes.length; ++i)
+    {
+      assert(hash != hashes[i], "bad hash function: conflicting hashes");
+      if (hash < hashes[i])
+        break;
+    }
+    // Insert hash and value into tables.
+    if (i == hashes.length)
+    {
+      hashes ~= hash;
+      values ~= value;
+    }
+    else
+    {
+      hashes = hashes[0..i] ~ hash ~ hashes[i..$]; // Insert before index.
+      values = values[0..i] ~ value ~ values[i..$]; // Insert before index.
+    }
+    assert(hashes[i] == hash && values[i] == value);
+  }
+  // Build source text:
+  char[] hashesText = "private static const uint[] hashes = [",
+         valuesText = "private static const dchar[] values = [";
+  foreach (i, hash; hashes)
+  {
+    hashesText ~= toString(hash) ~ ",";
+    valuesText ~= toString(values[i]) ~ ",";
+  }
+  hashesText ~= "];";
+  valuesText ~= "];";
+  return hashesText ~"\n"~ valuesText;
+}
+
+version(DDoc)
+{
+  /// Table of hash values of the entities' names.
+  private static const uint[] hashes;
+  /// Table of Unicode codepoints.
+  private static const dchar[] values;
+}
+else
+  mixin(generateHashAndValueArrays);
+// pragma(msg, generateHashAndValueArrays());
+
+/// Converts a named HTML entity into its equivalent Unicode codepoint.
+/// Returns: the entity's value or 0xFFFF if it doesn't exist.
+dchar entity2Unicode(char[] entity)
+{
+  auto hash = stringToHash(entity);
+  // Binary search:
+  size_t lower = void, index = void, upper = void;
+  lower = 0;
+  upper = hashes.length -1;
+  while (lower <= upper)
+  {
+    index = (lower + upper) / 2;
+    if (hash < hashes[index])
+      upper = index - 1;
+    else if (hash > hashes[index])
+      lower = index + 1;
+    else
+      return values[index]; // Return the Unicode codepoint.
+  }
+  return 0xFFFF; // Return error value.
+}
+
+unittest
+{
+  Stdout("Testing entity2Unicode().").newline;
+  alias entity2Unicode f;
+  foreach (entity; namedEntities)
+    assert(f(entity.name) == entity.value,
+      Format("'&{};' == \\u{:X4}, not \\u{:X4}", entity.name, entity.value, cast(uint)f(entity.name))
+    );
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/Information.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,123 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.Information;
+
+import dil.Messages;
+import common;
+
+public import dil.Location;
+
+/// Information that can be displayed to the user.
+class Information
+{
+
+}
+
+/// Collects information.
+class InfoManager
+{
+  Information[] info;
+
+  bool hasInfo()
+  {
+    return info.length != 0;
+  }
+
+  void opCatAssign(Information info)
+  {
+    this.info ~= info;
+  }
+
+  void opCatAssign(Information[] info)
+  {
+    this.info ~= info;
+  }
+}
+
+/// For reporting a problem in the compilation process.
+class Problem : Information
+{
+  Location location;
+  uint column; /// Cache variable for column.
+  string message;
+
+  this(Location location, string message)
+  {
+    assert(location !is null);
+    this.location = location;
+    this.message = message;
+  }
+
+  /// Returns the message.
+  string getMsg()
+  {
+    return this.message;
+  }
+
+  /// Returns the line of code.
+  size_t loc()
+  {
+    return location.lineNum;
+  }
+
+  /// Returns the column.
+  size_t col()
+  {
+    if (column == 0)
+      column = location.calculateColumn();
+    return column;
+  }
+
+  /// Returns the file path.
+  string filePath()
+  {
+    return location.filePath;
+  }
+}
+
+/// For reporting warnings.
+class Warning : Problem
+{
+  this(Location location, string message)
+  {
+    super(location, message);
+  }
+}
+
+/// For reporting a compiler error.
+class Error : Problem
+{
+  this(Location location, string message)
+  {
+    super(location, message);
+  }
+}
+
+/// An error reported by the Lexer.
+class LexerError : Error
+{
+  this(Location location, string message)
+  {
+    super(location, message);
+  }
+}
+
+/// An error reported by the Parser.
+class ParserError : Error
+{
+  this(Location location, string message)
+  {
+    super(location, message);
+  }
+}
+
+/// An error reported by a semantic analyzer.
+class SemanticError : Error
+{
+  this(Location location, string message)
+  {
+    super(location, message);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/Location.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,85 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.Location;
+
+import dil.lexer.Funcs;
+import dil.Unicode;
+
+/// Represents a location in a source text.
+final class Location
+{
+  char[] filePath; /// The file path.
+  size_t lineNum; /// The line number.
+  char* lineBegin, to; /// Used to calculate the column.
+
+  /// Forwards the parameters to the second constructor.
+  this(char[] filePath, size_t lineNum)
+  {
+    set(filePath, lineNum);
+  }
+
+  /// Constructs a Location object.
+  this(char[] filePath, size_t lineNum, char* lineBegin, char* to)
+  {
+    set(filePath, lineNum, lineBegin, to);
+  }
+
+  void set(char[] filePath, size_t lineNum)
+  {
+    set(filePath, lineNum, null, null);
+  }
+
+  void set(char[] filePath, size_t lineNum, char* lineBegin, char* to)
+  {
+    this.filePath  = filePath;
+    set(lineNum, lineBegin, to);
+  }
+
+  void set(size_t lineNum, char* lineBegin, char* to)
+  {
+    assert(lineBegin <= to);
+    this.lineNum   = lineNum;
+    this.lineBegin = lineBegin;
+    this.to        = to;
+  }
+
+  void setFilePath(char[] filePath)
+  {
+    this.filePath = filePath;
+  }
+
+  /// This is a primitive method to count the number of characters in a string.
+  /// Note: Unicode compound characters and other special characters are not
+  /// taken into account. The tabulator character is counted as one.
+  uint calculateColumn()
+  {
+    uint col;
+    auto p = lineBegin;
+    if (!p)
+      return 0;
+    for (; p <= to; ++p)
+    {
+      assert(delegate ()
+        {
+          // Check that there is no newline between p and to.
+          // But 'to' may point to a newline.
+          if (p != to && isNewline(*p))
+            return false;
+          if (to-p >= 2 && isUnicodeNewline(p))
+            return false;
+          return true;
+        }() == true
+      );
+
+      // Skip this byte if it is a trail byte of a UTF-8 sequence.
+      if (isTrailByte(*p))
+        continue; // *p == 0b10xx_xxxx
+      // Only count ASCII characters and the first byte of a UTF-8 sequence.
+      ++col;
+    }
+    return col;
+  }
+  alias calculateColumn colNum;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/Messages.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,164 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.Messages;
+
+import common;
+
+/// Enumeration of indices into the table of compiler messages.
+enum MID
+{
+  // Lexer messages:
+  IllegalCharacter,
+//   InvalidUnicodeCharacter,
+  InvalidUTF8Sequence,
+  // ''
+  UnterminatedCharacterLiteral,
+  EmptyCharacterLiteral,
+  // #line
+  ExpectedIdentifierSTLine,
+  ExpectedIntegerAfterSTLine,
+//   ExpectedFilespec,
+  UnterminatedFilespec,
+  UnterminatedSpecialToken,
+  // ""
+  UnterminatedString,
+  // x""
+  NonHexCharInHexString,
+  OddNumberOfDigitsInHexString,
+  UnterminatedHexString,
+  // /* */ /+ +/
+  UnterminatedBlockComment,
+  UnterminatedNestedComment,
+  // `` r""
+  UnterminatedRawString,
+  UnterminatedBackQuoteString,
+  // \x \u \U
+  UndefinedEscapeSequence,
+  InvalidUnicodeEscapeSequence,
+  InsufficientHexDigits,
+  // \&[a-zA-Z][a-zA-Z0-9]+;
+  UndefinedHTMLEntity,
+  UnterminatedHTMLEntity,
+  InvalidBeginHTMLEntity,
+  // integer overflows
+  OverflowDecimalSign,
+  OverflowDecimalNumber,
+  OverflowHexNumber,
+  OverflowBinaryNumber,
+  OverflowOctalNumber,
+  OverflowFloatNumber,
+  OctalNumberHasDecimals,
+  NoDigitsInHexNumber,
+  NoDigitsInBinNumber,
+  HexFloatExponentRequired,
+  HexFloatExpMustStartWithDigit,
+  FloatExpMustStartWithDigit,
+
+  // Parser messages:
+  ExpectedButFound,
+  RedundantStorageClass,
+  TemplateTupleParameter,
+  InContract,
+  OutContract,
+  MissingLinkageType,
+  UnrecognizedLinkageType,
+  ExpectedBaseClasses,
+  BaseClassInForwardDeclaration,
+
+  // Help messages:
+  HelpMain,
+  HelpGenerate,
+  HelpImportGraph,
+}
+
+/// The table of compiler messages.
+private string[] g_compilerMessages;
+
+static this()
+{
+  g_compilerMessages = new string[MID.max+1];
+}
+
+/// Sets the compiler messages.
+void SetMessages(string[] msgs)
+{
+  assert(MID.max+1 == msgs.length);
+  g_compilerMessages = msgs;
+}
+
+/// Returns the compiler message for mid.
+string GetMsg(MID mid)
+{
+  assert(mid < g_compilerMessages.length);
+  return g_compilerMessages[mid];
+}
+
+/// Returns a formatted string.
+char[] FormatMsg(MID mid, ...)
+{
+  return Format(_arguments, _argptr, GetMsg(mid));
+}
+
+/// Collection of error messages with no MID yet.
+struct MSG
+{
+static:
+  // Converter:
+  auto InvalidUTF16Character = "invalid UTF-16 character '\\u{:X4}'.";
+  auto InvalidUTF32Character = "invalid UTF-32 character '\\U{:X8}'.";
+  auto UTF16FileMustBeDivisibleBy2 = "the byte length of a UTF-16 source file must be divisible by 2.";
+  auto UTF32FileMustBeDivisibleBy4 = "the byte length of a UTF-32 source file must be divisible by 4.";
+  // DDoc macros:
+  auto UndefinedDDocMacro = "DDoc macro '{}' is undefined";
+  auto UnterminatedDDocMacro = "DDoc macro '{}' has no closing ')'";
+  // Lexer messages:
+  auto InvalidOctalEscapeSequence = "value of octal escape sequence is greater than 0xFF: '{}'";
+  // Parser messages:
+  auto InvalidUTF8SequenceInString = "invalid UTF-8 sequence in string literal: '{0}'";
+  auto ModuleDeclarationNotFirst = "a module declaration is only allowed as the first declaration in a file";
+  auto StringPostfixMismatch = "string literal has mistmatching postfix character";
+  auto ExpectedIdAfterTypeDot = "expected identifier after '(Type).', not '{}'";
+  auto ExpectedModuleIdentifier = "expected module identifier, not '{}'";
+  auto IllegalDeclaration = "illegal declaration found: {}";
+  auto ExpectedFunctionName = "expected function name, not '{}'";
+  auto ExpectedVariableName = "expected variable name, not '{}'";
+  auto ExpectedFunctionBody = "expected function body, not '{}'";
+  auto RedundantLinkageType = "redundant linkage type: {}";
+  auto ExpectedPragmaIdentifier = "expected pragma identifier, not '{}'";
+  auto ExpectedAliasModuleName = "expected alias module name, not '{}'";
+  auto ExpectedAliasImportName = "expected alias name, not '{}'";
+  auto ExpectedImportName = "expected an identifier, not '{}'";
+  auto ExpectedEnumMember = "expected enum member, not '{}'";
+  auto ExpectedEnumBody = "expected enum body, not '{}'";
+  auto ExpectedClassName = "expected class name, not '{}'";
+  auto ExpectedClassBody = "expected class body, not '{}'";
+  auto ExpectedInterfaceName = "expected interface name, not '{}'";
+  auto ExpectedInterfaceBody = "expected interface body, not '{}'";
+  auto ExpectedStructBody = "expected struct body, not '{}'";
+  auto ExpectedUnionBody = "expected union body, not '{}'";
+  auto ExpectedTemplateName = "expected template name, not '{}'";
+  auto ExpectedAnIdentifier = "expected an identifier, not '{}'";
+  auto IllegalStatement = "illegal statement found: {}";
+  auto ExpectedNonEmptyStatement = "didn't expect ';', use {{ } instead";
+  auto ExpectedScopeIdentifier = "expected 'exit', 'success' or 'failure', not '{}'";
+  auto InvalidScopeIdentifier = "'exit', 'success', 'failure' are valid scope identifiers, but not '{}'";
+  auto ExpectedIntegerAfterAlign = "expected an integer after align, not '{}'";
+  auto IllegalAsmStatement = "illegal asm statement found: {}";
+  auto ExpectedDeclaratorIdentifier = "expected declarator identifier, not '{}'";
+  auto ExpectedTemplateParameters = "expected one or more template parameters, not ')'";
+  auto ExpectedTypeOrExpression = "expected a type or and expression, not ')'";
+  auto ExpectedAliasTemplateParam = "expected name for alias template parameter, not '{}'";
+  auto ExpectedNameForThisTempParam = "expected name for 'this' template parameter, not '{}'";
+  auto ExpectedIdentOrInt = "expected an identifier or an integer, not '{}'";
+  auto MissingCatchOrFinally = "try statement is missing a catch or finally body.";
+  // Semantic analysis:
+  auto UndefinedIdentifier = "undefined identifier '{}'";
+  auto DeclConflictsWithDecl = "declaration '{}' conflicts with declaration @{}";
+  auto VariableConflictsWithDecl = "variable '{}' conflicts with declaration @{}";
+  auto InterfaceCantHaveVariables = "an interface can't have member variables";
+  auto MixinArgumentMustBeString = "the mixin argument must evaluate to a string";
+  auto DebugSpecModuleLevel = "debug={} must be a module level";
+  auto VersionSpecModuleLevel = "version={} must be a module level";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/SourceText.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,62 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.SourceText;
+
+import dil.Converter;
+import dil.Information;
+import common;
+
+import tango.io.File;
+
+/// Represents D source code.
+///
+/// The source text may come from a file or from a memory buffer.
+final class SourceText
+{
+  string filePath; /// The file path to the source text. Mainly used for error messages.
+  char[] data; /// The UTF-8, zero-terminated source text.
+
+  /// Constructs a SourceText object.
+  /// Params:
+  ///   filePath = file path to the source file.
+  ///   loadFile = whether to load the file in the constructor.
+  this(string filePath, bool loadFile = false)
+  {
+    this.filePath = filePath;
+    loadFile && load();
+  }
+
+  /// Constructs a SourceText object.
+  /// Params:
+  ///   filePath = file path for error messages.
+  ///   data = memory buffer.
+  this(string filePath, char[] data)
+  {
+    this(filePath);
+    this.data = data;
+    addSentinelCharacter();
+  }
+
+  /// Loads the source text from a file.
+  void load(InfoManager infoMan = null)
+  {
+    if (!infoMan)
+      infoMan = new InfoManager;
+    assert(filePath.length);
+    // Read the file.
+    auto rawdata = cast(ubyte[]) (new File(filePath)).read();
+    // Convert the data.
+    auto converter = Converter(filePath, infoMan);
+    data = converter.data2UTF8(rawdata);
+    addSentinelCharacter();
+  }
+
+  /// Adds '\0' to the text (if not already there.)
+  private void addSentinelCharacter()
+  {
+    if (data.length == 0 || data[$-1] != 0)
+      data ~= 0;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/Time.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,41 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.Time;
+
+import tango.stdc.time : time_t, time, ctime;
+import tango.stdc.string : strlen;
+
+/// Some convenience functions for dealing with C's time functions.
+struct Time
+{
+static:
+  /// Returns the current date as a string.
+  char[] toString()
+  {
+    time_t time_val;
+    .time(&time_val);
+    char* str = ctime(&time_val); // ctime returns a pointer to a static array.
+    char[] timeStr = str[0 .. strlen(str)-1]; // -1 removes trailing '\n'.
+    return timeStr.dup;
+  }
+
+  /// Returns the time of timeStr: hh:mm:ss
+  char[] time(char[] timeStr)
+  {
+    return timeStr[11..19];
+  }
+
+  /// Returns the month and day of timeStr: Mmm dd
+  char[] month_day(char[] timeStr)
+  {
+    return timeStr[4..10];
+  }
+
+  /// Returns the year of timeStr: yyyy
+  char[] year(char[] timeStr)
+  {
+    return timeStr[20..24];
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/Unicode.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,345 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.Unicode;
+public import util.uni : isUniAlpha;
+
+/// U+FFFD = �. Used to replace invalid Unicode characters.
+const dchar REPLACEMENT_CHAR = '\uFFFD';
+const char[3] REPLACEMENT_STR = \uFFFD; /// Ditto
+/// Invalid character, returned on errors.
+const dchar ERROR_CHAR = 0xD800;
+
+/// Returns: true if this character is not a surrogate
+/// code point and not higher than 0x10FFFF.
+bool isValidChar(dchar d)
+{
+  return d < 0xD800 || d > 0xDFFF && d <= 0x10FFFF;
+}
+
+/// There are a total of 66 noncharacters.
+/// Returns: true if this is one of them.
+/// See_also: Chapter 16.7 Noncharacters in Unicode 5.0
+bool isNoncharacter(dchar d)
+{
+  return 0xFDD0 <= d && d <= 0xFDEF || // 32
+         d <= 0x10FFFF && (d & 0xFFFF) >= 0xFFFE; // 34
+}
+
+/// Returns: true if this is a trail byte of a UTF-8 sequence.
+bool isTrailByte(ubyte b)
+{
+  return (b & 0xC0) == 0x80; // 10xx_xxxx
+}
+
+/// Returns: true if this is a lead byte of a UTF-8 sequence.
+bool isLeadByte(ubyte b)
+{
+  return (b & 0xC0) == 0xC0; // 11xx_xxxx
+}
+
+/// Advances ref_p only if this is a valid Unicode alpha character.
+bool isUnicodeAlpha(ref char* ref_p, char* end)
+in { assert(ref_p && ref_p < end); }
+body
+{
+  if (*ref_p < 0x80)
+    return false;
+  auto p = ref_p;
+  auto c = decode(p, end);
+  if (!isUniAlpha(c))
+    return false;
+  ref_p = p;
+  return true;
+}
+
+/// Decodes a character from str at index.
+/// Params:
+///   index = set to one past the ASCII char or one past the last trail byte
+///           of the valid UTF-8 sequence.
+dchar decode(char[] str, ref size_t index)
+in { assert(str.length && index < str.length); }
+out { assert(index <= str.length); }
+body
+{
+  char* p = str.ptr + index;
+  char* end = str.ptr + str.length;
+  dchar c = decode(p, end);
+  if (c != ERROR_CHAR)
+    index = p - str.ptr;
+  return c;
+}
+
+/// Decodes a character starting at ref_p.
+/// Params:
+///   ref_p = set to one past the ASCII char or one past the last trail byte
+///           of the valid UTF-8 sequence.
+dchar decode(ref char* ref_p, char* end)
+in { assert(ref_p && ref_p < end); }
+out(c) { assert(ref_p <= end && (isValidChar(c) || c == ERROR_CHAR)); }
+body
+{
+  char* p = ref_p;
+  dchar c = *p;
+
+  if (c < 0x80)
+    return ref_p++, c;
+
+  p++; // Move to second byte.
+  if (!(p < end))
+    return ERROR_CHAR;
+
+  // Error if second byte is not a trail byte.
+  if (!isTrailByte(*p))
+    return ERROR_CHAR;
+
+  // Check for overlong sequences.
+  switch (c)
+  {
+  case 0xE0, // 11100000 100xxxxx
+       0xF0, // 11110000 1000xxxx
+       0xF8, // 11111000 10000xxx
+       0xFC: // 11111100 100000xx
+    if ((*p & c) == 0x80)
+      return ERROR_CHAR;
+  default:
+    if ((c & 0xFE) == 0xC0) // 1100000x
+      return ERROR_CHAR;
+  }
+
+  const char[] checkNextByte = "if (!(++p < end && isTrailByte(*p)))"
+                                "  return ERROR_CHAR;";
+  const char[] appendSixBits = "c = (c << 6) | *p & 0b0011_1111;";
+
+  // Decode
+  if ((c & 0b1110_0000) == 0b1100_0000)
+  {
+    // 110xxxxx 10xxxxxx
+    c &= 0b0001_1111;
+    mixin(appendSixBits);
+  }
+  else if ((c & 0b1111_0000) == 0b1110_0000)
+  {
+    // 1110xxxx 10xxxxxx 10xxxxxx
+    c &= 0b0000_1111;
+    mixin(appendSixBits ~
+          checkNextByte ~ appendSixBits);
+  }
+  else if ((c & 0b1111_1000) == 0b1111_0000)
+  {
+    // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+    c &= 0b0000_0111;
+    mixin(appendSixBits ~
+          checkNextByte ~ appendSixBits ~
+          checkNextByte ~ appendSixBits);
+  }
+  else
+    // 5 and 6 byte UTF-8 sequences are not allowed yet.
+    // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+    // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+    return ERROR_CHAR;
+
+  assert(isTrailByte(*p));
+
+  if (!isValidChar(c))
+    return ERROR_CHAR;
+  ref_p = p+1;
+  return c;
+}
+
+/// Encodes c and appends it to str.
+void encode(ref char[] str, dchar c)
+{
+  assert(isValidChar(c), "check if character is valid before calling encode().");
+
+  char[6] b = void;
+  if (c < 0x80)
+    str ~= c;
+  else if (c < 0x800)
+  {
+    b[0] = 0xC0 | (c >> 6);
+    b[1] = 0x80 | (c & 0x3F);
+    str ~= b[0..2];
+  }
+  else if (c < 0x10000)
+  {
+    b[0] = 0xE0 | (c >> 12);
+    b[1] = 0x80 | ((c >> 6) & 0x3F);
+    b[2] = 0x80 | (c & 0x3F);
+    str ~= b[0..3];
+  }
+  else if (c < 0x200000)
+  {
+    b[0] = 0xF0 | (c >> 18);
+    b[1] = 0x80 | ((c >> 12) & 0x3F);
+    b[2] = 0x80 | ((c >> 6) & 0x3F);
+    b[3] = 0x80 | (c & 0x3F);
+    str ~= b[0..4];
+  }
+  /+ // There are no 5 and 6 byte UTF-8 sequences yet.
+  else if (c < 0x4000000)
+  {
+    b[0] = 0xF8 | (c >> 24);
+    b[1] = 0x80 | ((c >> 18) & 0x3F);
+    b[2] = 0x80 | ((c >> 12) & 0x3F);
+    b[3] = 0x80 | ((c >> 6) & 0x3F);
+    b[4] = 0x80 | (c & 0x3F);
+    str ~= b[0..5];
+  }
+  else if (c < 0x80000000)
+  {
+    b[0] = 0xFC | (c >> 30);
+    b[1] = 0x80 | ((c >> 24) & 0x3F);
+    b[2] = 0x80 | ((c >> 18) & 0x3F);
+    b[3] = 0x80 | ((c >> 12) & 0x3F);
+    b[4] = 0x80 | ((c >> 6) & 0x3F);
+    b[5] = 0x80 | (c & 0x3F);
+    str ~= b[0..6];
+  }
+  +/
+  else
+    assert(0);
+}
+
+/// Encodes c and appends it to str.
+void encode(ref wchar[] str, dchar c)
+in { assert(isValidChar(c)); }
+body
+{
+  if (c < 0x10000)
+    str ~= cast(wchar)c;
+  else
+  { // Encode with surrogate pair.
+    wchar[2] pair = void;
+    c -= 0x10000; // c'
+    // higher10bits(c') | 0b1101_10xx_xxxx_xxxx
+    pair[0] = (c >> 10) | 0xD800;
+    // lower10bits(c') | 0b1101_11yy_yyyy_yyyy
+    pair[1] = (c & 0x3FF) | 0xDC00;
+    str ~= pair;
+  }
+}
+
+/// Decodes a character from a UTF-16 sequence.
+/// Params:
+///   str = the UTF-16 sequence.
+///   index = where to start from.
+/// Returns: ERROR_CHAR in case of an error in the sequence.
+dchar decode(wchar[] str, ref size_t index)
+{
+  assert(str.length && index < str.length);
+  dchar c = str[index];
+  if (0xD800 > c || c > 0xDFFF)
+  {
+    ++index;
+    return c;
+  }
+  if (c <= 0xDBFF && index+1 != str.length)
+  {
+    wchar c2 = str[index+1];
+    if (0xDC00 <= c2 && c2 <= 0xDFFF)
+    { // Decode surrogate pair.
+      // (c - 0xD800) << 10 + 0x10000 ->
+      // (c - 0xD800 + 0x40) << 10 ->
+      c = (c - 0xD7C0) << 10;
+      c |= (c2 & 0x3FF);
+      index += 2;
+      return c;
+    }
+  }
+  return ERROR_CHAR;
+}
+
+/// Decodes a character from a UTF-16 sequence.
+/// Params:
+///   p = start of the UTF-16 sequence.
+///   end = one past the end of the sequence.
+/// Returns: ERROR_CHAR in case of an error in the sequence.
+dchar decode(ref wchar* p, wchar* end)
+{
+  assert(p && p < end);
+  dchar c = *p;
+  if (0xD800 > c || c > 0xDFFF)
+  {
+    ++p;
+    return c;
+  }
+  if (c <= 0xDBFF && p+1 != end)
+  {
+    wchar c2 = p[1];
+    if (0xDC00 <= c2 && c2 <= 0xDFFF)
+    {
+      c = (c - 0xD7C0) << 10;
+      c |= (c2 & 0x3FF);
+      p += 2;
+      return c;
+    }
+  }
+  return ERROR_CHAR;
+}
+
+/// Decodes a character from a zero-terminated UTF-16 string.
+/// Params:
+///   p = start of the UTF-16 sequence.
+/// Returns: ERROR_CHAR in case of an error in the sequence.
+dchar decode(ref wchar* p)
+{
+  assert(p);
+  dchar c = *p;
+  if (0xD800 > c || c > 0xDFFF)
+  {
+    ++p;
+    return c;
+  }
+  if (c <= 0xDBFF)
+  {
+    wchar c2 = p[1];
+    if (0xDC00 <= c2 && c2 <= 0xDFFF)
+    {
+      c = (c - 0xD7C0) << 10;
+      c |= (c2 & 0x3FF);
+      p += 2;
+      return c;
+    }
+  }
+  return ERROR_CHAR;
+}
+
+/// Converts a UTF-8 string to a UTF-16 string.
+wchar[] toUTF16(char[] str)
+{
+  wchar[] result;
+  size_t idx;
+  while (idx < str.length)
+  {
+    auto c = decode(str, idx);
+    if (c == ERROR_CHAR)
+    { // Skip trail bytes.
+      while (++idx < str.length && isTrailByte(str[idx]))
+      {}
+      c = REPLACEMENT_CHAR;
+    }
+    encode(result, c);
+  }
+  return result;
+}
+
+/// Converts a UTF-8 string to a UTF-32 string.
+dchar[] toUTF32(char[] str)
+{
+  dchar[] result;
+  size_t idx;
+  while (idx < str.length)
+  {
+    auto c = decode(str, idx);
+    if (c == ERROR_CHAR)
+    { // Skip trail bytes.
+      while (++idx < str.length && isTrailByte(str[idx]))
+      {}
+      c = REPLACEMENT_CHAR;
+    }
+    result ~= c;
+  }
+  return result;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/ast/Declaration.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,44 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.ast.Declaration;
+
+import dil.ast.Node;
+import dil.Enums;
+
+/// The root class of all declarations.
+abstract class Declaration : Node
+{
+  bool hasBody;
+  this()
+  {
+    super(NodeCategory.Declaration);
+  }
+
+  // Members relevant to semantic phase.
+  StorageClass stc; /// The storage classes of this declaration.
+  Protection prot;  /// The protection attribute of this declaration.
+
+  final bool isStatic()
+  {
+    return !!(stc & StorageClass.Static);
+  }
+
+  final bool isPublic()
+  {
+    return !!(prot & Protection.Public);
+  }
+
+  final void setStorageClass(StorageClass stc)
+  {
+    this.stc = stc;
+  }
+
+  final void setProtection(Protection prot)
+  {
+    this.prot = prot;
+  }
+
+  override abstract Declaration copy();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/ast/Declarations.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,720 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.ast.Declarations;
+
+public import dil.ast.Declaration;
+import dil.ast.Node;
+import dil.ast.Expression;
+import dil.ast.Types;
+import dil.ast.Statements;
+import dil.ast.Parameters;
+import dil.ast.NodeCopier;
+import dil.lexer.IdTable;
+import dil.semantic.Symbols;
+import dil.Enums;
+import common;
+
+class CompoundDeclaration : Declaration
+{
+  this()
+  {
+    hasBody = true;
+    mixin(set_kind);
+  }
+
+  void opCatAssign(Declaration d)
+  {
+    addChild(d);
+  }
+
+  void opCatAssign(CompoundDeclaration ds)
+  {
+    addChildren(ds.children);
+  }
+
+  Declaration[] decls()
+  {
+    return cast(Declaration[])this.children;
+  }
+
+  void decls(Declaration[] decls)
+  {
+    this.children = decls;
+  }
+
+  mixin(copyMethod);
+}
+
+/// Single semicolon.
+class EmptyDeclaration : Declaration
+{
+  this()
+  {
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+
+/// Illegal declarations encompass all tokens that don't
+/// start a DeclarationDefinition.
+/// See_Also: dil.lexer.Token.isDeclDefStartToken()
+class IllegalDeclaration : Declaration
+{
+  this()
+  {
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+
+/// FQN = fully qualified name
+alias Identifier*[] ModuleFQN; // Identifier(.Identifier)*
+
+class ModuleDeclaration : Declaration
+{
+  Identifier* moduleName;
+  Identifier*[] packages;
+  this(ModuleFQN moduleFQN)
+  {
+    mixin(set_kind);
+    assert(moduleFQN.length != 0);
+    this.moduleName = moduleFQN[$-1];
+    this.packages = moduleFQN[0..$-1];
+  }
+
+  char[] getFQN()
+  {
+    auto pname = getPackageName('.');
+    if (pname.length)
+      return pname ~ "." ~ getName();
+    else
+      return getName();
+  }
+
+  char[] getName()
+  {
+    if (moduleName)
+      return moduleName.str;
+    return null;
+  }
+
+  char[] getPackageName(char separator)
+  {
+    char[] pname;
+    foreach (pckg; packages)
+      if (pckg)
+        pname ~= pckg.str ~ separator;
+    if (pname.length)
+      pname = pname[0..$-1]; // Remove last separator
+    return pname;
+  }
+
+  mixin(copyMethod);
+}
+
+class ImportDeclaration : Declaration
+{
+  private alias Identifier*[] Ids;
+  ModuleFQN[] moduleFQNs;
+  Ids moduleAliases;
+  Ids bindNames;
+  Ids bindAliases;
+
+  this(ModuleFQN[] moduleFQNs, Ids moduleAliases, Ids bindNames, Ids bindAliases, bool isStatic)
+  {
+    mixin(set_kind);
+    this.moduleFQNs = moduleFQNs;
+    this.moduleAliases = moduleAliases;
+    this.bindNames = bindNames;
+    this.bindAliases = bindAliases;
+    if (isStatic)
+      this.stc |= StorageClass.Static;
+  }
+
+  char[][] getModuleFQNs(char separator)
+  {
+    char[][] FQNs;
+    foreach (moduleFQN; moduleFQNs)
+    {
+      char[] FQN;
+      foreach (ident; moduleFQN)
+        if (ident)
+          FQN ~= ident.str ~ separator;
+      FQNs ~= FQN[0..$-1]; // Remove last separator
+    }
+    return FQNs;
+  }
+
+  mixin(copyMethod);
+}
+
+class AliasDeclaration : Declaration
+{
+  Declaration decl;
+  this(Declaration decl)
+  {
+    mixin(set_kind);
+    addChild(decl);
+    this.decl = decl;
+  }
+  mixin(copyMethod);
+}
+
+class TypedefDeclaration : Declaration
+{
+  Declaration decl;
+  this(Declaration decl)
+  {
+    mixin(set_kind);
+    addChild(decl);
+    this.decl = decl;
+  }
+  mixin(copyMethod);
+}
+
+class EnumDeclaration : Declaration
+{
+  Identifier* name;
+  TypeNode baseType;
+  EnumMemberDeclaration[] members;
+  this(Identifier* name, TypeNode baseType, EnumMemberDeclaration[] members, bool hasBody)
+  {
+    super.hasBody = hasBody;
+    mixin(set_kind);
+    addOptChild(baseType);
+    addOptChildren(members);
+
+    this.name = name;
+    this.baseType = baseType;
+    this.members = members;
+  }
+
+  Enum symbol;
+
+  mixin(copyMethod);
+}
+
+class EnumMemberDeclaration : Declaration
+{
+  Identifier* name;
+  Expression value;
+  this(Identifier* name, Expression value)
+  {
+    mixin(set_kind);
+    addOptChild(value);
+
+    this.name = name;
+    this.value = value;
+  }
+
+  EnumMember symbol;
+
+  mixin(copyMethod);
+}
+
+class TemplateDeclaration : Declaration
+{
+  Identifier* name;
+  TemplateParameters tparams;
+  CompoundDeclaration decls;
+  this(Identifier* name, TemplateParameters tparams, CompoundDeclaration decls)
+  {
+    super.hasBody = true;
+    mixin(set_kind);
+    addChild(tparams);
+    addChild(decls);
+
+    this.name = name;
+    this.tparams = tparams;
+    this.decls = decls;
+  }
+
+  Template symbol; /// The template symbol for this declaration.
+
+  mixin(copyMethod);
+}
+
+abstract class AggregateDeclaration : Declaration
+{
+  Identifier* name;
+//   TemplateParameters tparams;
+  CompoundDeclaration decls;
+  this(Identifier* name, /+TemplateParameters tparams, +/CompoundDeclaration decls)
+  {
+    super.hasBody = decls !is null;
+    this.name = name;
+//     this.tparams = tparams;
+    this.decls = decls;
+  }
+  mixin(copyMethod);
+}
+
+class ClassDeclaration : AggregateDeclaration
+{
+  BaseClassType[] bases;
+  this(Identifier* name, /+TemplateParameters tparams, +/BaseClassType[] bases, CompoundDeclaration decls)
+  {
+    super(name, /+tparams, +/decls);
+    mixin(set_kind);
+//     addChild(tparams);
+    addOptChildren(bases);
+    addOptChild(decls);
+
+    this.bases = bases;
+  }
+
+  Class symbol; /// The class symbol for this declaration.
+
+  mixin(copyMethod);
+}
+
+class InterfaceDeclaration : AggregateDeclaration
+{
+  BaseClassType[] bases;
+  this(Identifier* name, /+TemplateParameters tparams, +/BaseClassType[] bases, CompoundDeclaration decls)
+  {
+    super(name, /+tparams, +/decls);
+    mixin(set_kind);
+//     addChild(tparams);
+    addOptChildren(bases);
+    addOptChild(decls);
+
+    this.bases = bases;
+  }
+
+  alias dil.semantic.Symbols.Interface Interface;
+
+  Interface symbol; /// The interface symbol for this declaration.
+
+  mixin(copyMethod);
+}
+
+class StructDeclaration : AggregateDeclaration
+{
+  uint alignSize;
+  this(Identifier* name, /+TemplateParameters tparams, +/CompoundDeclaration decls)
+  {
+    super(name, /+tparams, +/decls);
+    mixin(set_kind);
+//     addChild(tparams);
+    addOptChild(decls);
+  }
+
+  void setAlignSize(uint alignSize)
+  {
+    this.alignSize = alignSize;
+  }
+
+  Struct symbol; /// The struct symbol for this declaration.
+
+  mixin(copyMethod);
+}
+
+class UnionDeclaration : AggregateDeclaration
+{
+  this(Identifier* name, /+TemplateParameters tparams, +/CompoundDeclaration decls)
+  {
+    super(name, /+tparams, +/decls);
+    mixin(set_kind);
+//     addChild(tparams);
+    addOptChild(decls);
+  }
+
+  Union symbol; /// The union symbol for this declaration.
+
+  mixin(copyMethod);
+}
+
+class ConstructorDeclaration : Declaration
+{
+  Parameters params;
+  FuncBodyStatement funcBody;
+  this(Parameters params, FuncBodyStatement funcBody)
+  {
+    super.hasBody = true;
+    mixin(set_kind);
+    addChild(params);
+    addChild(funcBody);
+
+    this.params = params;
+    this.funcBody = funcBody;
+  }
+  mixin(copyMethod);
+}
+
+class StaticConstructorDeclaration : Declaration
+{
+  FuncBodyStatement funcBody;
+  this(FuncBodyStatement funcBody)
+  {
+    super.hasBody = true;
+    mixin(set_kind);
+    addChild(funcBody);
+
+    this.funcBody = funcBody;
+  }
+  mixin(copyMethod);
+}
+
+class DestructorDeclaration : Declaration
+{
+  FuncBodyStatement funcBody;
+  this(FuncBodyStatement funcBody)
+  {
+    super.hasBody = true;
+    mixin(set_kind);
+    addChild(funcBody);
+
+    this.funcBody = funcBody;
+  }
+  mixin(copyMethod);
+}
+
+class StaticDestructorDeclaration : Declaration
+{
+  FuncBodyStatement funcBody;
+  this(FuncBodyStatement funcBody)
+  {
+    super.hasBody = true;
+    mixin(set_kind);
+    addChild(funcBody);
+
+    this.funcBody = funcBody;
+  }
+  mixin(copyMethod);
+}
+
+class FunctionDeclaration : Declaration
+{
+  TypeNode returnType;
+  Identifier* name;
+//   TemplateParameters tparams;
+  Parameters params;
+  FuncBodyStatement funcBody;
+  LinkageType linkageType;
+  this(TypeNode returnType, Identifier* name,/+ TemplateParameters tparams,+/
+       Parameters params, FuncBodyStatement funcBody)
+  {
+    super.hasBody = funcBody.funcBody !is null;
+    mixin(set_kind);
+    addChild(returnType);
+//     addChild(tparams);
+    addChild(params);
+    addChild(funcBody);
+
+    this.returnType = returnType;
+    this.name = name;
+//     this.tparams = tparams;
+    this.params = params;
+    this.funcBody = funcBody;
+  }
+
+  void setLinkageType(LinkageType linkageType)
+  {
+    this.linkageType = linkageType;
+  }
+
+  bool isTemplatized()
+  { // E.g.: void func(T)(T t)
+    //                  ^ params.begin.prevNWS
+    return params.begin.prevNWS.kind == TOK.RParen;
+  }
+
+  mixin(copyMethod);
+}
+
+/// VariablesDeclaration := Type? Identifier ("=" Init)? ("," Identifier ("=" Init)?)* ";"
+class VariablesDeclaration : Declaration
+{
+  TypeNode typeNode;
+  Identifier*[] names;
+  Expression[] inits;
+  this(TypeNode typeNode, Identifier*[] names, Expression[] inits)
+  {
+    // No empty arrays allowed. Both arrays must be of same size.
+    assert(names.length != 0 && names.length == inits.length);
+    // If no type (in case of AutoDeclaration), first value mustn't be null.
+    assert(typeNode ? 1 : inits[0] !is null);
+    mixin(set_kind);
+    addOptChild(typeNode);
+    foreach(init; inits)
+      addOptChild(init);
+
+    this.typeNode = typeNode;
+    this.names = names;
+    this.inits = inits;
+  }
+
+  LinkageType linkageType;
+
+  void setLinkageType(LinkageType linkageType)
+  {
+    this.linkageType = linkageType;
+  }
+
+  Variable[] variables;
+
+  mixin(copyMethod);
+}
+
+class InvariantDeclaration : Declaration
+{
+  FuncBodyStatement funcBody;
+  this(FuncBodyStatement funcBody)
+  {
+    super.hasBody = true;
+    mixin(set_kind);
+    addChild(funcBody);
+
+    this.funcBody = funcBody;
+  }
+  mixin(copyMethod);
+}
+
+class UnittestDeclaration : Declaration
+{
+  FuncBodyStatement funcBody;
+  this(FuncBodyStatement funcBody)
+  {
+    super.hasBody = true;
+    mixin(set_kind);
+    addChild(funcBody);
+
+    this.funcBody = funcBody;
+  }
+  mixin(copyMethod);
+}
+
+abstract class ConditionalCompilationDeclaration : Declaration
+{
+  Token* spec;
+  Token* cond;
+  Declaration decls, elseDecls;
+
+  this(Token* spec, Token* cond, Declaration decls, Declaration elseDecls)
+  {
+    super.hasBody = decls !is null;
+    addOptChild(decls);
+    addOptChild(elseDecls);
+
+    this.spec = spec;
+    this.cond = cond;
+    this.decls = decls;
+    this.elseDecls = elseDecls;
+  }
+
+  bool isSpecification()
+  {
+    return decls is null;
+  }
+
+  bool isCondition()
+  {
+    return decls !is null;
+  }
+
+  /// The branch to be compiled in.
+  Declaration compiledDecls;
+}
+
+class DebugDeclaration : ConditionalCompilationDeclaration
+{
+  this(Token* spec, Token* cond, Declaration decls, Declaration elseDecls)
+  {
+    super(spec, cond, decls, elseDecls);
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+
+class VersionDeclaration : ConditionalCompilationDeclaration
+{
+  this(Token* spec, Token* cond, Declaration decls, Declaration elseDecls)
+  {
+    super(spec, cond, decls, elseDecls);
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+
+class StaticIfDeclaration : Declaration
+{
+  Expression condition;
+  Declaration ifDecls, elseDecls;
+  this(Expression condition, Declaration ifDecls, Declaration elseDecls)
+  {
+    super.hasBody = true;
+    mixin(set_kind);
+    addChild(condition);
+    addChild(ifDecls);
+    addOptChild(elseDecls);
+
+    this.condition = condition;
+    this.ifDecls = ifDecls;
+    this.elseDecls = elseDecls;
+  }
+  mixin(copyMethod);
+}
+
+class StaticAssertDeclaration : Declaration
+{
+  Expression condition, message;
+  this(Expression condition, Expression message)
+  {
+    super.hasBody = true;
+    mixin(set_kind);
+    addChild(condition);
+    addOptChild(message);
+
+    this.condition = condition;
+    this.message = message;
+  }
+  mixin(copyMethod);
+}
+
+class NewDeclaration : Declaration
+{
+  Parameters params;
+  FuncBodyStatement funcBody;
+  this(Parameters params, FuncBodyStatement funcBody)
+  {
+    super.hasBody = true;
+    mixin(set_kind);
+    addChild(params);
+    addChild(funcBody);
+
+    this.params = params;
+    this.funcBody = funcBody;
+  }
+  mixin(copyMethod);
+}
+
+class DeleteDeclaration : Declaration
+{
+  Parameters params;
+  FuncBodyStatement funcBody;
+  this(Parameters params, FuncBodyStatement funcBody)
+  {
+    super.hasBody = true;
+    mixin(set_kind);
+    addChild(params);
+    addChild(funcBody);
+
+    this.params = params;
+    this.funcBody = funcBody;
+  }
+  mixin(copyMethod);
+}
+
+abstract class AttributeDeclaration : Declaration
+{
+  Declaration decls;
+  this(Declaration decls)
+  {
+    super.hasBody = true;
+    addChild(decls);
+    this.decls = decls;
+  }
+}
+
+class ProtectionDeclaration : AttributeDeclaration
+{
+  Protection prot;
+  this(Protection prot, Declaration decls)
+  {
+    super(decls);
+    mixin(set_kind);
+    this.prot = prot;
+  }
+  mixin(copyMethod);
+}
+
+class StorageClassDeclaration : AttributeDeclaration
+{
+  StorageClass storageClass;
+  this(StorageClass storageClass, Declaration decl)
+  {
+    super(decl);
+    mixin(set_kind);
+
+    this.storageClass = storageClass;
+  }
+  mixin(copyMethod);
+}
+
+class LinkageDeclaration : AttributeDeclaration
+{
+  LinkageType linkageType;
+  this(LinkageType linkageType, Declaration decls)
+  {
+    super(decls);
+    mixin(set_kind);
+
+    this.linkageType = linkageType;
+  }
+  mixin(copyMethod);
+}
+
+class AlignDeclaration : AttributeDeclaration
+{
+  int size;
+  this(int size, Declaration decls)
+  {
+    super(decls);
+    mixin(set_kind);
+    this.size = size;
+  }
+  mixin(copyMethod);
+}
+
+class PragmaDeclaration : AttributeDeclaration
+{
+  Identifier* ident;
+  Expression[] args;
+  this(Identifier* ident, Expression[] args, Declaration decls)
+  {
+    addOptChildren(args); // Add args before calling super().
+    super(decls);
+    mixin(set_kind);
+
+    this.ident = ident;
+    this.args = args;
+  }
+  mixin(copyMethod);
+}
+
+class MixinDeclaration : Declaration
+{
+  /// IdExpression := IdentifierExpression | TemplateInstanceExpression
+  /// MixinTemplate := IdExpression ("." IdExpression)*
+  Expression templateExpr;
+  Identifier* mixinIdent; /// Optional mixin identifier.
+  Expression argument; /// "mixin" "(" AssignExpression ")"
+  Declaration decls; /// Initialized in the semantic phase.
+
+  this(Expression templateExpr, Identifier* mixinIdent)
+  {
+    mixin(set_kind);
+    addChild(templateExpr);
+
+    this.templateExpr = templateExpr;
+    this.mixinIdent = mixinIdent;
+  }
+
+  this(Expression argument)
+  {
+    mixin(set_kind);
+    addChild(argument);
+
+    this.argument = argument;
+  }
+
+  bool isMixinExpression()
+  {
+    return argument !is null;
+  }
+
+  mixin(copyMethod);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/ast/DefaultVisitor.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,375 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.ast.DefaultVisitor;
+
+import dil.ast.Visitor;
+
+import dil.ast.Node;
+import dil.ast.Declarations,
+       dil.ast.Expressions,
+       dil.ast.Statements,
+       dil.ast.Types,
+       dil.ast.Parameters;
+import common;
+
+/// This huge template function, when instantiated for a certain node class,
+/// generates a body of calls to visit() on the subnodes.
+returnType!(T.stringof) visitDefault(T)(T t)
+{
+  assert(t !is null, "node passed to visitDefault() is null");
+  //Stdout(t).newline;
+
+  alias t d, s, e, n; // Variable aliases of t.
+
+  static if (is(T : Declaration))
+  {
+    alias T D;
+    static if (is(D == CompoundDeclaration))
+      foreach (decl; d.decls)
+        visitD(decl);
+    //EmptyDeclaration,
+    //IllegalDeclaration,
+    //ModuleDeclaration have no subnodes.
+    static if (is(D == AliasDeclaration) ||
+               is(D == TypedefDeclaration))
+      visitD(d.decl);
+    static if (is(D == EnumDeclaration))
+    {
+      d.baseType && visitT(d.baseType);
+      foreach (member; d.members)
+        visitD(member);
+    }
+    static if (is(D == EnumMemberDeclaration))
+      d.value && visitE(d.value);
+    static if (is(D == ClassDeclaration) || is( D == InterfaceDeclaration))
+    {
+//       visitN(d.tparams);
+      foreach (base; d.bases)
+        visitT(base);
+      d.decls && visitD(d.decls);
+    }
+    static if (is(D == StructDeclaration) || is(D == UnionDeclaration))
+//       visitN(d.tparams),
+      d.decls && visitD(d.decls);
+    static if (is(D == ConstructorDeclaration))
+      visitN(d.params), visitS(d.funcBody);
+    static if (is(D == StaticConstructorDeclaration) ||
+               is(D == DestructorDeclaration) ||
+               is(D == StaticDestructorDeclaration) ||
+               is(D == InvariantDeclaration) ||
+               is(D == UnittestDeclaration))
+      visitS(d.funcBody);
+    static if (is(D == FunctionDeclaration))
+      visitT(d.returnType),
+//       visitN(d.tparams),
+      visitN(d.params),
+      visitS(d.funcBody);
+    static if (is(D == VariablesDeclaration))
+    {
+      d.typeNode && visitT(d.typeNode);
+      foreach(init; d.inits)
+        init && visitE(init);
+    }
+    static if (is(D == DebugDeclaration) || is(D == VersionDeclaration))
+      d.decls && visitD(d.decls),
+      d.elseDecls && visitD(d.elseDecls);
+    static if (is(D == StaticIfDeclaration))
+      visitE(d.condition),
+      visitD(d.ifDecls),
+      d.elseDecls && visitD(d.elseDecls);
+    static if (is(D == StaticAssertDeclaration))
+      visitE(d.condition),
+      d.message && visitE(d.message);
+    static if (is(D == TemplateDeclaration))
+      visitN(d.tparams),
+      visitD(d.decls);
+    static if (is(D == NewDeclaration) || is(D == DeleteDeclaration))
+      visitN(d.params),
+      visitS(d.funcBody);
+    static if (is(D == ProtectionDeclaration) ||
+               is(D == StorageClassDeclaration) ||
+               is(D == LinkageDeclaration) ||
+               is(D == AlignDeclaration))
+      visitD(d.decls);
+    static if (is(D == PragmaDeclaration))
+    {
+      foreach (arg; d.args)
+        visitE(arg);
+      visitD(d.decls);
+    }
+    static if (is(D == MixinDeclaration))
+      d.templateExpr ? visitE(d.templateExpr) : visitE(d.argument);
+  }
+  else
+  static if (is(T : Expression))
+  {
+    alias T E;
+    static if (is(E == IllegalExpression))
+    {}
+    else
+    static if (is(E == CondExpression))
+      visitE(e.condition), visitE(e.lhs), visitE(e.rhs);
+    else
+    static if (is(E : BinaryExpression))
+      visitE(e.lhs), visitE(e.rhs);
+    else
+    static if (is(E : UnaryExpression))
+    {
+      static if (is(E == CastExpression))
+        visitT(e.type);
+      visitE(e.e); // Visit member in base class UnaryExpression.
+      static if (is(E == IndexExpression))
+        foreach (arg; e.args)
+          visitE(arg);
+      static if (is(E == SliceExpression))
+        e.left && (visitE(e.left), visitE(e.right));
+      static if (is(E == AsmPostBracketExpression))
+        visitE(e.e2);
+    }
+    else
+    {
+      static if (is(E == NewExpression))
+      {
+        foreach (arg; e.newArgs)
+          visitE(arg);
+        visitT(e.type);
+        foreach (arg; e.ctorArgs)
+          visitE(arg);
+      }
+      static if (is(E == NewAnonClassExpression))
+      {
+        foreach (arg; e.newArgs)
+          visitE(arg);
+        foreach (base; e.bases)
+          visitT(base);
+        foreach (arg; e.ctorArgs)
+          visitE(arg);
+        visitD(e.decls);
+      }
+      static if (is(E == AsmBracketExpression))
+        visitE(e.e);
+      static if (is(E == TemplateInstanceExpression))
+        e.targs && visitN(e.targs);
+      static if (is(E == ArrayLiteralExpression))
+        foreach (value; e.values)
+          visitE(value);
+      static if (is(E == AArrayLiteralExpression))
+        foreach (i, key; e.keys)
+          visitE(key), visitE(e.values[i]);
+      static if (is(E == AssertExpression))
+        visitE(e.expr), e.msg && visitE(e.msg);
+      static if (is(E == MixinExpression) ||
+                 is(E == ImportExpression))
+        visitE(e.expr);
+      static if (is(E == TypeofExpression) ||
+                 is(E == TypeDotIdExpression) ||
+                 is(E == TypeidExpression))
+        visitT(e.type);
+      static if (is(E == IsExpression))
+        visitT(e.type), e.specType && visitT(e.specType),
+        e.tparams && visitN(e.tparams);
+      static if (is(E == FunctionLiteralExpression))
+        e.returnType && visitT(e.returnType),
+        e.params && visitN(e.params),
+        visitS(e.funcBody);
+      static if (is(E == ParenExpression))
+        visitE(e.next);
+      static if (is(E == TraitsExpression))
+        visitN(e.targs);
+      // VoidInitializer has no subnodes.
+      static if (is(E == ArrayInitExpression))
+        foreach (i, key; e.keys)
+          key && visitE(key), visitE(e.values[i]);
+      static if (is(E == StructInitExpression))
+        foreach (value; e.values)
+          visitE(value);
+    }
+  }
+  else
+  static if (is(T : Statement))
+  {
+    alias T S;
+    static if (is(S == CompoundStatement))
+      foreach (stmnt; s.stmnts)
+        visitS(stmnt);
+    //IllegalStatement has no subnodes.
+    static if (is(S == FuncBodyStatement))
+      s.funcBody && visitS(s.funcBody),
+      s.inBody && visitS(s.inBody),
+      s.outBody && visitS(s.outBody);
+    static if (is(S == ScopeStatement) || is(S == LabeledStatement))
+      visitS(s.s);
+    static if (is(S == ExpressionStatement))
+      visitE(s.e);
+    static if (is(S == DeclarationStatement))
+      visitD(s.decl);
+    static if (is(S == IfStatement))
+    {
+      s.variable ? cast(Node)visitS(s.variable) : visitE(s.condition);
+      visitS(s.ifBody), s.elseBody && visitS(s.elseBody);
+    }
+    static if (is(S == WhileStatement))
+      visitE(s.condition), visitS(s.whileBody);
+    static if (is(S == DoWhileStatement))
+      visitS(s.doBody), visitE(s.condition);
+    static if (is(S == ForStatement))
+      s.init && visitS(s.init),
+      s.condition && visitE(s.condition),
+      s.increment && visitE(s.increment),
+      visitS(s.forBody);
+    static if (is(S == ForeachStatement))
+      visitN(s.params), visitE(s.aggregate), visitS(s.forBody);
+    static if (is(S == ForeachRangeStatement))
+      visitN(s.params), visitE(s.lower), visitE(s.upper), visitS(s.forBody);
+    static if (is(S == SwitchStatement))
+      visitE(s.condition), visitS(s.switchBody);
+    static if (is(S == CaseStatement))
+    {
+      foreach (value; s.values)
+        visitE(value);
+      visitS(s.caseBody);
+    }
+    static if (is(S == DefaultStatement))
+      visitS(s.defaultBody);
+    //ContinueStatement,
+    //BreakStatement have no subnodes.
+    static if (is(S == ReturnStatement))
+      s.e && visitE(s.e);
+    static if (is(S == GotoStatement))
+      s.caseExpr && visitE(s.caseExpr);
+    static if (is(S == WithStatement))
+      visitE(s.e), visitS(s.withBody);
+    static if (is(S == SynchronizedStatement))
+      s.e && visitE(s.e), visitS(s.syncBody);
+    static if (is(S == TryStatement))
+    {
+      visitS(s.tryBody);
+      foreach (catchBody; s.catchBodies)
+        visitS(catchBody);
+      s.finallyBody && visitS(s.finallyBody);
+    }
+    static if (is(S == CatchStatement))
+      s.param && visitN(s.param), visitS(s.catchBody);
+    static if (is(S == FinallyStatement))
+      visitS(s.finallyBody);
+    static if (is(S == ScopeGuardStatement))
+      visitS(s.scopeBody);
+    static if (is(S == ThrowStatement))
+      visitE(s.e);
+    static if (is(S == VolatileStatement))
+      s.volatileBody && visitS(s.volatileBody);
+    static if (is(S == AsmBlockStatement))
+      visitS(s.statements);
+    static if (is(S == AsmStatement))
+      foreach (op; s.operands)
+        visitE(op);
+    //AsmAlignStatement,
+    //IllegalAsmStatement have no subnodes.
+    static if (is(S == PragmaStatement))
+    {
+      foreach (arg; s.args)
+        visitE(arg);
+      visitS(s.pragmaBody);
+    }
+    static if (is(S == MixinStatement))
+      visitE(s.templateExpr);
+    static if (is(S == StaticIfStatement))
+      visitE(s.condition), visitS(s.ifBody), s.elseBody && visitS(s.elseBody);
+    static if (is(S == StaticAssertStatement))
+      visitE(s.condition), s.message && visitE(s.message);
+    static if (is(S == DebugStatement) || is(S == VersionStatement))
+      visitS(s.mainBody), s.elseBody && visitS(s.elseBody);
+  }
+  else
+  static if (is(T : TypeNode))
+  {
+    //IllegalType,
+    //IntegralType,
+    //ModuleScopeType,
+    //IdentifierType have no subnodes.
+    static if (is(T == QualifiedType))
+      visitT(t.lhs), visitT(t.rhs);
+    static if (is(T == TypeofType))
+      visitE(t.e);
+    static if (is(T == TemplateInstanceType))
+      t.targs && visitN(t.targs);
+    static if (is(T == PointerType))
+      visitT(t.next);
+    static if (is(T == ArrayType))
+    {
+      visitT(t.next);
+      if (t.assocType)
+        visitT(t.assocType);
+      else if (t.e1)
+        visitE(t.e1), t.e2 && visitE(t.e2);
+    }
+    static if (is(T == FunctionType) || is(T == DelegateType))
+      visitT(t.returnType), visitN(t.params);
+    static if (is(T == CFuncPointerType))
+      visitT(t.next), t.params && visitN(t.params);
+    static if (is(T == BaseClassType) ||
+               is(T == ConstType) ||
+               is(T == InvariantType))
+      visitT(t.next);
+  }
+  else
+  static if (is(T == Parameter))
+  {
+    n.type && visitT(n.type);
+    n.defValue && visitE(n.defValue);
+  }
+  else
+  static if (is(T == Parameters) ||
+             is(T == TemplateParameters) ||
+             is(T == TemplateArguments))
+  {
+    foreach (node; n.children)
+      visitN(node);
+  }
+  else
+  static if (is(T : TemplateParameter))
+  {
+    static if (is(N == TemplateAliasParameter) ||
+               is(N == TemplateTypeParameter) ||
+               is(N == TemplateThisParameter))
+      n.specType && visitN(n.specType),
+      n.defType && visitN(n.defType);
+    static if (is(N == TemplateValueParameter))
+      visitT(n.valueType),
+      n.specValue && visitN(n.specValue),
+      n.defValue && visitN(n.defValue);
+    //TemplateTupleParameter has no subnodes.
+  }
+  else
+    static assert(0, "Missing default visit method for: "~typeof(t).stringof);
+  return t;
+}
+
+/// Generates the default visit methods.
+///
+/// E.g:
+/// ---
+/// private mixin .visitDefault!(ClassDeclaration) _ClassDeclaration;
+/// override returnType!("ClassDeclaration") visit(ClassDeclaration node)
+/// { return _ClassDeclaration.visitDefault(node); }
+/// ---
+char[] generateDefaultVisitMethods()
+{
+  char[] text;
+  foreach (className; g_classNames)
+    text ~= "private mixin .visitDefault!("~className~") _"~className~";\n"
+            "override returnType!(\""~className~"\") visit("~className~" node)"
+            "{return _"~className~".visitDefault(node);}\n";
+  return text;
+}
+// pragma(msg, generateDefaultVisitMethods());
+
+/// This class provides default methods for
+/// traversing nodes and their sub-nodes.
+class DefaultVisitor : Visitor
+{
+  // Comment out if too many errors are shown.
+  mixin(generateDefaultVisitMethods());
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/ast/Expression.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,22 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.ast.Expression;
+
+import dil.ast.Node;
+import dil.semantic.Types;
+import common;
+
+/// The root class of all expressions.
+abstract class Expression : Node
+{
+  Type type; /// The semantic type of this expression.
+
+  this()
+  {
+    super(NodeCategory.Expression);
+  }
+
+  override abstract Expression copy();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/ast/Expressions.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,1118 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.ast.Expressions;
+
+public import dil.ast.Expression;
+import dil.ast.Node;
+import dil.ast.Types;
+import dil.ast.Declarations;
+import dil.ast.Statements;
+import dil.ast.Parameters;
+import dil.ast.NodeCopier;
+import dil.lexer.Identifier;
+import dil.semantic.Types;
+import common;
+
+class IllegalExpression : Expression
+{
+  this()
+  {
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+
+abstract class BinaryExpression : Expression
+{
+  Expression lhs; /// Left-hand side expression.
+  Expression rhs; /// Right-hand side expression.
+  Token* tok;
+  this(Expression lhs, Expression rhs, Token* tok)
+  {
+    addChildren([lhs, rhs]);
+    this.lhs = lhs;
+    this.rhs = rhs;
+    this.tok = tok;
+  }
+  mixin(copyMethod);
+}
+
+class CondExpression : BinaryExpression
+{
+  Expression condition;
+  this(Expression condition, Expression left, Expression right, Token* tok)
+  {
+    addChild(condition);
+    super(left, right, tok);
+    mixin(set_kind);
+    this.condition = condition;
+  }
+  mixin(copyMethod);
+}
+
+class CommaExpression : BinaryExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+class OrOrExpression : BinaryExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+class AndAndExpression : BinaryExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+class OrExpression : BinaryExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+class XorExpression : BinaryExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+class AndExpression : BinaryExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+abstract class CmpExpression : BinaryExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+  }
+}
+
+class EqualExpression : CmpExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+/// Expression "!"? "is" Expression
+class IdentityExpression : CmpExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+class RelExpression : CmpExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+class InExpression : BinaryExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+class LShiftExpression : BinaryExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+class RShiftExpression : BinaryExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+class URShiftExpression : BinaryExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+class PlusExpression : BinaryExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+class MinusExpression : BinaryExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+class CatExpression : BinaryExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+class MulExpression : BinaryExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+class DivExpression : BinaryExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+class ModExpression : BinaryExpression
+{
+  this(Expression left, Expression right, Token* tok)
+  {
+    super(left, right, tok);
+    mixin(set_kind);
+  }
+}
+
+class AssignExpression : BinaryExpression
+{
+  this(Expression left, Expression right)
+  {
+    super(left, right, null);
+    mixin(set_kind);
+  }
+}
+class LShiftAssignExpression : BinaryExpression
+{
+  this(Expression left, Expression right)
+  {
+    super(left, right, null);
+    mixin(set_kind);
+  }
+}
+class RShiftAssignExpression : BinaryExpression
+{
+  this(Expression left, Expression right)
+  {
+    super(left, right, null);
+    mixin(set_kind);
+  }
+}
+class URShiftAssignExpression : BinaryExpression
+{
+  this(Expression left, Expression right)
+  {
+    super(left, right, null);
+    mixin(set_kind);
+  }
+}
+class OrAssignExpression : BinaryExpression
+{
+  this(Expression left, Expression right)
+  {
+    super(left, right, null);
+    mixin(set_kind);
+  }
+}
+class AndAssignExpression : BinaryExpression
+{
+  this(Expression left, Expression right)
+  {
+    super(left, right, null);
+    mixin(set_kind);
+  }
+}
+class PlusAssignExpression : BinaryExpression
+{
+  this(Expression left, Expression right)
+  {
+    super(left, right, null);
+    mixin(set_kind);
+  }
+}
+class MinusAssignExpression : BinaryExpression
+{
+  this(Expression left, Expression right)
+  {
+    super(left, right, null);
+    mixin(set_kind);
+  }
+}
+class DivAssignExpression : BinaryExpression
+{
+  this(Expression left, Expression right)
+  {
+    super(left, right, null);
+    mixin(set_kind);
+  }
+}
+class MulAssignExpression : BinaryExpression
+{
+  this(Expression left, Expression right)
+  {
+    super(left, right, null);
+    mixin(set_kind);
+  }
+}
+class ModAssignExpression : BinaryExpression
+{
+  this(Expression left, Expression right)
+  {
+    super(left, right, null);
+    mixin(set_kind);
+  }
+}
+class XorAssignExpression : BinaryExpression
+{
+  this(Expression left, Expression right)
+  {
+    super(left, right, null);
+    mixin(set_kind);
+  }
+}
+class CatAssignExpression : BinaryExpression
+{
+  this(Expression left, Expression right)
+  {
+    super(left, right, null);
+    mixin(set_kind);
+  }
+}
+
+/// DotExpression := Expression '.' Expression
+class DotExpression : BinaryExpression
+{
+  this(Expression left, Expression right)
+  {
+    super(left, right, null);
+    mixin(set_kind);
+  }
+}
+
+/*++++++++++++++++++++
++ Unary Expressions: +
+++++++++++++++++++++*/
+
+abstract class UnaryExpression : Expression
+{
+  Expression e;
+  this(Expression e)
+  {
+    addChild(e);
+    this.e = e;
+  }
+  mixin(copyMethod);
+}
+
+class AddressExpression : UnaryExpression
+{
+  this(Expression e)
+  {
+    super(e);
+    mixin(set_kind);
+  }
+}
+
+class PreIncrExpression : UnaryExpression
+{
+  this(Expression e)
+  {
+    super(e);
+    mixin(set_kind);
+  }
+}
+
+class PreDecrExpression : UnaryExpression
+{
+  this(Expression e)
+  {
+    super(e);
+    mixin(set_kind);
+  }
+}
+
+class PostIncrExpression : UnaryExpression
+{
+  this(Expression e)
+  {
+    super(e);
+    mixin(set_kind);
+  }
+}
+
+class PostDecrExpression : UnaryExpression
+{
+  this(Expression e)
+  {
+    super(e);
+    mixin(set_kind);
+  }
+}
+
+class DerefExpression : UnaryExpression
+{
+  this(Expression e)
+  {
+    super(e);
+    mixin(set_kind);
+  }
+}
+
+class SignExpression : UnaryExpression
+{
+  this(Expression e)
+  {
+    super(e);
+    mixin(set_kind);
+  }
+
+  bool isPos()
+  {
+    assert(begin !is null);
+    return begin.kind == TOK.Plus;
+  }
+
+  bool isNeg()
+  {
+    assert(begin !is null);
+    return begin.kind == TOK.Minus;
+  }
+}
+
+class NotExpression : UnaryExpression
+{
+  this(Expression e)
+  {
+    super(e);
+    mixin(set_kind);
+  }
+}
+
+class CompExpression : UnaryExpression
+{
+  this(Expression e)
+  {
+    super(e);
+    mixin(set_kind);
+  }
+}
+
+class CallExpression : UnaryExpression
+{
+  Expression[] args;
+  this(Expression e, Expression[] args)
+  {
+    super(e);
+    mixin(set_kind);
+    addOptChildren(args);
+    this.args = args;
+  }
+}
+
+class NewExpression : /*Unary*/Expression
+{
+  Expression[] newArgs;
+  TypeNode type;
+  Expression[] ctorArgs;
+  this(/*Expression e, */Expression[] newArgs, TypeNode type, Expression[] ctorArgs)
+  {
+    /*super(e);*/
+    mixin(set_kind);
+    addOptChildren(newArgs);
+    addChild(type);
+    addOptChildren(ctorArgs);
+    this.newArgs = newArgs;
+    this.type = type;
+    this.ctorArgs = ctorArgs;
+  }
+  mixin(copyMethod);
+}
+
+class NewAnonClassExpression : /*Unary*/Expression
+{
+  Expression[] newArgs;
+  BaseClassType[] bases;
+  Expression[] ctorArgs;
+  CompoundDeclaration decls;
+  this(/*Expression e, */Expression[] newArgs, BaseClassType[] bases, Expression[] ctorArgs, CompoundDeclaration decls)
+  {
+    /*super(e);*/
+    mixin(set_kind);
+    addOptChildren(newArgs);
+    addOptChildren(bases);
+    addOptChildren(ctorArgs);
+    addChild(decls);
+
+    this.newArgs = newArgs;
+    this.bases = bases;
+    this.ctorArgs = ctorArgs;
+    this.decls = decls;
+  }
+  mixin(copyMethod);
+}
+
+class DeleteExpression : UnaryExpression
+{
+  this(Expression e)
+  {
+    super(e);
+    mixin(set_kind);
+  }
+}
+
+class CastExpression : UnaryExpression
+{
+  TypeNode type;
+  this(Expression e, TypeNode type)
+  {
+    addChild(type); // Add type before super().
+    super(e);
+    mixin(set_kind);
+    this.type = type;
+  }
+  mixin(copyMethod);
+}
+
+class IndexExpression : UnaryExpression
+{
+  Expression[] args;
+  this(Expression e, Expression[] args)
+  {
+    super(e);
+    mixin(set_kind);
+    addChildren(args);
+    this.args = args;
+  }
+  mixin(copyMethod);
+}
+
+class SliceExpression : UnaryExpression
+{
+  Expression left, right;
+  this(Expression e, Expression left, Expression right)
+  {
+    super(e);
+    mixin(set_kind);
+    assert(left ? (right !is null) : right is null);
+    if (left)
+      addChildren([left, right]);
+
+    this.left = left;
+    this.right = right;
+  }
+  mixin(copyMethod);
+}
+
+/// Module scope operator: '.' (IdentifierExpression|TemplateInstanceExpression)
+class ModuleScopeExpression : UnaryExpression
+{
+  this(Expression e)
+  {
+    super(e);
+    assert(e.kind == NodeKind.IdentifierExpression ||
+           e.kind == NodeKind.TemplateInstanceExpression
+    );
+    mixin(set_kind);
+  }
+}
+
+/*++++++++++++++++++++++
++ Primary Expressions: +
+++++++++++++++++++++++*/
+
+class IdentifierExpression : Expression
+{
+  Identifier* identifier;
+  this(Identifier* identifier)
+  {
+    mixin(set_kind);
+    this.identifier = identifier;
+  }
+  mixin(copyMethod);
+}
+
+class SpecialTokenExpression : Expression
+{
+  Token* specialToken;
+  this(Token* specialToken)
+  {
+    mixin(set_kind);
+    this.specialToken = specialToken;
+  }
+
+  Expression value; /// The expression created in the semantic phase.
+
+  mixin(copyMethod);
+}
+
+class TemplateInstanceExpression : Expression
+{
+  Identifier* ident;
+  TemplateArguments targs;
+  this(Identifier* ident, TemplateArguments targs)
+  {
+    mixin(set_kind);
+    addOptChild(targs);
+    this.ident = ident;
+    this.targs = targs;
+  }
+  mixin(copyMethod);
+}
+
+class ThisExpression : Expression
+{
+  this()
+  {
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+
+class SuperExpression : Expression
+{
+  this()
+  {
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+
+class NullExpression : Expression
+{
+  this()
+  {
+    mixin(set_kind);
+  }
+
+  this(Type type)
+  {
+    this();
+    this.type = type;
+  }
+
+  mixin(copyMethod);
+}
+
+class DollarExpression : Expression
+{
+  this()
+  {
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+
+class BoolExpression : Expression
+{
+  this()
+  {
+    mixin(set_kind);
+  }
+
+  bool toBool()
+  {
+    assert(begin !is null);
+    return begin.kind == TOK.True ? true : false;
+  }
+
+  Expression value; /// IntExpression of type int.
+
+  mixin(copyMethod);
+}
+
+class IntExpression : Expression
+{
+  ulong number;
+
+  this(ulong number, Type type)
+  {
+    mixin(set_kind);
+    this.number = number;
+    this.type = type;
+  }
+
+  this(Token* token)
+  {
+    auto type = Types.Int; // Should be most common case.
+    switch (token.kind)
+    {
+    // case TOK.Int32:
+    //   type = Types.Int; break;
+    case TOK.Uint32:
+      type = Types.Uint; break;
+    case TOK.Int64:
+      type = Types.Long; break;
+    case TOK.Uint64:
+      type = Types.Ulong; break;
+    default:
+      assert(token.kind == TOK.Int32);
+    }
+    this(token.ulong_, type);
+  }
+
+  mixin(copyMethod);
+}
+
+class RealExpression : Expression
+{
+  real number;
+
+  this(real number, Type type)
+  {
+    mixin(set_kind);
+    this.number = number;
+    this.type = type;
+  }
+
+  this(Token* token)
+  {
+    auto type = Types.Double; // Most common case?
+    switch (token.kind)
+    {
+    case TOK.Float32:
+      type = Types.Float; break;
+    // case TOK.Float64:
+    //   type = Types.Double; break;
+    case TOK.Float80:
+      type = Types.Real; break;
+    case TOK.Imaginary32:
+      type = Types.Ifloat; break;
+    case TOK.Imaginary64:
+      type = Types.Idouble; break;
+    case TOK.Imaginary80:
+      type = Types.Ireal; break;
+    default:
+      assert(token.kind == TOK.Float64);
+    }
+    this(token.real_, type);
+  }
+
+  mixin(copyMethod);
+}
+
+
+/// This expression holds a complex number.
+/// It is only created in the semantic phase.
+class ComplexExpression : Expression
+{
+  creal number;
+  this(creal number, Type type)
+  {
+    mixin(set_kind);
+    this.number = number;
+    this.type = type;
+  }
+  mixin(copyMethod);
+}
+
+class CharExpression : Expression
+{
+  dchar character;
+  this(dchar character)
+  {
+    mixin(set_kind);
+    this.character = character;
+  }
+  mixin(copyMethod);
+}
+
+class StringExpression : Expression
+{
+  ubyte[] str;   /// The string data.
+  Type charType; /// The character type of the string.
+
+  this(ubyte[] str, Type charType)
+  {
+    mixin(set_kind);
+    this.str = str;
+    this.charType = charType;
+    type = new TypeSArray(charType, str.length);
+  }
+
+  this(char[] str)
+  {
+    this(cast(ubyte[])str, Types.Char);
+  }
+
+  this(wchar[] str)
+  {
+    this(cast(ubyte[])str, Types.Wchar);
+  }
+
+  this(dchar[] str)
+  {
+    this(cast(ubyte[])str, Types.Dchar);
+  }
+
+  /// Returns the string excluding the terminating 0.
+  char[] getString()
+  {
+    // TODO: convert to char[] if charType !is Types.Char.
+    return cast(char[])str[0..$-1];
+  }
+
+  mixin(copyMethod);
+}
+
+class ArrayLiteralExpression : Expression
+{
+  Expression[] values;
+  this(Expression[] values)
+  {
+    mixin(set_kind);
+    addOptChildren(values);
+    this.values = values;
+  }
+  mixin(copyMethod);
+}
+
+class AArrayLiteralExpression : Expression
+{
+  Expression[] keys, values;
+  this(Expression[] keys, Expression[] values)
+  {
+    assert(keys.length == values.length);
+    mixin(set_kind);
+    foreach (i, key; keys)
+      addChildren([key, values[i]]);
+    this.keys = keys;
+    this.values = values;
+  }
+  mixin(copyMethod);
+}
+
+class AssertExpression : Expression
+{
+  Expression expr, msg;
+  this(Expression expr, Expression msg)
+  {
+    mixin(set_kind);
+    addChild(expr);
+    addOptChild(msg);
+    this.expr = expr;
+    this.msg = msg;
+  }
+  mixin(copyMethod);
+}
+
+class MixinExpression : Expression
+{
+  Expression expr;
+  this(Expression expr)
+  {
+    mixin(set_kind);
+    addChild(expr);
+    this.expr = expr;
+  }
+  mixin(copyMethod);
+}
+
+class ImportExpression : Expression
+{
+  Expression expr;
+  this(Expression expr)
+  {
+    mixin(set_kind);
+    addChild(expr);
+    this.expr = expr;
+  }
+  mixin(copyMethod);
+}
+
+class TypeofExpression : Expression
+{
+  TypeNode type;
+  this(TypeNode type)
+  {
+    mixin(set_kind);
+    addChild(type);
+    this.type = type;
+  }
+  mixin(copyMethod);
+}
+
+class TypeDotIdExpression : Expression
+{
+  TypeNode type;
+  Identifier* ident;
+  this(TypeNode type, Identifier* ident)
+  {
+    mixin(set_kind);
+    addChild(type);
+    this.type = type;
+    this.ident = ident;
+  }
+  mixin(copyMethod);
+}
+
+class TypeidExpression : Expression
+{
+  TypeNode type;
+  this(TypeNode type)
+  {
+    mixin(set_kind);
+    addChild(type);
+    this.type = type;
+  }
+  mixin(copyMethod);
+}
+
+class IsExpression : Expression
+{
+  TypeNode type;
+  Identifier* ident;
+  Token* opTok, specTok;
+  TypeNode specType;
+  TemplateParameters tparams; // D 2.0
+  this(TypeNode type, Identifier* ident, Token* opTok, Token* specTok,
+       TypeNode specType, typeof(tparams) tparams)
+  {
+    mixin(set_kind);
+    addChild(type);
+    addOptChild(specType);
+  version(D2)
+    addOptChild(tparams);
+    this.type = type;
+    this.ident = ident;
+    this.opTok = opTok;
+    this.specTok = specTok;
+    this.specType = specType;
+    this.tparams = tparams;
+  }
+  mixin(copyMethod);
+}
+
+class FunctionLiteralExpression : Expression
+{
+  TypeNode returnType;
+  Parameters params;
+  FuncBodyStatement funcBody;
+
+  this()
+  {
+    mixin(set_kind);
+    addOptChild(returnType);
+    addOptChild(params);
+    addChild(funcBody);
+  }
+
+  this(TypeNode returnType, Parameters params, FuncBodyStatement funcBody)
+  {
+    this.returnType = returnType;
+    this.params = params;
+    this.funcBody = funcBody;
+    this();
+  }
+
+  this(FuncBodyStatement funcBody)
+  {
+    this.funcBody = funcBody;
+    this();
+  }
+
+  mixin(copyMethod);
+}
+
+/// ParenthesisExpression := "(" Expression ")"
+class ParenExpression : Expression
+{
+  Expression next;
+  this(Expression next)
+  {
+    mixin(set_kind);
+    addChild(next);
+    this.next = next;
+  }
+  mixin(copyMethod);
+}
+
+// version(D2)
+// {
+class TraitsExpression : Expression
+{
+  Identifier* ident;
+  TemplateArguments targs;
+  this(typeof(ident) ident, typeof(targs) targs)
+  {
+    mixin(set_kind);
+    addOptChild(targs);
+    this.ident = ident;
+    this.targs = targs;
+  }
+  mixin(copyMethod);
+}
+// }
+
+class VoidInitExpression : Expression
+{
+  this()
+  {
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+
+class ArrayInitExpression : Expression
+{
+  Expression[] keys;
+  Expression[] values;
+  this(Expression[] keys, Expression[] values)
+  {
+    assert(keys.length == values.length);
+    mixin(set_kind);
+    foreach (i, key; keys)
+    {
+      addOptChild(key); // The key is optional in ArrayInitializers.
+      addChild(values[i]);
+    }
+    this.keys = keys;
+    this.values = values;
+  }
+  mixin(copyMethod);
+}
+
+class StructInitExpression : Expression
+{
+  Identifier*[] idents;
+  Expression[] values;
+  this(Identifier*[] idents, Expression[] values)
+  {
+    mixin(set_kind);
+    addOptChildren(values);
+    this.idents = idents;
+    this.values = values;
+  }
+  mixin(copyMethod);
+}
+
+class AsmTypeExpression : UnaryExpression
+{
+  this(Expression e)
+  {
+    super(e);
+    mixin(set_kind);
+  }
+}
+
+class AsmOffsetExpression : UnaryExpression
+{
+  this(Expression e)
+  {
+    super(e);
+    mixin(set_kind);
+  }
+}
+
+class AsmSegExpression : UnaryExpression
+{
+  this(Expression e)
+  {
+    super(e);
+    mixin(set_kind);
+  }
+}
+
+class AsmPostBracketExpression : UnaryExpression
+{
+  Expression e2; /// Expression in brackets: e [ e2 ]
+  this(Expression e, Expression e2)
+  {
+    super(e);
+    mixin(set_kind);
+    addChild(e2);
+    this.e2 = e2;
+  }
+  mixin(copyMethod);
+}
+
+class AsmBracketExpression : Expression
+{
+  Expression e;
+  this(Expression e)
+  {
+    mixin(set_kind);
+    addChild(e);
+    this.e = e;
+  }
+  mixin(copyMethod);
+}
+
+class AsmLocalSizeExpression : Expression
+{
+  this()
+  {
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+
+class AsmRegisterExpression : Expression
+{
+  Identifier* register;
+  int number; // ST(0) - ST(7) or FS:0, FS:4, FS:8
+  this(Identifier* register, int number = -1)
+  {
+    mixin(set_kind);
+    this.register = register;
+    this.number = number;
+  }
+  mixin(copyMethod);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/ast/Node.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,98 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.ast.Node;
+
+import common;
+
+public import dil.lexer.Token;
+public import dil.ast.NodesEnum;
+
+/// The root class of all D syntax tree elements.
+abstract class Node
+{
+  NodeCategory category; /// The category of this node.
+  NodeKind kind; /// The kind of this node.
+  Node[] children; // Will be probably removed sometime.
+  Token* begin, end; /// The begin and end tokens of this node.
+
+  /// Constructs a node object.
+  this(NodeCategory category)
+  {
+    assert(category != NodeCategory.Undefined);
+    this.category = category;
+  }
+
+  void setTokens(Token* begin, Token* end)
+  {
+    this.begin = begin;
+    this.end = end;
+  }
+
+  Class setToks(Class)(Class node)
+  {
+    node.setTokens(this.begin, this.end);
+    return node;
+  }
+
+  void addChild(Node child)
+  {
+    assert(child !is null, "failed in " ~ this.classinfo.name);
+    this.children ~= child;
+  }
+
+  void addOptChild(Node child)
+  {
+    child is null || addChild(child);
+  }
+
+  void addChildren(Node[] children)
+  {
+    assert(children !is null && delegate{
+      foreach (child; children)
+        if (child is null)
+          return false;
+      return true; }(),
+      "failed in " ~ this.classinfo.name
+    );
+    this.children ~= children;
+  }
+
+  void addOptChildren(Node[] children)
+  {
+    children is null || addChildren(children);
+  }
+
+  /// Returns a reference to Class if this node can be cast to it.
+  Class Is(Class)()
+  {
+    if (kind == mixin("NodeKind." ~ typeof(Class).stringof))
+      return cast(Class)cast(void*)this;
+    return null;
+  }
+
+  /// Casts this node to Class.
+  Class to(Class)()
+  {
+    return cast(Class)cast(void*)this;
+  }
+
+  /// Returns a deep copy of this node.
+  abstract Node copy();
+
+  /// Returns a shallow copy of this object.
+  final Node dup()
+  {
+    // Find out the size of this object.
+    alias typeof(this.classinfo.init[0]) byte_t;
+    size_t size = this.classinfo.init.length;
+    // Copy this object's data.
+    byte_t[] data = (cast(byte_t*)this)[0..size].dup;
+    return cast(Node)data.ptr;
+  }
+
+  /// This string is mixed into the constructor of a class that inherits
+  /// from Node. It sets the member kind.
+  const string set_kind = `this.kind = mixin("NodeKind." ~ typeof(this).stringof);`;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/ast/NodeCopier.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,324 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.ast.NodeCopier;
+
+import common;
+
+/// Mixed into the body of a class that inherits from Node.
+const string copyMethod = `
+  override typeof(this) copy()
+  {
+    mixin copyNode!(typeof(this));
+    return copyNode(this);
+  }`;
+
+/// A helper function that generates code for copying subnodes.
+string doCopy_(string obj, string[] members)
+{
+  char[] result;
+  foreach (member; members)
+  {
+    if (member.length > 2 && member[$-2..$] == "[]") // Array copy.
+    {
+      member = member[0..$-2];
+      // obj.member = obj.member.dup;
+      // foreach (ref m_; obj.member)
+      //   m_ = m_.copy();
+      result ~= obj~"."~member~" = "~obj~"."~member~".dup;"
+      "foreach (ref m_; "~obj~"."~member~")"
+        "m_ = m_.copy();";
+    }
+    else if (member[$-1] == '?') // Optional member copy.
+    {
+      member = member[0..$-1];
+      // obj.member && (obj.member = obj.member.copy());
+      result ~= obj~"."~member~" && ("~obj~"."~member~" = "~obj~"."~member~".copy());";
+    }
+    else // Non-optional member copy.
+      // obj.member = obj.member.copy();
+      result ~= obj~"."~member~" = "~obj~"."~member~".copy();";
+  }
+  return result;
+}
+
+string doCopy(string[] members)
+{
+  return doCopy_("x", members);
+}
+
+string doCopy(string member)
+{
+  return doCopy_("x", [member]);
+}
+
+// pragma(msg, doCopy("decls?"));
+
+/// Returns a deep copy of node.
+T copyNode(T)(T node)
+{
+  assert(node !is null);
+
+  // Firstly do a shallow copy.
+  T x = cast(T)cast(void*)node.dup;
+
+  // Now copy the subnodes.
+  static if (is(Declaration) && is(T : Declaration))
+  {
+    alias T D;
+    static if (is(D == CompoundDeclaration))
+      mixin(doCopy("decls[]"));
+    //EmptyDeclaration,
+    //IllegalDeclaration,
+    //ModuleDeclaration have no subnodes.
+    static if (is(D == AliasDeclaration) ||
+               is(D == TypedefDeclaration))
+      mixin(doCopy("decl"));
+    static if (is(D == EnumDeclaration))
+      mixin(doCopy(["baseType?", "members[]"]));
+    static if (is(D == EnumMemberDeclaration))
+      mixin(doCopy("value"));
+    static if (is(D == ClassDeclaration) || is( D == InterfaceDeclaration))
+      mixin(doCopy(["bases[]", "decls"]));
+    static if (is(D == StructDeclaration) || is(D == UnionDeclaration))
+      mixin(doCopy("decls"));
+    static if (is(D == ConstructorDeclaration))
+      mixin(doCopy(["params", "funcBody"]));
+    static if (is(D == StaticConstructorDeclaration) ||
+               is(D == DestructorDeclaration) ||
+               is(D == StaticDestructorDeclaration) ||
+               is(D == InvariantDeclaration) ||
+               is(D == UnittestDeclaration))
+      mixin(doCopy("funcBody"));
+    static if (is(D == FunctionDeclaration))
+      mixin(doCopy(["returnType", "params", "funcBody"]));
+    static if (is(D == VariablesDeclaration))
+    {
+      mixin(doCopy("typeNode?"));
+      x.inits = x.inits.dup;
+      foreach(ref init; x.inits)
+        init && (init = init.copy());
+    }
+    static if (is(D == DebugDeclaration) || is(D == VersionDeclaration))
+      mixin(doCopy(["decls?","elseDecls?"]));
+    static if (is(D == StaticIfDeclaration))
+      mixin(doCopy(["condition","ifDecls", "elseDecls?"]));
+    static if (is(D == StaticAssertDeclaration))
+      mixin(doCopy(["condition","message?"]));
+    static if (is(D == TemplateDeclaration))
+      mixin(doCopy(["tparams","decls"]));
+    static if (is(D == NewDeclaration) || is(D == DeleteDeclaration))
+      mixin(doCopy(["params","funcBody"]));
+    static if (is(D == ProtectionDeclaration) ||
+               is(D == StorageClassDeclaration) ||
+               is(D == LinkageDeclaration) ||
+               is(D == AlignDeclaration))
+      mixin(doCopy("decls"));
+    static if (is(D == PragmaDeclaration))
+      mixin(doCopy(["args[]","decls"]));
+    static if (is(D == MixinDeclaration))
+      mixin(doCopy(["templateExpr?","argument?"]));
+  }
+  else
+  static if (is(Expression) && is(T : Expression))
+  {
+    alias T E;
+    static if (is(E == IllegalExpression))
+    {}
+    else
+    static if (is(E == CondExpression))
+      mixin(doCopy(["condition", "lhs", "rhs"]));
+    else
+    static if (is(E : BinaryExpression))
+      mixin(doCopy(["lhs", "rhs"]));
+    else
+    static if (is(E : UnaryExpression))
+    {
+      static if (is(E == CastExpression))
+        mixin(doCopy("type"));
+      mixin(doCopy("e")); // Copy member in base class UnaryExpression.
+      static if (is(E == IndexExpression))
+        mixin(doCopy("args[]"));
+      static if (is(E == SliceExpression))
+        mixin(doCopy(["left?", "right?"]));
+      static if (is(E == AsmPostBracketExpression))
+        mixin(doCopy("e2"));
+    }
+    else
+    {
+      static if (is(E == NewExpression))
+        mixin(doCopy(["newArgs[]", "type", "ctorArgs[]"]));
+      static if (is(E == NewAnonClassExpression))
+        mixin(doCopy(["newArgs[]", "bases[]", "ctorArgs[]", "decls"]));
+      static if (is(E == AsmBracketExpression))
+        mixin(doCopy("e"));
+      static if (is(E == TemplateInstanceExpression))
+        mixin(doCopy("targs?"));
+      static if (is(E == ArrayLiteralExpression))
+        mixin(doCopy("values[]"));
+      static if (is(E == AArrayLiteralExpression))
+        mixin(doCopy(["keys[]", "values[]"]));
+      static if (is(E == AssertExpression))
+        mixin(doCopy(["expr", "msg?"]));
+      static if (is(E == MixinExpression) ||
+                 is(E == ImportExpression))
+        mixin(doCopy("expr"));
+      static if (is(E == TypeofExpression) ||
+                 is(E == TypeDotIdExpression) ||
+                 is(E == TypeidExpression))
+        mixin(doCopy("type"));
+      static if (is(E == IsExpression))
+        mixin(doCopy(["type", "specType?", "tparams?"]));
+      static if (is(E == FunctionLiteralExpression))
+        mixin(doCopy(["returnType?", "params?", "funcBody"]));
+      static if (is(E == ParenExpression))
+        mixin(doCopy("next"));
+      static if (is(E == TraitsExpression))
+        mixin(doCopy("targs"));
+      // VoidInitializer has no subnodes.
+      static if (is(E == ArrayInitExpression))
+      {
+        mixin(doCopy("values[]"));
+        x.keys = x.keys.dup;
+        foreach(ref key; x.keys)
+          key && (key = key.copy());
+      }
+      static if (is(E == StructInitExpression))
+        mixin(doCopy("values[]"));
+      static if (is(E == StringExpression))
+        x.str = x.str.dup;
+    }
+  }
+  else
+  static if (is(Statement) && is(T : Statement))
+  {
+    alias T S;
+    static if (is(S == CompoundStatement))
+      mixin(doCopy("stmnts[]"));
+    //IllegalStatement,
+    //EmptyStatement have no subnodes.
+    static if (is(S == FuncBodyStatement))
+      mixin(doCopy(["funcBody?", "inBody?", "outBody?"]));
+    static if (is(S == ScopeStatement) || is(S == LabeledStatement))
+      mixin(doCopy("s"));
+    static if (is(S == ExpressionStatement))
+      mixin(doCopy("e"));
+    static if (is(S == DeclarationStatement))
+      mixin(doCopy("decl"));
+    static if (is(S == IfStatement))
+    {
+      if (x.variable)
+        mixin(doCopy("variable"));
+      else
+        mixin(doCopy("condition"));
+      mixin(doCopy(["ifBody", "elseBody?"]));
+    }
+    static if (is(S == WhileStatement))
+      mixin(doCopy(["condition", "whileBody"]));
+    static if (is(S == DoWhileStatement))
+      mixin(doCopy(["doBody", "condition"]));
+    static if (is(S == ForStatement))
+      mixin(doCopy(["init?", "condition?", "increment?", "forBody"]));
+    static if (is(S == ForeachStatement))
+      mixin(doCopy(["params", "aggregate", "forBody"]));
+    static if (is(S == ForeachRangeStatement))
+      mixin(doCopy(["params", "lower", "upper", "forBody"]));
+    static if (is(S == SwitchStatement))
+      mixin(doCopy(["condition", "switchBody"]));
+    static if (is(S == CaseStatement))
+      mixin(doCopy(["values[]", "caseBody"]));
+    static if (is(S == DefaultStatement))
+      mixin(doCopy("defaultBody"));
+    //ContinueStatement,
+    //BreakStatement have no subnodes.
+    static if (is(S == ReturnStatement))
+      mixin(doCopy("e?"));
+    static if (is(S == GotoStatement))
+      mixin(doCopy("caseExpr?"));
+    static if (is(S == WithStatement))
+      mixin(doCopy(["e", "withBody"]));
+    static if (is(S == SynchronizedStatement))
+      mixin(doCopy(["e?", "syncBody"]));
+    static if (is(S == TryStatement))
+      mixin(doCopy(["tryBody", "catchBodies[]", "finallyBody?"]));
+    static if (is(S == CatchStatement))
+      mixin(doCopy(["param?", "catchBody"]));
+    static if (is(S == FinallyStatement))
+      mixin(doCopy("finallyBody"));
+    static if (is(S == ScopeGuardStatement))
+      mixin(doCopy("scopeBody"));
+    static if (is(S == ThrowStatement))
+      mixin(doCopy("e"));
+    static if (is(S == VolatileStatement))
+      mixin(doCopy("volatileBody?"));
+    static if (is(S == AsmBlockStatement))
+      mixin(doCopy("statements"));
+    static if (is(S == AsmStatement))
+      mixin(doCopy("operands[]"));
+    //AsmAlignStatement,
+    //IllegalAsmStatement have no subnodes.
+    static if (is(S == PragmaStatement))
+      mixin(doCopy(["args[]", "pragmaBody"]));
+    static if (is(S == MixinStatement))
+      mixin(doCopy("templateExpr"));
+    static if (is(S == StaticIfStatement))
+      mixin(doCopy(["condition", "ifBody", "elseBody?"]));
+    static if (is(S == StaticAssertStatement))
+      mixin(doCopy(["condition", "message?"]));
+    static if (is(S == DebugStatement) || is(S == VersionStatement))
+      mixin(doCopy(["mainBody", "elseBody?"]));
+  }
+  else
+  static if (is(TypeNode) && is(T : TypeNode))
+  {
+    //IllegalType,
+    //IntegralType,
+    //ModuleScopeType,
+    //IdentifierType have no subnodes.
+    static if (is(T == QualifiedType))
+      mixin(doCopy(["lhs", "rhs"]));
+    static if (is(T == TypeofType))
+      mixin(doCopy("e"));
+    static if (is(T == TemplateInstanceType))
+      mixin(doCopy("targs?"));
+    static if (is(T == PointerType))
+      mixin(doCopy("next"));
+    static if (is(T == ArrayType))
+      mixin(doCopy(["next", "assocType?", "e1?", "e2?"]));
+    static if (is(T == FunctionType) || is(T == DelegateType))
+      mixin(doCopy(["returnType", "params"]));
+    static if (is(T == CFuncPointerType))
+      mixin(doCopy(["next", "params?"]));
+    static if (is(T == BaseClassType) ||
+               is(T == ConstType) ||
+               is(T == InvariantType))
+      mixin(doCopy("next"));
+  }
+  else
+  static if (is(Parameter) && is(T == Parameter))
+  {
+    mixin(doCopy(["type?", "defValue?"]));
+  }
+  else
+  static if (is(Parameter) && is(T == Parameters) ||
+             is(TemplateParameter) && is(T == TemplateParameters) ||
+             is(TemplateArguments) && is(T == TemplateArguments))
+  {
+    mixin(doCopy("children[]"));
+  }
+  else
+  static if (is(TemplateParameter) && is(T : TemplateParameter))
+  {
+    static if (is(N == TemplateAliasParameter) ||
+               is(N == TemplateTypeParameter) ||
+               is(N == TemplateThisParameter))
+      mixin(doCopy(["specType", "defType"]));
+    static if (is(N == TemplateValueParameter))
+      mixin(doCopy(["valueType", "specValue?", "defValue?"]));
+    //TemplateTupleParameter has no subnodes.
+  }
+  else
+    static assert(0, "copying of "~typeof(x).stringof~" is not handled");
+  return x;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/ast/NodesEnum.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,234 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.ast.NodesEnum;
+
+/// Enumerates the categories of a node.
+enum NodeCategory : ushort
+{
+  Undefined,
+  Declaration,
+  Statement,
+  Expression,
+  Type,
+  Other
+}
+
+/// A list of all class names that inherit from Node.
+static const char[][] g_classNames = [
+  // Declarations:
+  "CompoundDeclaration",
+  "EmptyDeclaration",
+  "IllegalDeclaration",
+  "ModuleDeclaration",
+  "ImportDeclaration",
+  "AliasDeclaration",
+  "TypedefDeclaration",
+  "EnumDeclaration",
+  "EnumMemberDeclaration",
+  "ClassDeclaration",
+  "InterfaceDeclaration",
+  "StructDeclaration",
+  "UnionDeclaration",
+  "ConstructorDeclaration",
+  "StaticConstructorDeclaration",
+  "DestructorDeclaration",
+  "StaticDestructorDeclaration",
+  "FunctionDeclaration",
+  "VariablesDeclaration",
+  "InvariantDeclaration",
+  "UnittestDeclaration",
+  "DebugDeclaration",
+  "VersionDeclaration",
+  "StaticIfDeclaration",
+  "StaticAssertDeclaration",
+  "TemplateDeclaration",
+  "NewDeclaration",
+  "DeleteDeclaration",
+  "ProtectionDeclaration",
+  "StorageClassDeclaration",
+  "LinkageDeclaration",
+  "AlignDeclaration",
+  "PragmaDeclaration",
+  "MixinDeclaration",
+
+  // Statements:
+  "CompoundStatement",
+  "IllegalStatement",
+  "EmptyStatement",
+  "FuncBodyStatement",
+  "ScopeStatement",
+  "LabeledStatement",
+  "ExpressionStatement",
+  "DeclarationStatement",
+  "IfStatement",
+  "WhileStatement",
+  "DoWhileStatement",
+  "ForStatement",
+  "ForeachStatement",
+  "ForeachRangeStatement", // D2.0
+  "SwitchStatement",
+  "CaseStatement",
+  "DefaultStatement",
+  "ContinueStatement",
+  "BreakStatement",
+  "ReturnStatement",
+  "GotoStatement",
+  "WithStatement",
+  "SynchronizedStatement",
+  "TryStatement",
+  "CatchStatement",
+  "FinallyStatement",
+  "ScopeGuardStatement",
+  "ThrowStatement",
+  "VolatileStatement",
+  "AsmBlockStatement",
+  "AsmStatement",
+  "AsmAlignStatement",
+  "IllegalAsmStatement",
+  "PragmaStatement",
+  "MixinStatement",
+  "StaticIfStatement",
+  "StaticAssertStatement",
+  "DebugStatement",
+  "VersionStatement",
+
+  // Expressions:
+  "IllegalExpression",
+  "CondExpression",
+  "CommaExpression",
+  "OrOrExpression",
+  "AndAndExpression",
+  "OrExpression",
+  "XorExpression",
+  "AndExpression",
+  "EqualExpression",
+  "IdentityExpression",
+  "RelExpression",
+  "InExpression",
+  "LShiftExpression",
+  "RShiftExpression",
+  "URShiftExpression",
+  "PlusExpression",
+  "MinusExpression",
+  "CatExpression",
+  "MulExpression",
+  "DivExpression",
+  "ModExpression",
+  "AssignExpression",
+  "LShiftAssignExpression",
+  "RShiftAssignExpression",
+  "URShiftAssignExpression",
+  "OrAssignExpression",
+  "AndAssignExpression",
+  "PlusAssignExpression",
+  "MinusAssignExpression",
+  "DivAssignExpression",
+  "MulAssignExpression",
+  "ModAssignExpression",
+  "XorAssignExpression",
+  "CatAssignExpression",
+  "AddressExpression",
+  "PreIncrExpression",
+  "PreDecrExpression",
+  "PostIncrExpression",
+  "PostDecrExpression",
+  "DerefExpression",
+  "SignExpression",
+  "NotExpression",
+  "CompExpression",
+  "CallExpression",
+  "NewExpression",
+  "NewAnonClassExpression",
+  "DeleteExpression",
+  "CastExpression",
+  "IndexExpression",
+  "SliceExpression",
+  "ModuleScopeExpression",
+  "IdentifierExpression",
+  "SpecialTokenExpression",
+  "DotExpression",
+  "TemplateInstanceExpression",
+  "ThisExpression",
+  "SuperExpression",
+  "NullExpression",
+  "DollarExpression",
+  "BoolExpression",
+  "IntExpression",
+  "RealExpression",
+  "ComplexExpression",
+  "CharExpression",
+  "StringExpression",
+  "ArrayLiteralExpression",
+  "AArrayLiteralExpression",
+  "AssertExpression",
+  "MixinExpression",
+  "ImportExpression",
+  "TypeofExpression",
+  "TypeDotIdExpression",
+  "TypeidExpression",
+  "IsExpression",
+  "ParenExpression",
+  "FunctionLiteralExpression",
+  "TraitsExpression", // D2.0
+  "VoidInitExpression",
+  "ArrayInitExpression",
+  "StructInitExpression",
+  "AsmTypeExpression",
+  "AsmOffsetExpression",
+  "AsmSegExpression",
+  "AsmPostBracketExpression",
+  "AsmBracketExpression",
+  "AsmLocalSizeExpression",
+  "AsmRegisterExpression",
+
+  // Types:
+  "IllegalType",
+  "IntegralType",
+  "QualifiedType",
+  "ModuleScopeType",
+  "IdentifierType",
+  "TypeofType",
+  "TemplateInstanceType",
+  "PointerType",
+  "ArrayType",
+  "FunctionType",
+  "DelegateType",
+  "CFuncPointerType",
+  "BaseClassType",
+  "ConstType", // D2.0
+  "InvariantType", // D2.0
+
+  // Other:
+  "Parameter",
+  "Parameters",
+  "TemplateAliasParameter",
+  "TemplateTypeParameter",
+  "TemplateThisParameter", // D2.0
+  "TemplateValueParameter",
+  "TemplateTupleParameter",
+  "TemplateParameters",
+  "TemplateArguments",
+];
+
+/// Generates the members of enum NodeKind.
+char[] generateNodeKindMembers()
+{
+  char[] text;
+  foreach (className; g_classNames)
+    text ~= className ~ ",";
+  return text;
+}
+// pragma(msg, generateNodeKindMembers());
+
+version(DDoc)
+  /// The node kind identifies every class that inherits from Node.
+  enum NodeKind : ushort;
+else
+mixin(
+  "enum NodeKind : ushort"
+  "{"
+    ~ generateNodeKindMembers ~
+  "}"
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/ast/Parameters.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,227 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.ast.Parameters;
+
+import dil.ast.Node;
+import dil.ast.Type;
+import dil.ast.Expression;
+import dil.ast.NodeCopier;
+import dil.lexer.Identifier;
+import dil.Enums;
+
+/// A function or foreach parameter.
+class Parameter : Node
+{
+  StorageClass stc; /// The storage classes of the parameter.
+  TypeNode type; /// The parameter's type.
+  Identifier* name; /// The name of the parameter.
+  Expression defValue; /// The default initialization value.
+
+  this(StorageClass stc, TypeNode type, Identifier* name, Expression defValue)
+  {
+    super(NodeCategory.Other);
+    mixin(set_kind);
+    // type can be null when param in foreach statement
+    addOptChild(type);
+    addOptChild(defValue);
+
+    this.stc = stc;
+    this.type = type;
+    this.name = name;
+    this.defValue = defValue;
+  }
+
+  /// Returns true if this is a D-style variadic parameter.
+  /// E.g.: func(int[] values ...)
+  bool isDVariadic()
+  {
+    return isVariadic && !isCVariadic;
+  }
+
+  /// Returns true if this is a C-style variadic parameter.
+  /// E.g.: func(...)
+  bool isCVariadic()
+  {
+    return stc == StorageClass.Variadic &&
+           type is null && name is null;
+  }
+
+  /// Returns true if this is a D- or C-style variadic parameter.
+  bool isVariadic()
+  {
+    return !!(stc & StorageClass.Variadic);
+  }
+
+  mixin(copyMethod);
+}
+
+/// Array of parameters.
+class Parameters : Node
+{
+  this()
+  {
+    super(NodeCategory.Other);
+    mixin(set_kind);
+  }
+
+  bool hasVariadic()
+  {
+    if (children.length != 0)
+      return items[$-1].isVariadic();
+    return false;
+  }
+
+  void opCatAssign(Parameter param)
+  { addChild(param); }
+
+  Parameter[] items()
+  { return cast(Parameter[])children; }
+
+  size_t length()
+  { return children.length; }
+
+  mixin(copyMethod);
+}
+
+/*~~~~~~~~~~~~~~~~~~~~~~
+~ Template parameters: ~
+~~~~~~~~~~~~~~~~~~~~~~*/
+
+/// Abstract base class for all template parameters.
+abstract class TemplateParameter : Node
+{
+  Identifier* ident;
+  this(Identifier* ident)
+  {
+    super(NodeCategory.Other);
+    this.ident = ident;
+  }
+  override abstract TemplateParameter copy();
+}
+
+/// E.g.: (alias T)
+class TemplateAliasParameter : TemplateParameter
+{
+  TypeNode specType, defType;
+  this(Identifier* ident, TypeNode specType, TypeNode defType)
+  {
+    super(ident);
+    mixin(set_kind);
+    addOptChild(specType);
+    addOptChild(defType);
+    this.ident = ident;
+    this.specType = specType;
+    this.defType = defType;
+  }
+  mixin(copyMethod);
+}
+
+/// E.g.: (T t)
+class TemplateTypeParameter : TemplateParameter
+{
+  TypeNode specType, defType;
+  this(Identifier* ident, TypeNode specType, TypeNode defType)
+  {
+    super(ident);
+    mixin(set_kind);
+    addOptChild(specType);
+    addOptChild(defType);
+    this.ident = ident;
+    this.specType = specType;
+    this.defType = defType;
+  }
+  mixin(copyMethod);
+}
+
+// version(D2)
+// {
+/// E.g.: (this T)
+class TemplateThisParameter : TemplateParameter
+{
+  TypeNode specType, defType;
+  this(Identifier* ident, TypeNode specType, TypeNode defType)
+  {
+    super(ident);
+    mixin(set_kind);
+    addOptChild(specType);
+    addOptChild(defType);
+    this.ident = ident;
+    this.specType = specType;
+    this.defType = defType;
+  }
+  mixin(copyMethod);
+}
+// }
+
+/// E.g.: (T)
+class TemplateValueParameter : TemplateParameter
+{
+  TypeNode valueType;
+  Expression specValue, defValue;
+  this(TypeNode valueType, Identifier* ident, Expression specValue, Expression defValue)
+  {
+    super(ident);
+    mixin(set_kind);
+    addChild(valueType);
+    addOptChild(specValue);
+    addOptChild(defValue);
+    this.valueType = valueType;
+    this.ident = ident;
+    this.specValue = specValue;
+    this.defValue = defValue;
+  }
+  mixin(copyMethod);
+}
+
+/// E.g.: (T...)
+class TemplateTupleParameter : TemplateParameter
+{
+  this(Identifier* ident)
+  {
+    super(ident);
+    mixin(set_kind);
+    this.ident = ident;
+  }
+  mixin(copyMethod);
+}
+
+/// Array of template parameters.
+class TemplateParameters : Node
+{
+  this()
+  {
+    super(NodeCategory.Other);
+    mixin(set_kind);
+  }
+
+  void opCatAssign(TemplateParameter parameter)
+  {
+    addChild(parameter);
+  }
+
+  TemplateParameter[] items()
+  {
+    return cast(TemplateParameter[])children;
+  }
+
+  mixin(copyMethod);
+}
+
+/// Array of template arguments.
+class TemplateArguments : Node
+{
+  this()
+  {
+    super(NodeCategory.Other);
+    mixin(set_kind);
+  }
+
+  void opCatAssign(Node argument)
+  {
+    addChild(argument);
+  }
+
+  mixin(copyMethod);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/ast/Statement.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,18 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.ast.Statement;
+
+import dil.ast.Node;
+
+/// The root class of all statements.
+abstract class Statement : Node
+{
+  this()
+  {
+    super(NodeCategory.Statement);
+  }
+
+  override abstract Statement copy();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/ast/Statements.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,607 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.ast.Statements;
+
+public import dil.ast.Statement;
+import dil.ast.Node;
+import dil.ast.Expression;
+import dil.ast.Declaration;
+import dil.ast.Type;
+import dil.ast.Parameters;
+import dil.ast.NodeCopier;
+import dil.lexer.IdTable;
+
+class CompoundStatement : Statement
+{
+  this()
+  {
+    mixin(set_kind);
+  }
+
+  void opCatAssign(Statement s)
+  {
+    addChild(s);
+  }
+
+  Statement[] stmnts()
+  {
+    return cast(Statement[])this.children;
+  }
+
+  void stmnts(Statement[] stmnts)
+  {
+    this.children = stmnts;
+  }
+
+  mixin(copyMethod);
+}
+
+class IllegalStatement : Statement
+{
+  this()
+  {
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+
+class EmptyStatement : Statement
+{
+  this()
+  {
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+
+class FuncBodyStatement : Statement
+{
+  Statement funcBody, inBody, outBody;
+  Identifier* outIdent;
+  this()
+  {
+    mixin(set_kind);
+  }
+
+  void finishConstruction()
+  {
+    addOptChild(funcBody);
+    addOptChild(inBody);
+    addOptChild(outBody);
+  }
+
+  bool isEmpty()
+  {
+    return funcBody is null;
+  }
+
+  mixin(copyMethod);
+}
+
+class ScopeStatement : Statement
+{
+  Statement s;
+  this(Statement s)
+  {
+    mixin(set_kind);
+    addChild(s);
+    this.s = s;
+  }
+  mixin(copyMethod);
+}
+
+class LabeledStatement : Statement
+{
+  Identifier* label;
+  Statement s;
+  this(Identifier* label, Statement s)
+  {
+    mixin(set_kind);
+    addChild(s);
+    this.label = label;
+    this.s = s;
+  }
+  mixin(copyMethod);
+}
+
+class ExpressionStatement : Statement
+{
+  Expression e;
+  this(Expression e)
+  {
+    mixin(set_kind);
+    addChild(e);
+    this.e = e;
+  }
+  mixin(copyMethod);
+}
+
+class DeclarationStatement : Statement
+{
+  Declaration decl;
+  this(Declaration decl)
+  {
+    mixin(set_kind);
+    addChild(decl);
+    this.decl = decl;
+  }
+  mixin(copyMethod);
+}
+
+class IfStatement : Statement
+{
+  Statement variable; // AutoDeclaration or VariableDeclaration
+  Expression condition;
+  Statement ifBody;
+  Statement elseBody;
+  this(Statement variable, Expression condition, Statement ifBody, Statement elseBody)
+  {
+    mixin(set_kind);
+    if (variable)
+      addChild(variable);
+    else
+      addChild(condition);
+    addChild(ifBody);
+    addOptChild(elseBody);
+
+    this.variable = variable;
+    this.condition = condition;
+    this.ifBody = ifBody;
+    this.elseBody = elseBody;
+  }
+  mixin(copyMethod);
+}
+
+class WhileStatement : Statement
+{
+  Expression condition;
+  Statement whileBody;
+  this(Expression condition, Statement whileBody)
+  {
+    mixin(set_kind);
+    addChild(condition);
+    addChild(whileBody);
+
+    this.condition = condition;
+    this.whileBody = whileBody;
+  }
+  mixin(copyMethod);
+}
+
+class DoWhileStatement : Statement
+{
+  Statement doBody;
+  Expression condition;
+  this(Expression condition, Statement doBody)
+  {
+    mixin(set_kind);
+    addChild(doBody);
+    addChild(condition);
+
+    this.condition = condition;
+    this.doBody = doBody;
+  }
+  mixin(copyMethod);
+}
+
+class ForStatement : Statement
+{
+  Statement init;
+  Expression condition, increment;
+  Statement forBody;
+
+  this(Statement init, Expression condition, Expression increment, Statement forBody)
+  {
+    mixin(set_kind);
+    addOptChild(init);
+    addOptChild(condition);
+    addOptChild(increment);
+    addChild(forBody);
+
+    this.init = init;
+    this.condition = condition;
+    this.increment = increment;
+    this.forBody = forBody;
+  }
+  mixin(copyMethod);
+}
+
+class ForeachStatement : Statement
+{
+  TOK tok;
+  Parameters params;
+  Expression aggregate;
+  Statement forBody;
+
+  this(TOK tok, Parameters params, Expression aggregate, Statement forBody)
+  {
+    mixin(set_kind);
+    addChildren([cast(Node)params, aggregate, forBody]);
+
+    this.tok = tok;
+    this.params = params;
+    this.aggregate = aggregate;
+    this.forBody = forBody;
+  }
+  mixin(copyMethod);
+}
+
+// version(D2)
+// {
+class ForeachRangeStatement : Statement
+{
+  TOK tok;
+  Parameters params;
+  Expression lower, upper;
+  Statement forBody;
+
+  this(TOK tok, Parameters params, Expression lower, Expression upper, Statement forBody)
+  {
+    mixin(set_kind);
+    addChildren([cast(Node)params, lower, upper, forBody]);
+
+    this.tok = tok;
+    this.params = params;
+    this.lower = lower;
+    this.upper = upper;
+    this.forBody = forBody;
+  }
+  mixin(copyMethod);
+}
+// }
+
+class SwitchStatement : Statement
+{
+  Expression condition;
+  Statement switchBody;
+
+  this(Expression condition, Statement switchBody)
+  {
+    mixin(set_kind);
+    addChild(condition);
+    addChild(switchBody);
+
+    this.condition = condition;
+    this.switchBody = switchBody;
+  }
+  mixin(copyMethod);
+}
+
+class CaseStatement : Statement
+{
+  Expression[] values;
+  Statement caseBody;
+
+  this(Expression[] values, Statement caseBody)
+  {
+    mixin(set_kind);
+    addChildren(values);
+    addChild(caseBody);
+
+    this.values = values;
+    this.caseBody = caseBody;
+  }
+  mixin(copyMethod);
+}
+
+class DefaultStatement : Statement
+{
+  Statement defaultBody;
+  this(Statement defaultBody)
+  {
+    mixin(set_kind);
+    addChild(defaultBody);
+
+    this.defaultBody = defaultBody;
+  }
+  mixin(copyMethod);
+}
+
+class ContinueStatement : Statement
+{
+  Identifier* ident;
+  this(Identifier* ident)
+  {
+    mixin(set_kind);
+    this.ident = ident;
+  }
+  mixin(copyMethod);
+}
+
+class BreakStatement : Statement
+{
+  Identifier* ident;
+  this(Identifier* ident)
+  {
+    mixin(set_kind);
+    this.ident = ident;
+  }
+  mixin(copyMethod);
+}
+
+class ReturnStatement : Statement
+{
+  Expression e;
+  this(Expression e)
+  {
+    mixin(set_kind);
+    addOptChild(e);
+    this.e = e;
+  }
+  mixin(copyMethod);
+}
+
+class GotoStatement : Statement
+{
+  Identifier* ident;
+  Expression caseExpr;
+  this(Identifier* ident, Expression caseExpr)
+  {
+    mixin(set_kind);
+    addOptChild(caseExpr);
+    this.ident = ident;
+    this.caseExpr = caseExpr;
+  }
+  mixin(copyMethod);
+}
+
+class WithStatement : Statement
+{
+  Expression e;
+  Statement withBody;
+  this(Expression e, Statement withBody)
+  {
+    mixin(set_kind);
+    addChild(e);
+    addChild(withBody);
+
+    this.e = e;
+    this.withBody = withBody;
+  }
+  mixin(copyMethod);
+}
+
+class SynchronizedStatement : Statement
+{
+  Expression e;
+  Statement syncBody;
+  this(Expression e, Statement syncBody)
+  {
+    mixin(set_kind);
+    addOptChild(e);
+    addChild(syncBody);
+
+    this.e = e;
+    this.syncBody = syncBody;
+  }
+  mixin(copyMethod);
+}
+
+class TryStatement : Statement
+{
+  Statement tryBody;
+  CatchStatement[] catchBodies;
+  FinallyStatement finallyBody;
+  this(Statement tryBody, CatchStatement[] catchBodies, FinallyStatement finallyBody)
+  {
+    mixin(set_kind);
+    addChild(tryBody);
+    addOptChildren(catchBodies);
+    addOptChild(finallyBody);
+
+    this.tryBody = tryBody;
+    this.catchBodies = catchBodies;
+    this.finallyBody = finallyBody;
+  }
+  mixin(copyMethod);
+}
+
+class CatchStatement : Statement
+{
+  Parameter param;
+  Statement catchBody;
+  this(Parameter param, Statement catchBody)
+  {
+    mixin(set_kind);
+    addOptChild(param);
+    addChild(catchBody);
+    this.param = param;
+    this.catchBody = catchBody;
+  }
+  mixin(copyMethod);
+}
+
+class FinallyStatement : Statement
+{
+  Statement finallyBody;
+  this(Statement finallyBody)
+  {
+    mixin(set_kind);
+    addChild(finallyBody);
+    this.finallyBody = finallyBody;
+  }
+  mixin(copyMethod);
+}
+
+class ScopeGuardStatement : Statement
+{
+  Identifier* condition;
+  Statement scopeBody;
+  this(Identifier* condition, Statement scopeBody)
+  {
+    mixin(set_kind);
+    addChild(scopeBody);
+    this.condition = condition;
+    this.scopeBody = scopeBody;
+  }
+  mixin(copyMethod);
+}
+
+class ThrowStatement : Statement
+{
+  Expression e;
+  this(Expression e)
+  {
+    mixin(set_kind);
+    addChild(e);
+    this.e = e;
+  }
+  mixin(copyMethod);
+}
+
+class VolatileStatement : Statement
+{
+  Statement volatileBody;
+  this(Statement volatileBody)
+  {
+    mixin(set_kind);
+    addOptChild(volatileBody);
+    this.volatileBody = volatileBody;
+  }
+  mixin(copyMethod);
+}
+
+class AsmBlockStatement : Statement
+{
+  CompoundStatement statements;
+  this(CompoundStatement statements)
+  {
+    mixin(set_kind);
+    addChild(statements);
+    this.statements = statements;
+  }
+  mixin(copyMethod);
+}
+
+class AsmStatement : Statement
+{
+  Identifier* ident;
+  Expression[] operands;
+  this(Identifier* ident, Expression[] operands)
+  {
+    mixin(set_kind);
+    addOptChildren(operands);
+    this.ident = ident;
+    this.operands = operands;
+  }
+  mixin(copyMethod);
+}
+
+class AsmAlignStatement : Statement
+{
+  int number;
+  this(int number)
+  {
+    mixin(set_kind);
+    this.number = number;
+  }
+  mixin(copyMethod);
+}
+
+class IllegalAsmStatement : IllegalStatement
+{
+  this()
+  {
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+
+class PragmaStatement : Statement
+{
+  Identifier* ident;
+  Expression[] args;
+  Statement pragmaBody;
+  this(Identifier* ident, Expression[] args, Statement pragmaBody)
+  {
+    mixin(set_kind);
+    addOptChildren(args);
+    addChild(pragmaBody);
+
+    this.ident = ident;
+    this.args = args;
+    this.pragmaBody = pragmaBody;
+  }
+  mixin(copyMethod);
+}
+
+class MixinStatement : Statement
+{
+  Expression templateExpr;
+  Identifier* mixinIdent;
+  this(Expression templateExpr, Identifier* mixinIdent)
+  {
+    mixin(set_kind);
+    addChild(templateExpr);
+    this.templateExpr = templateExpr;
+    this.mixinIdent = mixinIdent;
+  }
+  mixin(copyMethod);
+}
+
+class StaticIfStatement : Statement
+{
+  Expression condition;
+  Statement ifBody, elseBody;
+  this(Expression condition, Statement ifBody, Statement elseBody)
+  {
+    mixin(set_kind);
+    addChild(condition);
+    addChild(ifBody);
+    addOptChild(elseBody);
+    this.condition = condition;
+    this.ifBody = ifBody;
+    this.elseBody = elseBody;
+  }
+  mixin(copyMethod);
+}
+
+class StaticAssertStatement : Statement
+{
+  Expression condition, message;
+  this(Expression condition, Expression message)
+  {
+    mixin(set_kind);
+    addChild(condition);
+    addOptChild(message);
+    this.condition = condition;
+    this.message = message;
+  }
+  mixin(copyMethod);
+}
+
+abstract class ConditionalCompilationStatement : Statement
+{
+  Token* cond;
+  Statement mainBody, elseBody;
+  this(Token* cond, Statement mainBody, Statement elseBody)
+  {
+    addChild(mainBody);
+    addOptChild(elseBody);
+    this.cond = cond;
+    this.mainBody = mainBody;
+    this.elseBody = elseBody;
+  }
+}
+
+class DebugStatement : ConditionalCompilationStatement
+{
+  this(Token* cond, Statement debugBody, Statement elseBody)
+  {
+    super(cond, debugBody, elseBody);
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+
+class VersionStatement : ConditionalCompilationStatement
+{
+  this(Token* cond, Statement versionBody, Statement elseBody)
+  {
+    super(cond, versionBody, elseBody);
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/ast/Type.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,38 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.ast.Type;
+
+import dil.ast.Node;
+import dil.semantic.Types;
+
+/// The root class of all type nodes.
+abstract class TypeNode : Node
+{
+  TypeNode next; /// The next type in the type chain.
+  Type type; /// The semantic type of this type node.
+
+  this()
+  {
+    this(null);
+  }
+
+  this(TypeNode next)
+  {
+    super(NodeCategory.Type);
+    addOptChild(next);
+    this.next = next;
+  }
+
+  /// Returns the root type of the type chain.
+  TypeNode baseType()
+  {
+    auto type = this;
+    while (type.next)
+      type = type.next;
+    return type;
+  }
+
+  override abstract TypeNode copy();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/ast/Types.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,262 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.ast.Types;
+
+public import dil.ast.Type;
+import dil.ast.Node;
+import dil.ast.Expression;
+import dil.ast.Parameters;
+import dil.ast.NodeCopier;
+import dil.lexer.Identifier;
+import dil.semantic.Types;
+import dil.Enums;
+
+/// Syntax error.
+class IllegalType : TypeNode
+{
+  this()
+  {
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+
+/// char, int, float etc.
+class IntegralType : TypeNode
+{
+  TOK tok;
+  this(TOK tok)
+  {
+    mixin(set_kind);
+    this.tok = tok;
+  }
+  mixin(copyMethod);
+}
+
+/// Identifier
+class IdentifierType : TypeNode
+{
+  Identifier* ident;
+  this(Identifier* ident)
+  {
+    mixin(set_kind);
+    this.ident = ident;
+  }
+  mixin(copyMethod);
+}
+
+/// Type "." Type
+class QualifiedType : TypeNode
+{
+  alias next lhs; /// Left-hand side type.
+  TypeNode rhs; /// Right-hand side type.
+  this(TypeNode lhs, TypeNode rhs)
+  {
+    super(lhs);
+    mixin(set_kind);
+    addChild(rhs);
+    this.rhs = rhs;
+  }
+  mixin(copyMethod);
+}
+
+/// "." Type
+class ModuleScopeType : TypeNode
+{
+  this()
+  {
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+
+/// "typeof" "(" Expression ")" or$(BR)
+/// "typeof" "(" "return" ")" (D2.0)
+class TypeofType : TypeNode
+{
+  Expression e;
+  this(Expression e)
+  {
+    this();
+    addChild(e);
+    this.e = e;
+  }
+
+  // For D2.0: "typeof" "(" "return" ")"
+  this()
+  {
+    mixin(set_kind);
+  }
+
+  bool isTypeofReturn()
+  {
+    return e is null;
+  }
+
+  mixin(copyMethod);
+}
+
+/// Identifier "!" "(" TemplateParameters? ")"
+class TemplateInstanceType : TypeNode
+{
+  Identifier* ident;
+  TemplateArguments targs;
+  this(Identifier* ident, TemplateArguments targs)
+  {
+    mixin(set_kind);
+    addOptChild(targs);
+    this.ident = ident;
+    this.targs = targs;
+  }
+  mixin(copyMethod);
+}
+
+/// Type *
+class PointerType : TypeNode
+{
+  this(TypeNode next)
+  {
+    super(next);
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+
+/// Dynamic array: T[] or$(BR)
+/// Static array: T[E] or$(BR)
+/// Slice array (for tuples): T[E..E] or$(BR)
+/// Associative array: T[T]
+class ArrayType : TypeNode
+{
+  Expression e1, e2;
+  TypeNode assocType;
+
+  this(TypeNode t)
+  {
+    super(t);
+    mixin(set_kind);
+  }
+
+  this(TypeNode t, Expression e1, Expression e2)
+  {
+    this(t);
+    addChild(e1);
+    addOptChild(e2);
+    this.e1 = e1;
+    this.e2 = e2;
+  }
+
+  this(TypeNode t, TypeNode assocType)
+  {
+    this(t);
+    addChild(assocType);
+    this.assocType = assocType;
+  }
+
+  bool isDynamic()
+  {
+    return !assocType && !e1;
+  }
+
+  bool isStatic()
+  {
+    return e1 && !e2;
+  }
+
+  bool isSlice()
+  {
+    return e1 && e2;
+  }
+
+  bool isAssociative()
+  {
+    return assocType !is null;
+  }
+
+  mixin(copyMethod);
+}
+
+/// ReturnType "function" "(" Parameters? ")"
+class FunctionType : TypeNode
+{
+  alias next returnType;
+  Parameters params;
+  this(TypeNode returnType, Parameters params)
+  {
+    super(returnType);
+    mixin(set_kind);
+    addChild(params);
+    this.params = params;
+  }
+  mixin(copyMethod);
+}
+
+/// ReturnType "delegate" "(" Parameters? ")"
+class DelegateType : TypeNode
+{
+  alias next returnType;
+  Parameters params;
+  this(TypeNode returnType, Parameters params)
+  {
+    super(returnType);
+    mixin(set_kind);
+    addChild(params);
+    this.params = params;
+  }
+  mixin(copyMethod);
+}
+
+/// Type "(" BasicType2 Identifier ")" "(" Parameters? ")"
+class CFuncPointerType : TypeNode
+{
+  Parameters params;
+  this(TypeNode type, Parameters params)
+  {
+    super(type);
+    mixin(set_kind);
+    addOptChild(params);
+  }
+  mixin(copyMethod);
+}
+
+/// "class" Identifier : BaseClasses
+class BaseClassType : TypeNode
+{
+  Protection prot;
+  this(Protection prot, TypeNode type)
+  {
+    super(type);
+    mixin(set_kind);
+    this.prot = prot;
+  }
+  mixin(copyMethod);
+}
+
+// version(D2)
+// {
+/// "const" "(" Type ")"
+class ConstType : TypeNode
+{
+  this(TypeNode next)
+  {
+    // If t is null: cast(const)
+    super(next);
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+
+/// "invariant" "(" Type ")"
+class InvariantType : TypeNode
+{
+  this(TypeNode next)
+  {
+    // If t is null: cast(invariant)
+    super(next);
+    mixin(set_kind);
+  }
+  mixin(copyMethod);
+}
+// } // version(D2)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/ast/Visitor.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,155 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.ast.Visitor;
+
+import dil.ast.Node;
+import dil.ast.Declarations,
+       dil.ast.Expressions,
+       dil.ast.Statements,
+       dil.ast.Types,
+       dil.ast.Parameters;
+
+/// Generate visit methods.
+///
+/// E.g.:
+/// ---
+/// Declaration visit(ClassDeclaration){return null;};
+/// Expression visit(CommaExpression){return null;};
+/// ---
+char[] generateVisitMethods()
+{
+  char[] text;
+  foreach (className; g_classNames)
+    text ~= "returnType!(\""~className~"\") visit("~className~" node){return node;}\n";
+  return text;
+}
+// pragma(msg, generateAbstractVisitMethods());
+
+/// Gets the appropriate return type for the provided class.
+template returnType(char[] className)
+{
+  static if (is(typeof(mixin(className)) : Declaration))
+    alias Declaration returnType;
+  else
+  static if (is(typeof(mixin(className)) : Statement))
+    alias Statement returnType;
+  else
+  static if (is(typeof(mixin(className)) : Expression))
+    alias Expression returnType;
+  else
+  static if (is(typeof(mixin(className)) : TypeNode))
+    alias TypeNode returnType;
+  else
+    alias Node returnType;
+}
+
+/// Generate functions which do the second dispatch.
+///
+/// E.g.:
+/// ---
+/// Expression visitCommaExpression(Visitor visitor, CommaExpression c)
+/// { visitor.visit(c); /* Second dispatch. */ }
+/// ---
+/// The equivalent in the traditional visitor pattern would be:
+/// ---
+/// class CommaExpression : Expression
+/// {
+///   void accept(Visitor visitor)
+///   { visitor.visit(this); }
+/// }
+/// ---
+char[] generateDispatchFunctions()
+{
+  char[] text;
+  foreach (className; g_classNames)
+    text ~= "returnType!(\""~className~"\") visit"~className~"(Visitor visitor, "~className~" c)\n"
+            "{ return visitor.visit(c); }\n";
+  return text;
+}
+// pragma(msg, generateDispatchFunctions());
+
+/++
+ Generates an array of function pointers.
+
+ ---
+ [
+   cast(void*)&visitCommaExpression,
+   // etc.
+ ]
+ ---
++/
+char[] generateVTable()
+{
+  char[] text = "[";
+  foreach (className; g_classNames)
+    text ~= "cast(void*)&visit"~className~",\n";
+  return text[0..$-2]~"]"; // slice away last ",\n"
+}
+// pragma(msg, generateVTable());
+
+/// Implements a variation of the visitor pattern.
+///
+/// Inherited by classes that need to traverse a D syntax tree
+/// and do computations, transformations and other things on it.
+abstract class Visitor
+{
+  mixin(generateVisitMethods());
+
+  static
+    mixin(generateDispatchFunctions());
+
+  /// The table holding function pointers to the second dispatch functions.
+  static const void*[] dispatch_vtable = mixin(generateVTable());
+  static assert(dispatch_vtable.length == g_classNames.length, "vtable length doesn't match number of classes");
+
+  /// Looks up the second dispatch function for n and returns that.
+  Node function(Visitor, Node) getDispatchFunction()(Node n)
+  {
+    return cast(Node function(Visitor, Node))dispatch_vtable[n.kind];
+  }
+
+  /// The main and first dispatch function.
+  Node dispatch(Node n)
+  { // Second dispatch is done in the called function.
+    return getDispatchFunction(n)(this, n);
+  }
+
+final:
+  Declaration visit(Declaration n)
+  { return visitD(n); }
+  Statement visit(Statement n)
+  { return visitS(n); }
+  Expression visit(Expression n)
+  { return visitE(n); }
+  TypeNode visit(TypeNode n)
+  { return visitT(n); }
+  Node visit(Node n)
+  { return visitN(n); }
+
+  Declaration visitD(Declaration n)
+  {
+    return cast(Declaration)cast(void*)dispatch(n);
+  }
+
+  Statement visitS(Statement n)
+  {
+    return cast(Statement)cast(void*)dispatch(n);
+  }
+
+  Expression visitE(Expression n)
+  {
+    return cast(Expression)cast(void*)dispatch(n);
+  }
+
+  TypeNode visitT(TypeNode n)
+  {
+    return cast(TypeNode)cast(void*)dispatch(n);
+  }
+
+  Node visitN(Node n)
+  {
+    return dispatch(n);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/doc/Doc.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,463 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.doc.Doc;
+
+import dil.doc.Parser;
+import dil.ast.Node;
+import dil.lexer.Funcs;
+import dil.Unicode;
+import common;
+
+import tango.text.Ascii : icompare;
+
+/// Represents a sanitized and parsed DDoc comment.
+class DDocComment
+{
+  Section[] sections; /// The sections of this comment.
+  Section summary; /// Optional summary section.
+  Section description; /// Optional description section.
+
+  this(Section[] sections, Section summary, Section description)
+  {
+    this.sections = sections;
+    this.summary = summary;
+    this.description = description;
+  }
+
+  /// Removes the first copyright section and returns it.
+  Section takeCopyright()
+  {
+    foreach (i, section; sections)
+      if (section.Is("copyright"))
+      {
+        sections = sections[0..i] ~ sections[i+1..$];
+        return section;
+      }
+    return null;
+  }
+
+  /// Returns true if "ditto" is the only text in this comment.
+  bool isDitto()
+  {
+    if (summary && sections.length == 1 &&
+        icompare(strip(summary.text), "ditto") == 0)
+      return true;
+    return false;
+  }
+}
+
+/// Returns a node's DDocComment.
+DDocComment getDDocComment(Node node)
+{
+  DDocParser p;
+  auto docTokens = getDocTokens(node);
+  if (!docTokens.length)
+    return null;
+  p.parse(getDDocText(docTokens));
+  return new DDocComment(p.sections, p.summary, p.description);
+}
+
+/// Strips leading and trailing whitespace characters.
+/// Whitespace: ' ', '\t', '\v', '\f' and '\n'
+/// Returns: a slice into str.
+char[] strip(char[] str)
+{
+  if (str.length == 0)
+    return null;
+  uint i;
+  for (; i < str.length; i++)
+    if (!isspace(str[i]) && str[i] != '\n')
+      break;
+  if (str.length == i)
+    return null;
+  str = str[i..$];
+  assert(str.length);
+  for (i = str.length; i; i--)
+    if (!isspace(str[i-1]) && str[i-1] != '\n')
+      break;
+  return str[0..i];
+}
+
+/// Parses a DDoc comment string.
+struct DDocParser
+{
+  char* p; /// Current character pointer.
+  char* textEnd; /// Points one character past the end of the text.
+  Section[] sections; /// Parsed sections.
+  Section summary; /// Optional summary section.
+  Section description; /// Optional description section.
+
+  /// Parses the DDoc text into sections.
+  Section[] parse(string text)
+  {
+    if (!text.length)
+      return null;
+    p = text.ptr;
+    textEnd = p + text.length;
+
+    char* summaryBegin;
+    string ident, nextIdent;
+    char* bodyBegin, nextBodyBegin;
+
+    skipWhitespace(p);
+    summaryBegin = p;
+
+    if (findNextIdColon(ident, bodyBegin))
+    { // Check that this is not an explicit section.
+      if (summaryBegin != ident.ptr)
+        scanSummaryAndDescription(summaryBegin, ident.ptr);
+    }
+    else // There are no explicit sections.
+    {
+      scanSummaryAndDescription(summaryBegin, textEnd);
+      return sections;
+    }
+
+    assert(ident.length);
+    // Continue parsing.
+    while (findNextIdColon(nextIdent, nextBodyBegin))
+    {
+      sections ~= new Section(ident, textBody(bodyBegin, nextIdent.ptr));
+      ident = nextIdent;
+      bodyBegin = nextBodyBegin;
+    }
+    // Add last section.
+    sections ~= new Section(ident, textBody(bodyBegin, textEnd));
+    return sections;
+  }
+
+  /// Returns the text body. Trailing whitespace characters are not included.
+  char[] textBody(char* begin, char* end)
+  {
+    // The body of A is empty, e.g.:
+    // A:
+    // B: some text
+    // ^- begin and end point to B (or to this.textEnd in the 2nd case.)
+    if (begin is end)
+      return "";
+    // Remove trailing whitespace.
+    while (isspace(*--end) || *end == '\n')
+    {}
+    end++;
+    return makeString(begin, end);
+  }
+
+  /// Separates the text between p and end
+  /// into a summary and description section.
+  void scanSummaryAndDescription(char* p, char* end)
+  {
+    assert(p <= end);
+    char* sectionBegin = p;
+    // Search for the end of the first paragraph.
+    end--; // Decrement end, so we can look ahead one character.
+    while (p < end && !(*p == '\n' && p[1] == '\n'))
+    {
+      if (isCodeSection(p, end))
+        skipCodeSection(p, end);
+      p++;
+    }
+    end++;
+    if (p+1 >= end)
+      p = end;
+    assert(p == end || (*p == '\n' && p[1] == '\n'));
+    // The first paragraph is the summary.
+    summary = new Section("", makeString(sectionBegin, p));
+    sections ~= summary;
+    // The rest is the description section.
+    if (p < end)
+    {
+      skipWhitespace(p);
+      sectionBegin = p;
+      if (p < end)
+      {
+        description = new Section("", makeString(sectionBegin, end));
+        sections ~= description;
+      }
+    }
+  }
+
+  /// Returns true if p points to "$(DDD)".
+  bool isCodeSection(char* p, char* end)
+  {
+    return p+2 < end && *p == '-' && p[1] == '-' && p[2] == '-';
+  }
+
+  /// Skips over a code section.
+  ///
+  /// Note that dmd apparently doesn't skip over code sections when
+  /// parsing DDoc sections. However, from experience it seems
+  /// to be a good idea to do that.
+  void skipCodeSection(ref char* p, char* end)
+  out { assert(p+1 == end || *p == '-'); }
+  body
+  {
+    assert(isCodeSection(p, end));
+
+    while (p < end && *p == '-')
+      p++;
+    p--;
+    while (++p < end)
+      if (p+2 < end && *p == '-' && p[1] == '-' && p[2] == '-')
+        break;
+    while (p < end && *p == '-')
+      p++;
+    p--;
+  }
+
+  void skipWhitespace(ref char* p)
+  {
+    while (p < textEnd && (isspace(*p) || *p == '\n'))
+      p++;
+  }
+
+  /// Find next "Identifier:".
+  /// Params:
+  ///   ident = set to the Identifier.
+  ///   bodyBegin = set to the beginning of the text body (whitespace skipped.)
+  /// Returns: true if found.
+  bool findNextIdColon(ref char[] ident, ref char* bodyBegin)
+  {
+    while (p < textEnd)
+    {
+      skipWhitespace(p);
+      if (p >= textEnd)
+        break;
+      if (isCodeSection(p, textEnd))
+      {
+        skipCodeSection(p, textEnd);
+        p++;
+        continue;
+      }
+      assert(isascii(*p) || isLeadByte(*p));
+      auto idBegin = p;
+      if (isidbeg(*p) || isUnicodeAlpha(p, textEnd)) // IdStart
+      {
+        do // IdChar*
+          p++;
+        while (p < textEnd && (isident(*p) || isUnicodeAlpha(p, textEnd)))
+        auto idEnd = p;
+        if (p < textEnd && *p == ':') // :
+        {
+          p++;
+          skipWhitespace(p);
+          bodyBegin = p;
+          ident = makeString(idBegin, idEnd);
+          return true;
+        }
+      }
+      // Skip this line.
+      while (p < textEnd && *p != '\n')
+        p++;
+    }
+    return false;
+  }
+}
+
+/// Represents a DDoc section.
+class Section
+{
+  string name;
+  string text;
+  this(string name, string text)
+  {
+    this.name = name;
+    this.text = text;
+  }
+
+  /// Case-insensitively compares the section's name with name2.
+  bool Is(char[] name2)
+  {
+    return icompare(name, name2) == 0;
+  }
+}
+
+class ParamsSection : Section
+{
+  string[] paramNames; /// Parameter names.
+  string[] paramDescs; /// Parameter descriptions.
+  this(string name, string text)
+  {
+    super(name, text);
+    IdentValueParser parser;
+    auto idvalues = parser.parse(text);
+    this.paramNames = new string[idvalues.length];
+    this.paramDescs = new string[idvalues.length];
+    foreach (i, idvalue; idvalues)
+    {
+      this.paramNames[i] = idvalue.ident;
+      this.paramDescs[i] = idvalue.value;
+    }
+  }
+}
+
+class MacrosSection : Section
+{
+  string[] macroNames; /// Macro names.
+  string[] macroTexts; /// Macro texts.
+  this(string name, string text)
+  {
+    super(name, text);
+    IdentValueParser parser;
+    auto idvalues = parser.parse(text);
+    this.macroNames = new string[idvalues.length];
+    this.macroTexts = new string[idvalues.length];
+    foreach (i, idvalue; idvalues)
+    {
+      this.macroNames[i] = idvalue.ident;
+      this.macroTexts[i] = idvalue.value;
+    }
+  }
+}
+
+/// Returns true if token is a Doxygen comment.
+bool isDoxygenComment(Token* token)
+{ // Doxygen: '/+!' '/*!' '//!'
+  return token.kind == TOK.Comment && token.start[2] == '!';
+}
+
+/// Returns true if token is a DDoc comment.
+bool isDDocComment(Token* token)
+{ // DDOC: '/++' '/**' '///'
+  return token.kind == TOK.Comment && token.start[1] == token.start[2];
+}
+
+/// Returns the surrounding documentation comment tokens.
+/// Params:
+///   node = the node to find doc comments for.
+///   isDocComment = a function predicate that checks for doc comment tokens.
+/// Note: this function works correctly only if
+///       the source text is syntactically correct.
+Token*[] getDocTokens(Node node, bool function(Token*) isDocComment = &isDDocComment)
+{
+  Token*[] comments;
+  auto isEnumMember = node.kind == NodeKind.EnumMemberDeclaration;
+  // Get preceding comments.
+  auto token = node.begin;
+  // Scan backwards until we hit another declaration.
+Loop:
+  for (; token; token = token.prev)
+  {
+    if (token.kind == TOK.LBrace ||
+        token.kind == TOK.RBrace ||
+        token.kind == TOK.Semicolon ||
+        /+token.kind == TOK.HEAD ||+/
+        (isEnumMember && token.kind == TOK.Comma))
+      break;
+
+    if (token.kind == TOK.Comment)
+    { // Check that this comment doesn't belong to the previous declaration.
+      switch (token.prev.kind)
+      {
+      case TOK.Semicolon, TOK.RBrace, TOK.Comma:
+        break Loop;
+      default:
+        if (isDocComment(token))
+          comments = [token] ~ comments;
+      }
+    }
+  }
+  // Get single comment to the right.
+  token = node.end.next;
+  if (token.kind == TOK.Comment && isDocComment(token))
+    comments ~= token;
+  else if (isEnumMember)
+  {
+    token = node.end.nextNWS;
+    if (token.kind == TOK.Comma)
+    {
+      token = token.next;
+      if (token.kind == TOK.Comment && isDocComment(token))
+        comments ~= token;
+    }
+  }
+  return comments;
+}
+
+bool isLineComment(Token* t)
+{
+  assert(t.kind == TOK.Comment);
+  return t.start[1] == '/';
+}
+
+/// Extracts the text body of the comment tokens.
+string getDDocText(Token*[] tokens)
+{
+  if (tokens.length == 0)
+    return null;
+  string result;
+  foreach (token; tokens)
+  {
+    auto n = isLineComment(token) ? 0 : 2; // 0 for "//", 2 for "+/" and "*/".
+    result ~= sanitize(token.srcText[3 .. $-n], token.start[1]);
+    assert(token.next);
+    if (token.next.kind == TOK.Newline)
+      result ~= \n;
+    else
+      result ~= ' ';
+  }
+//   Stdout.formatln("→{}←", result);
+  return result[0..$-1]; // Remove \n or ' '
+}
+
+/// Sanitizes a DDoc comment string.
+///
+/// Leading "commentChar"s are removed from the lines.
+/// The various newline types are converted to '\n'.
+/// Params:
+///   comment = the string to be sanitized.
+///   commentChar = '/', '+', or '*'
+string sanitize(string comment, char commentChar)
+{
+  alias comment result;
+
+  bool newline = true; // True when at the beginning of a new line.
+  uint i, j;
+  auto len = result.length;
+  for (; i < len; i++, j++)
+  {
+    if (newline)
+    { // Ignore commentChars at the beginning of each new line.
+      newline = false;
+      auto begin = i;
+      while (i < len && isspace(result[i]))
+        i++;
+      if (i < len && result[i] == commentChar)
+        while (++i < len && result[i] == commentChar)
+        {}
+      else
+        i = begin; // Reset. No commentChar found.
+      if (i >= len)
+        break;
+    }
+    // Check for Newline.
+    switch (result[i])
+    {
+    case '\r':
+      if (i+1 < len && result[i+1] == '\n')
+        i++;
+    case '\n':
+      result[j] = '\n'; // Copy Newline as '\n'.
+      newline = true;
+      continue;
+    default:
+      if (!isascii(result[i]) && i+2 < len && isUnicodeNewline(result.ptr + i))
+      {
+        i += 2;
+        goto case '\n';
+      }
+    }
+    // Copy character.
+    result[j] = result[i];
+  }
+  result.length = j; // Adjust length.
+  // Lastly, strip trailing commentChars.
+  if (!result.length)
+    return null;
+  i = result.length;
+  for (; i && result[i-1] == commentChar; i--)
+  {}
+  result.length = i;
+  return result;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/doc/Macro.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,348 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.doc.Macro;
+
+import dil.doc.Parser;
+import dil.lexer.Funcs;
+import dil.Unicode;
+import dil.Information;
+import dil.Messages;
+import common;
+
+/// The DDoc macro class.
+class Macro
+{
+  string name; /// The name of the macro.
+  string text; /// The substitution text.
+  uint callLevel;  /// Recursive call level.
+  this (string name, string text)
+  {
+    this.name = name;
+    this.text = text;
+  }
+}
+
+/// Maps macro names to Macro objects.
+///
+/// MacroTables can be chained so that they build a linear hierarchy.
+/// Macro definitions in the current table override the ones in the parent tables.
+class MacroTable
+{
+  /// The parent in the hierarchy. Or null if this is the root.
+  MacroTable parent;
+  Macro[string] table; /// The associative array that holds the macro definitions.
+
+  /// Constructs a MacroTable instance.
+  this(MacroTable parent = null)
+  {
+    this.parent = parent;
+  }
+
+  /// Inserts the macro m into the table.
+  /// Overwrites the current macro if one exists.
+  void insert(Macro m)
+  {
+    table[m.name] = m;
+  }
+
+  /// Inserts an array of macros into the table.
+  void insert(Macro[] macros)
+  {
+    foreach (m; macros)
+      insert(m);
+  }
+
+  /// Creates a macro using name and text and inserts that into the table.
+  void insert(string name, string text)
+  {
+    insert(new Macro(name, text));
+  }
+
+  /// Creates a macro using name[n] and text[n] and inserts that into the table.
+  void insert(string[] names, string[] texts)
+  {
+    assert(names.length == texts.length);
+    foreach (i, name; names)
+      insert(name, texts[i]);
+  }
+
+  /// Searches for a macro.
+  ///
+  /// If the macro isn't found in this table the search
+  /// continues upwards in the table hierarchy.
+  /// Returns: the macro if found, or null if not.
+  Macro search(string name)
+  {
+    auto pmacro = name in table;
+    if (pmacro)
+      return *pmacro;
+    if (!isRoot())
+      return parent.search(name);
+    return null;
+  }
+
+  /// Returns: true if this is the root of the hierarchy.
+  bool isRoot()
+  { return parent is null; }
+}
+
+/// Parses a text with macro definitions.
+struct MacroParser
+{
+  Macro[] parse(string text)
+  {
+    IdentValueParser parser;
+    auto idvalues = parser.parse(text);
+    auto macros = new Macro[idvalues.length];
+    foreach (i, idvalue; idvalues)
+      macros[i] = new Macro(idvalue.ident, idvalue.value);
+    return macros;
+  }
+
+  /// Scans for a macro invocation. E.g.: &#36;(DDOC)
+  /// Returns: a pointer set to one char past the closing parenthesis,
+  /// or null if this isn't a macro invocation.
+  static char* scanMacro(char* p, char* textEnd)
+  {
+    assert(*p == '$');
+    if (p+2 < textEnd && p[1] == '(')
+    {
+      p += 2;
+      if (isidbeg(*p) || isUnicodeAlpha(p, textEnd)) // IdStart
+      {
+        do // IdChar*
+          p++;
+        while (p < textEnd && (isident(*p) || isUnicodeAlpha(p, textEnd)))
+        MacroExpander.scanArguments(p, textEnd);
+        p != textEnd && p++; // Skip ')'.
+        return p;
+      }
+    }
+    return null;
+  }
+}
+
+/// Expands DDoc macros in a text.
+struct MacroExpander
+{
+  MacroTable mtable; /// Used to look up macros.
+  InfoManager infoMan; /// Collects warning messages.
+  char[] filePath; /// Used in warning messages.
+
+  /// Starts expanding the macros.
+  static char[] expand(MacroTable mtable, char[] text, char[] filePath,
+                       InfoManager infoMan = null)
+  {
+    MacroExpander me;
+    me.mtable = mtable;
+    me.infoMan = infoMan;
+    me.filePath = filePath;
+    return me.expandMacros(text);
+  }
+
+  /// Reports a warning message.
+  void warning(char[] msg, char[] macroName)
+  {
+    msg = Format(msg, macroName);
+    if (infoMan)
+      infoMan ~= new Warning(new Location(filePath, 0), msg);
+  }
+
+  /// Expands the macros from the table in the text.
+  char[] expandMacros(char[] text, char[] prevArg0 = null/+, uint depth = 1000+/)
+  {
+    // if (depth == 0)
+    //   return  text;
+    // depth--;
+    char[] result;
+    char* p = text.ptr;
+    char* textEnd = p + text.length;
+    char* macroEnd = p;
+    while (p+3 < textEnd) // minimum 4 chars: $(x)
+    {
+      if (*p == '$' && p[1] == '(')
+      {
+        // Copy string between macros.
+        if (macroEnd != p)
+          result ~= makeString(macroEnd, p);
+        p += 2;
+        auto idBegin = p;
+        if (isidbeg(*p) || isUnicodeAlpha(p, textEnd)) // IdStart
+        {
+          do // IdChar*
+            p++;
+          while (p < textEnd && (isident(*p) || isUnicodeAlpha(p, textEnd)))
+          // Create macro name.
+          auto macroName = makeString(idBegin, p);
+          // Get arguments.
+          auto macroArgs = scanArguments(p, textEnd);
+          if (p == textEnd)
+          {
+            warning(MSG.UnterminatedDDocMacro, macroName);
+            result ~= "$(" ~ macroName ~ " ";
+          }
+          else
+            p++;
+          macroEnd = p; // Point past ')'.
+
+          auto macro_ = mtable.search(macroName);
+          if (macro_)
+          { // Ignore recursive macro if:
+            auto macroArg0 = macroArgs.length ? macroArgs[0] : null;
+            if (macro_.callLevel != 0 &&
+                (macroArgs.length == 0/+ || // Macro has no arguments.
+                 prevArg0 == macroArg0+/)) // macroArg0 equals previous arg0.
+            { continue; }
+            macro_.callLevel++;
+            // Expand the arguments in the macro text.
+            auto expandedText = expandArguments(macro_.text, macroArgs);
+            result ~= expandMacros(expandedText, macroArg0/+, depth+/);
+            macro_.callLevel--;
+          }
+          else
+          {
+            warning(MSG.UndefinedDDocMacro, macroName);
+            //result ~= makeString(macroName.ptr-2, macroEnd);
+          }
+          continue;
+        }
+      }
+      p++;
+    }
+    if (macroEnd == text.ptr)
+      return text; // No macros found. Return original text.
+    if (macroEnd < textEnd)
+      result ~= makeString(macroEnd, textEnd);
+    return result;
+  }
+
+  /// Scans until the closing parenthesis is found. Sets p to one char past it.
+  /// Returns: [arg0, arg1, arg2 ...].
+  static char[][] scanArguments(ref char* p, char* textEnd)
+  out(args) { assert(args.length != 1); }
+  body
+  {
+    // D specs: "The argument text can contain nested parentheses,
+    //           "" or '' strings, comments, or tags."
+    uint level = 1; // Nesting level of the parentheses.
+    char[][] args;
+
+    // Skip leading spaces.
+    while (p < textEnd && isspace(*p))
+      p++;
+
+    char* arg0Begin = p; // Whole argument list.
+    char* argBegin = p;
+  MainLoop:
+    while (p < textEnd)
+    {
+      switch (*p)
+      {
+      case ',':
+        if (level != 1) // Ignore comma if inside ().
+          break;
+        // Add a new argument.
+        args ~= makeString(argBegin, p);
+        while (++p < textEnd && isspace(*p)) // Skip spaces.
+        {}
+        argBegin = p;
+        continue;
+      case '(':
+        level++;
+        break;
+      case ')':
+        if (--level == 0)
+          break MainLoop;
+        break;
+      // Commented out: causes too many problems in the expansion pass.
+      // case '"', '\'':
+      //   auto c = *p;
+      //   while (++p < textEnd && *p != c) // Scan to next " or '.
+      //   {}
+      //   assert(*p == c || p == textEnd);
+      //   if (p == textEnd)
+      //     break MainLoop;
+      //   break;
+      case '<':
+        p++;
+        if (p+2 < textEnd && *p == '!' && p[1] == '-' && p[2] == '-') // <!--
+        {
+          p += 2; // Point to 2nd '-'.
+          // Scan to closing "-->".
+          while (++p < textEnd)
+            if (p+2 < textEnd && *p == '-' && p[1] == '-' && p[2] == '>')
+              p += 2; // Point to '>'.
+        } // <tag ...> or </tag>
+        else if (p < textEnd && (isalpha(*p) || *p == '/'))
+          while (++p < textEnd && *p != '>') // Skip to closing '>'.
+          {}
+        else
+          continue MainLoop;
+        if (p == textEnd)
+          break MainLoop;
+        assert(*p == '>');
+        break;
+      default:
+      }
+      p++;
+    }
+    assert(*p == ')' && level == 0 || p == textEnd);
+    if (arg0Begin == p)
+      return null;
+    // arg0 spans the whole argument list.
+    auto arg0 = makeString(arg0Begin, p);
+    // Add last argument.
+    args ~= makeString(argBegin, p);
+    return arg0 ~ args;
+  }
+
+  /// Expands "&#36;+", "&#36;0" - "&#36;9" with args[n] in text.
+  /// Params:
+  ///   text = the text to scan for argument placeholders.
+  ///   args = the first element, args[0], is the whole argument string and
+  ///          the following elements are slices into it.$(BR)
+  ///          The array is empty if there are no arguments.
+  char[] expandArguments(char[] text, char[][] args)
+  in { assert(args.length != 1, "zero or more than 1 args expected"); }
+  body
+  {
+    char[] result;
+    char* p = text.ptr;
+    char* textEnd = p + text.length;
+    char* placeholderEnd = p;
+
+    while (p+1 < textEnd)
+    {
+      if (*p == '$' && (*++p == '+' || isdigit(*p)))
+      {
+        // Copy string between argument placeholders.
+        if (placeholderEnd != p-1)
+          result ~= makeString(placeholderEnd, p-1);
+        placeholderEnd = p+1; // Set new placeholder end.
+
+        if (args.length == 0)
+          continue;
+
+        if (*p == '+')
+        { // $+ = $2 to $n
+          if (args.length > 2)
+            result ~= makeString(args[2].ptr, args[0].ptr + args[0].length);
+        }
+        else
+        { // 0 - 9
+          uint nthArg = *p - '0';
+          if (nthArg < args.length)
+            result ~= args[nthArg];
+        }
+      }
+      p++;
+    }
+    if (placeholderEnd == text.ptr)
+      return text; // No placeholders found. Return original text.
+    if (placeholderEnd < textEnd)
+      result ~= makeString(placeholderEnd, textEnd);
+    return result;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/doc/Parser.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,131 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.doc.Parser;
+
+import dil.lexer.Funcs;
+import dil.Unicode;
+import common;
+
+/// A pair of strings.
+class IdentValue
+{
+  string ident;
+  string value;
+  this (string ident, string value)
+  {
+    this.ident = ident;
+    this.value = value;
+  }
+}
+
+/// Parses text of the form:
+/// <pre>
+/// ident = value
+/// ident2 = value2
+///          more text
+/// </pre>
+struct IdentValueParser
+{
+  char* p; /// Current pointer.
+  char* textEnd;
+
+  IdentValue[] parse(string text)
+  {
+    if (!text.length)
+      return null;
+
+    p = text.ptr;
+    textEnd = p + text.length;
+
+    IdentValue[] idvalues;
+
+    string ident, nextIdent;
+    char* bodyBegin = p, nextBodyBegin;
+
+    // Init.
+    findNextIdent(ident, bodyBegin);
+    // Continue.
+    while (findNextIdent(nextIdent, nextBodyBegin))
+    {
+      idvalues ~= new IdentValue(ident, textBody(bodyBegin, nextIdent.ptr));
+      ident = nextIdent;
+      bodyBegin = nextBodyBegin;
+    }
+    // Add last ident value.
+    idvalues ~= new IdentValue(ident, textBody(bodyBegin, textEnd));
+    return idvalues;
+  }
+
+  /// Returns the text body. Trailing whitespace characters are not included.
+  char[] textBody(char* begin, char* end)
+  {
+    // The body of A is empty, e.g.:
+    // A =
+    // B = some text
+    // ^- begin and end point to B (or to this.textEnd in the 2nd case.)
+    if (begin is end)
+      return "";
+    // Remove trailing whitespace.
+    while (isspace(*--end) || *end == '\n')
+    {}
+    end++;
+    return makeString(begin, end);
+  }
+
+  /// Finds the next "Identifier =".
+  /// Params:
+  ///   ident = set to Identifier.
+  ///   bodyBegin = set to the beginning of the text body (whitespace skipped.)
+  /// Returns: true if found.
+  bool findNextIdent(ref string ident, ref char* bodyBegin)
+  {
+    while (p < textEnd)
+    {
+      skipWhitespace();
+      if (p >= textEnd)
+        break;
+      auto idBegin = p;
+      if (isidbeg(*p) || isUnicodeAlpha(p, textEnd)) // IdStart
+      {
+        do // IdChar*
+          p++;
+        while (p < textEnd && (isident(*p) || isUnicodeAlpha(p, textEnd)))
+        auto idEnd = p;
+
+        skipWhitespace();
+        if (p < textEnd && *p == '=')
+        {
+          p++;
+          skipWhitespace();
+          bodyBegin = p;
+          ident = makeString(idBegin, idEnd);
+          return true;
+        }
+      }
+      skipLine();
+    }
+    return false;
+  }
+
+  void skipWhitespace()
+  {
+    while (p < textEnd && (isspace(*p) || *p == '\n'))
+      p++;
+  }
+
+  void skipLine()
+  {
+    while (p < textEnd && *p != '\n')
+      p++;
+    p++;
+  }
+}
+
+/// Returns a string slice ranging from begin to end.
+char[] makeString(char* begin, char* end)
+{
+  assert(begin && end && begin <= end);
+  return begin[0 .. end - begin];
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/lexer/Funcs.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,174 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.lexer.Funcs;
+
+const char[3] LS = \u2028; /// Unicode line separator.
+const dchar LSd = 0x2028;  /// ditto
+const char[3] PS = \u2029; /// Unicode paragraph separator.
+const dchar PSd = 0x2029;  /// ditto
+static assert(LS[0] == PS[0] && LS[1] == PS[1]);
+
+const dchar _Z_ = 26; /// Control+Z.
+
+/// Returns: true if d is a Unicode line or paragraph separator.
+bool isUnicodeNewlineChar(dchar d)
+{
+  return d == LSd || d == PSd;
+}
+
+/// Returns: true if p points to a line or paragraph separator.
+bool isUnicodeNewline(char* p)
+{
+  return *p == LS[0] && p[1] == LS[1] && (p[2] == LS[2] || p[2] == PS[2]);
+}
+
+/// Returns: true if p points to the start of a Newline.
+/// Newline: \n | \r | \r\n | LS | PS
+bool isNewline(char* p)
+{
+  return *p == '\n' || *p == '\r' || isUnicodeNewline(p);
+}
+
+/// Returns: true if c is a Newline character.
+bool isNewline(dchar c)
+{
+  return c == '\n' || c == '\r' || isUnicodeNewlineChar(c);
+}
+
+/// Returns: true if p points to an EOF character.
+/// EOF: 0 | _Z_
+bool isEOF(dchar c)
+{
+  return c == 0 || c == _Z_;
+}
+
+/// Returns: true if p points to the first character of an EndOfLine.
+/// EndOfLine: Newline | EOF
+bool isEndOfLine(char* p)
+{
+  return isNewline(p) || isEOF(*p);
+}
+
+/// Scans a Newline and sets p one character past it.
+/// Returns: '\n' if found or 0 otherwise.
+dchar scanNewline(ref char* p)
+{
+  switch (*p)
+  {
+  case '\r':
+    if (p[1] == '\n')
+      ++p;
+  case '\n':
+    ++p;
+    return '\n';
+  default:
+    if (isUnicodeNewline(p))
+    {
+      p += 3;
+      return '\n';
+    }
+  }
+  return 0;
+}
+
+/// ASCII character properties table.
+static const int ptable[256] = [
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,32, 0,32,32, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+32, 0, 0x2200, 0, 0, 0, 0, 0x2700, 0, 0, 0, 0, 0, 0, 0, 0,
+ 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 0, 0, 0, 0, 0, 0x3f00,
+ 0,12,12,12,12,12,12, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0x5c00, 0, 0,16,
+ 0, 0x70c, 0x80c,12,12,12, 0xc0c, 8, 8, 8, 8, 8, 8, 8, 0xa08, 8,
+ 8, 8, 0xd08, 8, 0x908, 8, 0xb08, 8, 8, 8, 8, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+];
+
+/// Enumeration of character property flags.
+enum CProperty
+{
+       Octal = 1,    /// 0-7
+       Digit = 1<<1, /// 0-9
+         Hex = 1<<2, /// 0-9a-fA-F
+       Alpha = 1<<3, /// a-zA-Z
+  Underscore = 1<<4, /// _
+  Whitespace = 1<<5  /// ' ' \t \v \f
+}
+
+const uint EVMask = 0xFF00; // Bit mask for escape value.
+
+private alias CProperty CP;
+/// Returns: true if c is an octal digit.
+int isoctal(char c) { return ptable[c] & CP.Octal; }
+/// Returns: true if c is a decimal digit.
+int isdigit(char c) { return ptable[c] & CP.Digit; }
+/// Returns: true if c is a hexadecimal digit.
+int ishexad(char c) { return ptable[c] & CP.Hex; }
+/// Returns: true if c is a letter.
+int isalpha(char c) { return ptable[c] & CP.Alpha; }
+/// Returns: true if c is an alphanumeric.
+int isalnum(char c) { return ptable[c] & (CP.Alpha | CP.Digit); }
+/// Returns: true if c is the beginning of a D identifier (only ASCII.)
+int isidbeg(char c) { return ptable[c] & (CP.Alpha | CP.Underscore); }
+/// Returns: true if c is a D identifier character (only ASCII.)
+int isident(char c) { return ptable[c] & (CP.Alpha | CP.Underscore | CP.Digit); }
+/// Returns: true if c is a whitespace character.
+int isspace(char c) { return ptable[c] & CP.Whitespace; }
+/// Returns: the escape value for c.
+int char2ev(char c) { return ptable[c] >> 8; /*(ptable[c] & EVMask) >> 8;*/ }
+/// Returns: true if c is an ASCII character.
+int isascii(uint c) { return c < 128; }
+
+version(gen_ptable)
+static this()
+{
+  alias ptable p;
+  assert(p.length == 256);
+  // Initialize character properties table.
+  for (int i; i < p.length; ++i)
+  {
+    p[i] = 0; // Reset
+    if ('0' <= i && i <= '7')
+      p[i] |= CP.Octal;
+    if ('0' <= i && i <= '9')
+      p[i] |= CP.Digit | CP.Hex;
+    if ('a' <= i && i <= 'f' || 'A' <= i && i <= 'F')
+      p[i] |= CP.Hex;
+    if ('a' <= i && i <= 'z' || 'A' <= i && i <= 'Z')
+      p[i] |= CP.Alpha;
+    if (i == '_')
+      p[i] |= CP.Underscore;
+    if (i == ' ' || i == '\t' || i == '\v' || i == '\f')
+      p[i] |= CP.Whitespace;
+  }
+  // Store escape sequence values in second byte.
+  assert(CProperty.max <= ubyte.max, "character property flags and escape value byte overlap.");
+  p['\''] |= 39 << 8;
+  p['"'] |= 34 << 8;
+  p['?'] |= 63 << 8;
+  p['\\'] |= 92 << 8;
+  p['a'] |= 7 << 8;
+  p['b'] |= 8 << 8;
+  p['f'] |= 12 << 8;
+  p['n'] |= 10 << 8;
+  p['r'] |= 13 << 8;
+  p['t'] |= 9 << 8;
+  p['v'] |= 11 << 8;
+  // Print a formatted array literal.
+  char[] array = "[\n";
+  foreach (i, c; ptable)
+  {
+    array ~= Format((c>255?" 0x{0:x},":"{0,2},"), c) ~ (((i+1) % 16) ? "":"\n");
+  }
+  array[$-2..$] = "\n]";
+  Stdout(array).newline;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/lexer/IdTable.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,162 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.lexer.IdTable;
+
+import dil.lexer.TokensEnum;
+import dil.lexer.IdentsGenerator;
+import dil.lexer.Keywords;
+import common;
+
+public import dil.lexer.Identifier;
+public import dil.lexer.IdentsEnum;
+
+/// A namespace for the predefined identifiers.
+struct Ident
+{
+  const static
+  {
+    mixin(generateIdentMembers());
+  }
+
+  static Identifier*[] allIds()
+  {
+    return __allIds;
+  }
+}
+
+/// Global table for hoarding and retrieving identifiers.
+struct IdTable
+{
+static:
+  /// A set of common, predefined identifiers for fast lookups.
+  private Identifier*[string] staticTable;
+  /// A table that grows with every newly found, unique identifier.
+  private Identifier*[string] growingTable;
+
+  /// Loads keywords and predefined identifiers into the static table.
+  static this()
+  {
+    foreach (ref k; g_reservedIds)
+      staticTable[k.str] = &k;
+    foreach (id; Ident.allIds())
+      staticTable[id.str] = id;
+    staticTable.rehash;
+  }
+
+  /// Looks up idString in both tables.
+  Identifier* lookup(string idString)
+  {
+    auto id = inStatic(idString);
+    if (id)
+      return id;
+    return inGrowing(idString);
+  }
+
+  /// Looks up idString in the static table.
+  Identifier* inStatic(string idString)
+  {
+    auto id = idString in staticTable;
+    return id ? *id : null;
+  }
+
+  alias Identifier* function(string idString) LookupFunction;
+  /// Looks up idString in the growing table.
+  LookupFunction inGrowing = &_inGrowing_unsafe; // Default to unsafe function.
+
+  /// Sets the thread safety mode of the growing table.
+  void setThreadsafe(bool b)
+  {
+    if (b)
+      inGrowing = &_inGrowing_safe;
+    else
+      inGrowing = &_inGrowing_unsafe;
+  }
+
+  /// Returns true if access to the growing table is thread-safe.
+  bool isThreadsafe()
+  {
+    return inGrowing is &_inGrowing_safe;
+  }
+
+  /// Looks up idString in the table.
+  ///
+  /// Adds idString to the table if not found.
+  private Identifier* _inGrowing_unsafe(string idString)
+  out(id)
+  { assert(id !is null); }
+  body
+  {
+    auto id = idString in growingTable;
+    if (id)
+      return *id;
+    auto newID = Identifier(idString, TOK.Identifier);
+    growingTable[idString] = newID;
+    return newID;
+  }
+
+  /// Looks up idString in the table.
+  ///
+  /// Adds idString to the table if not found.
+  /// Access to the data structure is synchronized.
+  private Identifier* _inGrowing_safe(string idString)
+  {
+    synchronized
+      return _inGrowing_unsafe(idString);
+  }
+
+  /+
+  Identifier* addIdentifiers(char[][] idStrings)
+  {
+    auto ids = new Identifier*[idStrings.length];
+    foreach (i, idString; idStrings)
+    {
+      Identifier** id = idString in tabulatedIds;
+      if (!id)
+      {
+        auto newID = Identifier(TOK.Identifier, idString);
+        tabulatedIds[idString] = newID;
+        id = &newID;
+      }
+      ids[i] = *id;
+    }
+  }
+  +/
+
+  static uint anonCount; /// Counter for anonymous identifiers.
+
+  /// Generates an anonymous identifier.
+  ///
+  /// Concatenates prefix with anonCount.
+  /// The identifier is not inserted into the table.
+  Identifier* genAnonymousID(string prefix)
+  {
+    ++anonCount;
+    auto x = anonCount;
+    // Convert count to a string and append it to str.
+    char[] num;
+    do
+      num = cast(char)('0' + (x % 10)) ~ num;
+    while (x /= 10)
+    return Identifier(prefix ~ num, TOK.Identifier);
+  }
+
+  /// Generates an identifier for an anonymous enum.
+  Identifier* genAnonEnumID()
+  {
+    return genAnonymousID("__anonenum");
+  }
+}
+
+unittest
+{
+  // TODO: write benchmark.
+  // Single table
+
+  // Single table. synchronized
+
+  // Two tables.
+
+  // Two tables. synchronized
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/lexer/Identifier.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,54 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.lexer.Identifier;
+
+import dil.lexer.TokensEnum;
+import dil.lexer.IdentsEnum;
+import common;
+
+/// Represents an identifier as defined in the D specs.
+///
+///<pre>
+///  Identifier := IdStart IdChar*
+///  IdStart := "_" | Letter
+///  IdChar := IdStart | "0"-"9"
+///  Letter := UniAlpha
+///</pre>
+///  Unicode alphas are defined in Unicode 5.0.0.
+align(1)
+struct Identifier
+{
+  string str; /// The UTF-8 string of the identifier.
+  TOK kind;   /// The token kind.
+  IDK idKind; /// Only for predefined identifiers.
+
+  static Identifier* opCall(string str, TOK kind)
+  {
+    auto id = new Identifier;
+    id.str = str;
+    id.kind = kind;
+    return id;
+  }
+
+  static Identifier* opCall(string str, TOK kind, IDK idKind)
+  {
+    auto id = new Identifier;
+    id.str = str;
+    id.kind = kind;
+    id.idKind = idKind;
+    return id;
+  }
+
+  uint toHash()
+  {
+    uint hash;
+    foreach(c; str) {
+      hash *= 11;
+      hash += c;
+    }
+    return hash;
+  }
+}
+// pragma(msg, Identifier.sizeof.stringof);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/lexer/IdentsEnum.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,18 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.lexer.IdentsEnum;
+
+import dil.lexer.IdentsGenerator;
+
+version(DDoc)
+  enum IDK : ushort; /// Enumeration of predefined identifier kinds.
+else
+mixin(
+  // Enumerates predefined identifiers.
+  "enum IDK : ushort {"
+    "Null,"
+    ~ generateIDMembers ~
+  "}"
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/lexer/IdentsGenerator.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,117 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.lexer.IdentsGenerator;
+
+struct StrPair
+{
+const:
+  char[] str;   /// Identifier string in code.
+  char[] idStr; /// In table.
+}
+
+/// Table of predefined identifiers.
+static const StrPair[] identPairs = [
+  // Predefined version identifiers:
+  {"DigitalMars"}, {"X86"}, {"X86_64"},
+  /*{"Windows"}, */{"Win32"}, {"Win64"},
+  {"linux"}, {"LittleEndian"}, {"BigEndian"},
+  {"D_Coverage"}, {"D_InlineAsm_X86"}, {"D_Version2"},
+  {"none"}, {"all"},
+  // Variadic parameters:
+  {"_arguments"}, {"_argptr"},
+  // scope:
+  {"exit"}, {"success"}, {"failure"},
+  // pragma:
+  {"msg"}, {"lib"}, {"startaddress"},
+  // Linkage:
+  {"C"}, {"D"}, {"Windows"}, {"Pascal"}, {"System"},
+  // Con-/Destructor:
+  {"__ctor"}, {"__dtor"},
+  // new() and delete() methods.
+  {"__new"}, {"__delete"},
+  // Unittest and invariant.
+  {"__unittest"}, {"__invariant"},
+  // Operator methods:
+  {"opNeg"},
+  {"opPos"},
+  {"opComp"},
+  {"opAddAssign"},
+  {"opSubAssign"},
+  {"opPostInc"},
+  {"opPostDec"},
+  {"opCall"},
+  {"opCast"},
+  {"opIndex"},
+  {"opSlice"},
+  // ASM identifiers:
+  {"near"}, {"far"}, {"word"}, {"dword"}, {"qword"},
+  {"ptr"}, {"offset"}, {"seg"}, {"__LOCAL_SIZE"},
+  {"FS"}, {"ST"},
+  {"AL"}, {"AH"}, {"AX"}, {"EAX"},
+  {"BL"}, {"BH"}, {"BX"}, {"EBX"},
+  {"CL"}, {"CH"}, {"CX"}, {"ECX"},
+  {"DL"}, {"DH"}, {"DX"}, {"EDX"},
+  {"BP"}, {"EBP"}, {"SP"}, {"ESP"},
+  {"DI"}, {"EDI"}, {"SI"}, {"ESI"},
+  {"ES"}, {"CS"}, {"SS"}, {"DS"}, {"GS"},
+  {"CR0"}, {"CR2"}, {"CR3"}, {"CR4"},
+  {"DR0"}, {"DR1"}, {"DR2"}, {"DR3"}, {"DR6"}, {"DR7"},
+  {"TR3"}, {"TR4"}, {"TR5"}, {"TR6"}, {"TR7"},
+  {"MM0"}, {"MM1"}, {"MM2"}, {"MM3"},
+  {"MM4"}, {"MM5"}, {"MM6"}, {"MM7"},
+  {"XMM0"}, {"XMM1"}, {"XMM2"}, {"XMM3"},
+  {"XMM4"}, {"XMM5"}, {"XMM6"}, {"XMM7"},
+];
+
+/++
+ CTF for generating the members of the struct Ident.
+
+ The resulting string looks like this:
+ ---
+  private struct Ids {static const:
+    Identifier _str = {"str", TOK.Identifier, IDK.str};
+    // more ...
+  }
+  Identifier* str = &Ids._str;
+  // more ...
+  private Identifier*[] __allIds = [
+    str,
+    // more ...
+  ]
+ ---
++/
+char[] generateIdentMembers()
+{
+  char[] private_members = "private struct Ids {static const:";
+
+  char[] public_members = "";
+  char[] array = "private Identifier*[] __allIds = [";
+  foreach (pair; identPairs)
+  {
+    // N.B.: Compiler cries for some reason when trying to access pair.idStr.
+    // Identifier _str = {"str", TOK.Identifier, ID.str};
+    private_members ~= "Identifier _"~pair.str~` = {"`~pair.str~`", TOK.Identifier, IDK.`~pair.str~"};\n";
+    // Identifier* str = &_str;
+    public_members ~= "Identifier* "~pair.str~" = &Ids._"~pair.str~";\n";
+    array ~= pair.str~",";
+  }
+
+  private_members ~= "}"; // Close private {
+  array ~= "];";
+
+  return private_members ~ public_members ~ array;
+}
+
+/// CTF for generating the members of the enum IDK.
+char[] generateIDMembers()
+{
+  char[] members;
+  foreach (pair; identPairs)
+    members ~= pair.str ~ ",\n";
+  return members;
+}
+
+// pragma(msg, generateIdentMembers());
+// pragma(msg, generateIDMembers());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/lexer/Keywords.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,122 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.lexer.Keywords;
+
+import dil.lexer.Token;
+import dil.lexer.Identifier;
+
+/// Table of reserved identifiers.
+static const Identifier[] g_reservedIds = [
+  {"abstract", TOK.Abstract},
+  {"alias", TOK.Alias},
+  {"align", TOK.Align},
+  {"asm", TOK.Asm},
+  {"assert", TOK.Assert},
+  {"auto", TOK.Auto},
+  {"body", TOK.Body},
+  {"bool", TOK.Bool},
+  {"break", TOK.Break},
+  {"byte", TOK.Byte},
+  {"case", TOK.Case},
+  {"cast", TOK.Cast},
+  {"catch", TOK.Catch},
+  {"cdouble", TOK.Cdouble},
+  {"cent", TOK.Cent},
+  {"cfloat", TOK.Cfloat},
+  {"char", TOK.Char},
+  {"class", TOK.Class},
+  {"const", TOK.Const},
+  {"continue", TOK.Continue},
+  {"creal", TOK.Creal},
+  {"dchar", TOK.Dchar},
+  {"debug", TOK.Debug},
+  {"default", TOK.Default},
+  {"delegate", TOK.Delegate},
+  {"delete", TOK.Delete},
+  {"deprecated", TOK.Deprecated},
+  {"do", TOK.Do},
+  {"double", TOK.Double},
+  {"else", TOK.Else},
+  {"enum", TOK.Enum},
+  {"export", TOK.Export},
+  {"extern", TOK.Extern},
+  {"false", TOK.False},
+  {"final", TOK.Final},
+  {"finally", TOK.Finally},
+  {"float", TOK.Float},
+  {"for", TOK.For},
+  {"foreach", TOK.Foreach},
+  {"foreach_reverse", TOK.Foreach_reverse},
+  {"function", TOK.Function},
+  {"goto", TOK.Goto},
+  {"idouble", TOK.Idouble},
+  {"if", TOK.If},
+  {"ifloat", TOK.Ifloat},
+  {"import", TOK.Import},
+  {"in", TOK.In},
+  {"inout", TOK.Inout},
+  {"int", TOK.Int},
+  {"interface", TOK.Interface},
+  {"invariant", TOK.Invariant},
+  {"ireal", TOK.Ireal},
+  {"is", TOK.Is},
+  {"lazy", TOK.Lazy},
+  {"long", TOK.Long},
+  {"macro", TOK.Macro}, // D2.0
+  {"mixin", TOK.Mixin},
+  {"module", TOK.Module},
+  {"new", TOK.New},
+  {"nothrow", TOK.Nothrow}, // D2.0
+  {"null", TOK.Null},
+  {"out", TOK.Out},
+  {"override", TOK.Override},
+  {"package", TOK.Package},
+  {"pragma", TOK.Pragma},
+  {"private", TOK.Private},
+  {"protected", TOK.Protected},
+  {"public", TOK.Public},
+  {"pure", TOK.Pure}, // D2.0
+  {"real", TOK.Real},
+  {"ref", TOK.Ref},
+  {"return", TOK.Return},
+  {"scope", TOK.Scope},
+  {"short", TOK.Short},
+  {"static", TOK.Static},
+  {"struct", TOK.Struct},
+  {"super", TOK.Super},
+  {"switch", TOK.Switch},
+  {"synchronized", TOK.Synchronized},
+  {"template", TOK.Template},
+  {"this", TOK.This},
+  {"throw", TOK.Throw},
+  {"__traits", TOK.Traits}, // D2.0
+  {"true", TOK.True},
+  {"try", TOK.Try},
+  {"typedef", TOK.Typedef},
+  {"typeid", TOK.Typeid},
+  {"typeof", TOK.Typeof},
+  {"ubyte", TOK.Ubyte},
+  {"ucent", TOK.Ucent},
+  {"uint", TOK.Uint},
+  {"ulong", TOK.Ulong},
+  {"union", TOK.Union},
+  {"unittest", TOK.Unittest},
+  {"ushort", TOK.Ushort},
+  {"version", TOK.Version},
+  {"void", TOK.Void},
+  {"volatile", TOK.Volatile},
+  {"wchar", TOK.Wchar},
+  {"while", TOK.While},
+  {"with", TOK.With},
+  // Special tokens:
+  {"__FILE__", TOK.FILE},
+  {"__LINE__", TOK.LINE},
+  {"__DATE__", TOK.DATE},
+  {"__TIME__", TOK.TIME},
+  {"__TIMESTAMP__", TOK.TIMESTAMP},
+  {"__VENDOR__", TOK.VENDOR},
+  {"__VERSION__", TOK.VERSION},
+  {"__EOF__", TOK.EOF}, // D2.0
+];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/lexer/Lexer.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,2900 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.lexer.Lexer;
+
+import dil.lexer.Token;
+import dil.lexer.Keywords;
+import dil.lexer.Identifier;
+import dil.lexer.IdTable;
+import dil.Information;
+import dil.Messages;
+import dil.HtmlEntities;
+import dil.CompilerInfo;
+import dil.Unicode;
+import dil.SourceText;
+import dil.Time;
+import common;
+
+import tango.stdc.stdlib : strtof, strtod, strtold;
+import tango.stdc.errno : errno, ERANGE;
+
+public import dil.lexer.Funcs;
+
+/// The Lexer analyzes the characters of a source text and
+/// produces a doubly-linked list of tokens.
+class Lexer
+{
+  SourceText srcText; /// The source text.
+  char* p;            /// Points to the current character in the source text.
+  char* end;          /// Points one character past the end of the source text.
+
+  Token* head;  /// The head of the doubly linked token list.
+  Token* tail;  /// The tail of the linked list. Set in scan().
+  Token* token; /// Points to the current token in the token list.
+
+  // Members used for error messages:
+  InfoManager infoMan;
+  LexerError[] errors;
+  /// Always points to the first character of the current line.
+  char* lineBegin;
+//   Token* newline;     /// Current newline token.
+  uint lineNum = 1;   /// Current, actual source text line number.
+  uint lineNum_hline; /// Line number set by #line.
+  uint inTokenString; /// > 0 if inside q{ }
+  /// Holds the original file path and the modified one (by #line.)
+  NewlineData.FilePaths* filePaths;
+
+  /// Construct a Lexer object.
+  /// Params:
+  ///   srcText = the UTF-8 source code.
+  ///   infoMan = used for collecting error messages.
+  this(SourceText srcText, InfoManager infoMan = null)
+  {
+    this.srcText = srcText;
+    this.infoMan = infoMan;
+
+    assert(text.length && text[$-1] == 0, "source text has no sentinel character");
+    this.p = text.ptr;
+    this.end = this.p + text.length;
+    this.lineBegin = this.p;
+
+    this.head = new Token;
+    this.head.kind = TOK.HEAD;
+    this.head.start = this.head.end = this.p;
+    this.token = this.head;
+    // Initialize this.filePaths.
+    newFilePath(this.srcText.filePath);
+    // Add a newline as the first token after the head.
+    auto newline = new Token;
+    newline.kind = TOK.Newline;
+    newline.setWhitespaceFlag();
+    newline.start = newline.end = this.p;
+    newline.newline.filePaths = this.filePaths;
+    newline.newline.oriLineNum = 1;
+    newline.newline.setLineNum = 0;
+    // Link in.
+    this.token.next = newline;
+    newline.prev = this.token;
+    this.token = newline;
+//     this.newline = newline;
+    scanShebang();
+  }
+
+  /// The destructor deletes the doubly-linked token list.
+  ~this()
+  {
+    auto token = head.next;
+    while (token !is null)
+    {
+      assert(token.kind == TOK.EOF ? token == tail && token.next is null : 1);
+      delete token.prev;
+      token = token.next;
+    }
+    delete tail;
+  }
+
+  char[] text()
+  {
+    return srcText.data;
+  }
+
+  /// The "shebang" may optionally appear once at the beginning of a file.
+  /// Regexp: #![^\EndOfLine]*
+  void scanShebang()
+  {
+    if (*p == '#' && p[1] == '!')
+    {
+      auto t = new Token;
+      t.kind = TOK.Shebang;
+      t.setWhitespaceFlag();
+      t.start = p;
+      ++p;
+      while (!isEndOfLine(++p))
+        isascii(*p) || decodeUTF8();
+      t.end = p;
+      this.token.next = t;
+      t.prev = this.token;
+    }
+  }
+
+  /// Sets the value of the special token.
+  void finalizeSpecialToken(ref Token t)
+  {
+    assert(t.srcText[0..2] == "__");
+    switch (t.kind)
+    {
+    case TOK.FILE:
+      t.str = this.filePaths.setPath;
+      break;
+    case TOK.LINE:
+      t.uint_ = this.errorLineNumber(this.lineNum);
+      break;
+    case TOK.DATE,
+         TOK.TIME,
+         TOK.TIMESTAMP:
+      auto time_str = Time.toString();
+      switch (t.kind)
+      {
+      case TOK.DATE:
+        time_str = Time.month_day(time_str) ~ ' ' ~ Time.year(time_str); break;
+      case TOK.TIME:
+        time_str = Time.time(time_str); break;
+      case TOK.TIMESTAMP:
+        break; // time_str is the timestamp.
+      default: assert(0);
+      }
+      time_str ~= '\0'; // Terminate with a zero.
+      t.str = time_str;
+      break;
+    case TOK.VENDOR:
+      t.str = VENDOR;
+      break;
+    case TOK.VERSION:
+      t.uint_ = VERSION_MAJOR*1000 + VERSION_MINOR;
+      break;
+    default:
+      assert(0);
+    }
+  }
+
+  /// Sets a new file path.
+  void newFilePath(char[] newPath)
+  {
+    auto paths = new NewlineData.FilePaths;
+    paths.oriPath = this.srcText.filePath;
+    paths.setPath = newPath;
+    this.filePaths = paths;
+  }
+
+  private void setLineBegin(char* p)
+  {
+    // Check that we can look behind one character.
+    assert((p-1) >= text.ptr && p < end);
+    // Check that previous character is a newline.
+    assert(isNewlineEnd(p - 1));
+    this.lineBegin = p;
+  }
+
+  /// Scans the next token in the source text.
+  ///
+  /// Creates a new token if t.next is null and appends it to the list.
+  private void scanNext(ref Token* t)
+  {
+    assert(t !is null);
+    if (t.next)
+    {
+      t = t.next;
+//       if (t.kind == TOK.Newline)
+//         this.newline = t;
+    }
+    else if (t != this.tail)
+    {
+      Token* new_t = new Token;
+      scan(*new_t);
+      new_t.prev = t;
+      t.next = new_t;
+      t = new_t;
+    }
+  }
+
+  /// Advance t one token forward.
+  void peek(ref Token* t)
+  {
+    scanNext(t);
+  }
+
+  /// Advance to the next token in the source text.
+  TOK nextToken()
+  {
+    scanNext(this.token);
+    return this.token.kind;
+  }
+
+  /// Returns true if p points to the last character of a Newline.
+  bool isNewlineEnd(char* p)
+  {
+    if (*p == '\n' || *p == '\r')
+      return true;
+    if (*p == LS[2] || *p == PS[2])
+      if ((p-2) >= text.ptr)
+        if (p[-1] == LS[1] && p[-2] == LS[0])
+          return true;
+    return false;
+  }
+
+  /// The main method which recognizes the characters that make up a token.
+  ///
+  /// Complicated tokens are scanned in separate methods.
+  public void scan(ref Token t)
+  in
+  {
+    assert(text.ptr <= p && p < end);
+  }
+  out
+  {
+    assert(text.ptr <= t.start && t.start < end, Token.toString(t.kind));
+    assert(text.ptr <= t.end && t.end <= end, Token.toString(t.kind));
+  }
+  body
+  {
+    // Scan whitespace.
+    if (isspace(*p))
+    {
+      t.ws = p;
+      while (isspace(*++p))
+      {}
+    }
+
+    // Scan a token.
+    uint c = *p;
+    {
+      t.start = p;
+      // Newline.
+      switch (*p)
+      {
+      case '\r':
+        if (p[1] == '\n')
+          ++p;
+      case '\n':
+        assert(isNewlineEnd(p));
+        ++p;
+        ++lineNum;
+        setLineBegin(p);
+//         this.newline = &t;
+        t.kind = TOK.Newline;
+        t.setWhitespaceFlag();
+        t.newline.filePaths = this.filePaths;
+        t.newline.oriLineNum = lineNum;
+        t.newline.setLineNum = lineNum_hline;
+        t.end = p;
+        return;
+      default:
+        if (isUnicodeNewline(p))
+        {
+          ++p; ++p;
+          goto case '\n';
+        }
+      }
+      // Identifier or string literal.
+      if (isidbeg(c))
+      {
+        if (c == 'r' && p[1] == '"' && ++p)
+          return scanRawStringLiteral(t);
+        if (c == 'x' && p[1] == '"')
+          return scanHexStringLiteral(t);
+      version(D2)
+      {
+        if (c == 'q' && p[1] == '"')
+          return scanDelimitedStringLiteral(t);
+        if (c == 'q' && p[1] == '{')
+          return scanTokenStringLiteral(t);
+      }
+        // Scan identifier.
+      Lidentifier:
+        do
+        { c = *++p; }
+        while (isident(c) || !isascii(c) && isUnicodeAlpha())
+
+        t.end = p;
+
+        auto id = IdTable.lookup(t.srcText);
+        t.kind = id.kind;
+        t.ident = id;
+
+        if (t.kind == TOK.Identifier || t.isKeyword)
+          return;
+        else if (t.isSpecialToken)
+          finalizeSpecialToken(t);
+        else if (t.kind == TOK.EOF)
+        {
+          tail = &t;
+          assert(t.srcText == "__EOF__");
+        }
+        else
+          assert(0, "unexpected token type: " ~ Token.toString(t.kind));
+        return;
+      }
+
+      if (isdigit(c))
+        return scanNumber(t);
+
+      if (c == '/')
+      {
+        c = *++p;
+        switch(c)
+        {
+        case '=':
+          ++p;
+          t.kind = TOK.DivAssign;
+          t.end = p;
+          return;
+        case '+':
+          return scanNestedComment(t);
+        case '*':
+          return scanBlockComment(t);
+        case '/':
+          while (!isEndOfLine(++p))
+            isascii(*p) || decodeUTF8();
+          t.kind = TOK.Comment;
+          t.setWhitespaceFlag();
+          t.end = p;
+          return;
+        default:
+          t.kind = TOK.Div;
+          t.end = p;
+          return;
+        }
+      }
+
+      switch (c)
+      {
+      case '\'':
+        return scanCharacterLiteral(t);
+      case '`':
+        return scanRawStringLiteral(t);
+      case '"':
+        return scanNormalStringLiteral(t);
+      case '\\':
+        char[] buffer;
+        do
+        {
+          bool isBinary;
+          c = scanEscapeSequence(isBinary);
+          if (isascii(c) || isBinary)
+            buffer ~= c;
+          else
+            encodeUTF8(buffer, c);
+        } while (*p == '\\')
+        buffer ~= 0;
+        t.kind = TOK.String;
+        t.str = buffer;
+        t.end = p;
+        return;
+      case '>': /* >  >=  >>  >>=  >>>  >>>= */
+        c = *++p;
+        switch (c)
+        {
+        case '=':
+          t.kind = TOK.GreaterEqual;
+          goto Lcommon;
+        case '>':
+          if (p[1] == '>')
+          {
+            ++p;
+            if (p[1] == '=')
+            { ++p;
+              t.kind = TOK.URShiftAssign;
+            }
+            else
+              t.kind = TOK.URShift;
+          }
+          else if (p[1] == '=')
+          {
+            ++p;
+            t.kind = TOK.RShiftAssign;
+          }
+          else
+            t.kind = TOK.RShift;
+          goto Lcommon;
+        default:
+          t.kind = TOK.Greater;
+          goto Lcommon2;
+        }
+        assert(0);
+      case '<': /* <  <=  <>  <>=  <<  <<= */
+        c = *++p;
+        switch (c)
+        {
+        case '=':
+          t.kind = TOK.LessEqual;
+          goto Lcommon;
+        case '<':
+          if (p[1] == '=') {
+            ++p;
+            t.kind = TOK.LShiftAssign;
+          }
+          else
+            t.kind = TOK.LShift;
+          goto Lcommon;
+        case '>':
+          if (p[1] == '=') {
+            ++p;
+            t.kind = TOK.LorEorG;
+          }
+          else
+            t.kind = TOK.LorG;
+          goto Lcommon;
+        default:
+          t.kind = TOK.Less;
+          goto Lcommon2;
+        }
+        assert(0);
+      case '!': /* !  !<  !>  !<=  !>=  !<>  !<>= */
+        c = *++p;
+        switch (c)
+        {
+        case '<':
+          c = *++p;
+          if (c == '>')
+          {
+            if (p[1] == '=') {
+              ++p;
+              t.kind = TOK.Unordered;
+            }
+            else
+              t.kind = TOK.UorE;
+          }
+          else if (c == '=')
+          {
+            t.kind = TOK.UorG;
+          }
+          else {
+            t.kind = TOK.UorGorE;
+            goto Lcommon2;
+          }
+          goto Lcommon;
+        case '>':
+          if (p[1] == '=')
+          {
+            ++p;
+            t.kind = TOK.UorL;
+          }
+          else
+            t.kind = TOK.UorLorE;
+          goto Lcommon;
+        case '=':
+          t.kind = TOK.NotEqual;
+          goto Lcommon;
+        default:
+          t.kind = TOK.Not;
+          goto Lcommon2;
+        }
+        assert(0);
+      case '.': /* .  .[0-9]  ..  ... */
+        if (p[1] == '.')
+        {
+          ++p;
+          if (p[1] == '.') {
+            ++p;
+            t.kind = TOK.Ellipses;
+          }
+          else
+            t.kind = TOK.Slice;
+        }
+        else if (isdigit(p[1]))
+        {
+          return scanReal(t);
+        }
+        else
+          t.kind = TOK.Dot;
+        goto Lcommon;
+      case '|': /* |  ||  |= */
+        c = *++p;
+        if (c == '=')
+          t.kind = TOK.OrAssign;
+        else if (c == '|')
+          t.kind = TOK.OrLogical;
+        else {
+          t.kind = TOK.OrBinary;
+          goto Lcommon2;
+        }
+        goto Lcommon;
+      case '&': /* &  &&  &= */
+        c = *++p;
+        if (c == '=')
+          t.kind = TOK.AndAssign;
+        else if (c == '&')
+          t.kind = TOK.AndLogical;
+        else {
+          t.kind = TOK.AndBinary;
+          goto Lcommon2;
+        }
+        goto Lcommon;
+      case '+': /* +  ++  += */
+        c = *++p;
+        if (c == '=')
+          t.kind = TOK.PlusAssign;
+        else if (c == '+')
+          t.kind = TOK.PlusPlus;
+        else {
+          t.kind = TOK.Plus;
+          goto Lcommon2;
+        }
+        goto Lcommon;
+      case '-': /* -  --  -= */
+        c = *++p;
+        if (c == '=')
+          t.kind = TOK.MinusAssign;
+        else if (c == '-')
+          t.kind = TOK.MinusMinus;
+        else {
+          t.kind = TOK.Minus;
+          goto Lcommon2;
+        }
+        goto Lcommon;
+      case '=': /* =  == */
+        if (p[1] == '=') {
+          ++p;
+          t.kind = TOK.Equal;
+        }
+        else
+          t.kind = TOK.Assign;
+        goto Lcommon;
+      case '~': /* ~  ~= */
+         if (p[1] == '=') {
+           ++p;
+           t.kind = TOK.CatAssign;
+         }
+         else
+           t.kind = TOK.Tilde;
+         goto Lcommon;
+      case '*': /* *  *= */
+         if (p[1] == '=') {
+           ++p;
+           t.kind = TOK.MulAssign;
+         }
+         else
+           t.kind = TOK.Mul;
+         goto Lcommon;
+      case '^': /* ^  ^= */
+         if (p[1] == '=') {
+           ++p;
+           t.kind = TOK.XorAssign;
+         }
+         else
+           t.kind = TOK.Xor;
+         goto Lcommon;
+      case '%': /* %  %= */
+         if (p[1] == '=') {
+           ++p;
+           t.kind = TOK.ModAssign;
+         }
+         else
+           t.kind = TOK.Mod;
+         goto Lcommon;
+      // Single character tokens:
+      case '(':
+        t.kind = TOK.LParen;
+        goto Lcommon;
+      case ')':
+        t.kind = TOK.RParen;
+        goto Lcommon;
+      case '[':
+        t.kind = TOK.LBracket;
+        goto Lcommon;
+      case ']':
+        t.kind = TOK.RBracket;
+        goto Lcommon;
+      case '{':
+        t.kind = TOK.LBrace;
+        goto Lcommon;
+      case '}':
+        t.kind = TOK.RBrace;
+        goto Lcommon;
+      case ':':
+        t.kind = TOK.Colon;
+        goto Lcommon;
+      case ';':
+        t.kind = TOK.Semicolon;
+        goto Lcommon;
+      case '?':
+        t.kind = TOK.Question;
+        goto Lcommon;
+      case ',':
+        t.kind = TOK.Comma;
+        goto Lcommon;
+      case '$':
+        t.kind = TOK.Dollar;
+      Lcommon:
+        ++p;
+      Lcommon2:
+        t.end = p;
+        return;
+      case '#':
+        return scanSpecialTokenSequence(t);
+      default:
+      }
+
+      // Check for EOF
+      if (isEOF(c))
+      {
+        assert(isEOF(*p), ""~*p);
+        t.kind = TOK.EOF;
+        t.end = p;
+        tail = &t;
+        assert(t.start == t.end);
+        return;
+      }
+
+      if (!isascii(c))
+      {
+        c = decodeUTF8();
+        if (isUniAlpha(c))
+          goto Lidentifier;
+      }
+
+      error(t.start, MID.IllegalCharacter, cast(dchar)c);
+
+      ++p;
+      t.kind = TOK.Illegal;
+      t.setWhitespaceFlag();
+      t.dchar_ = c;
+      t.end = p;
+      return;
+    }
+  }
+
+  /// Converts a string literal to an integer.
+  template toUint(char[] T)
+  {
+    static assert(0 < T.length && T.length <= 4);
+    static if (T.length == 1)
+      const uint toUint = T[0];
+    else
+      const uint toUint = (T[0] << ((T.length-1)*8)) | toUint!(T[1..$]);
+  }
+  static assert(toUint!("\xAA\xBB\xCC\xDD") == 0xAABBCCDD);
+
+  /// Constructs case statements. E.g.:
+  /// ---
+  //// // case_!("<", "Less", "Lcommon") ->
+  /// case 60u:
+  ///   t.kind = TOK.Less;
+  ///   goto Lcommon;
+  /// ---
+  /// Note:Can't use this yet due to a $(DMDBUG 1534, bug) in DMD.
+  template case_(char[] str, char[] kind, char[] label)
+  {
+    const char[] case_ =
+      `case `~toUint!(str).stringof~`:`
+        `t.kind = TOK.`~kind~`;`
+        `goto `~label~`;`;
+  }
+  //pragma(msg, case_!("<", "Less", "Lcommon"));
+
+  template case_L4(char[] str, TOK kind)
+  {
+    const char[] case_L4 = case_!(str, kind, "Lcommon_4");
+  }
+
+  template case_L3(char[] str, TOK kind)
+  {
+    const char[] case_L3 = case_!(str, kind, "Lcommon_3");
+  }
+
+  template case_L2(char[] str, TOK kind)
+  {
+    const char[] case_L2 = case_!(str, kind, "Lcommon_2");
+  }
+
+  template case_L1(char[] str, TOK kind)
+  {
+    const char[] case_L3 = case_!(str, kind, "Lcommon");
+  }
+
+  /// An alternative scan method.
+  /// Profiling shows it's a bit slower.
+  public void scan_(ref Token t)
+  in
+  {
+    assert(text.ptr <= p && p < end);
+  }
+  out
+  {
+    assert(text.ptr <= t.start && t.start < end, Token.toString(t.kind));
+    assert(text.ptr <= t.end && t.end <= end, Token.toString(t.kind));
+  }
+  body
+  {
+    // Scan whitespace.
+    if (isspace(*p))
+    {
+      t.ws = p;
+      while (isspace(*++p))
+      {}
+    }
+
+    // Scan a token.
+    t.start = p;
+    // Newline.
+    switch (*p)
+    {
+    case '\r':
+      if (p[1] == '\n')
+        ++p;
+    case '\n':
+      assert(isNewlineEnd(p));
+      ++p;
+      ++lineNum;
+      setLineBegin(p);
+//       this.newline = &t;
+      t.kind = TOK.Newline;
+      t.setWhitespaceFlag();
+      t.newline.filePaths = this.filePaths;
+      t.newline.oriLineNum = lineNum;
+      t.newline.setLineNum = lineNum_hline;
+      t.end = p;
+      return;
+    default:
+      if (isUnicodeNewline(p))
+      {
+        ++p; ++p;
+        goto case '\n';
+      }
+    }
+
+    uint c = *p;
+    assert(end - p != 0);
+    switch (end - p)
+    {
+    case 1:
+      goto L1character;
+    case 2:
+      c <<= 8; c |= p[1];
+      goto L2characters;
+    case 3:
+      c <<= 8; c |= p[1]; c <<= 8; c |= p[2];
+      goto L3characters;
+    default:
+      version(BigEndian)
+        c = *cast(uint*)p;
+      else
+      {
+        c <<= 8; c |= p[1]; c <<= 8; c |= p[2]; c <<= 8; c |= p[3];
+        /+
+        c = *cast(uint*)p;
+        asm
+        {
+          mov EDX, c;
+          bswap EDX;
+          mov c, EDX;
+        }
+        +/
+      }
+    }
+
+    // 4 character tokens.
+    switch (c)
+    {
+    case toUint!(">>>="):
+      t.kind = TOK.RShiftAssign;
+      goto Lcommon_4;
+    case toUint!("!<>="):
+      t.kind = TOK.Unordered;
+    Lcommon_4:
+      p += 4;
+      t.end = p;
+      return;
+    default:
+    }
+
+    c >>>= 8;
+  L3characters:
+    assert(p == t.start);
+    // 3 character tokens.
+    switch (c)
+    {
+    case toUint!(">>="):
+      t.kind = TOK.RShiftAssign;
+      goto Lcommon_3;
+    case toUint!(">>>"):
+      t.kind = TOK.URShift;
+      goto Lcommon_3;
+    case toUint!("<>="):
+      t.kind = TOK.LorEorG;
+      goto Lcommon_3;
+    case toUint!("<<="):
+      t.kind = TOK.LShiftAssign;
+      goto Lcommon_3;
+    case toUint!("!<="):
+      t.kind = TOK.UorG;
+      goto Lcommon_3;
+    case toUint!("!>="):
+      t.kind = TOK.UorL;
+      goto Lcommon_3;
+    case toUint!("!<>"):
+      t.kind = TOK.UorE;
+      goto Lcommon_3;
+    case toUint!("..."):
+      t.kind = TOK.Ellipses;
+    Lcommon_3:
+      p += 3;
+      t.end = p;
+      return;
+    default:
+    }
+
+    c >>>= 8;
+  L2characters:
+    assert(p == t.start);
+    // 2 character tokens.
+    switch (c)
+    {
+    case toUint!("/+"):
+      ++p; // Skip /
+      return scanNestedComment(t);
+    case toUint!("/*"):
+      ++p; // Skip /
+      return scanBlockComment(t);
+    case toUint!("//"):
+      ++p; // Skip /
+      assert(*p == '/');
+      while (!isEndOfLine(++p))
+        isascii(*p) || decodeUTF8();
+      t.kind = TOK.Comment;
+      t.setWhitespaceFlag();
+      t.end = p;
+      return;
+    case toUint!(">="):
+      t.kind = TOK.GreaterEqual;
+      goto Lcommon_2;
+    case toUint!(">>"):
+      t.kind = TOK.RShift;
+      goto Lcommon_2;
+    case toUint!("<<"):
+      t.kind = TOK.LShift;
+      goto Lcommon_2;
+    case toUint!("<="):
+      t.kind = TOK.LessEqual;
+      goto Lcommon_2;
+    case toUint!("<>"):
+      t.kind = TOK.LorG;
+      goto Lcommon_2;
+    case toUint!("!<"):
+      t.kind = TOK.UorGorE;
+      goto Lcommon_2;
+    case toUint!("!>"):
+      t.kind = TOK.UorLorE;
+      goto Lcommon_2;
+    case toUint!("!="):
+      t.kind = TOK.NotEqual;
+      goto Lcommon_2;
+    case toUint!(".."):
+      t.kind = TOK.Slice;
+      goto Lcommon_2;
+    case toUint!("&&"):
+      t.kind = TOK.AndLogical;
+      goto Lcommon_2;
+    case toUint!("&="):
+      t.kind = TOK.AndAssign;
+      goto Lcommon_2;
+    case toUint!("||"):
+      t.kind = TOK.OrLogical;
+      goto Lcommon_2;
+    case toUint!("|="):
+      t.kind = TOK.OrAssign;
+      goto Lcommon_2;
+    case toUint!("++"):
+      t.kind = TOK.PlusPlus;
+      goto Lcommon_2;
+    case toUint!("+="):
+      t.kind = TOK.PlusAssign;
+      goto Lcommon_2;
+    case toUint!("--"):
+      t.kind = TOK.MinusMinus;
+      goto Lcommon_2;
+    case toUint!("-="):
+      t.kind = TOK.MinusAssign;
+      goto Lcommon_2;
+    case toUint!("=="):
+      t.kind = TOK.Equal;
+      goto Lcommon_2;
+    case toUint!("~="):
+      t.kind = TOK.CatAssign;
+      goto Lcommon_2;
+    case toUint!("*="):
+      t.kind = TOK.MulAssign;
+      goto Lcommon_2;
+    case toUint!("/="):
+      t.kind = TOK.DivAssign;
+      goto Lcommon_2;
+    case toUint!("^="):
+      t.kind = TOK.XorAssign;
+      goto Lcommon_2;
+    case toUint!("%="):
+      t.kind = TOK.ModAssign;
+    Lcommon_2:
+      p += 2;
+      t.end = p;
+      return;
+    default:
+    }
+
+    c >>>= 8;
+  L1character:
+    assert(p == t.start);
+    assert(*p == c, Format("p={0},c={1}", *p, cast(dchar)c));
+    // 1 character tokens.
+    // TODO: consider storing the token type in ptable.
+    switch (c)
+    {
+    case '\'':
+      return scanCharacterLiteral(t);
+    case '`':
+      return scanRawStringLiteral(t);
+    case '"':
+      return scanNormalStringLiteral(t);
+    case '\\':
+      char[] buffer;
+      do
+      {
+        bool isBinary;
+        c = scanEscapeSequence(isBinary);
+        if (isascii(c) || isBinary)
+          buffer ~= c;
+        else
+          encodeUTF8(buffer, c);
+      } while (*p == '\\')
+      buffer ~= 0;
+      t.kind = TOK.String;
+      t.str = buffer;
+      t.end = p;
+      return;
+    case '<':
+      t.kind = TOK.Greater;
+      goto Lcommon;
+    case '>':
+      t.kind = TOK.Less;
+      goto Lcommon;
+    case '^':
+      t.kind = TOK.Xor;
+      goto Lcommon;
+    case '!':
+      t.kind = TOK.Not;
+      goto Lcommon;
+    case '.':
+      if (isdigit(p[1]))
+        return scanReal(t);
+      t.kind = TOK.Dot;
+      goto Lcommon;
+    case '&':
+      t.kind = TOK.AndBinary;
+      goto Lcommon;
+    case '|':
+      t.kind = TOK.OrBinary;
+      goto Lcommon;
+    case '+':
+      t.kind = TOK.Plus;
+      goto Lcommon;
+    case '-':
+      t.kind = TOK.Minus;
+      goto Lcommon;
+    case '=':
+      t.kind = TOK.Assign;
+      goto Lcommon;
+    case '~':
+      t.kind = TOK.Tilde;
+      goto Lcommon;
+    case '*':
+      t.kind = TOK.Mul;
+      goto Lcommon;
+    case '/':
+      t.kind = TOK.Div;
+      goto Lcommon;
+    case '%':
+      t.kind = TOK.Mod;
+      goto Lcommon;
+    case '(':
+      t.kind = TOK.LParen;
+      goto Lcommon;
+    case ')':
+      t.kind = TOK.RParen;
+      goto Lcommon;
+    case '[':
+      t.kind = TOK.LBracket;
+      goto Lcommon;
+    case ']':
+      t.kind = TOK.RBracket;
+      goto Lcommon;
+    case '{':
+      t.kind = TOK.LBrace;
+      goto Lcommon;
+    case '}':
+      t.kind = TOK.RBrace;
+      goto Lcommon;
+    case ':':
+      t.kind = TOK.Colon;
+      goto Lcommon;
+    case ';':
+      t.kind = TOK.Semicolon;
+      goto Lcommon;
+    case '?':
+      t.kind = TOK.Question;
+      goto Lcommon;
+    case ',':
+      t.kind = TOK.Comma;
+      goto Lcommon;
+    case '$':
+      t.kind = TOK.Dollar;
+    Lcommon:
+      ++p;
+      t.end = p;
+      return;
+    case '#':
+      return scanSpecialTokenSequence(t);
+    default:
+    }
+
+    assert(p == t.start);
+    assert(*p == c);
+
+    // TODO: consider moving isidbeg() and isdigit() up.
+    if (isidbeg(c))
+    {
+      if (c == 'r' && p[1] == '"' && ++p)
+        return scanRawStringLiteral(t);
+      if (c == 'x' && p[1] == '"')
+        return scanHexStringLiteral(t);
+    version(D2)
+    {
+      if (c == 'q' && p[1] == '"')
+        return scanDelimitedStringLiteral(t);
+      if (c == 'q' && p[1] == '{')
+        return scanTokenStringLiteral(t);
+    }
+      // Scan identifier.
+    Lidentifier:
+      do
+      { c = *++p; }
+      while (isident(c) || !isascii(c) && isUnicodeAlpha())
+
+      t.end = p;
+
+      auto id = IdTable.lookup(t.srcText);
+      t.kind = id.kind;
+      t.ident = id;
+
+      if (t.kind == TOK.Identifier || t.isKeyword)
+        return;
+      else if (t.isSpecialToken)
+        finalizeSpecialToken(t);
+      else if (t.kind == TOK.EOF)
+      {
+        tail = &t;
+        assert(t.srcText == "__EOF__");
+      }
+      else
+        assert(0, "unexpected token type: " ~ Token.toString(t.kind));
+      return;
+    }
+
+    if (isdigit(c))
+      return scanNumber(t);
+
+    // Check for EOF
+    if (isEOF(c))
+    {
+      assert(isEOF(*p), *p~"");
+      t.kind = TOK.EOF;
+      t.end = p;
+      tail = &t;
+      assert(t.start == t.end);
+      return;
+    }
+
+    if (!isascii(c))
+    {
+      c = decodeUTF8();
+      if (isUniAlpha(c))
+        goto Lidentifier;
+    }
+
+    error(t.start, MID.IllegalCharacter, cast(dchar)c);
+
+    ++p;
+    t.kind = TOK.Illegal;
+    t.setWhitespaceFlag();
+    t.dchar_ = c;
+    t.end = p;
+    return;
+  }
+
+  /// Scans a block comment.
+  ///
+  /// BlockComment := "/*" AnyChar* "*/"
+  void scanBlockComment(ref Token t)
+  {
+    assert(p[-1] == '/' && *p == '*');
+    auto tokenLineNum = lineNum;
+    auto tokenLineBegin = lineBegin;
+  Loop:
+    while (1)
+    {
+      switch (*++p)
+      {
+      case '*':
+        if (p[1] != '/')
+          continue;
+        p += 2;
+        break Loop;
+      case '\r':
+        if (p[1] == '\n')
+          ++p;
+      case '\n':
+        assert(isNewlineEnd(p));
+        ++lineNum;
+        setLineBegin(p+1);
+        break;
+      default:
+        if (!isascii(*p))
+        {
+          if (isUnicodeNewlineChar(decodeUTF8()))
+            goto case '\n';
+        }
+        else if (isEOF(*p))
+        {
+          error(tokenLineNum, tokenLineBegin, t.start, MID.UnterminatedBlockComment);
+          break Loop;
+        }
+      }
+    }
+    t.kind = TOK.Comment;
+    t.setWhitespaceFlag();
+    t.end = p;
+    return;
+  }
+
+  /// Scans a nested comment.
+  ///
+  /// NestedComment := "/+" (AnyChar* | NestedComment) "+/"
+  void scanNestedComment(ref Token t)
+  {
+    assert(p[-1] == '/' && *p == '+');
+    auto tokenLineNum = lineNum;
+    auto tokenLineBegin = lineBegin;
+    uint level = 1;
+  Loop:
+    while (1)
+    {
+      switch (*++p)
+      {
+      case '/':
+        if (p[1] == '+')
+          ++p, ++level;
+        continue;
+      case '+':
+        if (p[1] != '/')
+          continue;
+        ++p;
+        if (--level != 0)
+          continue;
+        ++p;
+        break Loop;
+      case '\r':
+        if (p[1] == '\n')
+          ++p;
+      case '\n':
+        assert(isNewlineEnd(p));
+        ++lineNum;
+        setLineBegin(p+1);
+        continue;
+      default:
+        if (!isascii(*p))
+        {
+          if (isUnicodeNewlineChar(decodeUTF8()))
+            goto case '\n';
+        }
+        else if (isEOF(*p))
+        {
+          error(tokenLineNum, tokenLineBegin, t.start, MID.UnterminatedNestedComment);
+          break Loop;
+        }
+      }
+    }
+    t.kind = TOK.Comment;
+    t.setWhitespaceFlag();
+    t.end = p;
+    return;
+  }
+
+  /// Scans the postfix character of a string literal.
+  ///
+  /// PostfixChar := "c" | "w" | "d"
+  char scanPostfix()
+  {
+    assert(p[-1] == '"' || p[-1] == '`' ||
+      { version(D2) return p[-1] == '}';
+               else return 0; }()
+    );
+    switch (*p)
+    {
+    case 'c':
+    case 'w':
+    case 'd':
+      return *p++;
+    default:
+      return 0;
+    }
+    assert(0);
+  }
+
+  /// Scans a normal string literal.
+  ///
+  /// NormalStringLiteral := "\"" Char* "\""
+  void scanNormalStringLiteral(ref Token t)
+  {
+    assert(*p == '"');
+    auto tokenLineNum = lineNum;
+    auto tokenLineBegin = lineBegin;
+    t.kind = TOK.String;
+    char[] buffer;
+    uint c;
+    while (1)
+    {
+      c = *++p;
+      switch (c)
+      {
+      case '"':
+        ++p;
+        t.pf = scanPostfix();
+      Lreturn:
+        t.str = buffer ~ '\0';
+        t.end = p;
+        return;
+      case '\\':
+        bool isBinary;
+        c = scanEscapeSequence(isBinary);
+        --p;
+        if (isascii(c) || isBinary)
+          buffer ~= c;
+        else
+          encodeUTF8(buffer, c);
+        continue;
+      case '\r':
+        if (p[1] == '\n')
+          ++p;
+      case '\n':
+        assert(isNewlineEnd(p));
+        c = '\n'; // Convert Newline to \n.
+        ++lineNum;
+        setLineBegin(p+1);
+        break;
+      case 0, _Z_:
+        error(tokenLineNum, tokenLineBegin, t.start, MID.UnterminatedString);
+        goto Lreturn;
+      default:
+        if (!isascii(c))
+        {
+          c = decodeUTF8();
+          if (isUnicodeNewlineChar(c))
+            goto case '\n';
+          encodeUTF8(buffer, c);
+          continue;
+        }
+      }
+      assert(isascii(c));
+      buffer ~= c;
+    }
+    assert(0);
+  }
+
+  /// Scans a character literal.
+  ///
+  /// CharLiteral := "'" Char "'"
+  void scanCharacterLiteral(ref Token t)
+  {
+    assert(*p == '\'');
+    ++p;
+    t.kind = TOK.CharLiteral;
+    switch (*p)
+    {
+    case '\\':
+      bool notused;
+      t.dchar_ = scanEscapeSequence(notused);
+      break;
+    case '\'':
+      error(t.start, MID.EmptyCharacterLiteral);
+      break;
+    default:
+      if (isEndOfLine(p))
+        break;
+      uint c = *p;
+      if (!isascii(c))
+        c = decodeUTF8();
+      t.dchar_ = c;
+      ++p;
+    }
+
+    if (*p == '\'')
+      ++p;
+    else
+      error(t.start, MID.UnterminatedCharacterLiteral);
+    t.end = p;
+  }
+
+  /// Scans a raw string literal.
+  ///
+  /// RawStringLiteral := "r\"" AnyChar* "\"" | "`" AnyChar* "`"
+  void scanRawStringLiteral(ref Token t)
+  {
+    assert(*p == '`' || *p == '"' && p[-1] == 'r');
+    auto tokenLineNum = lineNum;
+    auto tokenLineBegin = lineBegin;
+    t.kind = TOK.String;
+    uint delim = *p;
+    char[] buffer;
+    uint c;
+    while (1)
+    {
+      c = *++p;
+      switch (c)
+      {
+      case '\r':
+        if (p[1] == '\n')
+          ++p;
+      case '\n':
+        assert(isNewlineEnd(p));
+        c = '\n'; // Convert Newline to '\n'.
+        ++lineNum;
+        setLineBegin(p+1);
+        break;
+      case '`':
+      case '"':
+        if (c == delim)
+        {
+          ++p;
+          t.pf = scanPostfix();
+        Lreturn:
+          t.str = buffer ~ '\0';
+          t.end = p;
+          return;
+        }
+        break;
+      case 0, _Z_:
+        error(tokenLineNum, tokenLineBegin, t.start,
+          delim == 'r' ? MID.UnterminatedRawString : MID.UnterminatedBackQuoteString);
+        goto Lreturn;
+      default:
+        if (!isascii(c))
+        {
+          c = decodeUTF8();
+          if (isUnicodeNewlineChar(c))
+            goto case '\n';
+          encodeUTF8(buffer, c);
+          continue;
+        }
+      }
+      assert(isascii(c));
+      buffer ~= c;
+    }
+    assert(0);
+  }
+
+  /// Scans a hexadecimal string literal.
+  ///
+  /// HexStringLiteral := "x\"" (HexChar HexChar)* "\""
+  void scanHexStringLiteral(ref Token t)
+  {
+    assert(p[0] == 'x' && p[1] == '"');
+    t.kind = TOK.String;
+
+    auto tokenLineNum = lineNum;
+    auto tokenLineBegin = lineBegin;
+
+    uint c;
+    ubyte[] buffer;
+    ubyte h; // hex number
+    uint n; // number of hex digits
+
+    ++p;
+    assert(*p == '"');
+    while (1)
+    {
+      c = *++p;
+      switch (c)
+      {
+      case '"':
+        if (n & 1)
+          error(tokenLineNum, tokenLineBegin, t.start, MID.OddNumberOfDigitsInHexString);
+        ++p;
+        t.pf = scanPostfix();
+      Lreturn:
+        t.str = cast(string) (buffer ~= 0);
+        t.end = p;
+        return;
+      case '\r':
+        if (p[1] == '\n')
+          ++p;
+      case '\n':
+        assert(isNewlineEnd(p));
+        ++lineNum;
+        setLineBegin(p+1);
+        continue;
+      default:
+        if (ishexad(c))
+        {
+          if (c <= '9')
+            c -= '0';
+          else if (c <= 'F')
+            c -= 'A' - 10;
+          else
+            c -= 'a' - 10;
+
+          if (n & 1)
+          {
+            h <<= 4;
+            h |= c;
+            buffer ~= h;
+          }
+          else
+            h = cast(ubyte)c;
+          ++n;
+          continue;
+        }
+        else if (isspace(c))
+          continue; // Skip spaces.
+        else if (isEOF(c))
+        {
+          error(tokenLineNum, tokenLineBegin, t.start, MID.UnterminatedHexString);
+          t.pf = 0;
+          goto Lreturn;
+        }
+        else
+        {
+          auto errorAt = p;
+          if (!isascii(c))
+          {
+            c = decodeUTF8();
+            if (isUnicodeNewlineChar(c))
+              goto case '\n';
+          }
+          error(errorAt, MID.NonHexCharInHexString, cast(dchar)c);
+        }
+      }
+    }
+    assert(0);
+  }
+
+version(DDoc)
+{
+  /// Scans a delimited string literal.
+  void scanDelimitedStringLiteral(ref Token t);
+  /// Scans a token string literal.
+  ///
+  /// TokenStringLiteral := "q{" Token* "}"
+  void scanTokenStringLiteral(ref Token t);
+}
+else
+version(D2)
+{
+  void scanDelimitedStringLiteral(ref Token t)
+  {
+    assert(p[0] == 'q' && p[1] == '"');
+    t.kind = TOK.String;
+
+    auto tokenLineNum = lineNum;
+    auto tokenLineBegin = lineBegin;
+
+    char[] buffer;
+    dchar opening_delim = 0, // 0 if no nested delimiter or '[', '(', '<', '{'
+          closing_delim; // Will be ']', ')', '>', '},
+                         // the first character of an identifier or
+                         // any other Unicode/ASCII character.
+    char[] str_delim; // Identifier delimiter.
+    uint level = 1; // Counter for nestable delimiters.
+
+    ++p; ++p; // Skip q"
+    uint c = *p;
+    switch (c)
+    {
+    case '(':
+      opening_delim = c;
+      closing_delim = ')'; // c + 1
+      break;
+    case '[', '<', '{':
+      opening_delim = c;
+      closing_delim = c + 2; // Get to closing counterpart. Feature of ASCII table.
+      break;
+    default:
+      dchar scanNewline()
+      {
+        switch (*p)
+        {
+        case '\r':
+          if (p[1] == '\n')
+            ++p;
+        case '\n':
+          assert(isNewlineEnd(p));
+          ++p;
+          ++lineNum;
+          setLineBegin(p);
+          return '\n';
+        default:
+          if (isUnicodeNewline(p))
+          {
+            ++p; ++p;
+            goto case '\n';
+          }
+        }
+        return 0;
+      }
+      // Skip leading newlines:
+      while (scanNewline() != 0)
+      {}
+      assert(!isNewline(p));
+
+      char* begin = p;
+      c = *p;
+      closing_delim = c;
+      // TODO: Check for non-printable characters?
+      if (!isascii(c))
+      {
+        closing_delim = decodeUTF8();
+        if (!isUniAlpha(closing_delim))
+          break; // Not an identifier.
+      }
+      else if (!isidbeg(c))
+        break; // Not an identifier.
+
+      // Parse Identifier + EndOfLine
+      do
+      { c = *++p; }
+      while (isident(c) || !isascii(c) && isUnicodeAlpha())
+      // Store identifier
+      str_delim = begin[0..p-begin];
+      // Scan newline
+      if (scanNewline() == '\n')
+        --p; // Go back one because of "c = *++p;" in main loop.
+      else
+      {
+        // TODO: error(p, MID.ExpectedNewlineAfterIdentDelim);
+      }
+    }
+
+    bool checkStringDelim(char* p)
+    {
+      assert(str_delim.length != 0);
+      if (buffer[$-1] == '\n' && // Last character copied to buffer must be '\n'.
+          end-p >= str_delim.length && // Check remaining length.
+          p[0..str_delim.length] == str_delim) // Compare.
+        return true;
+      return false;
+    }
+
+    while (1)
+    {
+      c = *++p;
+      switch (c)
+      {
+      case '\r':
+        if (p[1] == '\n')
+          ++p;
+      case '\n':
+        assert(isNewlineEnd(p));
+        c = '\n'; // Convert Newline to '\n'.
+        ++lineNum;
+        setLineBegin(p+1);
+        break;
+      case 0, _Z_:
+        // TODO: error(tokenLineNum, tokenLineBegin, t.start, MID.UnterminatedDelimitedString);
+        goto Lreturn3;
+      default:
+        if (!isascii(c))
+        {
+          auto begin = p;
+          c = decodeUTF8();
+          if (isUnicodeNewlineChar(c))
+            goto case '\n';
+          if (c == closing_delim)
+          {
+            if (str_delim.length)
+            {
+              if (checkStringDelim(begin))
+              {
+                p = begin + str_delim.length;
+                goto Lreturn2;
+              }
+            }
+            else
+            {
+              assert(level == 1);
+              --level;
+              goto Lreturn;
+            }
+          }
+          encodeUTF8(buffer, c);
+          continue;
+        }
+        else
+        {
+          if (c == opening_delim)
+            ++level;
+          else if (c == closing_delim)
+          {
+            if (str_delim.length)
+            {
+              if (checkStringDelim(p))
+              {
+                p += str_delim.length;
+                goto Lreturn2;
+              }
+            }
+            else if (--level == 0)
+              goto Lreturn;
+          }
+        }
+      }
+      assert(isascii(c));
+      buffer ~= c;
+    }
+  Lreturn: // Character delimiter.
+    assert(c == closing_delim);
+    assert(level == 0);
+    ++p; // Skip closing delimiter.
+  Lreturn2: // String delimiter.
+    if (*p == '"')
+      ++p;
+    else
+    {
+      // TODO: error(p, MID.ExpectedDblQuoteAfterDelim, str_delim.length ? str_delim : closing_delim~"");
+    }
+
+    t.pf = scanPostfix();
+  Lreturn3: // Error.
+    t.str = buffer ~ '\0';
+    t.end = p;
+  }
+
+  void scanTokenStringLiteral(ref Token t)
+  {
+    assert(p[0] == 'q' && p[1] == '{');
+    t.kind = TOK.String;
+
+    auto tokenLineNum = lineNum;
+    auto tokenLineBegin = lineBegin;
+
+    // A guard against changes to particular members:
+    // this.lineNum_hline and this.errorPath
+    ++inTokenString;
+
+    uint lineNum = this.lineNum;
+    uint level = 1;
+
+    ++p; ++p; // Skip q{
+
+    auto prev_t = &t;
+    Token* token;
+    while (1)
+    {
+      token = new Token;
+      scan(*token);
+      // Save the tokens in a doubly linked list.
+      // Could be useful for various tools.
+      token.prev = prev_t;
+      prev_t.next = token;
+      prev_t = token;
+      switch (token.kind)
+      {
+      case TOK.LBrace:
+        ++level;
+        continue;
+      case TOK.RBrace:
+        if (--level == 0)
+        {
+          t.tok_str = t.next;
+          t.next = null;
+          break;
+        }
+        continue;
+      case TOK.EOF:
+        // TODO: error(tokenLineNum, tokenLineBegin, t.start, MID.UnterminatedTokenString);
+        t.tok_str = t.next;
+        t.next = token;
+        break;
+      default:
+        continue;
+      }
+      break; // Exit loop.
+    }
+
+    assert(token.kind == TOK.RBrace || token.kind == TOK.EOF);
+    assert(token.kind == TOK.RBrace && t.next is null ||
+           token.kind == TOK.EOF && t.next !is null);
+
+    char[] buffer;
+    // token points to } or EOF
+    if (token.kind == TOK.EOF)
+    {
+      t.end = token.start;
+      buffer = t.srcText[2..$].dup ~ '\0';
+    }
+    else
+    {
+      // Assign to buffer before scanPostfix().
+      t.end = p;
+      buffer = t.srcText[2..$-1].dup ~ '\0';
+      t.pf = scanPostfix();
+      t.end = p; // Assign again because of postfix.
+    }
+    // Convert newlines to '\n'.
+    if (lineNum != this.lineNum)
+    {
+      assert(buffer[$-1] == '\0');
+      uint i, j;
+      for (; i < buffer.length; ++i)
+        switch (buffer[i])
+        {
+        case '\r':
+          if (buffer[i+1] == '\n')
+            ++i;
+        case '\n':
+          assert(isNewlineEnd(buffer.ptr + i));
+          buffer[j++] = '\n'; // Convert Newline to '\n'.
+          break;
+        default:
+          if (isUnicodeNewline(buffer.ptr + i))
+          {
+            ++i; ++i;
+            goto case '\n';
+          }
+          buffer[j++] = buffer[i]; // Copy.
+        }
+      buffer.length = j; // Adjust length.
+    }
+    assert(buffer[$-1] == '\0');
+    t.str = buffer;
+
+    --inTokenString;
+  }
+} // version(D2)
+
+  /// Scans an escape sequence.
+  ///
+  /// EscapeSequence := "\" (Octal{1,3} | ("x" Hex{2}) |
+  ///                       ("u" Hex{4}) | ("U" Hex{8}) |
+  ///                       "'" | "\"" | "\\" | "?" | "a" |
+  ///                       "b" | "f" | "n" | "r" | "t" | "v")
+  /// Params:
+  ///   isBinary = set to true for octal and hexadecimal escapes.
+  /// Returns: the escape value.
+  dchar scanEscapeSequence(ref bool isBinary)
+  out(result)
+  { assert(isValidChar(result)); }
+  body
+  {
+    assert(*p == '\\');
+
+    auto sequenceStart = p; // Used for error reporting.
+
+    ++p;
+    uint c = char2ev(*p);
+    if (c)
+    {
+      ++p;
+      return c;
+    }
+
+    uint digits = 2;
+
+    switch (*p)
+    {
+    case 'x':
+      isBinary = true;
+    case_Unicode:
+      assert(c == 0);
+      assert(digits == 2 || digits == 4 || digits == 8);
+      while (1)
+      {
+        ++p;
+        if (ishexad(*p))
+        {
+          c *= 16;
+          if (*p <= '9')
+            c += *p - '0';
+          else if (*p <= 'F')
+            c += *p - 'A' + 10;
+          else
+            c += *p - 'a' + 10;
+
+          if (--digits == 0)
+          {
+            ++p;
+            if (isValidChar(c))
+              return c; // Return valid escape value.
+
+            error(sequenceStart, MID.InvalidUnicodeEscapeSequence,
+                  sequenceStart[0..p-sequenceStart]);
+            break;
+          }
+          continue;
+        }
+
+        error(sequenceStart, MID.InsufficientHexDigits,
+              sequenceStart[0..p-sequenceStart]);
+        break;
+      }
+      break;
+    case 'u':
+      digits = 4;
+      goto case_Unicode;
+    case 'U':
+      digits = 8;
+      goto case_Unicode;
+    default:
+      if (isoctal(*p))
+      {
+        isBinary = true;
+        assert(c == 0);
+        c += *p - '0';
+        ++p;
+        if (!isoctal(*p))
+          return c;
+        c *= 8;
+        c += *p - '0';
+        ++p;
+        if (!isoctal(*p))
+          return c;
+        c *= 8;
+        c += *p - '0';
+        ++p;
+        if (c > 0xFF)
+          error(sequenceStart, MSG.InvalidOctalEscapeSequence,
+                sequenceStart[0..p-sequenceStart]);
+        return c; // Return valid escape value.
+      }
+      else if(*p == '&')
+      {
+        if (isalpha(*++p))
+        {
+          auto begin = p;
+          while (isalnum(*++p))
+          {}
+
+          if (*p == ';')
+          {
+            // Pass entity excluding '&' and ';'.
+            c = entity2Unicode(begin[0..p - begin]);
+            ++p; // Skip ;
+            if (c != 0xFFFF)
+              return c; // Return valid escape value.
+            else
+              error(sequenceStart, MID.UndefinedHTMLEntity, sequenceStart[0 .. p - sequenceStart]);
+          }
+          else
+            error(sequenceStart, MID.UnterminatedHTMLEntity, sequenceStart[0 .. p - sequenceStart]);
+        }
+        else
+          error(sequenceStart, MID.InvalidBeginHTMLEntity);
+      }
+      else if (isEndOfLine(p))
+        error(sequenceStart, MID.UndefinedEscapeSequence,
+          isEOF(*p) ? `\EOF` : `\NewLine`);
+      else
+      {
+        char[] str = `\`;
+        if (isascii(c))
+          str ~= *p;
+        else
+          encodeUTF8(str, decodeUTF8());
+        ++p;
+        // TODO: check for unprintable character?
+        error(sequenceStart, MID.UndefinedEscapeSequence, str);
+      }
+    }
+    return REPLACEMENT_CHAR; // Error: return replacement character.
+  }
+
+  /// Scans a number literal.
+  ///
+  /// $(PRE
+  /// IntegerLiteral := (Dec|Hex|Bin|Oct)Suffix?
+  /// Dec := (0|[1-9][0-9_]*)
+  /// Hex := 0[xX][_]*[0-9a-zA-Z][0-9a-zA-Z_]*
+  /// Bin := 0[bB][_]*[01][01_]*
+  /// Oct := 0[0-7_]*
+  /// Suffix := (L[uU]?|[uU]L?)
+  /// )
+  /// Invalid: "0b_", "0x_", "._" etc.
+  void scanNumber(ref Token t)
+  {
+    ulong ulong_;
+    bool overflow;
+    bool isDecimal;
+    size_t digits;
+
+    if (*p != '0')
+      goto LscanInteger;
+    ++p; // skip zero
+    // check for xX bB ...
+    switch (*p)
+    {
+    case 'x','X':
+      goto LscanHex;
+    case 'b','B':
+      goto LscanBinary;
+    case 'L':
+      if (p[1] == 'i')
+        goto LscanReal; // 0Li
+      break; // 0L
+    case '.':
+      if (p[1] == '.')
+        break; // 0..
+      // 0.
+    case 'i','f','F', // Imaginary and float literal suffixes.
+         'e', 'E':    // Float exponent.
+      goto LscanReal;
+    default:
+      if (*p == '_')
+        goto LscanOctal; // 0_
+      else if (isdigit(*p))
+      {
+        if (*p == '8' || *p == '9')
+          goto Loctal_hasDecimalDigits; // 08 or 09
+        else
+          goto Loctal_enter_loop; // 0[0-7]
+      }
+    }
+
+    // Number 0
+    assert(p[-1] == '0');
+    assert(*p != '_' && !isdigit(*p));
+    assert(ulong_ == 0);
+    isDecimal = true;
+    goto Lfinalize;
+
+  LscanInteger:
+    assert(*p != 0 && isdigit(*p));
+    isDecimal = true;
+    goto Lenter_loop_int;
+    while (1)
+    {
+      if (*++p == '_')
+        continue;
+      if (!isdigit(*p))
+        break;
+    Lenter_loop_int:
+      if (ulong_ < ulong.max/10 || (ulong_ == ulong.max/10 && *p <= '5'))
+      {
+        ulong_ *= 10;
+        ulong_ += *p - '0';
+        continue;
+      }
+      // Overflow: skip following digits.
+      overflow = true;
+      while (isdigit(*++p)) {}
+      break;
+    }
+
+    // The number could be a float, so check overflow below.
+    switch (*p)
+    {
+    case '.':
+      if (p[1] != '.')
+        goto LscanReal;
+      break;
+    case 'L':
+      if (p[1] != 'i')
+        break;
+    case 'i', 'f', 'F', 'e', 'E':
+      goto LscanReal;
+    default:
+    }
+
+    if (overflow)
+      error(t.start, MID.OverflowDecimalNumber);
+
+    assert((isdigit(p[-1]) || p[-1] == '_') && !isdigit(*p) && *p != '_');
+    goto Lfinalize;
+
+  LscanHex:
+    assert(digits == 0);
+    assert(*p == 'x' || *p == 'X');
+    while (1)
+    {
+      if (*++p == '_')
+        continue;
+      if (!ishexad(*p))
+        break;
+      ++digits;
+      ulong_ *= 16;
+      if (*p <= '9')
+        ulong_ += *p - '0';
+      else if (*p <= 'F')
+        ulong_ += *p - 'A' + 10;
+      else
+        ulong_ += *p - 'a' + 10;
+    }
+
+    assert(ishexad(p[-1]) || p[-1] == '_' || p[-1] == 'x' || p[-1] == 'X');
+    assert(!ishexad(*p) && *p != '_');
+
+    switch (*p)
+    {
+    case '.':
+      if (p[1] == '.')
+        break;
+    case 'p', 'P':
+      return scanHexReal(t);
+    default:
+    }
+
+    if (digits == 0 || digits > 16)
+      error(t.start, digits == 0 ? MID.NoDigitsInHexNumber : MID.OverflowHexNumber);
+
+    goto Lfinalize;
+
+  LscanBinary:
+    assert(digits == 0);
+    assert(*p == 'b' || *p == 'B');
+    while (1)
+    {
+      if (*++p == '0')
+      {
+        ++digits;
+        ulong_ *= 2;
+      }
+      else if (*p == '1')
+      {
+        ++digits;
+        ulong_ *= 2;
+        ulong_ += *p - '0';
+      }
+      else if (*p == '_')
+        continue; 
+      else
+        break;
+    }
+
+    if (digits == 0 || digits > 64)
+      error(t.start, digits == 0 ? MID.NoDigitsInBinNumber : MID.OverflowBinaryNumber);
+
+    assert(p[-1] == '0' || p[-1] == '1' || p[-1] == '_' || p[-1] == 'b' || p[-1] == 'B', p[-1] ~ "");
+    assert( !(*p == '0' || *p == '1' || *p == '_') );
+    goto Lfinalize;
+
+  LscanOctal:
+    assert(*p == '_');
+    while (1)
+    {
+      if (*++p == '_')
+        continue;
+      if (!isoctal(*p))
+        break;
+    Loctal_enter_loop:
+      if (ulong_ < ulong.max/2 || (ulong_ == ulong.max/2 && *p <= '1'))
+      {
+        ulong_ *= 8;
+        ulong_ += *p - '0';
+        continue;
+      }
+      // Overflow: skip following digits.
+      overflow = true;
+      while (isoctal(*++p)) {}
+      break;
+    }
+
+    bool hasDecimalDigits;
+    if (isdigit(*p))
+    {
+    Loctal_hasDecimalDigits:
+      hasDecimalDigits = true;
+      while (isdigit(*++p)) {}
+    }
+
+    // The number could be a float, so check errors below.
+    switch (*p)
+    {
+    case '.':
+      if (p[1] != '.')
+        goto LscanReal;
+      break;
+    case 'L':
+      if (p[1] != 'i')
+        break;
+    case 'i', 'f', 'F', 'e', 'E':
+      goto LscanReal;
+    default:
+    }
+
+    if (hasDecimalDigits)
+      error(t.start, MID.OctalNumberHasDecimals);
+
+    if (overflow)
+      error(t.start, MID.OverflowOctalNumber);
+//     goto Lfinalize;
+
+  Lfinalize:
+    enum Suffix
+    {
+      None     = 0,
+      Unsigned = 1,
+      Long     = 2
+    }
+
+    // Scan optional suffix: L, Lu, LU, u, uL, U or UL.
+    Suffix suffix;
+    while (1)
+    {
+      switch (*p)
+      {
+      case 'L':
+        if (suffix & Suffix.Long)
+          break;
+        suffix |= Suffix.Long;
+        ++p;
+        continue;
+      case 'u', 'U':
+        if (suffix & Suffix.Unsigned)
+          break;
+        suffix |= Suffix.Unsigned;
+        ++p;
+        continue;
+      default:
+        break;
+      }
+      break;
+    }
+
+    // Determine type of Integer.
+    switch (suffix)
+    {
+    case Suffix.None:
+      if (ulong_ & 0x8000_0000_0000_0000)
+      {
+        if (isDecimal)
+          error(t.start, MID.OverflowDecimalSign);
+        t.kind = TOK.Uint64;
+      }
+      else if (ulong_ & 0xFFFF_FFFF_0000_0000)
+        t.kind = TOK.Int64;
+      else if (ulong_ & 0x8000_0000)
+        t.kind = isDecimal ? TOK.Int64 : TOK.Uint32;
+      else
+        t.kind = TOK.Int32;
+      break;
+    case Suffix.Unsigned:
+      if (ulong_ & 0xFFFF_FFFF_0000_0000)
+        t.kind = TOK.Uint64;
+      else
+        t.kind = TOK.Uint32;
+      break;
+    case Suffix.Long:
+      if (ulong_ & 0x8000_0000_0000_0000)
+      {
+        if (isDecimal)
+          error(t.start, MID.OverflowDecimalSign);
+        t.kind = TOK.Uint64;
+      }
+      else
+        t.kind = TOK.Int64;
+      break;
+    case Suffix.Unsigned | Suffix.Long:
+      t.kind = TOK.Uint64;
+      break;
+    default:
+      assert(0);
+    }
+    t.ulong_ = ulong_;
+    t.end = p;
+    return;
+  LscanReal:
+    scanReal(t);
+    return;
+  }
+
+  /// Scans a floating point number literal.
+  ///
+  /// $(PRE
+  /// FloatLiteral := Float[fFL]?i?
+  /// Float := DecFloat | HexFloat
+  /// DecFloat := ([0-9][0-9_]*[.][0-9_]*DecExponent?) |
+  ///             [.][0-9][0-9_]*DecExponent? | [0-9][0-9_]*DecExponent
+  /// DecExponent := [eE][+-]?[0-9][0-9_]*
+  /// HexFloat := 0[xX](HexDigits[.]HexDigits |
+  ///                   [.][0-9a-zA-Z]HexDigits? |
+  ///                   HexDigits)HexExponent
+  /// HexExponent := [pP][+-]?[0-9][0-9_]*
+  /// )
+  void scanReal(ref Token t)
+  {
+    if (*p == '.')
+    {
+      assert(p[1] != '.');
+      // This function was called by scan() or scanNumber().
+      while (isdigit(*++p) || *p == '_') {}
+    }
+    else
+      // This function was called by scanNumber().
+      assert(delegate ()
+        {
+          switch (*p)
+          {
+          case 'L':
+            if (p[1] != 'i')
+              return false;
+          case 'i', 'f', 'F', 'e', 'E':
+            return true;
+          default:
+          }
+          return false;
+        }()
+      );
+
+    // Scan exponent.
+    if (*p == 'e' || *p == 'E')
+    {
+      ++p;
+      if (*p == '-' || *p == '+')
+        ++p;
+      if (isdigit(*p))
+        while (isdigit(*++p) || *p == '_') {}
+      else
+        error(t.start, MID.FloatExpMustStartWithDigit);
+    }
+
+    // Copy whole number and remove underscores from buffer.
+    char[] buffer = t.start[0..p-t.start].dup;
+    uint j;
+    foreach (c; buffer)
+      if (c != '_')
+        buffer[j++] = c;
+    buffer.length = j; // Adjust length.
+    buffer ~= 0; // Terminate for C functions.
+
+    finalizeFloat(t, buffer);
+  }
+
+  /// Scans a hexadecimal floating point number literal.
+  void scanHexReal(ref Token t)
+  {
+    assert(*p == '.' || *p == 'p' || *p == 'P');
+    MID mid;
+    if (*p == '.')
+      while (ishexad(*++p) || *p == '_')
+      {}
+    // Decimal exponent is required.
+    if (*p != 'p' && *p != 'P')
+    {
+      mid = MID.HexFloatExponentRequired;
+      goto Lerr;
+    }
+    // Scan exponent
+    assert(*p == 'p' || *p == 'P');
+    ++p;
+    if (*p == '+' || *p == '-')
+      ++p;
+    if (!isdigit(*p))
+    {
+      mid = MID.HexFloatExpMustStartWithDigit;
+      goto Lerr;
+    }
+    while (isdigit(*++p) || *p == '_')
+    {}
+    // Copy whole number and remove underscores from buffer.
+    char[] buffer = t.start[0..p-t.start].dup;
+    uint j;
+    foreach (c; buffer)
+      if (c != '_')
+        buffer[j++] = c;
+    buffer.length = j; // Adjust length.
+    buffer ~= 0; // Terminate for C functions.
+    finalizeFloat(t, buffer);
+    return;
+  Lerr:
+    t.kind = TOK.Float32;
+    t.end = p;
+    error(t.start, mid);
+  }
+
+  /// Sets the value of the token.
+  /// Params:
+  ///   t = receives the value.
+  ///   buffer = the well-formed float number.
+  void finalizeFloat(ref Token t, string buffer)
+  {
+    assert(buffer[$-1] == 0);
+    // Float number is well-formed. Check suffixes and do conversion.
+    switch (*p)
+    {
+    case 'f', 'F':
+      t.kind = TOK.Float32;
+      t.float_ = strtof(buffer.ptr, null);
+      ++p;
+      break;
+    case 'L':
+      t.kind = TOK.Float80;
+      t.real_ = strtold(buffer.ptr, null);
+      ++p;
+      break;
+    default:
+      t.kind = TOK.Float64;
+      t.double_ = strtod(buffer.ptr, null);
+    }
+    if (*p == 'i')
+    {
+      ++p;
+      t.kind += 3; // Switch to imaginary counterpart.
+      assert(t.kind == TOK.Imaginary32 ||
+             t.kind == TOK.Imaginary64 ||
+             t.kind == TOK.Imaginary80);
+    }
+    if (errno() == ERANGE)
+      error(t.start, MID.OverflowFloatNumber);
+    t.end = p;
+  }
+
+  /// Scans a special token sequence.
+  ///
+  /// SpecialTokenSequence := "#line" Integer Filespec? EndOfLine
+  void scanSpecialTokenSequence(ref Token t)
+  {
+    assert(*p == '#');
+    t.kind = TOK.HashLine;
+    t.setWhitespaceFlag();
+
+    MID mid;
+    char* errorAtColumn = p;
+    char* tokenEnd = ++p;
+
+    if (!(p[0] == 'l' && p[1] == 'i' && p[2] == 'n' && p[3] == 'e'))
+    {
+      mid = MID.ExpectedIdentifierSTLine;
+      goto Lerr;
+    }
+    p += 3;
+    tokenEnd = p + 1;
+
+    // TODO: #line58"path/file" is legal. Require spaces?
+    //       State.Space could be used for that purpose.
+    enum State
+    { /+Space,+/ Integer, Filespec, End }
+
+    State state = State.Integer;
+
+    while (!isEndOfLine(++p))
+    {
+      if (isspace(*p))
+        continue;
+      if (state == State.Integer)
+      {
+        if (!isdigit(*p))
+        {
+          errorAtColumn = p;
+          mid = MID.ExpectedIntegerAfterSTLine;
+          goto Lerr;
+        }
+        t.tokLineNum = new Token;
+        scan(*t.tokLineNum);
+        tokenEnd = p;
+        if (t.tokLineNum.kind != TOK.Int32 && t.tokLineNum.kind != TOK.Uint32)
+        {
+          errorAtColumn = t.tokLineNum.start;
+          mid = MID.ExpectedIntegerAfterSTLine;
+          goto Lerr;
+        }
+        --p; // Go one back because scan() advanced p past the integer.
+        state = State.Filespec;
+      }
+      else if (state == State.Filespec && *p == '"')
+      { // MID.ExpectedFilespec is deprecated.
+        // if (*p != '"')
+        // {
+        //   errorAtColumn = p;
+        //   mid = MID.ExpectedFilespec;
+        //   goto Lerr;
+        // }
+        t.tokLineFilespec = new Token;
+        t.tokLineFilespec.start = p;
+        t.tokLineFilespec.kind = TOK.Filespec;
+        t.tokLineFilespec.setWhitespaceFlag();
+        while (*++p != '"')
+        {
+          if (isEndOfLine(p))
+          {
+            errorAtColumn = t.tokLineFilespec.start;
+            mid = MID.UnterminatedFilespec;
+            t.tokLineFilespec.end = p;
+            tokenEnd = p;
+            goto Lerr;
+          }
+          isascii(*p) || decodeUTF8();
+        }
+        auto start = t.tokLineFilespec.start +1; // +1 skips '"'
+        t.tokLineFilespec.str = start[0 .. p - start];
+        t.tokLineFilespec.end = p + 1;
+        tokenEnd = p + 1;
+        state = State.End;
+      }
+      else/+ if (state == State.End)+/
+      {
+        mid = MID.UnterminatedSpecialToken;
+        goto Lerr;
+      }
+    }
+    assert(isEndOfLine(p));
+
+    if (state == State.Integer)
+    {
+      errorAtColumn = p;
+      mid = MID.ExpectedIntegerAfterSTLine;
+      goto Lerr;
+    }
+
+    // Evaluate #line only when not in token string.
+    if (!inTokenString && t.tokLineNum)
+    {
+      this.lineNum_hline = this.lineNum - t.tokLineNum.uint_ + 1;
+      if (t.tokLineFilespec)
+        newFilePath(t.tokLineFilespec.str);
+    }
+    p = tokenEnd;
+    t.end = tokenEnd;
+
+    return;
+  Lerr:
+    p = tokenEnd;
+    t.end = tokenEnd;
+    error(errorAtColumn, mid);
+  }
+
+  /// Inserts an empty dummy token (TOK.Empty) before t.
+  ///
+  /// Useful in the parsing phase for representing a node in the AST
+  /// that doesn't consume an actual token from the source text.
+  Token* insertEmptyTokenBefore(Token* t)
+  {
+    assert(t !is null && t.prev !is null);
+    assert(text.ptr <= t.start && t.start < end, Token.toString(t.kind));
+    assert(text.ptr <= t.end && t.end <= end, Token.toString(t.kind));
+
+    auto prev_t = t.prev;
+    auto new_t = new Token;
+    new_t.kind = TOK.Empty;
+    new_t.start = new_t.end = prev_t.end;
+    // Link in new token.
+    prev_t.next = new_t;
+    new_t.prev = prev_t;
+    new_t.next = t;
+    t.prev = new_t;
+    return new_t;
+  }
+
+  /// Returns the error line number.
+  uint errorLineNumber(uint lineNum)
+  {
+    return lineNum - this.lineNum_hline;
+  }
+
+  /// Forwards error parameters.
+  void error(char* columnPos, char[] msg, ...)
+  {
+    error_(this.lineNum, this.lineBegin, columnPos, msg, _arguments, _argptr);
+  }
+
+  /// ditto
+  void error(char* columnPos, MID mid, ...)
+  {
+    error_(this.lineNum, this.lineBegin, columnPos, GetMsg(mid), _arguments, _argptr);
+  }
+
+  /// ditto
+  void error(uint lineNum, char* lineBegin, char* columnPos, MID mid, ...)
+  {
+    error_(lineNum, lineBegin, columnPos, GetMsg(mid), _arguments, _argptr);
+  }
+
+  /// Creates an error report and appends it to a list.
+  /// Params:
+  ///   lineNum = the line number.
+  ///   lineBegin = points to the first character of the current line.
+  ///   columnPos = points to the character where the error is located.
+  ///   msg = the message.
+  void error_(uint lineNum, char* lineBegin, char* columnPos, char[] msg,
+              TypeInfo[] _arguments, Arg _argptr)
+  {
+    lineNum = this.errorLineNumber(lineNum);
+    auto errorPath = this.filePaths.setPath;
+    auto location = new Location(errorPath, lineNum, lineBegin, columnPos);
+    msg = Format(_arguments, _argptr, msg);
+    auto error = new LexerError(location, msg);
+    errors ~= error;
+    if (infoMan !is null)
+      infoMan ~= error;
+  }
+
+  /// Scans the whole source text until EOF is encountered.
+  void scanAll()
+  {
+    while (nextToken() != TOK.EOF)
+    {}
+  }
+
+  /// Returns the first token of the source text.
+  /// This can be the EOF token.
+  /// Structure: HEAD -> Newline -> First Token
+  Token* firstToken()
+  {
+    return this.head.next.next;
+  }
+
+  /// Returns true if str is a valid D identifier.
+  static bool isIdentifierString(char[] str)
+  {
+    if (str.length == 0 || isdigit(str[0]))
+      return false;
+    size_t idx;
+    do
+    {
+      auto c = dil.Unicode.decode(str, idx);
+      if (c == ERROR_CHAR || !(isident(c) || !isascii(c) && isUniAlpha(c)))
+        return false;
+    } while (idx < str.length)
+    return true;
+  }
+
+  /// Returns true if str is a keyword or a special token (__FILE__, __LINE__ etc.)
+  static bool isReservedIdentifier(char[] str)
+  {
+    if (!isIdentifierString(str))
+      return false; // str is not a valid identifier.
+
+    auto id = IdTable.inStatic(str);
+    if (id is null || id.kind == TOK.Identifier)
+      return false; // str is not in the table or a normal identifier.
+
+    return true;
+  }
+
+  /// Returns true if the current character to be decoded is
+  /// a Unicode alpha character.
+  ///
+  /// The current pointer 'p' is not advanced if false is returned.
+  bool isUnicodeAlpha()
+  {
+    assert(!isascii(*p), "check for ASCII char before calling decodeUTF8().");
+    char* p = this.p;
+    dchar d = *p;
+    ++p; // Move to second byte.
+    // Error if second byte is not a trail byte.
+    if (!isTrailByte(*p))
+      return false;
+    // Check for overlong sequences.
+    switch (d)
+    {
+    case 0xE0, 0xF0, 0xF8, 0xFC:
+      if ((*p & d) == 0x80)
+        return false;
+    default:
+      if ((d & 0xFE) == 0xC0) // 1100000x
+        return false;
+    }
+    const char[] checkNextByte = "if (!isTrailByte(*++p))"
+                                 "  return false;";
+    const char[] appendSixBits = "d = (d << 6) | *p & 0b0011_1111;";
+    // Decode
+    if ((d & 0b1110_0000) == 0b1100_0000)
+    {
+      d &= 0b0001_1111;
+      mixin(appendSixBits);
+    }
+    else if ((d & 0b1111_0000) == 0b1110_0000)
+    {
+      d &= 0b0000_1111;
+      mixin(appendSixBits ~
+            checkNextByte ~ appendSixBits);
+    }
+    else if ((d & 0b1111_1000) == 0b1111_0000)
+    {
+      d &= 0b0000_0111;
+      mixin(appendSixBits ~
+            checkNextByte ~ appendSixBits ~
+            checkNextByte ~ appendSixBits);
+    }
+    else
+      return false;
+
+    assert(isTrailByte(*p));
+    if (!isValidChar(d) || !isUniAlpha(d))
+      return false;
+    // Only advance pointer if this is a Unicode alpha character.
+    this.p = p;
+    return true;
+  }
+
+  /// Decodes the next UTF-8 sequence.
+  dchar decodeUTF8()
+  {
+    assert(!isascii(*p), "check for ASCII char before calling decodeUTF8().");
+    char* p = this.p;
+    dchar d = *p;
+
+    ++p; // Move to second byte.
+    // Error if second byte is not a trail byte.
+    if (!isTrailByte(*p))
+      goto Lerr2;
+
+    // Check for overlong sequences.
+    switch (d)
+    {
+    case 0xE0, // 11100000 100xxxxx
+         0xF0, // 11110000 1000xxxx
+         0xF8, // 11111000 10000xxx
+         0xFC: // 11111100 100000xx
+      if ((*p & d) == 0x80)
+        goto Lerr;
+    default:
+      if ((d & 0xFE) == 0xC0) // 1100000x
+        goto Lerr;
+    }
+
+    const char[] checkNextByte = "if (!isTrailByte(*++p))"
+                                 "  goto Lerr2;";
+    const char[] appendSixBits = "d = (d << 6) | *p & 0b0011_1111;";
+
+    // Decode
+    if ((d & 0b1110_0000) == 0b1100_0000)
+    { // 110xxxxx 10xxxxxx
+      d &= 0b0001_1111;
+      mixin(appendSixBits);
+    }
+    else if ((d & 0b1111_0000) == 0b1110_0000)
+    { // 1110xxxx 10xxxxxx 10xxxxxx
+      d &= 0b0000_1111;
+      mixin(appendSixBits ~
+            checkNextByte ~ appendSixBits);
+    }
+    else if ((d & 0b1111_1000) == 0b1111_0000)
+    { // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+      d &= 0b0000_0111;
+      mixin(appendSixBits ~
+            checkNextByte ~ appendSixBits ~
+            checkNextByte ~ appendSixBits);
+    }
+    else
+      // 5 and 6 byte UTF-8 sequences are not allowed yet.
+      // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+      // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+      goto Lerr;
+
+    assert(isTrailByte(*p));
+
+    if (!isValidChar(d))
+    {
+    Lerr:
+      // Three cases:
+      // *) the UTF-8 sequence was successfully decoded but the resulting
+      //    character is invalid.
+      //    p points to last trail byte in the sequence.
+      // *) the UTF-8 sequence is overlong.
+      //    p points to second byte in the sequence.
+      // *) the UTF-8 sequence has more than 4 bytes or starts with
+      //    a trail byte.
+      //    p points to second byte in the sequence.
+      assert(isTrailByte(*p));
+      // Move to next ASCII character or lead byte of a UTF-8 sequence.
+      while (p < (end-1) && isTrailByte(*p))
+        ++p;
+      --p;
+      assert(!isTrailByte(p[1]));
+    Lerr2:
+      d = REPLACEMENT_CHAR;
+      error(this.p, MID.InvalidUTF8Sequence, formatBytes(this.p, p));
+    }
+
+    this.p = p;
+    return d;
+  }
+
+  /// Encodes the character d and appends it to str.
+  static void encodeUTF8(ref char[] str, dchar d)
+  {
+    assert(!isascii(d), "check for ASCII char before calling encodeUTF8().");
+    assert(isValidChar(d), "check if character is valid before calling encodeUTF8().");
+
+    char[6] b = void;
+    if (d < 0x800)
+    {
+      b[0] = 0xC0 | (d >> 6);
+      b[1] = 0x80 | (d & 0x3F);
+      str ~= b[0..2];
+    }
+    else if (d < 0x10000)
+    {
+      b[0] = 0xE0 | (d >> 12);
+      b[1] = 0x80 | ((d >> 6) & 0x3F);
+      b[2] = 0x80 | (d & 0x3F);
+      str ~= b[0..3];
+    }
+    else if (d < 0x200000)
+    {
+      b[0] = 0xF0 | (d >> 18);
+      b[1] = 0x80 | ((d >> 12) & 0x3F);
+      b[2] = 0x80 | ((d >> 6) & 0x3F);
+      b[3] = 0x80 | (d & 0x3F);
+      str ~= b[0..4];
+    }
+    /+ // There are no 5 and 6 byte UTF-8 sequences yet.
+    else if (d < 0x4000000)
+    {
+      b[0] = 0xF8 | (d >> 24);
+      b[1] = 0x80 | ((d >> 18) & 0x3F);
+      b[2] = 0x80 | ((d >> 12) & 0x3F);
+      b[3] = 0x80 | ((d >> 6) & 0x3F);
+      b[4] = 0x80 | (d & 0x3F);
+      str ~= b[0..5];
+    }
+    else if (d < 0x80000000)
+    {
+      b[0] = 0xFC | (d >> 30);
+      b[1] = 0x80 | ((d >> 24) & 0x3F);
+      b[2] = 0x80 | ((d >> 18) & 0x3F);
+      b[3] = 0x80 | ((d >> 12) & 0x3F);
+      b[4] = 0x80 | ((d >> 6) & 0x3F);
+      b[5] = 0x80 | (d & 0x3F);
+      str ~= b[0..6];
+    }
+    +/
+    else
+     assert(0);
+  }
+
+  /// Formats the bytes between start and end.
+  /// Returns: e.g.: abc -> \x61\x62\x63
+  static char[] formatBytes(char* start, char* end)
+  {
+    auto strLen = end-start;
+    const formatLen = `\xXX`.length;
+    char[] result = new char[strLen*formatLen]; // Reserve space.
+    result.length = 0;
+    foreach (c; cast(ubyte[])start[0..strLen])
+      result ~= Format("\\x{:X}", c);
+    return result;
+  }
+
+  /// Searches for an invalid UTF-8 sequence in str.
+  /// Returns: a formatted string of the invalid sequence (e.g. \xC0\x80).
+  static string findInvalidUTF8Sequence(string str)
+  {
+    char* p = str.ptr, end = p + str.length;
+    while (p < end)
+    {
+      if (decode(p, end) == ERROR_CHAR)
+      {
+        auto begin = p;
+        // Skip trail-bytes.
+        while (++p < end && isTrailByte(*p))
+        {}
+        return Lexer.formatBytes(begin, p);
+      }
+    }
+    assert(p == end);
+    return "";
+  }
+}
+
+/// Tests the lexer with a list of tokens.
+unittest
+{
+  Stdout("Testing Lexer.\n");
+  struct Pair
+  {
+    char[] tokenText;
+    TOK kind;
+  }
+  static Pair[] pairs = [
+    {"#!äöüß",  TOK.Shebang},       {"\n",      TOK.Newline},
+    {"//çay",   TOK.Comment},       {"\n",      TOK.Newline},
+                                    {"&",       TOK.AndBinary},
+    {"/*çağ*/", TOK.Comment},       {"&&",      TOK.AndLogical},
+    {"/+çak+/", TOK.Comment},       {"&=",      TOK.AndAssign},
+    {">",       TOK.Greater},       {"+",       TOK.Plus},
+    {">=",      TOK.GreaterEqual},  {"++",      TOK.PlusPlus},
+    {">>",      TOK.RShift},        {"+=",      TOK.PlusAssign},
+    {">>=",     TOK.RShiftAssign},  {"-",       TOK.Minus},
+    {">>>",     TOK.URShift},       {"--",      TOK.MinusMinus},
+    {">>>=",    TOK.URShiftAssign}, {"-=",      TOK.MinusAssign},
+    {"<",       TOK.Less},          {"=",       TOK.Assign},
+    {"<=",      TOK.LessEqual},     {"==",      TOK.Equal},
+    {"<>",      TOK.LorG},          {"~",       TOK.Tilde},
+    {"<>=",     TOK.LorEorG},       {"~=",      TOK.CatAssign},
+    {"<<",      TOK.LShift},        {"*",       TOK.Mul},
+    {"<<=",     TOK.LShiftAssign},  {"*=",      TOK.MulAssign},
+    {"!",       TOK.Not},           {"/",       TOK.Div},
+    {"!=",      TOK.NotEqual},      {"/=",      TOK.DivAssign},
+    {"!<",      TOK.UorGorE},       {"^",       TOK.Xor},
+    {"!>",      TOK.UorLorE},       {"^=",      TOK.XorAssign},
+    {"!<=",     TOK.UorG},          {"%",       TOK.Mod},
+    {"!>=",     TOK.UorL},          {"%=",      TOK.ModAssign},
+    {"!<>",     TOK.UorE},          {"(",       TOK.LParen},
+    {"!<>=",    TOK.Unordered},     {")",       TOK.RParen},
+    {".",       TOK.Dot},           {"[",       TOK.LBracket},
+    {"..",      TOK.Slice},         {"]",       TOK.RBracket},
+    {"...",     TOK.Ellipses},      {"{",       TOK.LBrace},
+    {"|",       TOK.OrBinary},      {"}",       TOK.RBrace},
+    {"||",      TOK.OrLogical},     {":",       TOK.Colon},
+    {"|=",      TOK.OrAssign},      {";",       TOK.Semicolon},
+    {"?",       TOK.Question},      {",",       TOK.Comma},
+    {"$",       TOK.Dollar},        {"cam",     TOK.Identifier},
+    {"çay",     TOK.Identifier},    {".0",      TOK.Float64},
+    {"0",       TOK.Int32},         {"\n",      TOK.Newline},
+    {"\r",      TOK.Newline},       {"\r\n",    TOK.Newline},
+    {"\u2028",  TOK.Newline},       {"\u2029",  TOK.Newline}
+  ];
+
+  char[] src;
+
+  // Join all token texts into a single string.
+  foreach (i, pair; pairs)
+    if (pair.kind == TOK.Comment && pair.tokenText[1] == '/' || // Line comment.
+        pair.kind == TOK.Shebang)
+    {
+      assert(pairs[i+1].kind == TOK.Newline); // Must be followed by a newline.
+      src ~= pair.tokenText;
+    }
+    else
+      src ~= pair.tokenText ~ " ";
+
+  auto lx = new Lexer(new SourceText("", src));
+  auto token = lx.getTokens();
+
+  uint i;
+  assert(token == lx.head);
+  assert(token.next.kind == TOK.Newline);
+  token = token.next.next;
+  do
+  {
+    assert(i < pairs.length);
+    assert(token.srcText == pairs[i].tokenText, Format("Scanned '{0}' but expected '{1}'", token.srcText, pairs[i].tokenText));
+    ++i;
+    token = token.next;
+  } while (token.kind != TOK.EOF)
+}
+
+/// Tests the Lexer's peek() method.
+unittest
+{
+  Stdout("Testing method Lexer.peek()\n");
+  auto sourceText = new SourceText("", "unittest { }");
+  auto lx = new Lexer(sourceText, null);
+
+  auto next = lx.head;
+  lx.peek(next);
+  assert(next.kind == TOK.Newline);
+  lx.peek(next);
+  assert(next.kind == TOK.Unittest);
+  lx.peek(next);
+  assert(next.kind == TOK.LBrace);
+  lx.peek(next);
+  assert(next.kind == TOK.RBrace);
+  lx.peek(next);
+  assert(next.kind == TOK.EOF);
+
+  lx = new Lexer(new SourceText("", ""));
+  next = lx.head;
+  lx.peek(next);
+  assert(next.kind == TOK.Newline);
+  lx.peek(next);
+  assert(next.kind == TOK.EOF);
+}
+
+unittest
+{
+  // Numbers unittest
+  // 0L 0ULi 0_L 0_UL 0x0U 0x0p2 0_Fi 0_e2 0_F 0_i
+  // 0u 0U 0uL 0UL 0L 0LU 0Lu
+  // 0Li 0f 0F 0fi 0Fi 0i
+  // 0b_1_LU 0b1000u
+  // 0x232Lu
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/lexer/Token.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,400 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.lexer.Token;
+
+import dil.lexer.Identifier;
+import dil.lexer.Funcs;
+import dil.Location;
+import tango.stdc.stdlib : malloc, free;
+import tango.core.Exception;
+import common;
+
+public import dil.lexer.TokensEnum;
+
+/// A Token is a sequence of characters formed by the lexical analyzer.
+struct Token
+{ /// Flags set by the Lexer.
+  enum Flags : ushort
+  {
+    None,
+    Whitespace = 1, /// Tokens with this flag are ignored by the Parser.
+  }
+
+  TOK kind; /// The token kind.
+  Flags flags; /// The flags of the token.
+  /// Pointers to the next and previous tokens (doubly-linked list.)
+  Token* next, prev;
+
+  /// Start of whitespace characters before token. Null if no WS.
+  /// TODO: remove to save space; can be replaced by 'prev.end'.
+  char* ws;
+  char* start; /// Points to the first character of the token.
+  char* end;   /// Points one character past the end of the token.
+
+  /// Data associated with this token.
+  /// TODO: move data structures out; use only pointers here to keep Token.sizeof small.
+  union
+  {
+    /// For newline tokens.
+    NewlineData newline;
+    /// For #line tokens.
+    struct
+    {
+      Token* tokLineNum; /// #line number
+      Token* tokLineFilespec; /// #line number filespec
+    }
+    /// The value of a string token.
+    struct
+    {
+      string str; /// Zero-terminated string. (The zero is included in the length.)
+      char pf;    /// Postfix 'c', 'w', 'd' or 0 for none.
+    version(D2)
+      Token* tok_str; /++ Points to the contents of a token string stored as a
+                          doubly linked list. The last token is always '}' or
+                          EOF in case end of source text is "q{" EOF.
+                      +/
+    }
+    Identifier* ident; /// For keywords and identifiers.
+    dchar  dchar_;   /// A character value.
+    long   long_;    /// A long integer value.
+    ulong  ulong_;   /// An unsigned long integer value.
+    int    int_;     /// An integer value.
+    uint   uint_;    /// An unsigned integer value.
+    float  float_;   /// A float value.
+    double double_;  /// A double value.
+    real   real_;    /// A real value.
+  }
+
+  /// Returns the text of the token.
+  string srcText()
+  {
+    assert(start && end);
+    return start[0 .. end - start];
+  }
+
+  /// Returns the preceding whitespace of the token.
+  string wsChars()
+  {
+    assert(ws && start);
+    return ws[0 .. start - ws];
+  }
+
+  /// Finds the next non-whitespace token.
+  /// Returns: 'this' token if the next token is TOK.EOF or null.
+  Token* nextNWS()
+  out(token)
+  {
+    assert(token !is null);
+  }
+  body
+  {
+    auto token = next;
+    while (token !is null && token.isWhitespace)
+      token = token.next;
+    if (token is null || token.kind == TOK.EOF)
+      return this;
+    return token;
+  }
+
+  /// Finds the previous non-whitespace token.
+  /// Returns: 'this' token if the previous token is TOK.HEAD or null.
+  Token* prevNWS()
+  out(token)
+  {
+    assert(token !is null);
+  }
+  body
+  {
+    auto token = prev;
+    while (token !is null && token.isWhitespace)
+      token = token.prev;
+    if (token is null || token.kind == TOK.HEAD)
+      return this;
+    return token;
+  }
+
+  /// Returns the string for a token kind.
+  static string toString(TOK kind)
+  {
+    return tokToString[kind];
+  }
+
+  /// Adds Flags.Whitespace to this.flags.
+  void setWhitespaceFlag()
+  {
+    this.flags |= Flags.Whitespace;
+  }
+
+  /// Returns true if this is a token that can have newlines in it.
+  ///
+  /// These can be block and nested comments and any string literal
+  /// except for escape string literals.
+  bool isMultiline()
+  {
+    return kind == TOK.String && start[0] != '\\' ||
+           kind == TOK.Comment && start[1] != '/';
+  }
+
+  /// Returns true if this is a keyword token.
+  bool isKeyword()
+  {
+    return KeywordsBegin <= kind && kind <= KeywordsEnd;
+  }
+
+  /// Returns true if this is an integral type token.
+  bool isIntegralType()
+  {
+    return IntegralTypeBegin <= kind && kind <= IntegralTypeEnd;
+  }
+
+  /// Returns true if this is a whitespace token.
+  bool isWhitespace()
+  {
+    return !!(flags & Flags.Whitespace);
+  }
+
+  /// Returns true if this is a special token.
+  bool isSpecialToken()
+  {
+    return SpecialTokensBegin <= kind && kind <= SpecialTokensEnd;
+  }
+
+version(D2)
+{
+  /// Returns true if this is a token string literal.
+  bool isTokenStringLiteral()
+  {
+    return kind == TOK.String && tok_str !is null;
+  }
+}
+
+  /// Returns true if this token starts a DeclarationDefinition.
+  bool isDeclDefStart()
+  {
+    return isDeclDefStartToken(kind);
+  }
+
+  /// Returns true if this token starts a Statement.
+  bool isStatementStart()
+  {
+    return isStatementStartToken(kind);
+  }
+
+  /// Returns true if this token starts an AsmStatement.
+  bool isAsmStatementStart()
+  {
+    return isAsmStatementStartToken(kind);
+  }
+
+  int opEquals(TOK kind2)
+  {
+    return kind == kind2;
+  }
+
+  int opCmp(Token* rhs)
+  {
+    return start < rhs.start;
+  }
+
+  /// Returns the Location of this token.
+  Location getLocation(bool realLocation)()
+  {
+    auto search_t = this.prev;
+    // Find previous newline token.
+    while (search_t.kind != TOK.Newline)
+      search_t = search_t.prev;
+    static if (realLocation)
+    {
+      auto filePath  = search_t.newline.filePaths.oriPath;
+      auto lineNum   = search_t.newline.oriLineNum;
+    }
+    else
+    {
+      auto filePath  = search_t.newline.filePaths.setPath;
+      auto lineNum   = search_t.newline.oriLineNum - search_t.newline.setLineNum;
+    }
+    auto lineBegin = search_t.end;
+    // Determine actual line begin and line number.
+    while (1)
+    {
+      search_t = search_t.next;
+      if (search_t == this)
+        break;
+      // Multiline tokens must be rescanned for newlines.
+      if (search_t.isMultiline)
+      {
+        auto p = search_t.start, end = search_t.end;
+        while (p != end)
+        {
+          if (scanNewline(p) == '\n')
+          {
+            lineBegin = p;
+            ++lineNum;
+          }
+          else
+            ++p;
+        }
+      }
+    }
+    return new Location(filePath, lineNum, lineBegin, this.start);
+  }
+
+  alias getLocation!(true) getRealLocation;
+  alias getLocation!(false) getErrorLocation;
+
+  uint lineCount()
+  {
+    uint count = 1;
+    if (this.isMultiline)
+    {
+      auto p = this.start, end = this.end;
+      while (p != end)
+      {
+        if (scanNewline(p) == '\n')
+          ++count;
+        else
+          ++p;
+      }
+    }
+    return count;
+  }
+
+  /// Return the source text enclosed by the left and right token.
+  static char[] textSpan(Token* left, Token* right)
+  {
+    assert(left.end <= right.start || left is right );
+    return left.start[0 .. right.end - left.start];
+  }
+
+  /// Uses malloc() to allocate memory for a token.
+  new(size_t size)
+  {
+    void* p = malloc(size);
+    if (p is null)
+      throw new OutOfMemoryException(__FILE__, __LINE__);
+    // TODO: Token.init should be all zeros.
+    // Maybe use calloc() to avoid this line?
+    *cast(Token*)p = Token.init;
+    return p;
+  }
+
+  /// Deletes a token using free().
+  delete(void* p)
+  {
+    auto token = cast(Token*)p;
+    if (token)
+    {
+      if(token.kind == TOK.HashLine)
+        token.destructHashLineToken();
+      else
+      {
+      version(D2)
+        if (token.isTokenStringLiteral)
+          token.destructTokenStringLiteral();
+      }
+    }
+    free(p);
+  }
+
+  void destructHashLineToken()
+  {
+    assert(kind == TOK.HashLine);
+    delete tokLineNum;
+    delete tokLineFilespec;
+  }
+
+version(D2)
+{
+  void destructTokenStringLiteral()
+  {
+    assert(kind == TOK.String);
+    assert(start && *start == 'q' && start[1] == '{');
+    assert(tok_str !is null);
+    auto tok_it = tok_str;
+    auto tok_del = tok_str;
+    while (tok_it && tok_it.kind != TOK.EOF)
+    {
+      tok_it = tok_it.next;
+      assert(tok_del && tok_del.kind != TOK.EOF);
+      delete tok_del;
+      tok_del = tok_it;
+    }
+  }
+}
+}
+
+/// Data associated with newline tokens.
+struct NewlineData
+{
+  struct FilePaths
+  {
+    char[] oriPath;   /// Original path to the source text.
+    char[] setPath;   /// Path set by #line.
+  }
+  FilePaths* filePaths;
+  uint oriLineNum;  /// Actual line number in the source text.
+  uint setLineNum;  /// Delta line number set by #line.
+}
+
+/// Returns true if this token starts a DeclarationDefinition.
+bool isDeclDefStartToken(TOK tok)
+{
+  switch (tok)
+  {
+  alias TOK T;
+  case  T.Align, T.Pragma, T.Export, T.Private, T.Package, T.Protected,
+        T.Public, T.Extern, T.Deprecated, T.Override, T.Abstract,
+        T.Synchronized, T.Static, T.Final, T.Const, T.Invariant/*D 2.0*/,
+        T.Auto, T.Scope, T.Alias, T.Typedef, T.Import, T.Enum, T.Class,
+        T.Interface, T.Struct, T.Union, T.This, T.Tilde, T.Unittest, T.Debug,
+        T.Version, T.Template, T.New, T.Delete, T.Mixin, T.Semicolon,
+        T.Identifier, T.Dot, T.Typeof:
+    return true;
+  default:
+    if (IntegralTypeBegin <= tok && tok <= IntegralTypeEnd)
+      return true;
+  }
+  return false;
+}
+
+/// Returns true if this token starts a Statement.
+bool isStatementStartToken(TOK tok)
+{
+  switch (tok)
+  {
+  alias TOK T;
+  case  T.Align, T.Extern, T.Final, T.Const, T.Auto, T.Identifier, T.Dot,
+        T.Typeof, T.If, T.While, T.Do, T.For, T.Foreach, T.Foreach_reverse,
+        T.Switch, T.Case, T.Default, T.Continue, T.Break, T.Return, T.Goto,
+        T.With, T.Synchronized, T.Try, T.Throw, T.Scope, T.Volatile, T.Asm,
+        T.Pragma, T.Mixin, T.Static, T.Debug, T.Version, T.Alias, T.Semicolon,
+        T.Enum, T.Class, T.Interface, T.Struct, T.Union, T.LBrace, T.Typedef,
+        T.This, T.Super, T.Null, T.True, T.False, T.Int32, T.Int64, T.Uint32,
+        T.Uint64, T.Float32, T.Float64, T.Float80, T.Imaginary32,
+        T.Imaginary64, T.Imaginary80, T.CharLiteral, T.String, T.LBracket,
+        T.Function, T.Delegate, T.Assert, T.Import, T.Typeid, T.Is, T.LParen,
+        T.Traits/*D2.0*/, T.AndBinary, T.PlusPlus, T.MinusMinus, T.Mul,
+        T.Minus, T.Plus, T.Not, T.Tilde, T.New, T.Delete, T.Cast:
+    return true;
+  default:
+    if (IntegralTypeBegin <= tok && tok <= IntegralTypeEnd ||
+        SpecialTokensBegin <= tok && tok <= SpecialTokensEnd)
+      return true;
+  }
+  return false;
+}
+
+/// Returns true if this token starts an AsmStatement.
+bool isAsmStatementStartToken(TOK tok)
+{
+  switch(tok)
+  {
+  alias TOK T;
+  case T.In, T.Int, T.Out, T.Identifier, T.Align, T.Semicolon:
+    return true;
+  default:
+  }
+  return false;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/lexer/TokensEnum.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,219 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.lexer.TokensEnum;
+
+import common;
+
+/// Enumeration of token kinds.
+enum TOK : ushort
+{
+  Invalid,
+
+  Illegal,
+  Comment,
+  Shebang,
+  HashLine,
+  Filespec,
+  Newline,
+  Empty,
+
+  Identifier,
+  String,
+  CharLiteral,
+
+  // Special tokens
+  FILE,
+  LINE,
+  DATE,
+  TIME,
+  TIMESTAMP,
+  VENDOR,
+  VERSION,
+
+  // Number literals
+  Int32, Int64, Uint32, Uint64,
+  // Floating point number scanner relies on this order. (FloatXY + 3 == ImaginaryXY)
+  Float32, Float64, Float80,
+  Imaginary32, Imaginary64, Imaginary80,
+
+
+  // Brackets
+  LParen,
+  RParen,
+  LBracket,
+  RBracket,
+  LBrace,
+  RBrace,
+
+  Dot, Slice, Ellipses,
+
+  // Floating point number operators
+  Unordered,
+  UorE,
+  UorG,
+  UorGorE,
+  UorL,
+  UorLorE,
+  LorEorG,
+  LorG,
+
+  // Normal operators
+  Assign, Equal, NotEqual, Not,
+  LessEqual, Less,
+  GreaterEqual, Greater,
+  LShiftAssign, LShift,
+  RShiftAssign,RShift,
+  URShiftAssign, URShift,
+  OrAssign, OrLogical, OrBinary,
+  AndAssign, AndLogical, AndBinary,
+  PlusAssign, PlusPlus, Plus,
+  MinusAssign, MinusMinus, Minus,
+  DivAssign, Div,
+  MulAssign, Mul,
+  ModAssign, Mod,
+  XorAssign, Xor,
+  CatAssign,
+  Tilde,
+
+  Colon,
+  Semicolon,
+  Question,
+  Comma,
+  Dollar,
+
+  /* Keywords:
+     NB.: Token.isKeyword() depends on this list being contiguous.
+  */
+  Abstract, Alias, Align, Asm, Assert, Auto, Body,
+  Break, Case, Cast, Catch,
+  Class, Const, Continue,
+  Debug, Default, Delegate, Delete, Deprecated, Do,
+  Else, Enum, Export, Extern, False, Final,
+  Finally, For, Foreach, Foreach_reverse, Function, Goto,
+  If, Import, In, Inout,
+  Interface, Invariant, Is, Lazy, Macro/+D2.0+/,
+  Mixin, Module, New, Nothrow/+D2.0+/, Null, Out, Override, Package,
+  Pragma, Private, Protected, Public, Pure/+D2.0+/, Ref, Return,
+  Scope, Static, Struct, Super, Switch, Synchronized,
+  Template, This, Throw, Traits/+D2.0+/, True, Try, Typedef, Typeid,
+  Typeof, Union, Unittest,
+  Version, Volatile, While, With,
+  // Integral types.
+  Char,   Wchar,   Dchar, Bool,
+  Byte,   Ubyte,   Short, Ushort,
+  Int,    Uint,    Long,  Ulong,
+  Cent,   Ucent,
+  Float,  Double,  Real,
+  Ifloat, Idouble, Ireal,
+  Cfloat, Cdouble, Creal, Void,
+
+  HEAD, // start of linked list
+  EOF,
+  MAX
+}
+
+alias TOK.Abstract KeywordsBegin;
+alias TOK.Void KeywordsEnd;
+alias TOK.Char IntegralTypeBegin;
+alias TOK.Void IntegralTypeEnd;
+alias TOK.FILE SpecialTokensBegin;
+alias TOK.VERSION SpecialTokensEnd;
+
+/// A table that maps each token kind to a string.
+const string[TOK.MAX] tokToString = [
+  "Invalid",
+
+  "Illegal",
+  "Comment",
+  "#! /shebang/",
+  "#line",
+  `"filespec"`,
+  "Newline",
+  "Empty",
+
+  "Identifier",
+  "String",
+  "CharLiteral",
+
+  "__FILE__",
+  "__LINE__",
+  "__DATE__",
+  "__TIME__",
+  "__TIMESTAMP__",
+  "__VENDOR__",
+  "__VERSION__",
+
+  "Int32", "Int64", "Uint32", "Uint64",
+  "Float32", "Float64", "Float80",
+  "Imaginary32", "Imaginary64", "Imaginary80",
+
+  "(",
+  ")",
+  "[",
+  "]",
+  "{",
+  "}",
+
+  ".", "..", "...",
+
+  "!<>=", // Unordered
+  "!<>",  // UorE
+  "!<=",  // UorG
+  "!<",   // UorGorE
+  "!>=",  // UorL
+  "!>",   // UorLorE
+  "<>=",  // LorEorG
+  "<>",   // LorG
+
+  "=", "==", "!=", "!",
+  "<=", "<",
+  ">=", ">",
+  "<<=", "<<",
+  ">>=",">>",
+  ">>>=", ">>>",
+  "|=", "||", "|",
+  "&=", "&&", "&",
+  "+=", "++", "+",
+  "-=", "--", "-",
+  "/=", "/",
+  "*=", "*",
+  "%=", "%",
+  "^=", "^",
+  "~=",
+  "~",
+
+  ":",
+  ";",
+  "?",
+  ",",
+  "$",
+
+  "abstract","alias","align","asm","assert","auto","body",
+  "break","case","cast","catch",
+  "class","const","continue",
+  "debug","default","delegate","delete","deprecated","do",
+  "else","enum","export","extern","false","final",
+  "finally","for","foreach","foreach_reverse","function","goto",
+  "if","import","in","inout",
+  "interface","invariant","is","lazy","macro",
+  "mixin","module","new","nothrow","null","out","override","package",
+  "pragma","private","protected","public","pure","ref","return",
+  "scope","static","struct","super","switch","synchronized",
+  "template","this","throw","__traits","true","try","typedef","typeid",
+  "typeof","union","unittest",
+  "version","volatile","while","with",
+  // Integral types.
+  "char",   "wchar",   "dchar", "bool",
+  "byte",   "ubyte",   "short", "ushort",
+  "int",    "uint",    "long",  "ulong",
+  "cent",   "ucent",
+  "float",  "double",  "real",
+  "ifloat", "idouble", "ireal",
+  "cfloat", "cdouble", "creal", "void",
+
+  "HEAD",
+  "EOF"
+];
+static assert(tokToString.length == TOK.EOF+1);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/parser/ImportParser.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,373 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.parser.ImportParser;
+
+import dil.parser.Parser;
+import dil.ast.Node;
+import dil.ast.Declarations;
+import dil.ast.Statements;
+import dil.SourceText;
+import dil.Enums;
+import common;
+
+private alias TOK T;
+
+/// A light-weight parser which looks only for import statements
+/// in the source text.
+class ImportParser : Parser
+{
+  this(SourceText srcText)
+  {
+    super(srcText);
+  }
+
+  override CompoundDeclaration start()
+  {
+    auto decls = new CompoundDeclaration;
+    super.init();
+    if (token.kind == T.Module)
+      decls ~= parseModuleDeclaration();
+    while (token.kind != T.EOF)
+      parseDeclarationDefinition(Protection.None);
+    return decls;
+  }
+
+  void parseDeclarationDefinitionsBlock(Protection prot)
+  {
+    skip(T.LBrace);
+    while (token.kind != T.RBrace && token.kind != T.EOF)
+      parseDeclarationDefinition(prot);
+    skip(T.RBrace);
+  }
+
+  void parseDeclarationsBlock(Protection prot)
+  {
+    switch (token.kind)
+    {
+    case T.LBrace:
+      parseDeclarationDefinitionsBlock(prot);
+      break;
+    case T.Colon:
+      nT();
+      while (token.kind != T.RBrace && token.kind != T.EOF)
+        parseDeclarationDefinition(prot);
+      break;
+    default:
+      parseDeclarationDefinition(prot);
+    }
+  }
+
+  bool skipToClosing(T opening, T closing)
+  {
+    alias token next;
+    uint level = 1;
+    while (1)
+    {
+      lexer.peek(next);
+      if (next.kind == opening)
+        ++level;
+      else if (next.kind == closing && --level == 0)
+        return true;
+      else if (next.kind == T.EOF)
+        break;
+    }
+    return false;
+  }
+
+  void skipToTokenAfterClosingParen()
+  {
+    skipToClosing(T.LParen, T.RParen);
+    nT();
+  }
+
+  void skipToTokenAfterClosingBrace()
+  {
+    skipToClosing(T.LBrace, T.RBrace);
+    nT();
+  }
+
+  void skip(TOK tok)
+  {
+    token.kind == tok && nT();
+  }
+
+  void parseProtectionAttribute()
+  {
+    Protection prot;
+    switch (token.kind)
+    {
+    case T.Private:
+      prot = Protection.Private; break;
+    case T.Package:
+      prot = Protection.Package; break;
+    case T.Protected:
+      prot = Protection.Protected; break;
+    case T.Public:
+      prot = Protection.Public; break;
+    case T.Export:
+      prot = Protection.Export; break;
+    default:
+      assert(0);
+    }
+    nT();
+    parseDeclarationsBlock(prot);
+  }
+
+  void parseDeclarationDefinition(Protection prot)
+  {
+    switch (token.kind)
+    {
+    case T.Align:
+      nT();
+      if (token.kind == T.LParen)
+        nT(), nT(), nT(); // ( Integer )
+      parseDeclarationsBlock(prot);
+      break;
+    case T.Pragma:
+      nT();
+      skipToTokenAfterClosingParen();
+      parseDeclarationsBlock(prot);
+      break;
+    case T.Export,
+         T.Private,
+         T.Package,
+         T.Protected,
+         T.Public:
+      parseProtectionAttribute();
+      break;
+    // Storage classes
+    case T.Extern:
+      nT();
+      token.kind == T.LParen && skipToTokenAfterClosingParen();
+      parseDeclarationsBlock(prot);
+      break;
+    case T.Const:
+    version(D2)
+    {
+      if (peekNext() == T.LParen)
+        goto case_Declaration;
+    }
+    case T.Override,
+         T.Deprecated,
+         T.Abstract,
+         T.Synchronized,
+         // T.Static,
+         T.Final,
+         T.Auto,
+         T.Scope:
+    case_StaticAttribute:
+    case_InvariantAttribute:
+      nT();
+      parseDeclarationsBlock(prot);
+      break;
+    // End of storage classes.
+    case T.Alias, T.Typedef:
+      nT();
+      goto case_Declaration;
+    case T.Static:
+      switch (peekNext())
+      {
+      case T.Import:
+        goto case_Import;
+      case T.This:
+        nT(), nT(); // static this
+        skipToTokenAfterClosingParen();
+        parseFunctionBody();
+        break;
+      case T.Tilde:
+        nT(), nT(), nT(), nT(), nT(); // static ~ this ( )
+        parseFunctionBody();
+        break;
+      case T.If:
+        nT(), nT();
+        skipToTokenAfterClosingParen();
+        parseDeclarationsBlock(prot);
+        if (token.kind == T.Else)
+          nT(), parseDeclarationsBlock(prot);
+        break;
+      case T.Assert:
+        nT(), nT(); // static assert
+        skipToTokenAfterClosingParen();
+        skip(T.Semicolon);
+        break;
+      default:
+        goto case_StaticAttribute;
+      }
+      break;
+    case T.Import:
+    case_Import:
+      auto decl = parseImportDeclaration();
+      decl.setProtection(prot); // Set the protection attribute.
+      imports ~= decl.to!(ImportDeclaration);
+      break;
+    case T.Enum:
+      nT();
+      token.kind == T.Identifier && nT();
+      if (token.kind == T.Colon)
+      {
+        nT();
+        while (token.kind != T.LBrace && token.kind != T.EOF)
+          nT();
+      }
+      if (token.kind == T.Semicolon)
+        nT();
+      else
+        skipToTokenAfterClosingBrace();
+      break;
+    case T.Class:
+    case T.Interface:
+      nT(), skip(T.Identifier); // class Identifier
+      token.kind == T.LParen && skipToTokenAfterClosingParen(); // Skip template params.
+      if (token.kind == T.Colon)
+      { // BaseClasses
+        nT();
+        while (token.kind != T.LBrace && token.kind != T.EOF)
+          if (token.kind == T.LParen) // Skip ( tokens... )
+            skipToTokenAfterClosingParen();
+          else
+            nT();
+      }
+      if (token.kind == T.Semicolon)
+        nT();
+      else
+        parseDeclarationDefinitionsBlock(Protection.None);
+      break;
+    case T.Struct, T.Union:
+      nT(); skip(T.Identifier);
+      token.kind == T.LParen && skipToTokenAfterClosingParen();
+      if (token.kind == T.Semicolon)
+        nT();
+      else
+        parseDeclarationDefinitionsBlock(Protection.None);
+      break;
+    case T.Tilde:
+      nT(); // ~
+    case T.This:
+      nT(); nT(); nT(); // this ( )
+      parseFunctionBody();
+      break;
+    case T.Invariant:
+    version(D2)
+    {
+      auto next = token;
+      if (peekAfter(next) == T.LParen)
+      {
+        if (peekAfter(next) != T.RParen)
+          goto case_Declaration;
+      }
+      else
+        goto case_InvariantAttribute;
+    }
+      nT();
+      token.kind == T.LParen && skipToTokenAfterClosingParen();
+      parseFunctionBody();
+      break;
+    case T.Unittest:
+      nT();
+      parseFunctionBody();
+      break;
+    case T.Debug:
+      nT();
+      if (token.kind == T.Assign)
+      {
+        nT(), nT(), nT(); // = Condition ;
+        break;
+      }
+      if (token.kind == T.LParen)
+        nT(), nT(), nT(); // ( Condition )
+      parseDeclarationsBlock(prot);
+      if (token.kind == T.Else)
+        nT(), parseDeclarationsBlock(prot);
+      break;
+    case T.Version:
+      nT();
+      if (token.kind == T.Assign)
+      {
+        nT(), nT(), nT(); // = Condition ;
+        break;
+      }
+      nT(), nT(), nT(); // ( Condition )
+      parseDeclarationsBlock(prot);
+      if (token.kind == T.Else)
+        nT(), parseDeclarationsBlock(prot);
+      break;
+    case T.Template:
+      nT();
+      skip(T.Identifier);
+      skipToTokenAfterClosingParen();
+      parseDeclarationDefinitionsBlock(Protection.None);
+      break;
+    case T.New:
+      nT();
+      skipToTokenAfterClosingParen();
+      parseFunctionBody();
+      break;
+    case T.Delete:
+      nT();
+      skipToTokenAfterClosingParen();
+      parseFunctionBody();
+      break;
+    case T.Mixin:
+      while (token.kind != T.Semicolon && token.kind != T.EOF)
+        if (token.kind == T.LParen)
+          skipToTokenAfterClosingParen();
+        else
+          nT();
+      skip(T.Semicolon);
+      break;
+    case T.Semicolon:
+      nT();
+      break;
+    // Declaration
+    case T.Identifier, T.Dot, T.Typeof:
+    case_Declaration:
+      while (token.kind != T.Semicolon && token.kind != T.EOF)
+        if (token.kind == T.LParen)
+          skipToTokenAfterClosingParen();
+        else if (token.kind == T.LBrace)
+          skipToTokenAfterClosingBrace();
+        else
+          nT();
+      skip(T.Semicolon);
+      break;
+    default:
+      if (token.isIntegralType)
+        goto case_Declaration;
+      nT();
+    }
+  }
+
+  FuncBodyStatement parseFunctionBody()
+  {
+    while (1)
+    {
+      switch (token.kind)
+      {
+      case T.LBrace:
+        skipToTokenAfterClosingBrace();
+        break;
+      case T.Semicolon:
+        nT();
+        break;
+      case T.In:
+        nT();
+        skipToTokenAfterClosingBrace();
+        continue;
+      case T.Out:
+        nT();
+        if (token.kind == T.LParen)
+          nT(), nT(), nT(); // ( Identifier )
+        skipToTokenAfterClosingBrace();
+        continue;
+      case T.Body:
+        nT();
+        goto case T.LBrace;
+      default:
+      }
+      break; // Exit loop.
+    }
+    return null;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/parser/Parser.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,4127 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.parser.Parser;
+
+import dil.lexer.Lexer;
+import dil.ast.Node;
+import dil.ast.Declarations;
+import dil.ast.Statements;
+import dil.ast.Expressions;
+import dil.ast.Types;
+import dil.ast.Parameters;
+import dil.lexer.IdTable;
+import dil.Messages;
+import dil.Information;
+import dil.Enums;
+import dil.CompilerInfo;
+import dil.SourceText;
+import dil.Unicode;
+import common;
+
+/// The Parser produces a full parse tree by examining
+/// the list of tokens provided by the Lexer.
+class Parser
+{
+  Lexer lexer; /// Used to lex the source code.
+  Token* token; /// Current non-whitespace token.
+  Token* prevToken; /// Previous non-whitespace token.
+
+  InfoManager infoMan;
+  ParserError[] errors;
+
+  ImportDeclaration[] imports; /// ImportDeclarations in the source text.
+
+  /// Attributes are evaluated in the parsing phase.
+  /// TODO: will be removed. SemanticPass1 takes care of attributes.
+  LinkageType linkageType;
+  Protection protection; /// ditto
+  StorageClass storageClass; /// ditto
+  uint alignSize = DEFAULT_ALIGN_SIZE; /// ditto
+
+  private alias TOK T; /// Used often in this class.
+  private alias TypeNode Type;
+
+  /// Constructs a Parser object.
+  /// Params:
+  ///   text     = the UTF-8 source code.
+  ///   infoMan  = used for collecting error messages.
+  this(SourceText srcText, InfoManager infoMan = null)
+  {
+    this.infoMan = infoMan;
+    lexer = new Lexer(srcText, infoMan);
+  }
+
+  /// Moves to the first token.
+  protected void init()
+  {
+    nT();
+    prevToken = token;
+  }
+
+  /// Moves to the next token.
+  void nT()
+  {
+    prevToken = token;
+    do
+    {
+      lexer.nextToken();
+      token = lexer.token;
+    } while (token.isWhitespace) // Skip whitespace
+  }
+
+  /// Start the parser and return the parsed Declarations.
+  CompoundDeclaration start()
+  {
+    init();
+    auto begin = token;
+    auto decls = new CompoundDeclaration;
+    if (token.kind == T.Module)
+      decls ~= parseModuleDeclaration();
+    decls.addOptChildren(parseDeclarationDefinitions());
+    set(decls, begin);
+    return decls;
+  }
+
+  /// Start the parser and return the parsed Expression.
+  Expression start2()
+  {
+    init();
+    return parseExpression();
+  }
+
+  // Members related to the method try_().
+  uint trying; /// Greater than 0 if Parser is in try_().
+  uint errorCount; /// Used to track nr. of errors while being in try_().
+
+  /// This method executes the delegate parseMethod and when an error occurred
+  /// the state of the lexer and parser are restored.
+  /// Returns: the return value of parseMethod().
+  ReturnType try_(ReturnType)(ReturnType delegate() parseMethod, out bool success)
+  {
+    // Save members.
+    auto oldToken     = this.token;
+    auto oldPrevToken = this.prevToken;
+    auto oldCount     = this.errorCount;
+
+    ++trying;
+    auto result = parseMethod();
+    --trying;
+    // Check if an error occurred.
+    if (errorCount != oldCount)
+    { // Restore members.
+      token       = oldToken;
+      prevToken   = oldPrevToken;
+      lexer.token = oldToken;
+      errorCount  = oldCount;
+      success = false;
+    }
+    else
+      success = true;
+    return result;
+  }
+
+  /// Sets the begin and end tokens of a syntax tree node.
+  Class set(Class)(Class node, Token* begin)
+  {
+    node.setTokens(begin, this.prevToken);
+    return node;
+  }
+
+  /// Sets the begin and end tokens of a syntax tree node.
+  Class set(Class)(Class node, Token* begin, Token* end)
+  {
+    node.setTokens(begin, end);
+    return node;
+  }
+
+  /// Returns true if set() has been called on a node.
+  static bool isNodeSet(Node node)
+  {
+    return node.begin !is null && node.end !is null;
+  }
+
+  /// Returns the token kind of the next token.
+  TOK peekNext()
+  {
+    Token* next = token;
+    do
+      lexer.peek(next);
+    while (next.isWhitespace) // Skip whitespace
+    return next.kind;
+  }
+
+  /// Returns the token kind of the token that comes after t.
+  TOK peekAfter(ref Token* t)
+  {
+    assert(t !is null);
+    do
+      lexer.peek(t);
+    while (t.isWhitespace) // Skip whitespace
+    return t.kind;
+  }
+
+  /// Consumes the current token if its kind matches k and returns true.
+  bool consumed()(TOK k) // Templatized, so it's inlined.
+  {
+    return token.kind == k ? (nT(), true) : false;
+  }
+
+  /// Asserts that the current token is of kind expectedKind,
+  /// and then moves to the next token.
+  void skip()(TOK expectedKind)
+  {
+    assert(token.kind == expectedKind /+|| *(int*).init+/, token.srcText());
+    nT();
+  }
+
+  /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  |                        Declaration parsing methods                        |
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
+
+  Declaration parseModuleDeclaration()
+  {
+    skip(T.Module);
+    auto begin = token;
+    ModuleFQN moduleFQN;
+    do
+      moduleFQN ~= requireIdentifier(MSG.ExpectedModuleIdentifier);
+    while (consumed(T.Dot))
+    require(T.Semicolon);
+    return set(new ModuleDeclaration(moduleFQN), begin);
+  }
+
+  /// Parses DeclarationDefinitions until the end of file is hit.
+  /// $(PRE
+  /// DeclDefs :=
+  ///     DeclDef
+  ///     DeclDefs
+  /// )
+  Declaration[] parseDeclarationDefinitions()
+  {
+    Declaration[] decls;
+    while (token.kind != T.EOF)
+      decls ~= parseDeclarationDefinition();
+    return decls;
+  }
+
+  /// Parse the body of a template, class, interface, struct or union.
+  /// $(PRE
+  /// DeclDefsBlock :=
+  ///     { }
+  ///     { DeclDefs }
+  /// )
+  CompoundDeclaration parseDeclarationDefinitionsBody()
+  {
+    // Save attributes.
+    auto linkageType  = this.linkageType;
+    auto protection   = this.protection;
+    auto storageClass = this.storageClass;
+    // Clear attributes.
+    this.linkageType  = LinkageType.None;
+    this.protection   = Protection.None;
+    this.storageClass = StorageClass.None;
+
+    // Parse body.
+    auto begin = token;
+    auto decls = new CompoundDeclaration;
+    require(T.LBrace);
+    while (token.kind != T.RBrace && token.kind != T.EOF)
+      decls ~= parseDeclarationDefinition();
+    require(T.RBrace);
+    set(decls, begin);
+
+    // Restore original values.
+    this.linkageType  = linkageType;
+    this.protection   = protection;
+    this.storageClass = storageClass;
+
+    return decls;
+  }
+
+  /// Parses a DeclarationDefinition.
+  Declaration parseDeclarationDefinition()
+  out(decl)
+  { assert(isNodeSet(decl)); }
+  body
+  {
+    auto begin = token;
+    Declaration decl;
+    switch (token.kind)
+    {
+    case T.Align,
+         T.Pragma,
+         // Protection attributes
+         T.Export,
+         T.Private,
+         T.Package,
+         T.Protected,
+         T.Public:
+      decl = parseAttributeSpecifier();
+      break;
+    // Storage classes
+    case T.Extern,
+         T.Deprecated,
+         T.Override,
+         T.Abstract,
+         T.Synchronized,
+         //T.Static,
+         T.Final,
+         T.Const,
+         //T.Invariant, // D 2.0
+         T.Auto,
+         T.Scope:
+    case_StaticAttribute:
+    case_InvariantAttribute: // D 2.0
+      return parseStorageAttribute();
+    case T.Alias:
+      nT();
+      decl = new AliasDeclaration(parseVariableOrFunction());
+      break;
+    case T.Typedef:
+      nT();
+      decl = new TypedefDeclaration(parseVariableOrFunction());
+      break;
+    case T.Static:
+      switch (peekNext())
+      {
+      case T.Import:
+        goto case_Import;
+      case T.This:
+        decl = parseStaticConstructorDeclaration();
+        break;
+      case T.Tilde:
+        decl = parseStaticDestructorDeclaration();
+        break;
+      case T.If:
+        decl = parseStaticIfDeclaration();
+        break;
+      case T.Assert:
+        decl = parseStaticAssertDeclaration();
+        break;
+      default:
+        goto case_StaticAttribute;
+      }
+      break;
+    case T.Import:
+    case_Import:
+      decl = parseImportDeclaration();
+      imports ~= decl.to!(ImportDeclaration);
+      // Handle specially. StorageClass mustn't be set.
+      decl.setProtection(this.protection);
+      return set(decl, begin);
+    case T.Enum:
+      decl = parseEnumDeclaration();
+      break;
+    case T.Class:
+      decl = parseClassDeclaration();
+      break;
+    case T.Interface:
+      decl = parseInterfaceDeclaration();
+      break;
+    case T.Struct, T.Union:
+      decl = parseStructOrUnionDeclaration();
+      break;
+    case T.This:
+      decl = parseConstructorDeclaration();
+      break;
+    case T.Tilde:
+      decl = parseDestructorDeclaration();
+      break;
+    case T.Invariant:
+    version(D2)
+    {
+      auto next = token;
+      if (peekAfter(next) == T.LParen)
+      {
+        if (peekAfter(next) != T.RParen)
+          goto case_Declaration;
+      }
+      else
+        goto case_InvariantAttribute;
+    }
+      decl = parseInvariantDeclaration();
+      break;
+    case T.Unittest:
+      decl = parseUnittestDeclaration();
+      break;
+    case T.Debug:
+      decl = parseDebugDeclaration();
+      break;
+    case T.Version:
+      decl = parseVersionDeclaration();
+      break;
+    case T.Template:
+      decl = parseTemplateDeclaration();
+      break;
+    case T.New:
+      decl = parseNewDeclaration();
+      break;
+    case T.Delete:
+      decl = parseDeleteDeclaration();
+      break;
+    case T.Mixin:
+      decl = parseMixin!(MixinDeclaration)();
+      break;
+    case T.Semicolon:
+      nT();
+      decl = new EmptyDeclaration();
+      break;
+    // Declaration
+    case T.Identifier, T.Dot, T.Typeof:
+    case_Declaration:
+      return parseVariableOrFunction(this.storageClass, this.protection, this.linkageType);
+    default:
+      if (token.isIntegralType)
+        goto case_Declaration;
+      else if (token.kind == T.Module)
+      {
+        decl = parseModuleDeclaration();
+        error(begin, MSG.ModuleDeclarationNotFirst);
+        return decl;
+      }
+
+      decl = new IllegalDeclaration();
+      // Skip to next valid token.
+      do
+        nT();
+      while (!token.isDeclDefStart &&
+              token.kind != T.RBrace &&
+              token.kind != T.EOF)
+      auto text = Token.textSpan(begin, this.prevToken);
+      error(begin, MSG.IllegalDeclaration, text);
+    }
+    decl.setProtection(this.protection);
+    decl.setStorageClass(this.storageClass);
+    assert(!isNodeSet(decl));
+    set(decl, begin);
+    return decl;
+  }
+
+  /// Parses a DeclarationsBlock.
+  /// $(PRE
+  /// DeclarationsBlock :=
+  ///     : DeclDefs
+  ///     { }
+  ///     { DeclDefs }
+  ///     DeclDef
+  /// )
+  Declaration parseDeclarationsBlock(/+bool noColon = false+/)
+  {
+    Declaration d;
+    switch (token.kind)
+    {
+    case T.LBrace:
+      auto begin = token;
+      nT();
+      auto decls = new CompoundDeclaration;
+      while (token.kind != T.RBrace && token.kind != T.EOF)
+        decls ~= parseDeclarationDefinition();
+      require(T.RBrace);
+      d = set(decls, begin);
+      break;
+    case T.Colon:
+      // if (noColon == true)
+      //   goto default;
+      nT();
+      auto begin = token;
+      auto decls = new CompoundDeclaration;
+      while (token.kind != T.RBrace && token.kind != T.EOF)
+        decls ~= parseDeclarationDefinition();
+      d = set(decls, begin);
+      break;
+    default:
+      d = parseDeclarationDefinition();
+    }
+    assert(isNodeSet(d));
+    return d;
+  }
+
+  // Declaration parseDeclarationsBlockNoColon()
+  // {
+  //   return parseDeclarationsBlock(true);
+  // }
+
+  /// Parses either a VariableDeclaration or a FunctionDeclaration.
+  /// Params:
+  ///   stc = previously parsed storage classes
+  ///   protection = previously parsed protection attribute
+  ///   linkType = previously parsed linkage type
+  ///   testAutoDeclaration = whether to check for an AutoDeclaration
+  ///   optionalParameterList = a hint for how to parse C-style function pointers
+  Declaration parseVariableOrFunction(StorageClass stc = StorageClass.None,
+                                      Protection protection = Protection.None,
+                                      LinkageType linkType = LinkageType.None,
+                                      bool testAutoDeclaration = false,
+                                      bool optionalParameterList = true)
+  {
+    auto begin = token;
+    Type type;
+    Identifier* name;
+
+    // Check for AutoDeclaration: StorageClasses Identifier =
+    if (testAutoDeclaration &&
+        token.kind == T.Identifier &&
+        peekNext() == T.Assign)
+    {
+      name = token.ident;
+      skip(T.Identifier);
+    }
+    else
+    {
+      type = parseType(); // VariableType or ReturnType
+      if (token.kind == T.LParen)
+      {
+        // C-style function pointers make the grammar ambiguous.
+        // We have to treat them specially at function scope.
+        // Example:
+        //   void foo() {
+        //     // A pointer to a function taking an integer and returning 'some_type'.
+        //     some_type (*p_func)(int);
+        //     // In the following case precedence is given to a CallExpression.
+        //     something(*p); // 'something' may be a function/method or an object having opCall overloaded.
+        //   }
+        //   // A pointer to a function taking no parameters and returning 'something'.
+        //   something(*p);
+        type = parseCFunctionPointerType(type, name, optionalParameterList);
+      }
+      else if (peekNext() == T.LParen)
+      { // Type FunctionName ( ParameterList ) FunctionBody
+        name = requireIdentifier(MSG.ExpectedFunctionName);
+        name || nT(); // Skip non-identifier token.
+        assert(token.kind == T.LParen);
+        // It's a function declaration
+        TemplateParameters tparams;
+        if (tokenAfterParenIs(T.LParen))
+          // ( TemplateParameterList ) ( ParameterList )
+          tparams = parseTemplateParameterList();
+
+        auto params = parseParameterList();
+      version(D2)
+      {
+        switch (token.kind)
+        {
+        case T.Const:
+          stc |= StorageClass.Const;
+          nT();
+          break;
+        case T.Invariant:
+          stc |= StorageClass.Invariant;
+          nT();
+          break;
+        default:
+        }
+      }
+        // ReturnType FunctionName ( ParameterList )
+        auto funcBody = parseFunctionBody();
+        auto fd = new FunctionDeclaration(type, name,/+ tparams,+/ params, funcBody);
+        fd.setStorageClass(stc);
+        fd.setLinkageType(linkType);
+        fd.setProtection(protection);
+        if (tparams)
+        {
+          auto d = putInsideTemplateDeclaration(begin, name, fd, tparams);
+          d.setStorageClass(stc);
+          d.setProtection(protection);
+          return set(d, begin);
+        }
+        return set(fd, begin);
+      }
+      else
+      { // Type VariableName DeclaratorSuffix
+        name = requireIdentifier(MSG.ExpectedVariableName);
+        type = parseDeclaratorSuffix(type);
+      }
+    }
+
+    // It's a variables declaration.
+    Identifier*[] names = [name]; // One identifier has been parsed already.
+    Expression[] values;
+    goto LenterLoop; // Enter the loop and check for an initializer.
+    while (consumed(T.Comma))
+    {
+      names ~= requireIdentifier(MSG.ExpectedVariableName);
+    LenterLoop:
+      if (consumed(T.Assign))
+        values ~= parseInitializer();
+      else
+        values ~= null;
+    }
+    require(T.Semicolon);
+    auto d = new VariablesDeclaration(type, names, values);
+    d.setStorageClass(stc);
+    d.setLinkageType(linkType);
+    d.setProtection(protection);
+    return set(d, begin);
+  }
+
+  /// Parses a variable initializer.
+  Expression parseInitializer()
+  {
+    if (token.kind == T.Void)
+    {
+      auto begin = token;
+      auto next = peekNext();
+      if (next == T.Comma || next == T.Semicolon)
+      {
+        skip(T.Void);
+        return set(new VoidInitExpression(), begin);
+      }
+    }
+    return parseNonVoidInitializer();
+  }
+
+  Expression parseNonVoidInitializer()
+  {
+    auto begin = token;
+    Expression init;
+    switch (token.kind)
+    {
+    case T.LBracket:
+      // ArrayInitializer:
+      //         [ ]
+      //         [ ArrayMemberInitializations ]
+      Expression[] keys;
+      Expression[] values;
+
+      skip(T.LBracket);
+      while (token.kind != T.RBracket)
+      {
+        auto e = parseNonVoidInitializer();
+        if (consumed(T.Colon))
+        {
+          keys ~= e;
+          values ~= parseNonVoidInitializer();
+        }
+        else
+        {
+          keys ~= null;
+          values ~= e;
+        }
+
+        if (!consumed(T.Comma))
+          break;
+      }
+      require(T.RBracket);
+      init = new ArrayInitExpression(keys, values);
+      break;
+    case T.LBrace:
+      // StructInitializer:
+      //         { }
+      //         { StructMemberInitializers }
+      Expression parseStructInitializer()
+      {
+        Identifier*[] idents;
+        Expression[] values;
+
+        skip(T.LBrace);
+        while (token.kind != T.RBrace)
+        {
+          if (token.kind == T.Identifier &&
+              // Peek for colon to see if this is a member identifier.
+              peekNext() == T.Colon)
+          {
+            idents ~= token.ident;
+            skip(T.Identifier), skip(T.Colon);
+          }
+          else
+            idents ~= null;
+
+          // NonVoidInitializer
+          values ~= parseNonVoidInitializer();
+
+          if (!consumed(T.Comma))
+            break;
+        }
+        require(T.RBrace);
+        return new StructInitExpression(idents, values);
+      }
+
+      bool success;
+      auto si = try_(&parseStructInitializer, success);
+      if (success)
+      {
+        init = si;
+        break;
+      }
+      assert(token.kind == T.LBrace);
+      //goto default;
+    default:
+      init = parseAssignExpression();
+    }
+    set(init, begin);
+    return init;
+  }
+
+  FuncBodyStatement parseFunctionBody()
+  {
+    auto begin = token;
+    auto func = new FuncBodyStatement;
+    while (1)
+    {
+      switch (token.kind)
+      {
+      case T.LBrace:
+        func.funcBody = parseStatements();
+        break;
+      case T.Semicolon:
+        nT();
+        break;
+      case T.In:
+        if (func.inBody)
+          error(MID.InContract);
+        nT();
+        func.inBody = parseStatements();
+        continue;
+      case T.Out:
+        if (func.outBody)
+          error(MID.OutContract);
+        nT();
+        if (consumed(T.LParen))
+        {
+          func.outIdent = requireIdentifier(MSG.ExpectedAnIdentifier);
+          require(T.RParen);
+        }
+        func.outBody = parseStatements();
+        continue;
+      case T.Body:
+        nT();
+        goto case T.LBrace;
+      default:
+        error(token, MSG.ExpectedFunctionBody, token.srcText);
+      }
+      break; // Exit loop.
+    }
+    set(func, begin);
+    func.finishConstruction();
+    return func;
+  }
+
+  LinkageType parseLinkageType()
+  {
+    LinkageType linkageType;
+
+    if (!consumed(T.LParen))
+      return linkageType;
+
+    if (consumed(T.RParen))
+    { // extern()
+      error(MID.MissingLinkageType);
+      return linkageType;
+    }
+
+    auto identTok = requireId();
+
+    IDK idKind = identTok ? identTok.ident.idKind : IDK.Null;
+
+    switch (idKind)
+    {
+    case IDK.C:
+      if (consumed(T.PlusPlus))
+      {
+        linkageType = LinkageType.Cpp;
+        break;
+      }
+      linkageType = LinkageType.C;
+      break;
+    case IDK.D:
+      linkageType = LinkageType.D;
+      break;
+    case IDK.Windows:
+      linkageType = LinkageType.Windows;
+      break;
+    case IDK.Pascal:
+      linkageType = LinkageType.Pascal;
+      break;
+    case IDK.System:
+      linkageType = LinkageType.System;
+      break;
+    default:
+      error(MID.UnrecognizedLinkageType, token.srcText);
+    }
+    require(T.RParen);
+    return linkageType;
+  }
+
+  void checkLinkageType(ref LinkageType prev_lt, LinkageType lt, Token* begin)
+  {
+    if (prev_lt == LinkageType.None)
+      prev_lt = lt;
+    else
+      error(begin, MSG.RedundantLinkageType, Token.textSpan(begin, this.prevToken));
+  }
+
+  Declaration parseStorageAttribute()
+  {
+    StorageClass stc, stc_tmp;
+    LinkageType prev_linkageType;
+
+    auto saved_storageClass = this.storageClass; // Save.
+    // Nested function.
+    Declaration parse()
+    {
+      Declaration decl;
+      auto begin = token;
+      switch (token.kind)
+      {
+      case T.Extern:
+        if (peekNext() != T.LParen)
+        {
+          stc_tmp = StorageClass.Extern;
+          goto Lcommon;
+        }
+
+        nT();
+        auto linkageType = parseLinkageType();
+        checkLinkageType(prev_linkageType, linkageType, begin);
+
+        auto saved = this.linkageType; // Save.
+        this.linkageType = linkageType; // Set.
+        decl = new LinkageDeclaration(linkageType, parse());
+        set(decl, begin);
+        this.linkageType = saved; // Restore.
+        break;
+      case T.Override:
+        stc_tmp = StorageClass.Override;
+        goto Lcommon;
+      case T.Deprecated:
+        stc_tmp = StorageClass.Deprecated;
+        goto Lcommon;
+      case T.Abstract:
+        stc_tmp = StorageClass.Abstract;
+        goto Lcommon;
+      case T.Synchronized:
+        stc_tmp = StorageClass.Synchronized;
+        goto Lcommon;
+      case T.Static:
+        stc_tmp = StorageClass.Static;
+        goto Lcommon;
+      case T.Final:
+        stc_tmp = StorageClass.Final;
+        goto Lcommon;
+      case T.Const:
+      version(D2)
+      {
+        if (peekNext() == T.LParen)
+          goto case_Declaration;
+      }
+        stc_tmp = StorageClass.Const;
+        goto Lcommon;
+      version(D2)
+      {
+      case T.Invariant: // D 2.0
+        auto next = token;
+        if (peekAfter(next) == T.LParen)
+        {
+          if (peekAfter(next) != T.RParen)
+            goto case_Declaration; // invariant ( Type )
+          decl = parseDeclarationDefinition(); // invariant ( )
+          decl.setStorageClass(stc);
+          break;
+        }
+        // invariant as StorageClass.
+        stc_tmp = StorageClass.Invariant;
+        goto Lcommon;
+      }
+      case T.Auto:
+        stc_tmp = StorageClass.Auto;
+        goto Lcommon;
+      case T.Scope:
+        stc_tmp = StorageClass.Scope;
+        goto Lcommon;
+      Lcommon:
+        // Issue error if redundant.
+        if (stc & stc_tmp)
+          error(MID.RedundantStorageClass, token.srcText);
+        else
+          stc |= stc_tmp;
+
+        nT();
+        decl = new StorageClassDeclaration(stc_tmp, parse());
+        set(decl, begin);
+        break;
+      case T.Identifier:
+      case_Declaration:
+        // This could be a normal Declaration or an AutoDeclaration
+        decl = parseVariableOrFunction(stc, this.protection, prev_linkageType, true);
+        break;
+      default:
+        this.storageClass = stc; // Set.
+        decl = parseDeclarationsBlock();
+        this.storageClass = saved_storageClass; // Reset.
+      }
+      assert(isNodeSet(decl));
+      return decl;
+    }
+    return parse();
+  }
+
+  uint parseAlignAttribute()
+  {
+    skip(T.Align);
+    uint size = DEFAULT_ALIGN_SIZE; // Global default.
+    if (consumed(T.LParen))
+    {
+      if (token.kind == T.Int32)
+        (size = token.int_), skip(T.Int32);
+      else
+        expected(T.Int32);
+      require(T.RParen);
+    }
+    return size;
+  }
+
+  Declaration parseAttributeSpecifier()
+  {
+    Declaration decl;
+
+    switch (token.kind)
+    {
+    case T.Align:
+      uint alignSize = parseAlignAttribute();
+      auto saved = this.alignSize; // Save.
+      this.alignSize = alignSize; // Set.
+      decl = new AlignDeclaration(alignSize, parseDeclarationsBlock());
+      this.alignSize = saved; // Restore.
+      break;
+    case T.Pragma:
+      // Pragma:
+      //     pragma ( Identifier )
+      //     pragma ( Identifier , ExpressionList )
+      nT();
+      Identifier* ident;
+      Expression[] args;
+
+      require(T.LParen);
+      ident = requireIdentifier(MSG.ExpectedPragmaIdentifier);
+
+      if (consumed(T.Comma))
+        args = parseExpressionList();
+      require(T.RParen);
+
+      decl = new PragmaDeclaration(ident, args, parseDeclarationsBlock());
+      break;
+    default:
+      // Protection attributes
+      Protection prot;
+      switch (token.kind)
+      {
+      case T.Private:
+        prot = Protection.Private; break;
+      case T.Package:
+        prot = Protection.Package; break;
+      case T.Protected:
+        prot = Protection.Protected; break;
+      case T.Public:
+        prot = Protection.Public; break;
+      case T.Export:
+        prot = Protection.Export; break;
+      default:
+        assert(0);
+      }
+      nT();
+      auto saved = this.protection; // Save.
+      this.protection = prot; // Set.
+      decl = new ProtectionDeclaration(prot, parseDeclarationsBlock());
+      this.protection = saved; // Restore.
+    }
+    return decl;
+  }
+
+  Declaration parseImportDeclaration()
+  {
+    bool isStatic = consumed(T.Static);
+    skip(T.Import);
+
+    ModuleFQN[] moduleFQNs;
+    Identifier*[] moduleAliases;
+    Identifier*[] bindNames;
+    Identifier*[] bindAliases;
+
+    do
+    {
+      ModuleFQN moduleFQN;
+      Identifier* moduleAlias;
+      // AliasName = ModuleName
+      if (peekNext() == T.Assign)
+      {
+        moduleAlias = requireIdentifier(MSG.ExpectedAliasModuleName);
+        skip(T.Assign);
+      }
+      // Identifier ("." Identifier)*
+      do
+        moduleFQN ~= requireIdentifier(MSG.ExpectedModuleIdentifier);
+      while (consumed(T.Dot))
+      // Push identifiers.
+      moduleFQNs ~= moduleFQN;
+      moduleAliases ~= moduleAlias;
+    } while (consumed(T.Comma))
+
+    if (consumed(T.Colon))
+    { // BindAlias "=" BindName ("," BindAlias "=" BindName)*;
+      // BindName ("," BindName)*;
+      do
+      {
+        Identifier* bindAlias;
+        // BindAlias = BindName
+        if (peekNext() == T.Assign)
+        {
+          bindAlias = requireIdentifier(MSG.ExpectedAliasImportName);
+          skip(T.Assign);
+        }
+        // Push identifiers.
+        bindNames ~= requireIdentifier(MSG.ExpectedImportName);
+        bindAliases ~= bindAlias;
+      } while (consumed(T.Comma))
+    }
+    require(T.Semicolon);
+
+    return new ImportDeclaration(moduleFQNs, moduleAliases, bindNames, bindAliases, isStatic);
+  }
+
+  Declaration parseEnumDeclaration()
+  {
+    skip(T.Enum);
+
+    Identifier* enumName;
+    Type baseType;
+    EnumMemberDeclaration[] members;
+    bool hasBody;
+
+    enumName = optionalIdentifier();
+
+    if (consumed(T.Colon))
+      baseType = parseBasicType();
+
+    if (enumName && consumed(T.Semicolon))
+    {}
+    else if (consumed(T.LBrace))
+    {
+      hasBody = true;
+      while (token.kind != T.RBrace)
+      {
+        auto begin = token;
+        auto name = requireIdentifier(MSG.ExpectedEnumMember);
+        Expression value;
+
+        if (consumed(T.Assign))
+          value = parseAssignExpression();
+        else
+          value = null;
+
+        members ~= set(new EnumMemberDeclaration(name, value), begin);
+
+        if (!consumed(T.Comma))
+          break;
+      }
+      require(T.RBrace);
+    }
+    else
+      error(token, MSG.ExpectedEnumBody, token.srcText);
+
+    return new EnumDeclaration(enumName, baseType, members, hasBody);
+  }
+
+  /// Wraps a declaration inside a template declaration.
+  /// Params:
+  ///   begin = begin token of decl.
+  ///   name = name of decl.
+  ///   decl = the declaration to be wrapped.
+  ///   tparams = the template parameters.
+  TemplateDeclaration putInsideTemplateDeclaration(Token* begin,
+                                                   Identifier* name,
+                                                   Declaration decl,
+                                                   TemplateParameters tparams)
+  {
+    set(decl, begin);
+    auto cd = new CompoundDeclaration;
+    cd ~= decl;
+    set(cd, begin);
+    return new TemplateDeclaration(name, tparams, cd);
+  }
+
+  Declaration parseClassDeclaration()
+  {
+    auto begin = token;
+    skip(T.Class);
+
+    Identifier* className;
+    TemplateParameters tparams;
+    BaseClassType[] bases;
+    CompoundDeclaration decls;
+
+    className = requireIdentifier(MSG.ExpectedClassName);
+
+    if (token.kind == T.LParen)
+      tparams = parseTemplateParameterList();
+
+    if (token.kind == T.Colon)
+      bases = parseBaseClasses();
+
+    if (bases.length == 0 && consumed(T.Semicolon))
+    {}
+    else if (token.kind == T.LBrace)
+      decls = parseDeclarationDefinitionsBody();
+    else
+      error(token, MSG.ExpectedClassBody, token.srcText);
+
+    Declaration d = new ClassDeclaration(className, /+tparams, +/bases, decls);
+    if (tparams)
+      d = putInsideTemplateDeclaration(begin, className, d, tparams);
+    return d;
+  }
+
+  BaseClassType[] parseBaseClasses(bool colonLeadsOff = true)
+  {
+    colonLeadsOff && skip(T.Colon);
+
+    BaseClassType[] bases;
+    do
+    {
+      Protection prot = Protection.Public;
+      switch (token.kind)
+      {
+      case T.Identifier, T.Dot, T.Typeof: goto LparseBasicType;
+      case T.Private:   prot = Protection.Private;   break;
+      case T.Protected: prot = Protection.Protected; break;
+      case T.Package:   prot = Protection.Package;   break;
+      case T.Public:  /*prot = Protection.Public;*/  break;
+      default:
+        error(MID.ExpectedBaseClasses, token.srcText);
+        return bases;
+      }
+      nT(); // Skip protection attribute.
+    LparseBasicType:
+      auto begin = token;
+      auto type = parseBasicType();
+      bases ~= set(new BaseClassType(prot, type), begin);
+    } while (consumed(T.Comma))
+    return bases;
+  }
+
+  Declaration parseInterfaceDeclaration()
+  {
+    auto begin = token;
+    skip(T.Interface);
+
+    Identifier* name;
+    TemplateParameters tparams;
+    BaseClassType[] bases;
+    CompoundDeclaration decls;
+
+    name = requireIdentifier(MSG.ExpectedInterfaceName);
+
+    if (token.kind == T.LParen)
+      tparams = parseTemplateParameterList();
+
+    if (token.kind == T.Colon)
+      bases = parseBaseClasses();
+
+    if (bases.length == 0 && consumed(T.Semicolon))
+    {}
+    else if (token.kind == T.LBrace)
+      decls = parseDeclarationDefinitionsBody();
+    else
+      error(token, MSG.ExpectedInterfaceBody, token.srcText);
+
+    Declaration d = new InterfaceDeclaration(name, /+tparams, +/bases, decls);
+    if (tparams)
+      d = putInsideTemplateDeclaration(begin, name, d, tparams);
+    return d;
+  }
+
+  Declaration parseStructOrUnionDeclaration()
+  {
+    assert(token.kind == T.Struct || token.kind == T.Union);
+    auto begin = token;
+    skip(token.kind);
+
+    Identifier* name;
+    TemplateParameters tparams;
+    CompoundDeclaration decls;
+
+    name = optionalIdentifier();
+
+    if (name && token.kind == T.LParen)
+      tparams = parseTemplateParameterList();
+
+    if (name && consumed(T.Semicolon))
+    {}
+    else if (token.kind == T.LBrace)
+      decls = parseDeclarationDefinitionsBody();
+    else
+      error(token, begin.kind == T.Struct ?
+                   MSG.ExpectedStructBody :
+                   MSG.ExpectedUnionBody, token.srcText);
+
+    Declaration d;
+    if (begin.kind == T.Struct)
+    {
+      auto sd = new StructDeclaration(name, /+tparams, +/decls);
+      sd.setAlignSize(this.alignSize);
+      d = sd;
+    }
+    else
+      d = new UnionDeclaration(name, /+tparams, +/decls);
+
+    if (tparams)
+      d = putInsideTemplateDeclaration(begin, name, d, tparams);
+    return d;
+  }
+
+  Declaration parseConstructorDeclaration()
+  {
+    skip(T.This);
+    auto parameters = parseParameterList();
+    auto funcBody = parseFunctionBody();
+    return new ConstructorDeclaration(parameters, funcBody);
+  }
+
+  Declaration parseDestructorDeclaration()
+  {
+    skip(T.Tilde);
+    require(T.This);
+    require(T.LParen);
+    require(T.RParen);
+    auto funcBody = parseFunctionBody();
+    return new DestructorDeclaration(funcBody);
+  }
+
+  Declaration parseStaticConstructorDeclaration()
+  {
+    skip(T.Static);
+    skip(T.This);
+    require(T.LParen);
+    require(T.RParen);
+    auto funcBody = parseFunctionBody();
+    return new StaticConstructorDeclaration(funcBody);
+  }
+
+  Declaration parseStaticDestructorDeclaration()
+  {
+    skip(T.Static);
+    skip(T.Tilde);
+    require(T.This);
+    require(T.LParen);
+    require(T.RParen);
+    auto funcBody = parseFunctionBody();
+    return new StaticDestructorDeclaration(funcBody);
+  }
+
+  Declaration parseInvariantDeclaration()
+  {
+    skip(T.Invariant);
+    // Optional () for getting ready porting to D 2.0
+    if (consumed(T.LParen))
+      require(T.RParen);
+    auto funcBody = parseFunctionBody();
+    return new InvariantDeclaration(funcBody);
+  }
+
+  Declaration parseUnittestDeclaration()
+  {
+    skip(T.Unittest);
+    auto funcBody = parseFunctionBody();
+    return new UnittestDeclaration(funcBody);
+  }
+
+  Token* parseIdentOrInt()
+  {
+    if (consumed(T.Int32) || consumed(T.Identifier))
+      return this.prevToken;
+    error(token, MSG.ExpectedIdentOrInt, token.srcText);
+    return null;
+  }
+
+  Declaration parseDebugDeclaration()
+  {
+    skip(T.Debug);
+
+    Token* spec;
+    Token* cond;
+    Declaration decls, elseDecls;
+
+    if (consumed(T.Assign))
+    { // debug = Integer ;
+      // debug = Identifier ;
+      spec = parseIdentOrInt();
+      require(T.Semicolon);
+    }
+    else
+    { // ( Condition )
+      if (consumed(T.LParen))
+      {
+        cond = parseIdentOrInt();
+        require(T.RParen);
+      }
+      // debug DeclarationsBlock
+      // debug ( Condition ) DeclarationsBlock
+      decls = parseDeclarationsBlock();
+      // else DeclarationsBlock
+      if (consumed(T.Else))
+        elseDecls = parseDeclarationsBlock();
+    }
+
+    return new DebugDeclaration(spec, cond, decls, elseDecls);
+  }
+
+  Declaration parseVersionDeclaration()
+  {
+    skip(T.Version);
+
+    Token* spec;
+    Token* cond;
+    Declaration decls, elseDecls;
+
+    if (consumed(T.Assign))
+    { // version = Integer ;
+      // version = Identifier ;
+      spec = parseIdentOrInt();
+      require(T.Semicolon);
+    }
+    else
+    { // ( Condition )
+      require(T.LParen);
+      cond = parseIdentOrInt();
+      require(T.RParen);
+      // version ( Condition ) DeclarationsBlock
+      decls = parseDeclarationsBlock();
+      // else DeclarationsBlock
+      if (consumed(T.Else))
+        elseDecls = parseDeclarationsBlock();
+    }
+
+    return new VersionDeclaration(spec, cond, decls, elseDecls);
+  }
+
+  Declaration parseStaticIfDeclaration()
+  {
+    skip(T.Static);
+    skip(T.If);
+
+    Expression condition;
+    Declaration ifDecls, elseDecls;
+
+    require(T.LParen);
+    condition = parseAssignExpression();
+    require(T.RParen);
+
+    ifDecls = parseDeclarationsBlock();
+
+    if (consumed(T.Else))
+      elseDecls = parseDeclarationsBlock();
+
+    return new StaticIfDeclaration(condition, ifDecls, elseDecls);
+  }
+
+  Declaration parseStaticAssertDeclaration()
+  {
+    skip(T.Static);
+    skip(T.Assert);
+    Expression condition, message;
+    require(T.LParen);
+    condition = parseAssignExpression();
+    if (consumed(T.Comma))
+      message = parseAssignExpression();
+    require(T.RParen);
+    require(T.Semicolon);
+    return new StaticAssertDeclaration(condition, message);
+  }
+
+  Declaration parseTemplateDeclaration()
+  {
+    skip(T.Template);
+    auto templateName = requireIdentifier(MSG.ExpectedTemplateName);
+    auto templateParams = parseTemplateParameterList();
+    auto decls = parseDeclarationDefinitionsBody();
+    return new TemplateDeclaration(templateName, templateParams, decls);
+  }
+
+  Declaration parseNewDeclaration()
+  {
+    skip(T.New);
+    auto parameters = parseParameterList();
+    auto funcBody = parseFunctionBody();
+    return new NewDeclaration(parameters, funcBody);
+  }
+
+  Declaration parseDeleteDeclaration()
+  {
+    skip(T.Delete);
+    auto parameters = parseParameterList();
+    auto funcBody = parseFunctionBody();
+    return new DeleteDeclaration(parameters, funcBody);
+  }
+
+  Type parseTypeofType()
+  {
+    auto begin = token;
+    skip(T.Typeof);
+    require(T.LParen);
+    Type type;
+    switch (token.kind)
+    {
+    version(D2)
+    {
+    case T.Return:
+      nT();
+      type = new TypeofType();
+      break;
+    }
+    default:
+      type = new TypeofType(parseExpression());
+    }
+    require(T.RParen);
+    set(type, begin);
+    return type;
+  }
+
+  /// Parses a MixinDeclaration or MixinStatement.
+  /// $(PRE
+  /// TemplateMixin :=
+  ///         mixin ( AssignExpression ) ;
+  ///         mixin TemplateIdentifier ;
+  ///         mixin TemplateIdentifier MixinIdentifier ;
+  ///         mixin TemplateIdentifier !( TemplateArguments ) ;
+  ///         mixin TemplateIdentifier !( TemplateArguments ) MixinIdentifier ;
+  /// )
+  Class parseMixin(Class)()
+  {
+  static assert(is(Class == MixinDeclaration) || is(Class == MixinStatement));
+    skip(T.Mixin);
+
+  static if (is(Class == MixinDeclaration))
+  {
+    if (consumed(T.LParen))
+    {
+      auto e = parseAssignExpression();
+      require(T.RParen);
+      require(T.Semicolon);
+      return new MixinDeclaration(e);
+    }
+  }
+
+    auto begin = token;
+    Expression e;
+    Identifier* mixinIdent;
+
+    if (consumed(T.Dot))
+      e = set(new ModuleScopeExpression(parseIdentifierExpression()), begin);
+    else
+      e = parseIdentifierExpression();
+
+    while (consumed(T.Dot))
+      e = set(new DotExpression(e, parseIdentifierExpression()), begin);
+
+    mixinIdent = optionalIdentifier();
+    require(T.Semicolon);
+
+    return new Class(e, mixinIdent);
+  }
+
+  /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  |                         Statement parsing methods                         |
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
+
+  CompoundStatement parseStatements()
+  {
+    auto begin = token;
+    require(T.LBrace);
+    auto statements = new CompoundStatement();
+    while (token.kind != T.RBrace && token.kind != T.EOF)
+      statements ~= parseStatement();
+    require(T.RBrace);
+    return set(statements, begin);
+  }
+
+  /// Parses a Statement.
+  Statement parseStatement()
+  {
+    auto begin = token;
+    Statement s;
+    Declaration d;
+
+    if (token.isIntegralType)
+    {
+      d = parseVariableOrFunction();
+      goto LreturnDeclarationStatement;
+    }
+
+    switch (token.kind)
+    {
+    case T.Align:
+      uint size = parseAlignAttribute();
+      // Restrict align attribute to structs in parsing phase.
+      StructDeclaration structDecl;
+      if (token.kind == T.Struct)
+      {
+        auto begin2 = token;
+        structDecl = parseStructOrUnionDeclaration().to!(StructDeclaration);
+        structDecl.setAlignSize(size);
+        set(structDecl, begin2);
+      }
+      else
+        expected(T.Struct);
+
+      d = new AlignDeclaration(size, structDecl ? cast(Declaration)structDecl : new CompoundDeclaration);
+      goto LreturnDeclarationStatement;
+      /+ Not applicable for statements.
+         T.Private, T.Package, T.Protected, T.Public, T.Export,
+         T.Deprecated, T.Override, T.Abstract,+/
+    case T.Extern,
+         T.Final,
+         T.Const,
+         T.Auto:
+         //T.Scope
+         //T.Static
+    case_parseAttribute:
+      s = parseAttributeStatement();
+      return s;
+    case T.Identifier:
+      if (peekNext() == T.Colon)
+      {
+        auto ident = token.ident;
+        skip(T.Identifier); skip(T.Colon);
+        s = new LabeledStatement(ident, parseNoScopeOrEmptyStatement());
+        break;
+      }
+      goto case T.Dot;
+    case T.Dot, T.Typeof:
+      bool success;
+      d = try_(delegate {
+          return parseVariableOrFunction(StorageClass.None,
+                                         Protection.None,
+                                         LinkageType.None, false, false);
+        }, success
+      );
+      if (success)
+        goto LreturnDeclarationStatement; // Declaration
+      else
+        goto case_parseExpressionStatement; // Expression
+
+    case T.If:
+      s = parseIfStatement();
+      break;
+    case T.While:
+      s = parseWhileStatement();
+      break;
+    case T.Do:
+      s = parseDoWhileStatement();
+      break;
+    case T.For:
+      s = parseForStatement();
+      break;
+    case T.Foreach, T.Foreach_reverse:
+      s = parseForeachStatement();
+      break;
+    case T.Switch:
+      s = parseSwitchStatement();
+      break;
+    case T.Case:
+      s = parseCaseStatement();
+      break;
+    case T.Default:
+      s = parseDefaultStatement();
+      break;
+    case T.Continue:
+      s = parseContinueStatement();
+      break;
+    case T.Break:
+      s = parseBreakStatement();
+      break;
+    case T.Return:
+      s = parseReturnStatement();
+      break;
+    case T.Goto:
+      s = parseGotoStatement();
+      break;
+    case T.With:
+      s = parseWithStatement();
+      break;
+    case T.Synchronized:
+      s = parseSynchronizedStatement();
+      break;
+    case T.Try:
+      s = parseTryStatement();
+      break;
+    case T.Throw:
+      s = parseThrowStatement();
+      break;
+    case T.Scope:
+      if (peekNext() != T.LParen)
+        goto case_parseAttribute;
+      s = parseScopeGuardStatement();
+      break;
+    case T.Volatile:
+      s = parseVolatileStatement();
+      break;
+    case T.Asm:
+      s = parseAsmBlockStatement();
+      break;
+    case T.Pragma:
+      s = parsePragmaStatement();
+      break;
+    case T.Mixin:
+      if (peekNext() == T.LParen)
+        goto case_parseExpressionStatement; // Parse as expression.
+      s = parseMixin!(MixinStatement)();
+      break;
+    case T.Static:
+      switch (peekNext())
+      {
+      case T.If:
+        s = parseStaticIfStatement();
+        break;
+      case T.Assert:
+        s = parseStaticAssertStatement();
+        break;
+      default:
+        goto case_parseAttribute;
+      }
+      break;
+    case T.Debug:
+      s = parseDebugStatement();
+      break;
+    case T.Version:
+      s = parseVersionStatement();
+      break;
+    // DeclDef
+    case T.Alias, T.Typedef:
+      d = parseDeclarationDefinition();
+      goto LreturnDeclarationStatement;
+    case T.Enum:
+      d = parseEnumDeclaration();
+      goto LreturnDeclarationStatement;
+    case T.Class:
+      d = parseClassDeclaration();
+      goto LreturnDeclarationStatement;
+    case T.Interface:
+      d = parseInterfaceDeclaration();
+      goto LreturnDeclarationStatement;
+    case T.Struct, T.Union:
+      d = parseStructOrUnionDeclaration();
+      // goto LreturnDeclarationStatement;
+    LreturnDeclarationStatement:
+      set(d, begin);
+      s = new DeclarationStatement(d);
+      break;
+    case T.LBrace:
+      s = parseScopeStatement();
+      break;
+    case T.Semicolon:
+      nT();
+      s = new EmptyStatement();
+      break;
+    // Parse an ExpressionStatement:
+    // Tokens that start a PrimaryExpression.
+    // case T.Identifier, T.Dot, T.Typeof:
+    case T.This:
+    case T.Super:
+    case T.Null:
+    case T.True, T.False:
+    // case T.Dollar:
+    case T.Int32, T.Int64, T.Uint32, T.Uint64:
+    case T.Float32, T.Float64, T.Float80,
+         T.Imaginary32, T.Imaginary64, T.Imaginary80:
+    case T.CharLiteral:
+    case T.String:
+    case T.LBracket:
+    // case T.LBrace:
+    case T.Function, T.Delegate:
+    case T.Assert:
+    // case T.Mixin:
+    case T.Import:
+    case T.Typeid:
+    case T.Is:
+    case T.LParen:
+    case T.Traits: // D2.0
+    // Tokens that can start a UnaryExpression:
+    case T.AndBinary, T.PlusPlus, T.MinusMinus, T.Mul, T.Minus,
+         T.Plus, T.Not, T.Tilde, T.New, T.Delete, T.Cast:
+    case_parseExpressionStatement:
+      s = new ExpressionStatement(parseExpression());
+      require(T.Semicolon);
+      break;
+    default:
+      if (token.isSpecialToken)
+        goto case_parseExpressionStatement;
+
+      if (token.kind != T.Dollar)
+        // Assert that this isn't a valid expression.
+        assert(delegate bool(){
+            bool success;
+            auto expression = try_(&parseExpression, success);
+            return success;
+          }() == false, "Didn't expect valid expression."
+        );
+
+      // Report error: it's an illegal statement.
+      s = new IllegalStatement();
+      // Skip to next valid token.
+      do
+        nT();
+      while (!token.isStatementStart &&
+              token.kind != T.RBrace &&
+              token.kind != T.EOF)
+      auto text = Token.textSpan(begin, this.prevToken);
+      error(begin, MSG.IllegalStatement, text);
+    }
+    assert(s !is null);
+    set(s, begin);
+    return s;
+  }
+
+  /// $(PRE
+  /// Parses a ScopeStatement.
+  /// ScopeStatement :=
+  ///     NoScopeStatement
+  /// )
+  Statement parseScopeStatement()
+  {
+    return new ScopeStatement(parseNoScopeStatement());
+  }
+
+  /// $(PRE
+  /// NoScopeStatement :=
+  ///     NonEmptyStatement
+  ///     BlockStatement
+  /// BlockStatement :=
+  ///     { }
+  ///     { StatementList }
+  /// )
+  Statement parseNoScopeStatement()
+  {
+    auto begin = token;
+    Statement s;
+    if (consumed(T.LBrace))
+    {
+      auto ss = new CompoundStatement();
+      while (token.kind != T.RBrace && token.kind != T.EOF)
+        ss ~= parseStatement();
+      require(T.RBrace);
+      s = set(ss, begin);
+    }
+    else if (token.kind == T.Semicolon)
+    {
+      error(token, MSG.ExpectedNonEmptyStatement);
+      nT();
+      s = set(new EmptyStatement(), begin);
+    }
+    else
+      s = parseStatement();
+    return s;
+  }
+
+  /// $(PRE
+  /// NoScopeOrEmptyStatement :=
+  ///     ;
+  ///     NoScopeStatement
+  /// )
+  Statement parseNoScopeOrEmptyStatement()
+  {
+    if (consumed(T.Semicolon))
+      return set(new EmptyStatement(), this.prevToken);
+    else
+      return parseNoScopeStatement();
+  }
+
+  Statement parseAttributeStatement()
+  {
+    StorageClass stc, stc_tmp;
+    LinkageType prev_linkageType;
+
+    Declaration parse() // Nested function.
+    {
+      auto begin = token;
+      Declaration d;
+      switch (token.kind)
+      {
+      case T.Extern:
+        if (peekNext() != T.LParen)
+        {
+          stc_tmp = StorageClass.Extern;
+          goto Lcommon;
+        }
+
+        nT();
+        auto linkageType = parseLinkageType();
+        checkLinkageType(prev_linkageType, linkageType, begin);
+
+        d = new LinkageDeclaration(linkageType, parse());
+        break;
+      case T.Static:
+        stc_tmp = StorageClass.Static;
+        goto Lcommon;
+      case T.Final:
+        stc_tmp = StorageClass.Final;
+        goto Lcommon;
+      case T.Const:
+      version(D2)
+      {
+        if (peekNext() == T.LParen)
+          goto case_Declaration;
+      }
+        stc_tmp = StorageClass.Const;
+        goto Lcommon;
+      version(D2)
+      {
+      case T.Invariant: // D 2.0
+        if (peekNext() == T.LParen)
+          goto case_Declaration;
+        stc_tmp = StorageClass.Invariant;
+        goto Lcommon;
+      }
+      case T.Auto:
+        stc_tmp = StorageClass.Auto;
+        goto Lcommon;
+      case T.Scope:
+        stc_tmp = StorageClass.Scope;
+        goto Lcommon;
+      Lcommon:
+        // Issue error if redundant.
+        if (stc & stc_tmp)
+          error(MID.RedundantStorageClass, token.srcText);
+        else
+          stc |= stc_tmp;
+
+        nT();
+        d = new StorageClassDeclaration(stc_tmp, parse());
+        break;
+      // TODO: allow "scope class", "abstract scope class" in function bodies?
+      //case T.Class:
+      default:
+      case_Declaration:
+        return parseVariableOrFunction(stc, Protection.None, prev_linkageType, true);
+      }
+      return set(d, begin);
+    }
+    return new DeclarationStatement(parse());
+  }
+
+  Statement parseIfStatement()
+  {
+    skip(T.If);
+
+    Statement variable;
+    Expression condition;
+    Statement ifBody, elseBody;
+
+    require(T.LParen);
+
+    Identifier* ident;
+    auto begin = token; // For start of AutoDeclaration or normal Declaration.
+    // auto Identifier = Expression
+    if (consumed(T.Auto))
+    {
+      ident = requireIdentifier(MSG.ExpectedVariableName);
+      require(T.Assign);
+      auto init = parseExpression();
+      auto v = new VariablesDeclaration(null, [ident], [init]);
+      set(v, begin.nextNWS);
+      auto d = new StorageClassDeclaration(StorageClass.Auto, v);
+      set(d, begin);
+      variable = new DeclarationStatement(d);
+      set(variable, begin);
+    }
+    else
+    { // Declarator = Expression
+      Type parseDeclaratorAssign()
+      {
+        auto type = parseDeclarator(ident);
+        require(T.Assign);
+        return type;
+      }
+      bool success;
+      auto type = try_(&parseDeclaratorAssign, success);
+      if (success)
+      {
+        auto init = parseExpression();
+        auto v = new VariablesDeclaration(type, [ident], [init]);
+        set(v, begin);
+        variable = new DeclarationStatement(v);
+        set(variable, begin);
+      }
+      else
+        condition = parseExpression();
+    }
+    require(T.RParen);
+    ifBody = parseScopeStatement();
+    if (consumed(T.Else))
+      elseBody = parseScopeStatement();
+    return new IfStatement(variable, condition, ifBody, elseBody);
+  }
+
+  Statement parseWhileStatement()
+  {
+    skip(T.While);
+    require(T.LParen);
+    auto condition = parseExpression();
+    require(T.RParen);
+    return new WhileStatement(condition, parseScopeStatement());
+  }
+
+  Statement parseDoWhileStatement()
+  {
+    skip(T.Do);
+    auto doBody = parseScopeStatement();
+    require(T.While);
+    require(T.LParen);
+    auto condition = parseExpression();
+    require(T.RParen);
+    return new DoWhileStatement(condition, doBody);
+  }
+
+  Statement parseForStatement()
+  {
+    skip(T.For);
+
+    Statement init, forBody;
+    Expression condition, increment;
+
+    require(T.LParen);
+    if (!consumed(T.Semicolon))
+      init = parseNoScopeStatement();
+    if (token.kind != T.Semicolon)
+      condition = parseExpression();
+    require(T.Semicolon);
+    if (token.kind != T.RParen)
+      increment = parseExpression();
+    require(T.RParen);
+    forBody = parseScopeStatement();
+    return new ForStatement(init, condition, increment, forBody);
+  }
+
+  Statement parseForeachStatement()
+  {
+    assert(token.kind == T.Foreach || token.kind == T.Foreach_reverse);
+    TOK tok = token.kind;
+    nT();
+
+    auto params = new Parameters;
+    Expression e; // Aggregate or LwrExpression
+
+    require(T.LParen);
+    auto paramsBegin = token;
+    do
+    {
+      auto paramBegin = token;
+      StorageClass stc;
+      Type type;
+      Identifier* ident;
+
+      switch (token.kind)
+      {
+      case T.Ref, T.Inout:
+        stc = StorageClass.Ref;
+        nT();
+        // fall through
+      case T.Identifier:
+        auto next = peekNext();
+        if (next == T.Comma || next == T.Semicolon || next == T.RParen)
+        {
+          ident = requireIdentifier(MSG.ExpectedVariableName);
+          break;
+        }
+        // fall through
+      default:
+        type = parseDeclarator(ident);
+      }
+
+      params ~= set(new Parameter(stc, type, ident, null), paramBegin);
+    } while (consumed(T.Comma))
+    set(params, paramsBegin);
+    require(T.Semicolon);
+    e = parseExpression();
+  version(D2)
+  { //Foreach (ForeachType; LwrExpression .. UprExpression ) ScopeStatement
+    if (consumed(T.Slice))
+    {
+      // if (params.length != 1)
+        // error(MID.XYZ); // TODO: issue error msg
+      auto upper = parseExpression();
+      require(T.RParen);
+      auto forBody = parseScopeStatement();
+      return new ForeachRangeStatement(tok, params, e, upper, forBody);
+    }
+  }
+    // Foreach (ForeachTypeList; Aggregate) ScopeStatement
+    require(T.RParen);
+    auto forBody = parseScopeStatement();
+    return new ForeachStatement(tok, params, e, forBody);
+  }
+
+  Statement parseSwitchStatement()
+  {
+    skip(T.Switch);
+    require(T.LParen);
+    auto condition = parseExpression();
+    require(T.RParen);
+    auto switchBody = parseScopeStatement();
+    return new SwitchStatement(condition, switchBody);
+  }
+
+  /// Helper function for parsing the body of a default or case statement.
+  Statement parseCaseOrDefaultBody()
+  {
+    // This function is similar to parseNoScopeStatement()
+    auto begin = token;
+    auto s = new CompoundStatement();
+    while (token.kind != T.Case &&
+           token.kind != T.Default &&
+           token.kind != T.RBrace &&
+           token.kind != T.EOF)
+      s ~= parseStatement();
+    set(s, begin);
+    return set(new ScopeStatement(s), begin);
+  }
+
+  Statement parseCaseStatement()
+  {
+    skip(T.Case);
+    auto values = parseExpressionList();
+    require(T.Colon);
+    auto caseBody = parseCaseOrDefaultBody();
+    return new CaseStatement(values, caseBody);
+  }
+
+  Statement parseDefaultStatement()
+  {
+    skip(T.Default);
+    require(T.Colon);
+    auto defaultBody = parseCaseOrDefaultBody();
+    return new DefaultStatement(defaultBody);
+  }
+
+  Statement parseContinueStatement()
+  {
+    skip(T.Continue);
+    auto ident = optionalIdentifier();
+    require(T.Semicolon);
+    return new ContinueStatement(ident);
+  }
+
+  Statement parseBreakStatement()
+  {
+    skip(T.Break);
+    auto ident = optionalIdentifier();
+    require(T.Semicolon);
+    return new BreakStatement(ident);
+  }
+
+  Statement parseReturnStatement()
+  {
+    skip(T.Return);
+    Expression expr;
+    if (token.kind != T.Semicolon)
+      expr = parseExpression();
+    require(T.Semicolon);
+    return new ReturnStatement(expr);
+  }
+
+  Statement parseGotoStatement()
+  {
+    skip(T.Goto);
+    Identifier* ident;
+    Expression caseExpr;
+    switch (token.kind)
+    {
+    case T.Case:
+      ident = token.ident;
+      nT();
+      if (token.kind == T.Semicolon)
+        break;
+      caseExpr = parseExpression();
+      break;
+    case T.Default:
+      ident = token.ident;
+      nT();
+      break;
+    default:
+      ident = requireIdentifier(MSG.ExpectedAnIdentifier);
+    }
+    require(T.Semicolon);
+    return new GotoStatement(ident, caseExpr);
+  }
+
+  Statement parseWithStatement()
+  {
+    skip(T.With);
+    require(T.LParen);
+    auto expr = parseExpression();
+    require(T.RParen);
+    return new WithStatement(expr, parseScopeStatement());
+  }
+
+  Statement parseSynchronizedStatement()
+  {
+    skip(T.Synchronized);
+    Expression expr;
+    if (consumed(T.LParen))
+    {
+      expr = parseExpression();
+      require(T.RParen);
+    }
+    return new SynchronizedStatement(expr, parseScopeStatement());
+  }
+
+  Statement parseTryStatement()
+  {
+    auto begin = token;
+    skip(T.Try);
+
+    auto tryBody = parseScopeStatement();
+    CatchStatement[] catchBodies;
+    FinallyStatement finBody;
+
+    while (consumed(T.Catch))
+    {
+      Parameter param;
+      if (consumed(T.LParen))
+      {
+        auto begin2 = token;
+        Identifier* ident;
+        auto type = parseDeclarator(ident, true);
+        param = new Parameter(StorageClass.None, type, ident, null);
+        set(param, begin2);
+        require(T.RParen);
+      }
+      catchBodies ~= set(new CatchStatement(param, parseNoScopeStatement()), begin);
+      if (param is null)
+        break; // This is a LastCatch
+      begin = token;
+    }
+
+    if (consumed(T.Finally))
+      finBody = set(new FinallyStatement(parseNoScopeStatement()), prevToken);
+
+    if (catchBodies.length == 0 && finBody is null)
+      assert(begin.kind == T.Try), error(begin, MSG.MissingCatchOrFinally);
+
+    return new TryStatement(tryBody, catchBodies, finBody);
+  }
+
+  Statement parseThrowStatement()
+  {
+    skip(T.Throw);
+    auto expr = parseExpression();
+    require(T.Semicolon);
+    return new ThrowStatement(expr);
+  }
+
+  Statement parseScopeGuardStatement()
+  {
+    skip(T.Scope);
+    skip(T.LParen);
+    auto condition = requireIdentifier(MSG.ExpectedScopeIdentifier);
+    if (condition)
+      switch (condition.idKind)
+      {
+      case IDK.exit, IDK.success, IDK.failure:
+        break;
+      default:
+        error(this.prevToken, MSG.InvalidScopeIdentifier, this.prevToken.srcText);
+      }
+    require(T.RParen);
+    Statement scopeBody;
+    if (token.kind == T.LBrace)
+      scopeBody = parseScopeStatement();
+    else
+      scopeBody = parseNoScopeStatement();
+    return new ScopeGuardStatement(condition, scopeBody);
+  }
+
+  Statement parseVolatileStatement()
+  {
+    skip(T.Volatile);
+    Statement volatileBody;
+    if (token.kind == T.Semicolon)
+      nT();
+    else if (token.kind == T.LBrace)
+      volatileBody = parseScopeStatement();
+    else
+      volatileBody = parseStatement();
+    return new VolatileStatement(volatileBody);
+  }
+
+  Statement parsePragmaStatement()
+  {
+    skip(T.Pragma);
+
+    Identifier* ident;
+    Expression[] args;
+    Statement pragmaBody;
+
+    require(T.LParen);
+    ident = requireIdentifier(MSG.ExpectedPragmaIdentifier);
+
+    if (consumed(T.Comma))
+      args = parseExpressionList();
+    require(T.RParen);
+
+    pragmaBody = parseNoScopeOrEmptyStatement();
+
+    return new PragmaStatement(ident, args, pragmaBody);
+  }
+
+  Statement parseStaticIfStatement()
+  {
+    skip(T.Static);
+    skip(T.If);
+    Expression condition;
+    Statement ifBody, elseBody;
+
+    require(T.LParen);
+    condition = parseExpression();
+    require(T.RParen);
+    ifBody = parseNoScopeStatement();
+    if (consumed(T.Else))
+      elseBody = parseNoScopeStatement();
+    return new StaticIfStatement(condition, ifBody, elseBody);
+  }
+
+  Statement parseStaticAssertStatement()
+  {
+    skip(T.Static);
+    skip(T.Assert);
+    Expression condition, message;
+
+    require(T.LParen);
+    condition = parseAssignExpression(); // Condition.
+    if (consumed(T.Comma))
+      message = parseAssignExpression(); // Error message.
+    require(T.RParen);
+    require(T.Semicolon);
+    return new StaticAssertStatement(condition, message);
+  }
+
+  Statement parseDebugStatement()
+  {
+    skip(T.Debug);
+    Token* cond;
+    Statement debugBody, elseBody;
+
+    // ( Condition )
+    if (consumed(T.LParen))
+    {
+      cond = parseIdentOrInt();
+      require(T.RParen);
+    }
+    // debug Statement
+    // debug ( Condition ) Statement
+    debugBody = parseNoScopeStatement();
+    // else Statement
+    if (consumed(T.Else))
+      elseBody = parseNoScopeStatement();
+
+    return new DebugStatement(cond, debugBody, elseBody);
+  }
+
+  Statement parseVersionStatement()
+  {
+    skip(T.Version);
+    Token* cond;
+    Statement versionBody, elseBody;
+
+    // ( Condition )
+    require(T.LParen);
+    cond = parseIdentOrInt();
+    require(T.RParen);
+    // version ( Condition ) Statement
+    versionBody = parseNoScopeStatement();
+    // else Statement
+    if (consumed(T.Else))
+      elseBody = parseNoScopeStatement();
+
+    return new VersionStatement(cond, versionBody, elseBody);
+  }
+
+  /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  |                         Assembler parsing methods                         |
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
+
+  /// Parses an AsmBlockStatement.
+  Statement parseAsmBlockStatement()
+  {
+    skip(T.Asm);
+    require(T.LBrace);
+    auto ss = new CompoundStatement;
+    while (token.kind != T.RBrace && token.kind != T.EOF)
+      ss ~= parseAsmStatement();
+    require(T.RBrace);
+    return new AsmBlockStatement(ss);
+  }
+
+  Statement parseAsmStatement()
+  {
+    auto begin = token;
+    Statement s;
+    Identifier* ident;
+    switch (token.kind)
+    {
+    // Keywords that are valid opcodes.
+    case T.In, T.Int, T.Out:
+      ident = token.ident;
+      nT();
+      goto LOpcode;
+    case T.Identifier:
+      ident = token.ident;
+      nT();
+      if (consumed(T.Colon))
+      { // Identifier : AsmStatement
+        s = new LabeledStatement(ident, parseAsmStatement());
+        break;
+      }
+
+    LOpcode:
+      // Opcode ;
+      // Opcode Operands ;
+      // Opcode
+      //     Identifier
+      Expression[] es;
+      if (token.kind != T.Semicolon)
+        do
+          es ~= parseAsmExpression();
+        while (consumed(T.Comma))
+      require(T.Semicolon);
+      s = new AsmStatement(ident, es);
+      break;
+    case T.Align:
+      // align Integer;
+      nT();
+      int number = -1;
+      if (token.kind == T.Int32)
+        (number = token.int_), skip(T.Int32);
+      else
+        error(token, MSG.ExpectedIntegerAfterAlign, token.srcText);
+      require(T.Semicolon);
+      s = new AsmAlignStatement(number);
+      break;
+    case T.Semicolon:
+      s = new EmptyStatement();
+      nT();
+      break;
+    default:
+      s = new IllegalAsmStatement();
+      // Skip to next valid token.
+      do
+        nT();
+      while (!token.isAsmStatementStart &&
+              token.kind != T.RBrace &&
+              token.kind != T.EOF)
+      auto text = Token.textSpan(begin, this.prevToken);
+      error(begin, MSG.IllegalAsmStatement, text);
+    }
+    set(s, begin);
+    return s;
+  }
+
+  Expression parseAsmExpression()
+  {
+    auto begin = token;
+    auto e = parseAsmOrOrExpression();
+    if (consumed(T.Question))
+    {
+      auto tok = this.prevToken;
+      auto iftrue = parseAsmExpression();
+      require(T.Colon);
+      auto iffalse = parseAsmExpression();
+      e = new CondExpression(e, iftrue, iffalse, tok);
+      set(e, begin);
+    }
+    // TODO: create AsmExpression that contains e?
+    return e;
+  }
+
+  Expression parseAsmOrOrExpression()
+  {
+    alias parseAsmAndAndExpression parseNext;
+    auto begin = token;
+    auto e = parseNext();
+    while (token.kind == T.OrLogical)
+    {
+      auto tok = token;
+      nT();
+      e = new OrOrExpression(e, parseNext(), tok);
+      set(e, begin);
+    }
+    return e;
+  }
+
+  Expression parseAsmAndAndExpression()
+  {
+    alias parseAsmOrExpression parseNext;
+    auto begin = token;
+    auto e = parseNext();
+    while (token.kind == T.AndLogical)
+    {
+      auto tok = token;
+      nT();
+      e = new AndAndExpression(e, parseNext(), tok);
+      set(e, begin);
+    }
+    return e;
+  }
+
+  Expression parseAsmOrExpression()
+  {
+    alias parseAsmXorExpression parseNext;
+    auto begin = token;
+    auto e = parseNext();
+    while (token.kind == T.OrBinary)
+    {
+      auto tok = token;
+      nT();
+      e = new OrExpression(e, parseNext(), tok);
+      set(e, begin);
+    }
+    return e;
+  }
+
+  Expression parseAsmXorExpression()
+  {
+    alias parseAsmAndExpression parseNext;
+    auto begin = token;
+    auto e = parseNext();
+    while (token.kind == T.Xor)
+    {
+      auto tok = token;
+      nT();
+      e = new XorExpression(e, parseNext(), tok);
+      set(e, begin);
+    }
+    return e;
+  }
+
+  Expression parseAsmAndExpression()
+  {
+    alias parseAsmCmpExpression parseNext;
+    auto begin = token;
+    auto e = parseNext();
+    while (token.kind == T.AndBinary)
+    {
+      auto tok = token;
+      nT();
+      e = new AndExpression(e, parseNext(), tok);
+      set(e, begin);
+    }
+    return e;
+  }
+
+  Expression parseAsmCmpExpression()
+  {
+    alias parseAsmShiftExpression parseNext;
+    auto begin = token;
+    auto e = parseNext();
+
+    auto operator = token;
+    switch (operator.kind)
+    {
+    case T.Equal, T.NotEqual:
+      nT();
+      e = new EqualExpression(e, parseNext(), operator);
+      break;
+    case T.LessEqual, T.Less, T.GreaterEqual, T.Greater:
+      nT();
+      e = new RelExpression(e, parseNext(), operator);
+      break;
+    default:
+      return e;
+    }
+    set(e, begin);
+    return e;
+  }
+
+  Expression parseAsmShiftExpression()
+  {
+    alias parseAsmAddExpression parseNext;
+    auto begin = token;
+    auto e = parseNext();
+    while (1)
+    {
+      auto operator = token;
+      switch (operator.kind)
+      {
+      case T.LShift:  nT(); e = new LShiftExpression(e, parseNext(), operator); break;
+      case T.RShift:  nT(); e = new RShiftExpression(e, parseNext(), operator); break;
+      case T.URShift: nT(); e = new URShiftExpression(e, parseNext(), operator); break;
+      default:
+        return e;
+      }
+      set(e, begin);
+    }
+    assert(0);
+  }
+
+  Expression parseAsmAddExpression()
+  {
+    alias parseAsmMulExpression parseNext;
+    auto begin = token;
+    auto e = parseNext();
+    while (1)
+    {
+      auto operator = token;
+      switch (operator.kind)
+      {
+      case T.Plus:  nT(); e = new PlusExpression(e, parseNext(), operator); break;
+      case T.Minus: nT(); e = new MinusExpression(e, parseNext(), operator); break;
+      // Not allowed in asm
+      //case T.Tilde: nT(); e = new CatExpression(e, parseNext(), operator); break;
+      default:
+        return e;
+      }
+      set(e, begin);
+    }
+    assert(0);
+  }
+
+  Expression parseAsmMulExpression()
+  {
+    alias parseAsmPostExpression parseNext;
+    auto begin = token;
+    auto e = parseNext();
+    while (1)
+    {
+      auto operator = token;
+      switch (operator.kind)
+      {
+      case T.Mul: nT(); e = new MulExpression(e, parseNext(), operator); break;
+      case T.Div: nT(); e = new DivExpression(e, parseNext(), operator); break;
+      case T.Mod: nT(); e = new ModExpression(e, parseNext(), operator); break;
+      default:
+        return e;
+      }
+      set(e, begin);
+    }
+    assert(0);
+  }
+
+  Expression parseAsmPostExpression()
+  {
+    auto begin = token;
+    auto e = parseAsmUnaryExpression();
+    while (consumed(T.LBracket))
+    {
+      e = new AsmPostBracketExpression(e, parseAsmExpression());
+      require(T.RBracket);
+      set(e, begin);
+    }
+    return e;
+  }
+
+  Expression parseAsmUnaryExpression()
+  {
+    auto begin = token;
+    Expression e;
+    switch (token.kind)
+    {
+    case T.Byte,  T.Short,  T.Int,
+         T.Float, T.Double, T.Real:
+      goto LAsmTypePrefix;
+    case T.Identifier:
+      switch (token.ident.idKind)
+      {
+      case IDK.near, IDK.far,/* "byte",  "short",  "int",*/
+           IDK.word, IDK.dword, IDK.qword/*, "float", "double", "real"*/:
+      LAsmTypePrefix:
+        nT();
+        if (token.kind == T.Identifier && token.ident is Ident.ptr)
+          skip(T.Identifier);
+        else
+          error(MID.ExpectedButFound, "ptr", token.srcText);
+        e = new AsmTypeExpression(parseAsmExpression());
+        break;
+      case IDK.offset:
+        nT();
+        e = new AsmOffsetExpression(parseAsmExpression());
+        break;
+      case IDK.seg:
+        nT();
+        e = new AsmSegExpression(parseAsmExpression());
+        break;
+      default:
+        goto LparseAsmPrimaryExpression;
+      }
+      break;
+    case T.Minus:
+    case T.Plus:
+      nT();
+      e = new SignExpression(parseAsmUnaryExpression());
+      break;
+    case T.Not:
+      nT();
+      e = new NotExpression(parseAsmUnaryExpression());
+      break;
+    case T.Tilde:
+      nT();
+      e = new CompExpression(parseAsmUnaryExpression());
+      break;
+    case T.Dot:
+      nT();
+      e = new ModuleScopeExpression(parseIdentifierExpression());
+      while (consumed(TOK.Dot))
+      {
+        e = new DotExpression(e, parseIdentifierExpression());
+        set(e, begin);
+      }
+      break;
+    default:
+    LparseAsmPrimaryExpression:
+      e = parseAsmPrimaryExpression();
+      return e;
+    }
+    set(e, begin);
+    return e;
+  }
+
+  Expression parseAsmPrimaryExpression()
+  {
+    auto begin = token;
+    Expression e;
+    switch (token.kind)
+    {
+    case T.Int32, T.Int64, T.Uint32, T.Uint64:
+      e = new IntExpression(token);
+      nT();
+      break;
+    case T.Float32, T.Float64, T.Float80,
+         T.Imaginary32, T.Imaginary64, T.Imaginary80:
+      e = new RealExpression(token);
+      nT();
+      break;
+    case T.Dollar:
+      e = new DollarExpression();
+      nT();
+      break;
+    case T.LBracket:
+      // [ AsmExpression ]
+      nT();
+      e = parseAsmExpression();
+      require(T.RBracket);
+      e = new AsmBracketExpression(e);
+      break;
+    case T.Identifier:
+      auto register = token.ident;
+      switch (register.idKind)
+      {
+      // __LOCAL_SIZE
+      case IDK.__LOCAL_SIZE:
+        nT();
+        e = new AsmLocalSizeExpression();
+        break;
+      // Register
+      case IDK.ST:
+        nT();
+        // (1) - (7)
+        int number = -1;
+        if (consumed(T.LParen))
+        {
+          if (token.kind == T.Int32)
+            (number = token.int_), skip(T.Int32);
+          else
+            expected(T.Int32);
+          require(T.RParen);
+        }
+        e = new AsmRegisterExpression(register, number);
+        break;
+      case IDK.FS:
+        nT();
+        // TODO: is the colon-number part optional?
+        int number = -1;
+        if (consumed(T.Colon))
+        {
+          // :0, :4, :8
+          if (token.kind == T.Int32)
+            (number = token.int_), skip(T.Int32);
+          if (number != 0 && number != 4 && number != 8)
+            error(MID.ExpectedButFound, "0, 4 or 8", token.srcText);
+        }
+        e = new AsmRegisterExpression(register, number);
+        break;
+      case IDK.AL, IDK.AH, IDK.AX, IDK.EAX,
+           IDK.BL, IDK.BH, IDK.BX, IDK.EBX,
+           IDK.CL, IDK.CH, IDK.CX, IDK.ECX,
+           IDK.DL, IDK.DH, IDK.DX, IDK.EDX,
+           IDK.BP, IDK.EBP, IDK.SP, IDK.ESP,
+           IDK.DI, IDK.EDI, IDK.SI, IDK.ESI,
+           IDK.ES, IDK.CS, IDK.SS, IDK.DS, IDK.GS,
+           IDK.CR0, IDK.CR2, IDK.CR3, IDK.CR4,
+           IDK.DR0, IDK.DR1, IDK.DR2, IDK.DR3, IDK.DR6, IDK.DR7,
+           IDK.TR3, IDK.TR4, IDK.TR5, IDK.TR6, IDK.TR7,
+           IDK.MM0, IDK.MM1, IDK.MM2, IDK.MM3,
+           IDK.MM4, IDK.MM5, IDK.MM6, IDK.MM7,
+           IDK.XMM0, IDK.XMM1, IDK.XMM2, IDK.XMM3,
+           IDK.XMM4, IDK.XMM5, IDK.XMM6, IDK.XMM7:
+        nT();
+        e = new AsmRegisterExpression(register);
+        break;
+      default:
+        e = parseIdentifierExpression();
+        while (consumed(TOK.Dot))
+        {
+          e = new DotExpression(e, parseIdentifierExpression());
+          set(e, begin);
+        }
+      } // end of switch
+      break;
+    default:
+      error(MID.ExpectedButFound, "Expression", token.srcText);
+      e = new IllegalExpression();
+      if (!trying)
+      { // Insert a dummy token and don't consume current one.
+        begin = lexer.insertEmptyTokenBefore(token);
+        this.prevToken = begin;
+      }
+    }
+    set(e, begin);
+    return e;
+  }
+
+  /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  |                        Expression parsing methods                         |
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
+
+  /// Parses an Expression.
+  Expression parseExpression()
+  {
+    alias parseAssignExpression parseNext;
+    auto begin = token;
+    auto e = parseNext();
+    while (token.kind == T.Comma)
+    {
+      auto comma = token;
+      nT();
+      e = new CommaExpression(e, parseNext(), comma);
+      set(e, begin);
+    }
+    return e;
+  }
+
+  Expression parseAssignExpression()
+  {
+    alias parseAssignExpression parseNext;
+    auto begin = token;
+    auto e = parseCondExpression();
+    switch (token.kind)
+    {
+    case T.Assign:
+      nT(); e = new AssignExpression(e, parseNext()); break;
+    case T.LShiftAssign:
+      nT(); e = new LShiftAssignExpression(e, parseNext()); break;
+    case T.RShiftAssign:
+      nT(); e = new RShiftAssignExpression(e, parseNext()); break;
+    case T.URShiftAssign:
+      nT(); e = new URShiftAssignExpression(e, parseNext()); break;
+    case T.OrAssign:
+      nT(); e = new OrAssignExpression(e, parseNext()); break;
+    case T.AndAssign:
+      nT(); e = new AndAssignExpression(e, parseNext()); break;
+    case T.PlusAssign:
+      nT(); e = new PlusAssignExpression(e, parseNext()); break;
+    case T.MinusAssign:
+      nT(); e = new MinusAssignExpression(e, parseNext()); break;
+    case T.DivAssign:
+      nT(); e = new DivAssignExpression(e, parseNext()); break;
+    case T.MulAssign:
+      nT(); e = new MulAssignExpression(e, parseNext()); break;
+    case T.ModAssign:
+      nT(); e = new ModAssignExpression(e, parseNext()); break;
+    case T.XorAssign:
+      nT(); e = new XorAssignExpression(e, parseNext()); break;
+    case T.CatAssign:
+      nT(); e = new CatAssignExpression(e, parseNext()); break;
+    default:
+      return e;
+    }
+    set(e, begin);
+    return e;
+  }
+
+  Expression parseCondExpression()
+  {
+    auto begin = token;
+    auto e = parseOrOrExpression();
+    if (token.kind == T.Question)
+    {
+      auto tok = token;
+      nT();
+      auto iftrue = parseExpression();
+      require(T.Colon);
+      auto iffalse = parseCondExpression();
+      e = new CondExpression(e, iftrue, iffalse, tok);
+      set(e, begin);
+    }
+    return e;
+  }
+
+  Expression parseOrOrExpression()
+  {
+    alias parseAndAndExpression parseNext;
+    auto begin = token;
+    auto e = parseNext();
+    while (token.kind == T.OrLogical)
+    {
+      auto tok = token;
+      nT();
+      e = new OrOrExpression(e, parseNext(), tok);
+      set(e, begin);
+    }
+    return e;
+  }
+
+  Expression parseAndAndExpression()
+  {
+    alias parseOrExpression parseNext;
+    auto begin = token;
+    auto e = parseNext();
+    while (token.kind == T.AndLogical)
+    {
+      auto tok = token;
+      nT();
+      e = new AndAndExpression(e, parseNext(), tok);
+      set(e, begin);
+    }
+    return e;
+  }
+
+  Expression parseOrExpression()
+  {
+    alias parseXorExpression parseNext;
+    auto begin = token;
+    auto e = parseNext();
+    while (token.kind == T.OrBinary)
+    {
+      auto tok = token;
+      nT();
+      e = new OrExpression(e, parseNext(), tok);
+      set(e, begin);
+    }
+    return e;
+  }
+
+  Expression parseXorExpression()
+  {
+    alias parseAndExpression parseNext;
+    auto begin = token;
+    auto e = parseNext();
+    while (token.kind == T.Xor)
+    {
+      auto tok = token;
+      nT();
+      e = new XorExpression(e, parseNext(), tok);
+      set(e, begin);
+    }
+    return e;
+  }
+
+  Expression parseAndExpression()
+  {
+    alias parseCmpExpression parseNext;
+    auto begin = token;
+    auto e = parseNext();
+    while (token.kind == T.AndBinary)
+    {
+      auto tok = token;
+      nT();
+      e = new AndExpression(e, parseNext(), tok);
+      set(e, begin);
+    }
+    return e;
+  }
+
+  Expression parseCmpExpression()
+  {
+    alias parseShiftExpression parseNext;
+    auto begin = token;
+    auto e = parseShiftExpression();
+
+    auto operator = token;
+    switch (operator.kind)
+    {
+    case T.Equal, T.NotEqual:
+      nT();
+      e = new EqualExpression(e, parseNext(), operator);
+      break;
+    case T.Not:
+      if (peekNext() != T.Is)
+        break;
+      nT();
+      // fall through
+    case T.Is:
+      nT();
+      e = new IdentityExpression(e, parseNext(), operator);
+      break;
+    case T.LessEqual, T.Less, T.GreaterEqual, T.Greater,
+         T.Unordered, T.UorE, T.UorG, T.UorGorE,
+         T.UorL, T.UorLorE, T.LorEorG, T.LorG:
+      nT();
+      e = new RelExpression(e, parseNext(), operator);
+      break;
+    case T.In:
+      nT();
+      e = new InExpression(e, parseNext(), operator);
+      break;
+    default:
+      return e;
+    }
+    set(e, begin);
+    return e;
+  }
+
+  Expression parseShiftExpression()
+  {
+    alias parseAddExpression parseNext;
+    auto begin = token;
+    auto e = parseNext();
+    while (1)
+    {
+      auto operator = token;
+      switch (operator.kind)
+      {
+      case T.LShift:  nT(); e = new LShiftExpression(e, parseNext(), operator); break;
+      case T.RShift:  nT(); e = new RShiftExpression(e, parseNext(), operator); break;
+      case T.URShift: nT(); e = new URShiftExpression(e, parseNext(), operator); break;
+      default:
+        return e;
+      }
+      set(e, begin);
+    }
+    assert(0);
+  }
+
+  Expression parseAddExpression()
+  {
+    alias parseMulExpression parseNext;
+    auto begin = token;
+    auto e = parseNext();
+    while (1)
+    {
+      auto operator = token;
+      switch (operator.kind)
+      {
+      case T.Plus:  nT(); e = new PlusExpression(e, parseNext(), operator); break;
+      case T.Minus: nT(); e = new MinusExpression(e, parseNext(), operator); break;
+      case T.Tilde: nT(); e = new CatExpression(e, parseNext(), operator); break;
+      default:
+        return e;
+      }
+      set(e, begin);
+    }
+    assert(0);
+  }
+
+  Expression parseMulExpression()
+  {
+    alias parsePostExpression parseNext;
+    auto begin = token;
+    auto e = parseNext();
+    while (1)
+    {
+      auto operator = token;
+      switch (operator.kind)
+      {
+      case T.Mul: nT(); e = new MulExpression(e, parseNext(), operator); break;
+      case T.Div: nT(); e = new DivExpression(e, parseNext(), operator); break;
+      case T.Mod: nT(); e = new ModExpression(e, parseNext(), operator); break;
+      default:
+        return e;
+      }
+      set(e, begin);
+    }
+    assert(0);
+  }
+
+  Expression parsePostExpression()
+  {
+    auto begin = token;
+    auto e = parseUnaryExpression();
+    while (1)
+    {
+      while (consumed(T.Dot))
+      {
+        e = new DotExpression(e, parseNewOrIdentifierExpression());
+        set(e, begin);
+      }
+
+      switch (token.kind)
+      {
+      case T.PlusPlus:
+        e = new PostIncrExpression(e);
+        break;
+      case T.MinusMinus:
+        e = new PostDecrExpression(e);
+        break;
+      case T.LParen:
+        e = new CallExpression(e, parseArguments());
+        goto Lset;
+      case T.LBracket:
+        // parse Slice- and IndexExpression
+        nT();
+        // [] is a SliceExpression
+        if (token.kind == T.RBracket)
+        {
+          e = new SliceExpression(e, null, null);
+          break;
+        }
+
+        Expression[] es = [parseAssignExpression()];
+
+        // [ AssignExpression .. AssignExpression ]
+        if (consumed(T.Slice))
+        {
+          e = new SliceExpression(e, es[0], parseAssignExpression());
+          require(T.RBracket);
+          goto Lset;
+        }
+
+        // [ ExpressionList ]
+        if (consumed(T.Comma))
+           es ~= parseExpressionList();
+        require(T.RBracket);
+
+        e = new IndexExpression(e, es);
+        goto Lset;
+      default:
+        return e;
+      }
+      nT();
+    Lset: // Jumped here to skip nT().
+      set(e, begin);
+    }
+    assert(0);
+  }
+
+  Expression parseUnaryExpression()
+  {
+    auto begin = token;
+    Expression e;
+    switch (token.kind)
+    {
+    case T.AndBinary:
+      nT();
+      e = new AddressExpression(parseUnaryExpression());
+      break;
+    case T.PlusPlus:
+      nT();
+      e = new PreIncrExpression(parseUnaryExpression());
+      break;
+    case T.MinusMinus:
+      nT();
+      e = new PreDecrExpression(parseUnaryExpression());
+      break;
+    case T.Mul:
+      nT();
+      e = new DerefExpression(parseUnaryExpression());
+      break;
+    case T.Minus:
+    case T.Plus:
+      nT();
+      e = new SignExpression(parseUnaryExpression());
+      break;
+    case T.Not:
+      nT();
+      e = new NotExpression(parseUnaryExpression());
+      break;
+    case T.Tilde:
+      nT();
+      e = new CompExpression(parseUnaryExpression());
+      break;
+    case T.New:
+      e = parseNewExpression();
+      return e;
+    case T.Delete:
+      nT();
+      e = new DeleteExpression(parseUnaryExpression());
+      break;
+    case T.Cast:
+      requireNext(T.LParen);
+      Type type;
+      switch (token.kind)
+      {
+      version(D2)
+      {
+      auto begin2 = token;
+      case T.Const:
+        type = new ConstType(null);
+        goto case_break;
+      case T.Invariant:
+        type = new InvariantType(null);
+      case_break:
+        nT();
+        set(type, begin2);
+        break;
+      }
+      default:
+       type = parseType();
+      }
+      require(T.RParen);
+      e = new CastExpression(parseUnaryExpression(), type);
+      break;
+    case T.LParen:
+      // ( Type ) . Identifier
+      Type parseType_()
+      {
+        skip(T.LParen);
+        auto type = parseType();
+        require(T.RParen);
+        require(T.Dot);
+        return type;
+      }
+      bool success;
+      auto type = try_(&parseType_, success);
+      if (success)
+      {
+        auto ident = requireIdentifier(MSG.ExpectedIdAfterTypeDot);
+        e = new TypeDotIdExpression(type, ident);
+        break;
+      }
+      goto default;
+    case T.Dot:
+      nT();
+      e = new ModuleScopeExpression(parseIdentifierExpression());
+      break;
+    default:
+      e = parsePrimaryExpression();
+      return e;
+    }
+    assert(e !is null);
+    set(e, begin);
+    return e;
+  }
+
+  /// $(PRE
+  /// IdentifierExpression :=
+  ///         Identifier
+  ///         TemplateInstance
+  /// TemplateInstance :=
+  ///         Identifier !( TemplateArguments )
+  /// )
+  Expression parseIdentifierExpression()
+  {
+    auto begin = token;
+    auto ident = requireIdentifier(MSG.ExpectedAnIdentifier);
+    Expression e;
+    // Peek for '(' to avoid matching: id !is id
+    if (token.kind == T.Not && peekNext() == T.LParen)
+    { // Identifier !( TemplateArguments )
+      skip(T.Not);
+      auto tparams = parseTemplateArguments();
+      e = new TemplateInstanceExpression(ident, tparams);
+    }
+    else // Identifier
+      e = new IdentifierExpression(ident);
+    return set(e, begin);
+  }
+
+  Expression parseNewOrIdentifierExpression()
+  {
+    return token.kind == T.New ? parseNewExpression() :  parseIdentifierExpression();
+  }
+
+  Expression parsePrimaryExpression()
+  {
+    auto begin = token;
+    Expression e;
+    switch (token.kind)
+    {
+    case T.Identifier:
+      e = parseIdentifierExpression();
+      return e;
+    case T.Typeof:
+      e = new TypeofExpression(parseTypeofType());
+      break;
+    case T.This:
+      nT();
+      e = new ThisExpression();
+      break;
+    case T.Super:
+      nT();
+      e = new SuperExpression();
+      break;
+    case T.Null:
+      nT();
+      e = new NullExpression();
+      break;
+    case T.True, T.False:
+      nT();
+      e = new BoolExpression();
+      break;
+    case T.Dollar:
+      nT();
+      e = new DollarExpression();
+      break;
+    case T.Int32, T.Int64, T.Uint32, T.Uint64:
+      e = new IntExpression(token);
+      nT();
+      break;
+    case T.Float32, T.Float64, T.Float80,
+         T.Imaginary32, T.Imaginary64, T.Imaginary80:
+      e = new RealExpression(token);
+      nT();
+      break;
+    case T.CharLiteral:
+      e = new CharExpression(token.dchar_);
+      nT();
+      break;
+    case T.String:
+      char[] str = token.str;
+      char postfix = token.pf;
+      nT();
+      while (token.kind == T.String)
+      {
+        /+if (postfix == 0)
+            postfix = token.pf;
+        else+/
+        if (token.pf && token.pf != postfix)
+          error(token, MSG.StringPostfixMismatch);
+        str.length = str.length - 1; // Exclude '\0'.
+        str ~= token.str;
+        nT();
+      }
+      switch (postfix)
+      {
+      case 'w':
+        if (checkString(begin, str))
+          goto default;
+        e = new StringExpression(dil.Unicode.toUTF16(str)); break;
+      case 'd':
+        if (checkString(begin, str))
+          goto default;
+        e = new StringExpression(dil.Unicode.toUTF32(str)); break;
+      case 'c':
+      default:
+        // No checking done to allow for binary data.
+        e = new StringExpression(str); break;
+      }
+      break;
+    case T.LBracket:
+      Expression[] values;
+
+      nT();
+      if (!consumed(T.RBracket))
+      {
+        e = parseAssignExpression();
+        if (consumed(T.Colon))
+          goto LparseAssocArray;
+        if (consumed(T.Comma))
+          values = [e] ~ parseExpressionList();
+        require(T.RBracket);
+      }
+
+      e = new ArrayLiteralExpression(values);
+      break;
+
+    LparseAssocArray:
+      Expression[] keys = [e];
+
+      goto LenterLoop;
+      do
+      {
+        keys ~= parseAssignExpression();
+        require(T.Colon);
+      LenterLoop:
+        values ~= parseAssignExpression();
+      } while (consumed(T.Comma))
+      require(T.RBracket);
+      e = new AArrayLiteralExpression(keys, values);
+      break;
+    case T.LBrace:
+      // DelegateLiteral := { Statements }
+      auto funcBody = parseFunctionBody();
+      e = new FunctionLiteralExpression(funcBody);
+      break;
+    case T.Function, T.Delegate:
+      // FunctionLiteral := ("function"|"delegate") Type? "(" ArgumentList ")" FunctionBody
+      nT(); // Skip function or delegate keyword.
+      Type returnType;
+      Parameters parameters;
+      if (token.kind != T.LBrace)
+      {
+        if (token.kind != T.LParen) // Optional return type
+          returnType = parseType();
+        parameters = parseParameterList();
+      }
+      auto funcBody = parseFunctionBody();
+      e = new FunctionLiteralExpression(returnType, parameters, funcBody);
+      break;
+    case T.Assert:
+      Expression msg;
+      requireNext(T.LParen);
+      e = parseAssignExpression();
+      if (consumed(T.Comma))
+        msg = parseAssignExpression();
+      require(T.RParen);
+      e = new AssertExpression(e, msg);
+      break;
+    case T.Mixin:
+      requireNext(T.LParen);
+      e = parseAssignExpression();
+      require(T.RParen);
+      e = new MixinExpression(e);
+      break;
+    case T.Import:
+      requireNext(T.LParen);
+      e = parseAssignExpression();
+      require(T.RParen);
+      e = new ImportExpression(e);
+      break;
+    case T.Typeid:
+      requireNext(T.LParen);
+      auto type = parseType();
+      require(T.RParen);
+      e = new TypeidExpression(type);
+      break;
+    case T.Is:
+      requireNext(T.LParen);
+
+      Type type, specType;
+      Identifier* ident; // optional Identifier
+      Token* opTok, specTok;
+
+      type = parseDeclarator(ident, true);
+
+      switch (token.kind)
+      {
+      case T.Colon, T.Equal:
+        opTok = token;
+        nT();
+        switch (token.kind)
+        {
+        case T.Typedef,
+             T.Struct,
+             T.Union,
+             T.Class,
+             T.Interface,
+             T.Enum,
+             T.Function,
+             T.Delegate,
+             T.Super,
+             T.Return:
+        case_Const_Invariant:
+          specTok = token;
+          nT();
+          break;
+        case T.Const, T.Invariant:
+          if (peekNext() != T.LParen)
+            goto case_Const_Invariant;
+          // Fall through. It's a type.
+        default:
+          specType = parseType();
+        }
+      default:
+      }
+
+      TemplateParameters tparams;
+    version(D2)
+    {
+      // is ( Type Identifier : TypeSpecialization , TemplateParameterList )
+      // is ( Type Identifier == TypeSpecialization , TemplateParameterList )
+      if (ident && specType && token.kind == T.Comma)
+        tparams = parseTemplateParameterList2();
+    }
+      require(T.RParen);
+      e = new IsExpression(type, ident, opTok, specTok, specType, tparams);
+      break;
+    case T.LParen:
+      if (tokenAfterParenIs(T.LBrace)) // Check for "(...) {"
+      { // ( ParameterList ) FunctionBody
+        auto parameters = parseParameterList();
+        auto funcBody = parseFunctionBody();
+        e = new FunctionLiteralExpression(null, parameters, funcBody);
+      }
+      else
+      { // ( Expression )
+        skip(T.LParen);
+        e = parseExpression();
+        require(T.RParen);
+        e = new ParenExpression(e);
+      }
+      break;
+    version(D2)
+    {
+    case T.Traits:
+      requireNext(T.LParen);
+      auto id = requireIdentifier(MSG.ExpectedAnIdentifier);
+      TemplateArguments args;
+      if (token.kind == T.Comma)
+        args = parseTemplateArguments2();
+      else
+        require(T.RParen);
+      e = new TraitsExpression(id, args);
+      break;
+    }
+    default:
+      if (token.isIntegralType)
+      { // IntegralType . Identifier
+        auto type = new IntegralType(token.kind);
+        nT();
+        set(type, begin);
+        require(T.Dot);
+        auto ident = requireIdentifier(MSG.ExpectedIdAfterTypeDot);
+        e = new TypeDotIdExpression(type, ident);
+      }
+      else if (token.isSpecialToken)
+      {
+        e = new SpecialTokenExpression(token);
+        nT();
+      }
+      else
+      {
+        error(MID.ExpectedButFound, "Expression", token.srcText);
+        e = new IllegalExpression();
+        if (!trying)
+        { // Insert a dummy token and don't consume current one.
+          begin = lexer.insertEmptyTokenBefore(token);
+          this.prevToken = begin;
+        }
+      }
+    }
+    set(e, begin);
+    return e;
+  }
+
+  Expression parseNewExpression(/*Expression e*/)
+  {
+    auto begin = token;
+    skip(T.New);
+
+    Expression[] newArguments;
+    Expression[] ctorArguments;
+
+    if (token.kind == T.LParen)
+      newArguments = parseArguments();
+
+    // NewAnonClassExpression:
+    //         new (ArgumentList)opt class (ArgumentList)opt SuperClassopt InterfaceClassesopt ClassBody
+    if (consumed(T.Class))
+    {
+      if (token.kind == T.LParen)
+        ctorArguments = parseArguments();
+
+      BaseClassType[] bases = token.kind != T.LBrace ? parseBaseClasses(false) : null ;
+
+      auto decls = parseDeclarationDefinitionsBody();
+      return set(new NewAnonClassExpression(/*e, */newArguments, bases, ctorArguments, decls), begin);
+    }
+
+    // NewExpression:
+    //         NewArguments Type [ AssignExpression ]
+    //         NewArguments Type ( ArgumentList )
+    //         NewArguments Type
+    auto type = parseType();
+
+    if (token.kind == T.LParen)
+      ctorArguments = parseArguments();
+
+    return set(new NewExpression(/*e, */newArguments, type, ctorArguments), begin);
+  }
+
+  /// Parses a Type.
+  Type parseType()
+  {
+    return parseBasicType2(parseBasicType());
+  }
+
+  Type parseIdentifierType()
+  {
+    auto begin = token;
+    auto ident = requireIdentifier(MSG.ExpectedAnIdentifier);
+    Type t;
+    if (consumed(T.Not)) // Identifier !( TemplateArguments )
+      t = new TemplateInstanceType(ident, parseTemplateArguments());
+    else // Identifier
+      t = new IdentifierType(ident);
+    return set(t, begin);
+  }
+
+  Type parseQualifiedType()
+  {
+    auto begin = token;
+    Type type;
+    if (token.kind == T.Dot)
+      type = set(new ModuleScopeType(), begin, begin);
+    else if (token.kind == T.Typeof)
+      type = parseTypeofType();
+    else
+      type = parseIdentifierType();
+
+    while (consumed(T.Dot))
+      type = set(new QualifiedType(type, parseIdentifierType()), begin);
+    return type;
+  }
+
+  Type parseBasicType()
+  {
+    auto begin = token;
+    Type t;
+
+    if (token.isIntegralType)
+    {
+      t = new IntegralType(token.kind);
+      nT();
+    }
+    else
+    switch (token.kind)
+    {
+    case T.Identifier, T.Typeof, T.Dot:
+      t = parseQualifiedType();
+      return t;
+    version(D2)
+    {
+    case T.Const:
+      // const ( Type )
+      requireNext(T.LParen);
+      t = parseType();
+      require(T.RParen);
+      t = new ConstType(t);
+      break;
+    case T.Invariant:
+      // invariant ( Type )
+      requireNext(T.LParen);
+      t = parseType();
+      require(T.RParen);
+      t = new InvariantType(t);
+      break;
+    } // version(D2)
+    default:
+      error(MID.ExpectedButFound, "BasicType", token.srcText);
+      t = new IllegalType();
+      nT();
+    }
+    return set(t, begin);
+  }
+
+  Type parseBasicType2(Type t)
+  {
+    while (1)
+    {
+      auto begin = token;
+      switch (token.kind)
+      {
+      case T.Mul:
+        t = new PointerType(t);
+        nT();
+        break;
+      case T.LBracket:
+        t = parseArrayType(t);
+        continue;
+      case T.Function, T.Delegate:
+        TOK tok = token.kind;
+        nT();
+        auto parameters = parseParameterList();
+        if (tok == T.Function)
+          t = new FunctionType(t, parameters);
+        else
+          t = new DelegateType(t, parameters);
+        break;
+      default:
+        return t;
+      }
+      set(t, begin);
+    }
+    assert(0);
+  }
+
+  /// Returns true if the token after the closing parenthesis
+  /// is of kind tok.
+  bool tokenAfterParenIs(TOK tok)
+  {
+    // We count nested parentheses tokens because template types
+    // may appear inside parameter lists. E.g.: (int x, Foo!(int) y)
+    assert(token.kind == T.LParen);
+    Token* next = token;
+    uint level = 1;
+  Loop:
+    while (1)
+    {
+      lexer.peek(next);
+      switch (next.kind)
+      {
+      case T.RParen:
+        if (--level == 0)
+        { // Last, closing parentheses found.
+          do
+            lexer.peek(next);
+          while (next.isWhitespace)
+          break Loop;
+        }
+        break;
+      case T.LParen:
+        ++level;
+        break;
+      case T.EOF:
+        break Loop;
+      default:
+      }
+    }
+    return next.kind == tok;
+  }
+
+  /// Parse the array types after the declarator (C-style.) E.g.: int a[]
+  Type parseDeclaratorSuffix(Type lhsType)
+  {
+    // The Type chain should be as follows:
+    // int[3]* Identifier [][32]
+    //   <- <-             ->  -.
+    //       ^-----------------´
+    // Resulting chain: [][32]*[3]int
+    Type parseNext() // Nested function required to accomplish this.
+    {
+      if (token.kind != T.LBracket)
+        return lhsType; // Break recursion; return Type on the left hand side of the Identifier.
+
+      auto begin = token;
+      Type t;
+      skip(T.LBracket);
+      if (consumed(T.RBracket))
+        t = new ArrayType(parseNext()); // [ ]
+      else
+      {
+        bool success;
+        Type parseAAType()
+        {
+          auto type = parseType();
+          require(T.RBracket);
+          return type;
+        }
+        auto assocType = try_(&parseAAType, success);
+        if (success)
+          t = new ArrayType(parseNext(), assocType); // [ Type ]
+        else
+        {
+          Expression e = parseExpression(), e2;
+          if (consumed(T.Slice))
+            e2 = parseExpression();
+          require(T.RBracket);
+          t = new ArrayType(parseNext(), e, e2); // [ Expression .. Expression ]
+        }
+      }
+      set(t, begin);
+      return t;
+    }
+    return parseNext();
+  }
+
+  Type parseArrayType(Type t)
+  {
+    auto begin = token;
+    skip(T.LBracket);
+    if (consumed(T.RBracket))
+      t = new ArrayType(t);
+    else
+    {
+      bool success;
+      Type parseAAType()
+      {
+        auto type = parseType();
+        require(T.RBracket);
+        return type;
+      }
+      auto assocType = try_(&parseAAType, success);
+      if (success)
+        t = new ArrayType(t, assocType);
+      else
+      {
+        Expression e = parseExpression(), e2;
+        if (consumed(T.Slice))
+          e2 = parseExpression();
+        require(T.RBracket);
+        t = new ArrayType(t, e, e2);
+      }
+    }
+    set(t, begin);
+    return t;
+  }
+
+  Type parseCFunctionPointerType(Type type, ref Identifier* ident, bool optionalParamList)
+  {
+    assert(type !is null);
+    auto begin = token;
+    skip(T.LParen);
+
+    type = parseBasicType2(type);
+    if (token.kind == T.LParen)
+    { // Can be nested.
+      type = parseCFunctionPointerType(type, ident, true);
+    }
+    else if (token.kind == T.Identifier)
+    { // The identifier of the function pointer and the declaration.
+      ident = token.ident;
+      nT();
+      type = parseDeclaratorSuffix(type);
+    }
+    require(T.RParen);
+
+    Parameters params;
+    if (optionalParamList)
+      params = token.kind == T.LParen ? parseParameterList() : null;
+    else
+      params = parseParameterList();
+
+    type = new CFuncPointerType(type, params);
+    return set(type, begin);
+  }
+
+  Type parseDeclarator(ref Identifier* ident, bool identOptional = false)
+  {
+    auto t = parseType();
+
+    if (token.kind == T.LParen)
+      t = parseCFunctionPointerType(t, ident, true);
+    else if (token.kind == T.Identifier)
+    {
+      ident = token.ident;
+      nT();
+      t = parseDeclaratorSuffix(t);
+    }
+
+    if (ident is null && !identOptional)
+      error(token, MSG.ExpectedDeclaratorIdentifier, token.srcText);
+
+    return t;
+  }
+
+  /// Parses a list of AssignExpressions.
+  /// $(PRE
+  /// ExpressionList :=
+  ///   AssignExpression
+  ///   AssignExpression , ExpressionList
+  /// )
+  Expression[] parseExpressionList()
+  {
+    Expression[] expressions;
+    do
+      expressions ~= parseAssignExpression();
+    while(consumed(T.Comma))
+    return expressions;
+  }
+
+  /// Parses a list of Arguments.
+  /// $(PRE
+  /// Arguments :=
+  ///   ( )
+  ///   ( ExpressionList )
+  /// )
+  Expression[] parseArguments()
+  {
+    skip(T.LParen);
+    Expression[] args;
+    if (token.kind != T.RParen)
+      args = parseExpressionList();
+    require(T.RParen);
+    return args;
+  }
+
+  /// Parses a ParameterList.
+  Parameters parseParameterList()
+  out(params)
+  {
+    if (params.length > 1)
+      foreach (param; params.items[0..$-1])
+      {
+        if (param.isVariadic())
+          assert(0, "variadic arguments can only appear at the end of the parameter list.");
+      }
+  }
+  body
+  {
+    auto begin = token;
+    require(T.LParen);
+
+    auto params = new Parameters();
+
+    if (consumed(T.RParen))
+      return set(params, begin);
+
+    do
+    {
+      auto paramBegin = token;
+      StorageClass stc, stc_;
+      Type type;
+      Identifier* ident;
+      Expression defValue;
+
+      void pushParameter()
+      {
+        params ~= set(new Parameter(stc, type, ident, defValue), paramBegin);
+      }
+
+      if (consumed(T.Ellipses))
+      {
+        stc = StorageClass.Variadic;
+        pushParameter(); // type, ident and defValue will be null.
+        break;
+      }
+
+      while (1)
+      { // Parse storage classes.
+        switch (token.kind)
+        {
+      version(D2)
+      {
+        case T.Invariant: // D2.0
+          if (peekNext() == T.LParen)
+            break;
+          stc_ = StorageClass.Invariant;
+          goto Lcommon;
+        case T.Const: // D2.0
+          if (peekNext() == T.LParen)
+            break;
+          stc_ = StorageClass.Const;
+          goto Lcommon;
+        case T.Final: // D2.0
+          stc_ = StorageClass.Final;
+          goto Lcommon;
+        case T.Scope: // D2.0
+          stc_ = StorageClass.Scope;
+          goto Lcommon;
+        case T.Static: // D2.0
+          stc_ = StorageClass.Static;
+          goto Lcommon;
+      }
+        case T.In:
+          stc_ = StorageClass.In;
+          goto Lcommon;
+        case T.Out:
+          stc_ = StorageClass.Out;
+          goto Lcommon;
+        case T.Inout, T.Ref:
+          stc_ = StorageClass.Ref;
+          goto Lcommon;
+        case T.Lazy:
+          stc_ = StorageClass.Lazy;
+          goto Lcommon;
+        Lcommon:
+          // Check for redundancy.
+          if (stc & stc_)
+            error(MID.RedundantStorageClass, token.srcText);
+          else
+            stc |= stc_;
+          nT();
+        version(D2)
+          continue;
+        else
+          break; // In D1.0 the grammar only allows one storage class.
+        default:
+        }
+        break; // Break out of inner loop.
+      }
+      type = parseDeclarator(ident, true);
+
+      if (consumed(T.Assign))
+        defValue = parseAssignExpression();
+
+      if (consumed(T.Ellipses))
+      {
+        stc |= StorageClass.Variadic;
+        pushParameter();
+        break;
+      }
+      pushParameter();
+
+    } while (consumed(T.Comma))
+    require(T.RParen);
+    return set(params, begin);
+  }
+
+  TemplateArguments parseTemplateArguments()
+  {
+    TemplateArguments targs;
+    require(T.LParen);
+    if (token.kind != T.RParen)
+      targs = parseTemplateArguments_();
+    require(T.RParen);
+    return targs;
+  }
+
+version(D2)
+{
+  TemplateArguments parseTemplateArguments2()
+  {
+    skip(T.Comma);
+    TemplateArguments targs;
+    if (token.kind != T.RParen)
+      targs = parseTemplateArguments_();
+    else
+      error(token, MSG.ExpectedTypeOrExpression);
+    require(T.RParen);
+    return targs;
+  }
+} // version(D2)
+
+  TemplateArguments parseTemplateArguments_()
+  {
+    auto begin = token;
+    auto targs = new TemplateArguments;
+    do
+    {
+      Type parseType_()
+      {
+        auto type = parseType();
+        if (token.kind == T.Comma || token.kind == T.RParen)
+          return type;
+        errorCount++; // Cause try_() to fail.
+        return null;
+      }
+      bool success;
+      auto typeArgument = try_(&parseType_, success);
+      if (success)
+        // TemplateArgument:
+        //         Type
+        //         Symbol
+        targs ~= typeArgument;
+      else
+        // TemplateArgument:
+        //         AssignExpression
+        targs ~= parseAssignExpression();
+    } while (consumed(T.Comma))
+    set(targs, begin);
+    return targs;
+  }
+
+  TemplateParameters parseTemplateParameterList()
+  {
+    auto begin = token;
+    auto tparams = new TemplateParameters;
+    require(T.LParen);
+    if (token.kind != T.RParen)
+      parseTemplateParameterList_(tparams);
+    require(T.RParen);
+    return set(tparams, begin);
+  }
+
+version(D2)
+{
+  TemplateParameters parseTemplateParameterList2()
+  {
+    skip(T.Comma);
+    auto begin = token;
+    auto tparams = new TemplateParameters;
+    if (token.kind != T.RParen)
+      parseTemplateParameterList_(tparams);
+    else
+      error(token, MSG.ExpectedTemplateParameters);
+    return set(tparams, begin);
+  }
+} // version(D2)
+
+  /// Parses template parameters.
+  void parseTemplateParameterList_(TemplateParameters tparams)
+  {
+    do
+    {
+      auto paramBegin = token;
+      TemplateParameter tp;
+      Identifier* ident;
+      Type specType, defType;
+
+      void parseSpecAndOrDefaultType()
+      {
+        // : SpecializationType
+        if (consumed(T.Colon))
+          specType = parseType();
+        // = DefaultType
+        if (consumed(T.Assign))
+          defType = parseType();
+      }
+
+      switch (token.kind)
+      {
+      case T.Alias:
+        // TemplateAliasParameter:
+        //         alias Identifier
+        skip(T.Alias);
+        ident = requireIdentifier(MSG.ExpectedAliasTemplateParam);
+        parseSpecAndOrDefaultType();
+        tp = new TemplateAliasParameter(ident, specType, defType);
+        break;
+      case T.Identifier:
+        ident = token.ident;
+        switch (peekNext())
+        {
+        case T.Ellipses:
+          // TemplateTupleParameter:
+          //         Identifier ...
+          skip(T.Identifier); skip(T.Ellipses);
+          if (token.kind == T.Comma)
+            error(MID.TemplateTupleParameter);
+          tp = new TemplateTupleParameter(ident);
+          break;
+        case T.Comma, T.RParen, T.Colon, T.Assign:
+          // TemplateTypeParameter:
+          //         Identifier
+          skip(T.Identifier);
+          parseSpecAndOrDefaultType();
+          tp = new TemplateTypeParameter(ident, specType, defType);
+          break;
+        default:
+          // TemplateValueParameter:
+          //         Declarator
+          ident = null;
+          goto LTemplateValueParameter;
+        }
+        break;
+      version(D2)
+      {
+      case T.This:
+        // TemplateThisParameter
+        //         this TemplateTypeParameter
+        skip(T.This);
+        ident = requireIdentifier(MSG.ExpectedNameForThisTempParam);
+        parseSpecAndOrDefaultType();
+        tp = new TemplateThisParameter(ident, specType, defType);
+        break;
+      }
+      default:
+      LTemplateValueParameter:
+        // TemplateValueParameter:
+        //         Declarator
+        Expression specValue, defValue;
+        auto valueType = parseDeclarator(ident);
+        // : SpecializationValue
+        if (consumed(T.Colon))
+          specValue = parseCondExpression();
+        // = DefaultValue
+        if (consumed(T.Assign))
+          defValue = parseCondExpression();
+        tp = new TemplateValueParameter(valueType, ident, specValue, defValue);
+      }
+
+      // Push template parameter.
+      tparams ~= set(tp, paramBegin);
+
+    } while (consumed(T.Comma))
+  }
+
+  alias require expected;
+
+  /// Requires a token of kind tok.
+  void require(TOK tok)
+  {
+    if (token.kind == tok)
+      nT();
+    else
+      error(MID.ExpectedButFound, Token.toString(tok), token.srcText);
+  }
+
+  /// Requires the next token to be of kind tok.
+  void requireNext(TOK tok)
+  {
+    nT();
+    require(tok);
+  }
+
+  /// Optionally parses an identifier.
+  /// Returns: null or the identifier.
+  Identifier* optionalIdentifier()
+  {
+    Identifier* id;
+    if (token.kind == T.Identifier)
+      (id = token.ident), skip(T.Identifier);
+    return id;
+  }
+
+  Identifier* requireIdentifier()
+  {
+    Identifier* id;
+    if (token.kind == T.Identifier)
+      (id = token.ident), skip(T.Identifier);
+    else
+      error(MID.ExpectedButFound, "Identifier", token.srcText);
+    return id;
+  }
+
+  /// Reports an error if the current token is not an identifier.
+  /// Params:
+  ///   errorMsg = the error message to be used.
+  /// Returns: null or the identifier.
+  Identifier* requireIdentifier(char[] errorMsg)
+  {
+    Identifier* id;
+    if (token.kind == T.Identifier)
+      (id = token.ident), skip(T.Identifier);
+    else
+      error(token, errorMsg, token.srcText);
+    return id;
+  }
+
+  /// Reports an error if the current token is not an identifier.
+  /// Params:
+  ///   mid = the error message ID to be used.
+  /// Returns: null or the identifier.
+  Identifier* requireIdentifier(MID mid)
+  {
+    Identifier* id;
+    if (token.kind == T.Identifier)
+      (id = token.ident), skip(T.Identifier);
+    else
+      error(mid, token.srcText);
+    return id;
+  }
+
+  /// Reports an error if the current token is not an identifier.
+  /// Returns: null or the token.
+  Token* requireId()
+  {
+    Token* idtok;
+    if (token.kind == T.Identifier)
+      (idtok = token), skip(T.Identifier);
+    else
+      error(MID.ExpectedButFound, "Identifier", token.srcText);
+    return idtok;
+  }
+
+  Token* requireIdToken(char[] errorMsg)
+  {
+    Token* idtok;
+    if (token.kind == T.Identifier)
+      (idtok = token), skip(T.Identifier);
+    else
+    {
+      error(token, errorMsg, token.srcText);
+      idtok = lexer.insertEmptyTokenBefore(token);
+      this.prevToken = idtok;
+    }
+    return idtok;
+  }
+
+  /// Returns true if the string str has an invalid UTF-8 sequence.
+  bool checkString(Token* begin, string str)
+  {
+    auto utf8Seq = Lexer.findInvalidUTF8Sequence(str);
+    if (utf8Seq.length)
+      error(begin, MSG.InvalidUTF8SequenceInString, utf8Seq);
+    return utf8Seq.length != 0;
+  }
+
+  /// Forwards error parameters.
+  void error(Token* token, char[] formatMsg, ...)
+  {
+    error_(token, formatMsg, _arguments, _argptr);
+  }
+
+  /// ditto
+  void error(MID mid, ...)
+  {
+    error_(this.token, GetMsg(mid), _arguments, _argptr);
+  }
+
+  /// Creates an error report and appends it to a list.
+  /// Params:
+  ///   token = used to get the location of where the error is.
+  ///   formatMsg = the compiler error message.
+  void error_(Token* token, char[] formatMsg, TypeInfo[] _arguments, Arg _argptr)
+  {
+    if (trying)
+    {
+      ++errorCount;
+      return;
+    }
+    auto location = token.getErrorLocation();
+    auto msg = Format(_arguments, _argptr, formatMsg);
+    auto error = new ParserError(location, msg);
+    errors ~= error;
+    if (infoMan !is null)
+      infoMan ~= error;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/semantic/Analysis.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,106 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.semantic.Analysis;
+
+import dil.ast.Node;
+import dil.ast.Expressions;
+import dil.semantic.Scope;
+import dil.lexer.IdTable;
+import dil.Compilation;
+import common;
+
+/// Common semantics for pragma declarations and statements.
+void pragmaSemantic(Scope scop, Token* pragmaLoc,
+                    Identifier* ident,
+                    Expression[] args)
+{
+  if (ident is Ident.msg)
+    pragma_msg(scop, pragmaLoc, args);
+  else if (ident is Ident.lib)
+    pragma_lib(scop, pragmaLoc, args);
+  // else
+  //   scop.error(begin, "unrecognized pragma");
+}
+
+/// Evaluates a msg pragma.
+void pragma_msg(Scope scop, Token* pragmaLoc, Expression[] args)
+{
+  if (args.length == 0)
+    return /*scop.error(pragmaLoc, "expected expression arguments to pragma")*/;
+
+  foreach (arg; args)
+  {
+    auto e = arg/+.evaluate()+/;
+    if (e is null)
+    {
+      // scop.error(e.begin, "expression is not evaluatable at compile time");
+    }
+    else if (auto stringExpr = e.Is!(StringExpression))
+      // Print string to standard output.
+      Stdout(stringExpr.getString());
+    else
+    {
+      // scop.error(e.begin, "expression must evaluate to a string");
+    }
+  }
+  // Print a newline at the end.
+  Stdout('\n');
+}
+
+/// Evaluates a lib pragma.
+void pragma_lib(Scope scop, Token* pragmaLoc, Expression[] args)
+{
+  if (args.length != 1)
+    return /*scop.error(pragmaLoc, "expected one expression argument to pragma")*/;
+
+  auto e = args[0]/+.evaluate()+/;
+  if (e is null)
+  {
+    // scop.error(e.begin, "expression is not evaluatable at compile time");
+  }
+  else if (auto stringExpr = e.Is!(StringExpression))
+  {
+    // TODO: collect library paths in Module?
+    // scop.modul.addLibrary(stringExpr.getString());
+  }
+  else
+  {
+    // scop.error(e.begin, "expression must evaluate to a string");
+  }
+}
+
+/// Returns true if the first branch (of a debug declaration/statement) or
+/// false if the else-branch should be compiled in.
+bool debugBranchChoice(Token* cond, CompilationContext context)
+{
+  if (cond)
+  {
+    if (cond.kind == TOK.Identifier)
+    {
+      if (context.findDebugId(cond.ident.str))
+        return true;
+    }
+    else if (cond.uint_ <= context.debugLevel)
+      return true;
+  }
+  else if (1 <= context.debugLevel)
+    return true;
+  return false;
+}
+
+/// Returns true if the first branch (of a version declaration/statement) or
+/// false if the else-branch should be compiled in.
+bool versionBranchChoice(Token* cond, CompilationContext context)
+{
+  assert(cond);
+  if (cond.kind == TOK.Identifier)
+  {
+    if (context.findVersionId(cond.ident.str))
+      return true;
+  }
+  else if (cond.uint_ >= context.versionLevel)
+    return true;
+  return false;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/semantic/Interpreter.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,74 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.semantic.Interpreter;
+
+import dil.ast.Visitor;
+import dil.ast.Node,
+       dil.ast.Declarations,
+       dil.ast.Expressions,
+       dil.ast.Statements,
+       dil.ast.Types,
+       dil.ast.Parameters;
+
+import dil.semantic.Symbol,
+       dil.semantic.Symbols,
+       dil.semantic.Scope,
+       dil.semantic.Types;
+import dil.Information;
+
+/// Used for compile-time evaluation of expressions.
+class Interpreter : Visitor
+{
+  // Scope scop;
+  InfoManager infoMan;
+
+  static class Result : Expression
+  {
+    override Result copy(){return null;}
+  }
+
+  static const Result NAR; /// Not a Result. Similar to NAN in floating point arithmetics.
+
+  static this()
+  {
+    NAR = new Result;
+    NAR.type = Types.Error;
+  }
+
+  /// Evaluates the expression e.
+  /// Returns: NAR or a value.
+  static Expression interpret(Expression e, InfoManager infoMan/+, Scope scop+/)
+  {
+    return (new Interpreter(/+scop,+/ infoMan)).eval(e);
+  }
+
+  /// Constructs an Interpreter object.
+  this(/+Scope scop, +/InfoManager infoMan)
+  {
+    // this.scop = scop;
+    this.infoMan = infoMan;
+  }
+
+  /// Start evaluation.
+  Expression eval(Expression e)
+  {
+    return e;
+  }
+
+  /// Returns true if e is immutable.
+  bool isImmutable(Expression e)
+  {
+    switch (e.kind)
+    {
+    alias NodeKind NK;
+    case NK.IntExpression, NK.RealExpression,
+         NK.ComplexExpression, NK.CharExpression,
+         NK.BoolExpression, NK.StringExpression:
+      return true;
+    default:
+    }
+    return false;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/semantic/Module.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,158 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.semantic.Module;
+
+import dil.ast.Node;
+import dil.ast.Declarations;
+import dil.parser.Parser;
+import dil.lexer.Lexer;
+import dil.semantic.Symbol;
+import dil.semantic.Symbols;
+import dil.Information;
+import dil.SourceText;
+import common;
+
+import tango.io.FilePath;
+import tango.io.FileConst;
+
+alias FileConst.PathSeparatorChar dirSep;
+
+/// Represents a semantic D module and a source file.
+class Module : ScopeSymbol
+{
+  SourceText sourceText; /// The source file of this module.
+  string moduleFQN; /// Fully qualified name of the module. E.g.: dil.ast.Node
+  string packageName; /// E.g.: dil.ast
+  string moduleName; /// E.g.: Node
+
+  CompoundDeclaration root; /// The root of the parse tree.
+  ImportDeclaration[] imports; /// ImportDeclarations found in this file.
+  ModuleDeclaration moduleDecl; /// The optional ModuleDeclaration in this file.
+  Parser parser; /// The parser used to parse this file.
+
+  // Module[] modules;
+
+  InfoManager infoMan; /// Collects error messages.
+
+  this()
+  {
+    super(SYM.Module, null, null);
+  }
+
+  /// Constructs a Module object.
+  /// Params:
+  ///   filePath = file path to the source text; loaded in the constructor.
+  ///   infoMan = used for collecting error messages.
+  this(string filePath, InfoManager infoMan = null)
+  {
+    this();
+    this.sourceText = new SourceText(filePath);
+    this.infoMan = infoMan;
+    this.sourceText.load(infoMan);
+  }
+
+  /// Returns the file path of the source text.
+  string filePath()
+  {
+    return sourceText.filePath;
+  }
+
+  /// Returns the file extension: "d" or "di".
+  string fileExtension()
+  {
+    foreach_reverse(i, c; filePath)
+      if (c == '.')
+        return filePath[i+1..$];
+    return "";
+  }
+
+  /// Sets the parser to be used for parsing the source text.
+  void setParser(Parser parser)
+  {
+    this.parser = parser;
+  }
+
+  /// Parses the module.
+  /// Throws:
+  ///   An Exception if the there's no ModuleDeclaration and
+  ///   the file name is an invalid or reserved D identifier.
+  void parse()
+  {
+    if (this.parser is null)
+      this.parser = new Parser(sourceText, infoMan);
+
+    this.root = parser.start();
+    this.imports = parser.imports;
+
+    if (root.children.length)
+    { // moduleDecl will be null if first node isn't a ModuleDeclaration.
+      this.moduleDecl = root.children[0].Is!(ModuleDeclaration);
+      if (this.moduleDecl)
+        this.setFQN(moduleDecl.getFQN());
+    }
+
+    if (!this.moduleFQN.length)
+    { // Take base name of file path as module name.
+      auto str = (new FilePath(filePath)).name();
+      if (Lexer.isReservedIdentifier(str))
+        throw new Exception("'"~str~"' is not a valid module name; it's a reserved or invalid D identifier.");
+      this.moduleFQN = this.moduleName = str;
+    }
+  }
+
+  /// Returns the first token of the module's source text.
+  Token* firstToken()
+  {
+    return parser.lexer.firstToken();
+  }
+
+  /// Returns true if there are errors in the source file.
+  bool hasErrors()
+  {
+    return parser.errors.length || parser.lexer.errors.length;
+  }
+
+  /// Returns a list of import paths.
+  /// E.g.: ["dil/ast/Node", "dil/semantic/Module"]
+  string[] getImportPaths()
+  {
+    string[] result;
+    foreach (import_; imports)
+      result ~= import_.getModuleFQNs(dirSep);
+    return result;
+  }
+
+  /// Returns the fully qualified name of this module.
+  /// E.g.: dil.ast.Node
+  string getFQN()
+  {
+    return moduleFQN;
+  }
+
+  /// Set's the module's FQN.
+  void setFQN(string moduleFQN)
+  {
+    uint i = moduleFQN.length;
+    if (i != 0) // Don't decrement if string has zero length.
+      i--;
+    // Find last dot.
+    for (; i != 0 && moduleFQN[i] != '.'; i--)
+    {}
+    this.moduleFQN = moduleFQN;
+    this.packageName = moduleFQN[0..i];
+    this.moduleName = moduleFQN[(i == 0 ? 0 : i+1) .. $];
+  }
+
+  /// Returns the module's FQN with slashes instead of dots.
+  /// E.g.: dil/ast/Node
+  string getFQNPath()
+  {
+    string FQNPath = moduleFQN.dup;
+    foreach (i, c; FQNPath)
+      if (c == '.')
+        FQNPath[i] = dirSep;
+    return FQNPath;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/semantic/Package.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,12 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.semantic.Package;
+
+import dil.semantic.Symbol;
+
+class Package : Symbol
+{
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/semantic/Pass1.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,504 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.semantic.Pass1;
+
+import dil.ast.Visitor;
+import dil.ast.Node,
+       dil.ast.Declarations,
+       dil.ast.Expressions,
+       dil.ast.Statements,
+       dil.ast.Types,
+       dil.ast.Parameters;
+import dil.lexer.IdTable;
+import dil.semantic.Symbol,
+       dil.semantic.Symbols,
+       dil.semantic.Types,
+       dil.semantic.Scope,
+       dil.semantic.Module,
+       dil.semantic.Analysis;
+import dil.Compilation;
+import dil.Location;
+import dil.Information;
+import dil.Messages;
+import dil.Enums;
+import dil.CompilerInfo;
+import common;
+
+/// The first pass is the declaration pass.
+///
+/// The basic task of this class is to traverse the parse tree,
+/// find all kinds of declarations and add them
+/// to the symbol tables of their respective scopes.
+class SemanticPass1 : Visitor
+{
+  Scope scop; /// The current scope.
+  Module modul; /// The module to be semantically checked.
+  CompilationContext context; /// The compilation context.
+
+  // Attributes:
+  LinkageType linkageType; /// Current linkage type.
+  Protection protection; /// Current protection attribute.
+  StorageClass storageClass; /// Current storage classes.
+  uint alignSize; /// Current align size.
+
+  /// Constructs a SemanticPass1 object.
+  /// Params:
+  ///   modul = the module to be processed.
+  ///   context = the compilation context.
+  this(Module modul, CompilationContext context)
+  {
+    this.modul = modul;
+    this.context = new CompilationContext(context);
+    this.alignSize = context.structAlign;
+  }
+
+  /// Starts processing the module.
+  void start()
+  {
+    assert(modul.root !is null);
+    // Create module scope.
+    scop = new Scope(null, modul);
+    visit(modul.root);
+  }
+
+  /// Enters a new scope.
+  void enterScope(ScopeSymbol s)
+  {
+    scop = scop.enter(s);
+  }
+
+  /// Exits the current scope.
+  void exitScope()
+  {
+    scop = scop.exit();
+  }
+
+  /// Returns true if this is the module scope.
+  bool isModuleScope()
+  {
+    return scop.symbol.isModule();
+  }
+
+  /// Inserts a symbol into the current scope.
+  void insert(Symbol symbol, Identifier* name)
+  {
+    auto symX = scop.symbol.lookup(name);
+    if (symX)
+      reportSymbolConflict(symbol, symX, name);
+    else
+      scop.symbol.insert(symbol, name);
+    // Set the current scope symbol as the parent.
+    symbol.parent = scop.symbol;
+  }
+
+  /// Inserts a symbol into scopeSym.
+  void insert(Symbol symbol, ScopeSymbol scopeSym)
+  {
+    auto symX = scopeSym.lookup(symbol.name);
+    if (symX)
+      reportSymbolConflict(symbol, symX, symbol.name);
+    else
+      scopeSym.insert(symbol, symbol.name);
+    // Set the current scope symbol as the parent.
+    symbol.parent = scopeSym;
+  }
+
+  /// Inserts a symbol, overloading on the name, into the current scope.
+  void insertOverload(Symbol sym, Identifier* name)
+  {
+    auto sym2 = scop.symbol.lookup(name);
+    if (sym2)
+    {
+      if (sym2.isOverloadSet)
+        (cast(OverloadSet)cast(void*)sym2).add(sym);
+      else
+        reportSymbolConflict(sym, sym2, name);
+    }
+    else
+      // Create a new overload set.
+      scop.symbol.insert(new OverloadSet(name, sym.node), name);
+    // Set the current scope symbol as the parent.
+    sym.parent = scop.symbol;
+  }
+
+  /// Reports an error: new symbol s1 conflicts with existing symbol s2.
+  void reportSymbolConflict(Symbol s1, Symbol s2, Identifier* name)
+  {
+    auto loc = s2.node.begin.getErrorLocation();
+    auto locString = Format("{}({},{})", loc.filePath, loc.lineNum, loc.colNum);
+    error(s1.node.begin, MSG.DeclConflictsWithDecl, name.str, locString);
+  }
+
+  /// Creates an error report.
+  void error(Token* token, char[] formatMsg, ...)
+  {
+    if (!modul.infoMan)
+      return;
+    auto location = token.getErrorLocation();
+    auto msg = Format(_arguments, _argptr, formatMsg);
+    modul.infoMan ~= new SemanticError(location, msg);
+  }
+
+
+  /// Collects info about nodes which have to be evaluated later.
+  static class Deferred
+  {
+    Node node;
+    ScopeSymbol symbol;
+    // Saved attributes.
+    LinkageType linkageType;
+    Protection protection;
+    StorageClass storageClass;
+    uint alignSize;
+  }
+
+  /// List of mixin, static if, static assert and pragma(msg,...) declarations.
+  ///
+  /// Their analysis must be deferred because they entail
+  /// evaluation of expressions.
+  Deferred[] deferred;
+
+  /// Adds a deferred node to the list.
+  void addDeferred(Node node)
+  {
+    auto d = new Deferred;
+    d.node = node;
+    d.symbol = scop.symbol;
+    d.linkageType = linkageType;
+    d.protection = protection;
+    d.storageClass = storageClass;
+    d.alignSize = alignSize;
+    deferred ~= d;
+  }
+
+  private alias Declaration D; /// A handy alias. Saves typing.
+
+override
+{
+  D visit(CompoundDeclaration d)
+  {
+    foreach (decl; d.decls)
+      visitD(decl);
+    return d;
+  }
+
+  D visit(IllegalDeclaration)
+  { assert(0, "semantic pass on invalid AST"); return null; }
+
+  D visit(EmptyDeclaration ed)
+  { return ed; }
+
+  D visit(ModuleDeclaration)
+  { return null; }
+
+  D visit(ImportDeclaration d)
+  {
+    return d;
+  }
+
+  D visit(AliasDeclaration ad)
+  {
+    return ad;
+  }
+
+  D visit(TypedefDeclaration td)
+  {
+    return td;
+  }
+
+  D visit(EnumDeclaration d)
+  {
+    // Create the symbol.
+    d.symbol = new Enum(d.name, d);
+    auto isAnonymous = d.name is null;
+    if (isAnonymous)
+      d.symbol.name = IdTable.genAnonEnumID();
+    insert(d.symbol, d.symbol.name);
+    auto parentScopeSymbol = scop.symbol;
+    enterScope(d.symbol);
+    // Declare members.
+    foreach (member; d.members)
+    {
+      visitD(member);
+      if (isAnonymous) // Also insert into parent scope if enum is anonymous.
+        insert(member.symbol, parentScopeSymbol);
+      member.symbol.parent = d.symbol;
+    }
+    exitScope();
+    return d;
+  }
+
+  D visit(EnumMemberDeclaration d)
+  {
+    d.symbol = new EnumMember(d.name, protection, storageClass, linkageType, d);
+    insert(d.symbol, d.symbol.name);
+    return d;
+  }
+
+  D visit(ClassDeclaration d)
+  {
+    if (d.symbol)
+      return d;
+    d.symbol = new Class(d.name, d);
+    // Insert into current scope.
+    insert(d.symbol, d.name);
+    enterScope(d.symbol);
+    // Continue semantic analysis.
+    d.decls && visitD(d.decls);
+    exitScope();
+    return d;
+  }
+
+  D visit(InterfaceDeclaration d)
+  {
+    if (d.symbol)
+      return d;
+    d.symbol = new dil.semantic.Symbols.Interface(d.name, d);
+    // Insert into current scope.
+    insert(d.symbol, d.name);
+    enterScope(d.symbol);
+    // Continue semantic analysis.
+    d.decls && visitD(d.decls);
+    exitScope();
+    return d;
+  }
+
+  D visit(StructDeclaration d)
+  {
+    if (d.symbol)
+      return d;
+    d.symbol = new Struct(d.name, d);
+    // Insert into current scope.
+    if (d.name)
+      insert(d.symbol, d.name);
+    enterScope(d.symbol);
+    // Continue semantic analysis.
+    d.decls && visitD(d.decls);
+    exitScope();
+    return d;
+  }
+
+  D visit(UnionDeclaration d)
+  {
+    if (d.symbol)
+      return d;
+    d.symbol = new Union(d.name, d);
+    // Insert into current scope.
+    if (d.name)
+      insert(d.symbol, d.name);
+    enterScope(d.symbol);
+    // Continue semantic analysis.
+    d.decls && visitD(d.decls);
+    exitScope();
+    return d;
+  }
+
+  D visit(ConstructorDeclaration d)
+  {
+    auto func = new Function(Ident.__ctor, d);
+    insertOverload(func, func.name);
+    return d;
+  }
+
+  D visit(StaticConstructorDeclaration d)
+  {
+    auto func = new Function(Ident.__ctor, d);
+    insertOverload(func, func.name);
+    return d;
+  }
+
+  D visit(DestructorDeclaration d)
+  {
+    auto func = new Function(Ident.__dtor, d);
+    insertOverload(func, func.name);
+    return d;
+  }
+
+  D visit(StaticDestructorDeclaration d)
+  {
+    auto func = new Function(Ident.__dtor, d);
+    insertOverload(func, func.name);
+    return d;
+  }
+
+  D visit(FunctionDeclaration d)
+  {
+    auto func = new Function(d.name, d);
+    insertOverload(func, func.name);
+    return d;
+  }
+
+  D visit(VariablesDeclaration vd)
+  {
+    // Error if we are in an interface.
+    if (scop.symbol.isInterface && !vd.isStatic)
+      return error(vd.begin, MSG.InterfaceCantHaveVariables), vd;
+
+    // Insert variable symbols in this declaration into the symbol table.
+    foreach (i, name; vd.names)
+    {
+      auto variable = new Variable(name, protection, storageClass, linkageType, vd);
+      variable.value = vd.inits[i];
+      vd.variables ~= variable;
+      insert(variable, name);
+    }
+    return vd;
+  }
+
+  D visit(InvariantDeclaration d)
+  {
+    auto func = new Function(Ident.__invariant, d);
+    insert(func, func.name);
+    return d;
+  }
+
+  D visit(UnittestDeclaration d)
+  {
+    auto func = new Function(Ident.__unittest, d);
+    insertOverload(func, func.name);
+    return d;
+  }
+
+  D visit(DebugDeclaration d)
+  {
+    if (d.isSpecification)
+    {
+      if (!isModuleScope())
+        error(d.begin, MSG.DebugSpecModuleLevel, d.spec.srcText);
+      else if (d.spec.kind == TOK.Identifier)
+        context.addDebugId(d.spec.ident.str);
+      else
+        context.debugLevel = d.spec.uint_;
+    }
+    else
+    {
+      if (debugBranchChoice(d.cond, context))
+        d.compiledDecls = d.decls;
+      else
+        d.compiledDecls = d.elseDecls;
+      d.compiledDecls && visitD(d.compiledDecls);
+    }
+    return d;
+  }
+
+  D visit(VersionDeclaration d)
+  {
+    if (d.isSpecification)
+    {
+      if (!isModuleScope())
+        error(d.begin, MSG.VersionSpecModuleLevel, d.spec.srcText);
+      else if (d.spec.kind == TOK.Identifier)
+        context.addVersionId(d.spec.ident.str);
+      else
+        context.versionLevel = d.spec.uint_;
+    }
+    else
+    {
+      if (versionBranchChoice(d.cond, context))
+        d.compiledDecls = d.decls;
+      else
+        d.compiledDecls = d.elseDecls;
+      d.compiledDecls && visitD(d.compiledDecls);
+    }
+    return d;
+  }
+
+  D visit(TemplateDeclaration d)
+  {
+    if (d.symbol)
+      return d;
+    d.symbol = new Template(d.name, d);
+    // Insert into current scope.
+    insertOverload(d.symbol, d.name);
+    enterScope(d.symbol);
+    // Continue semantic analysis.
+    visitD(d.decls);
+    exitScope();
+    return d;
+  }
+
+  D visit(NewDeclaration d)
+  {
+    auto func = new Function(Ident.__new, d);
+    insert(func, func.name);
+    return d;
+  }
+
+  D visit(DeleteDeclaration d)
+  {
+    auto func = new Function(Ident.__delete, d);
+    insert(func, func.name);
+    return d;
+  }
+
+  D visit(ProtectionDeclaration d)
+  {
+    auto saved = protection; // Save.
+    protection = d.prot; // Set.
+    visitD(d.decls);
+    protection = saved; // Restore.
+    return d;
+  }
+
+  D visit(StorageClassDeclaration d)
+  {
+    auto saved = storageClass; // Save.
+    storageClass = d.storageClass; // Set.
+    visitD(d.decls);
+    storageClass = saved; // Restore.
+    return d;
+  }
+
+  D visit(LinkageDeclaration d)
+  {
+    auto saved = linkageType; // Save.
+    linkageType = d.linkageType; // Set.
+    visitD(d.decls);
+    linkageType = saved; // Restore.
+    return d;
+  }
+
+  D visit(AlignDeclaration d)
+  {
+    auto saved = alignSize; // Save.
+    alignSize = d.size; // Set.
+    visitD(d.decls);
+    alignSize = saved; // Restore.
+    return d;
+  }
+
+  // Deferred declarations:
+
+  D visit(StaticAssertDeclaration d)
+  {
+    addDeferred(d);
+    return d;
+  }
+
+  D visit(StaticIfDeclaration d)
+  {
+    addDeferred(d);
+    return d;
+  }
+
+  D visit(MixinDeclaration d)
+  {
+    addDeferred(d);
+    return d;
+  }
+
+  D visit(PragmaDeclaration d)
+  {
+    if (d.ident is Ident.msg)
+      addDeferred(d);
+    else
+    {
+      pragmaSemantic(scop, d.begin, d.ident, d.args);
+      visitD(d.decls);
+    }
+    return d;
+  }
+} // override
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/semantic/Pass2.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,436 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.semantic.Pass2;
+
+import dil.ast.DefaultVisitor;
+import dil.ast.Node,
+       dil.ast.Declarations,
+       dil.ast.Expressions,
+       dil.ast.Statements,
+       dil.ast.Types,
+       dil.ast.Parameters;
+import dil.lexer.Identifier;
+import dil.semantic.Symbol,
+       dil.semantic.Symbols,
+       dil.semantic.Types,
+       dil.semantic.Scope,
+       dil.semantic.Module,
+       dil.semantic.Analysis,
+       dil.semantic.Interpreter;
+import dil.parser.Parser;
+import dil.SourceText;
+import dil.Location;
+import dil.Information;
+import dil.Messages;
+import dil.Enums;
+import dil.CompilerInfo;
+import common;
+
+/// The second pass determines the types of symbols and the types
+/// of expressions and also evaluates them.
+class SemanticPass2 : DefaultVisitor
+{
+  Scope scop; /// The current scope.
+  Module modul; /// The module to be semantically checked.
+
+  /// Constructs a SemanticPass2 object.
+  /// Params:
+  ///   modul = the module to be checked.
+  this(Module modul)
+  {
+    this.modul = modul;
+  }
+
+  /// Start semantic analysis.
+  void start()
+  {
+    assert(modul.root !is null);
+    // Create module scope.
+    scop = new Scope(null, modul);
+    visit(modul.root);
+  }
+
+  /// Enters a new scope.
+  void enterScope(ScopeSymbol s)
+  {
+    scop = scop.enter(s);
+  }
+
+  /// Exits the current scope.
+  void exitScope()
+  {
+    scop = scop.exit();
+  }
+
+  /// Evaluates e and returns the result.
+  Expression interpret(Expression e)
+  {
+    return Interpreter.interpret(e, modul.infoMan/+, scop+/);
+  }
+
+  /// Creates an error report.
+  void error(Token* token, char[] formatMsg, ...)
+  {
+    auto location = token.getErrorLocation();
+    auto msg = Format(_arguments, _argptr, formatMsg);
+    modul.infoMan ~= new SemanticError(location, msg);
+  }
+
+  /// Some handy aliases.
+  private alias Declaration D;
+  private alias Expression E; /// ditto
+  private alias Statement S; /// ditto
+  private alias TypeNode T; /// ditto
+
+  /// The current scope symbol to use for looking up identifiers.
+  /// E.g.:
+  /// ---
+  /// object.method(); // *) object is looked up in the current scope.
+  ///                  // *) idScope is set if object is a ScopeSymbol.
+  ///                  // *) method will be looked up in idScope.
+  /// dil.ast.Node.Node node; // A fully qualified type.
+  /// ---
+  ScopeSymbol idScope;
+
+  /// Searches for a symbol.
+  Symbol search(Token* idTok)
+  {
+    assert(idTok.kind == TOK.Identifier);
+    auto id = idTok.ident;
+    Symbol symbol;
+
+    if (idScope is null)
+      for (auto sc = scop; sc; sc = sc.parent)
+      {
+        symbol = sc.lookup(id);
+        if (symbol)
+          return symbol;
+      }
+    else
+      symbol = idScope.lookup(id);
+
+    if (symbol is null)
+      error(idTok, MSG.UndefinedIdentifier, id.str);
+    else if (auto scopSymbol = cast(ScopeSymbol)symbol)
+      idScope = scopSymbol;
+
+    return symbol;
+  }
+
+override
+{
+  D visit(CompoundDeclaration d)
+  {
+    return super.visit(d);
+  }
+
+  D visit(EnumDeclaration d)
+  {
+    d.symbol.setCompleting();
+
+    Type type = Types.Int; // Default to int.
+    if (d.baseType)
+      type = visitT(d.baseType).type;
+    d.symbol.type = new TypeEnum(d.symbol, type);
+
+    enterScope(d.symbol);
+
+    foreach (member; d.members)
+    {
+      Expression finalValue;
+      member.symbol.setCompleting();
+      if (member.value)
+      {
+        member.value = visitE(member.value);
+        finalValue = interpret(member.value);
+        if (finalValue is Interpreter.NAR)
+          finalValue = new IntExpression(0, d.symbol.type);
+      }
+      //else
+        // TODO: increment a number variable and assign that to value.
+      member.symbol.type = d.symbol.type; // Assign TypeEnum.
+      member.symbol.value = finalValue;
+      member.symbol.setComplete();
+    }
+
+    exitScope();
+    d.symbol.setComplete();
+    return d;
+  }
+
+  D visit(MixinDeclaration md)
+  {
+    if (md.decls)
+      return md.decls;
+    if (md.isMixinExpression)
+    {
+      md.argument = visitE(md.argument);
+      auto expr = interpret(md.argument);
+      if (expr is Interpreter.NAR)
+        return md;
+      auto stringExpr = expr.Is!(StringExpression);
+      if (stringExpr is null)
+      {
+        error(md.begin, MSG.MixinArgumentMustBeString);
+        return md;
+      }
+      else
+      { // Parse the declarations in the string.
+        auto loc = md.begin.getErrorLocation();
+        auto filePath = loc.filePath;
+        auto sourceText = new SourceText(filePath, stringExpr.getString());
+        auto parser = new Parser(sourceText, modul.infoMan);
+        md.decls = parser.start();
+      }
+    }
+    else
+    {
+      // TODO: implement template mixin.
+    }
+    return md.decls;
+  }
+
+  // Type nodes:
+
+  T visit(TypeofType t)
+  {
+    t.e = visitE(t.e);
+    t.type = t.e.type;
+    return t;
+  }
+
+  T visit(ArrayType t)
+  {
+    auto baseType = visitT(t.next).type;
+    if (t.isAssociative)
+      t.type = baseType.arrayOf(visitT(t.assocType).type);
+    else if (t.isDynamic)
+      t.type = baseType.arrayOf();
+    else if (t.isStatic)
+    {}
+    else
+      assert(t.isSlice);
+    return t;
+  }
+
+  T visit(PointerType t)
+  {
+    t.type = visitT(t.next).type.ptrTo();
+    return t;
+  }
+
+  T visit(QualifiedType t)
+  {
+    if (t.lhs.Is!(QualifiedType) is null)
+      idScope = null; // Reset at left-most type.
+    visitT(t.lhs);
+    visitT(t.rhs);
+    t.type = t.rhs.type;
+    return t;
+  }
+
+  T visit(IdentifierType t)
+  {
+    auto idToken = t.begin;
+    auto symbol = search(idToken);
+    // TODO: save symbol or its type in t.
+    return t;
+  }
+
+  T visit(TemplateInstanceType t)
+  {
+    auto idToken = t.begin;
+    auto symbol = search(idToken);
+    // TODO: save symbol or its type in t.
+    return t;
+  }
+
+  T visit(ModuleScopeType t)
+  {
+    idScope = modul;
+    return t;
+  }
+
+  T visit(IntegralType t)
+  {
+    // A table mapping the kind of a token to its corresponding semantic Type.
+    TypeBasic[TOK] tok2Type = [
+      TOK.Char : Types.Char,   TOK.Wchar : Types.Wchar,   TOK.Dchar : Types.Dchar, TOK.Bool : Types.Bool,
+      TOK.Byte : Types.Byte,   TOK.Ubyte : Types.Ubyte,   TOK.Short : Types.Short, TOK.Ushort : Types.Ushort,
+      TOK.Int : Types.Int,    TOK.Uint : Types.Uint,    TOK.Long : Types.Long,  TOK.Ulong : Types.Ulong,
+      TOK.Cent : Types.Cent,   TOK.Ucent : Types.Ucent,
+      TOK.Float : Types.Float,  TOK.Double : Types.Double,  TOK.Real : Types.Real,
+      TOK.Ifloat : Types.Ifloat, TOK.Idouble : Types.Idouble, TOK.Ireal : Types.Ireal,
+      TOK.Cfloat : Types.Cfloat, TOK.Cdouble : Types.Cdouble, TOK.Creal : Types.Creal, TOK.Void : Types.Void
+    ];
+    assert(t.tok in tok2Type);
+    t.type = tok2Type[t.tok];
+    return t;
+  }
+
+  // Expression nodes:
+
+  E visit(ParenExpression e)
+  {
+    if (!e.type)
+    {
+      e.next = visitE(e.next);
+      e.type = e.next.type;
+    }
+    return e;
+  }
+
+  E visit(CommaExpression e)
+  {
+    if (!e.type)
+    {
+      e.lhs = visitE(e.lhs);
+      e.rhs = visitE(e.rhs);
+      e.type = e.rhs.type;
+    }
+    return e;
+  }
+
+  E visit(OrOrExpression)
+  { return null; }
+
+  E visit(AndAndExpression)
+  { return null; }
+
+  E visit(SpecialTokenExpression e)
+  {
+    if (e.type)
+      return e.value;
+    switch (e.specialToken.kind)
+    {
+    case TOK.LINE, TOK.VERSION:
+      e.value = new IntExpression(e.specialToken.uint_, Types.Uint);
+      break;
+    case TOK.FILE, TOK.DATE, TOK.TIME, TOK.TIMESTAMP, TOK.VENDOR:
+      e.value = new StringExpression(e.specialToken.str);
+      break;
+    default:
+      assert(0);
+    }
+    e.type = e.value.type;
+    return e.value;
+  }
+
+  E visit(DollarExpression e)
+  {
+    if (e.type)
+      return e;
+    e.type = Types.Size_t;
+    // if (!inArraySubscript)
+    //   error("$ can only be in an array subscript.");
+    return e;
+  }
+
+  E visit(NullExpression e)
+  {
+    if (!e.type)
+      e.type = Types.Void_ptr;
+    return e;
+  }
+
+  E visit(BoolExpression e)
+  {
+    if (e.type)
+      return e;
+    e.value = new IntExpression(e.toBool(), Types.Bool);
+    e.type = Types.Bool;
+    return e;
+  }
+
+  E visit(IntExpression e)
+  {
+    if (e.type)
+      return e;
+
+    if (e.number & 0x8000_0000_0000_0000)
+      e.type = Types.Ulong; // 0xFFFF_FFFF_FFFF_FFFF
+    else if (e.number & 0xFFFF_FFFF_0000_0000)
+      e.type = Types.Long; // 0x7FFF_FFFF_FFFF_FFFF
+    else if (e.number & 0x8000_0000)
+      e.type = Types.Uint; // 0xFFFF_FFFF
+    else
+      e.type = Types.Int; // 0x7FFF_FFFF
+    return e;
+  }
+
+  E visit(RealExpression e)
+  {
+    if (!e.type)
+      e.type = Types.Double;
+    return e;
+  }
+
+  E visit(ComplexExpression e)
+  {
+    if (!e.type)
+      e.type = Types.Cdouble;
+    return e;
+  }
+
+  E visit(CharExpression e)
+  {
+    if (e.type)
+      return e;
+    if (e.character <= 0xFF)
+      e.type = Types.Char;
+    else if (e.character <= 0xFFFF)
+      e.type = Types.Wchar;
+    else
+      e.type = Types.Dchar;
+    return e;
+  }
+
+  E visit(StringExpression e)
+  {
+    return e;
+  }
+
+  E visit(MixinExpression me)
+  {
+    if (me.type)
+      return me.expr;
+    me.expr = visitE(me.expr);
+    auto expr = interpret(me.expr);
+    if (expr is Interpreter.NAR)
+      return me;
+    auto stringExpr = expr.Is!(StringExpression);
+    if (stringExpr is null)
+     error(me.begin, MSG.MixinArgumentMustBeString);
+    else
+    {
+      auto loc = me.begin.getErrorLocation();
+      auto filePath = loc.filePath;
+      auto sourceText = new SourceText(filePath, stringExpr.getString());
+      auto parser = new Parser(sourceText, modul.infoMan);
+      expr = parser.start2();
+      expr = visitE(expr); // Check expression.
+    }
+    me.expr = expr;
+    me.type = expr.type;
+    return me.expr;
+  }
+
+  E visit(ImportExpression ie)
+  {
+    if (ie.type)
+      return ie.expr;
+    ie.expr = visitE(ie.expr);
+    auto expr = interpret(ie.expr);
+    if (expr is Interpreter.NAR)
+      return ie;
+    auto stringExpr = expr.Is!(StringExpression);
+    //if (stringExpr is null)
+    //  error(me.begin, MSG.ImportArgumentMustBeString);
+    // TODO: load file
+    //ie.expr = new StringExpression(loadImportFile(stringExpr.getString()));
+    return ie.expr;
+  }
+}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/semantic/Scope.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,72 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.semantic.Scope;
+
+import dil.semantic.Symbol;
+import dil.semantic.Symbols;
+import dil.lexer.Identifier;
+import common;
+
+/// Builds a hierarchy of environments.
+class Scope
+{
+  Scope parent; /// The surrounding scope, or null if this is the root scope.
+
+  ScopeSymbol symbol; /// The current symbol with the symbol table.
+
+  this(Scope parent, ScopeSymbol symbol)
+  {
+    this.parent = parent;
+    this.symbol = symbol;
+  }
+
+  /// Find a symbol in this scope.
+  /// Params:
+  ///   name = the name of the symbol.
+  Symbol lookup(Identifier* name)
+  {
+    return symbol.lookup(name);
+  }
+
+  /// Create a new inner scope and return that.
+  Scope enter(ScopeSymbol symbol)
+  {
+    return new Scope(this, symbol);
+  }
+
+  /// Destroy this scope and return the outer scope.
+  Scope exit()
+  {
+    auto sc = parent;
+    // delete this;
+    return sc;
+  }
+
+  /// Search for the enclosing Class scope.
+  Scope classScope()
+  {
+    auto scop = this;
+    do
+    {
+      if (scop.symbol.isClass)
+        return scop;
+      scop = scop.parent;
+    } while (scop)
+    return null;
+  }
+
+  /// Search for the enclosing Module scope.
+  Scope moduleScope()
+  {
+    auto scop = this;
+    do
+    {
+      if (scop.symbol.isModule)
+        return scop;
+      scop = scop.parent;
+    } while (scop)
+    return null;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/semantic/Symbol.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,111 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.semantic.Symbol;
+
+import dil.ast.Node;
+import dil.lexer.Identifier;
+import common;
+
+/// Enumeration of Symbol IDs.
+enum SYM
+{
+  Module,
+  Class,
+  Interface,
+  Struct,
+  Union,
+  Enum,
+  EnumMember,
+  Template,
+  Variable,
+  Function,
+  Alias,
+  OverloadSet,
+//   Type,
+}
+
+/// A symbol represents an object with semantic code information.
+class Symbol
+{ /// Enumeration of symbol statuses.
+  enum Status : ushort
+  {
+    Declared,   /// The symbol has been declared.
+    Completing, /// The symbol is being processed.
+    Complete    /// The symbol is complete.
+  }
+
+  SYM sid; /// The ID of this symbol.
+  Status status; /// The semantic status of this symbol.
+  Symbol parent; /// The parent this symbol belongs to.
+  Identifier* name; /// The name of this symbol.
+  /// The syntax tree node that produced this symbol.
+  /// Useful for source code location info and retrieval of doc comments.
+  Node node;
+
+  /// Constructs a Symbol object.
+  /// Params:
+  ///   sid = the symbol's ID.
+  ///   name = the symbol's name.
+  ///   node = the symbol's node.
+  this(SYM sid, Identifier* name, Node node)
+  {
+    this.sid = sid;
+    this.name = name;
+    this.node = node;
+  }
+
+  /// Change the status to Status.Completing.
+  void setCompleting()
+  { status = Status.Completing; }
+
+  /// Change the status to Status.Complete.
+  void setComplete()
+  { status = Status.Complete; }
+
+  /// Returns true if the symbol is being completed.
+  bool isCompleting()
+  { return status == Status.Completing; }
+
+  /// Returns true if the symbols is complete.
+  bool isComplete()
+  { return status == Status.Complete; }
+
+  /// A template macro for building isXYZ() methods.
+  private template isX(char[] kind)
+  {
+    const char[] isX = `bool is`~kind~`(){ return sid == SYM.`~kind~`; }`;
+  }
+  mixin(isX!("Module"));
+  mixin(isX!("Class"));
+  mixin(isX!("Interface"));
+  mixin(isX!("Struct"));
+  mixin(isX!("Union"));
+  mixin(isX!("Enum"));
+  mixin(isX!("EnumMember"));
+  mixin(isX!("Template"));
+  mixin(isX!("Variable"));
+  mixin(isX!("Function"));
+  mixin(isX!("Alias"));
+  mixin(isX!("OverloadSet"));
+//   mixin(isX!("Type"));
+
+  /// Casts the symbol to Class.
+  Class to(Class)()
+  {
+    assert(mixin(`this.sid == mixin("SYM." ~ typeof(Class).stringof)`));
+    return cast(Class)cast(void*)this;
+  }
+
+  /// Returns: the fully qualified name of this symbol.
+  /// E.g.: dil.semantic.Symbol.Symbol.getFQN
+  char[] getFQN()
+  {
+    if (!name)
+      return parent ? parent.getFQN() : "";
+    if (parent)
+      return parent.getFQN() ~ '.' ~ name.str;
+    return name.str;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/semantic/SymbolTable.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,30 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.semantic.SymbolTable;
+
+import dil.semantic.Symbol;
+import dil.lexer.Identifier;
+import common;
+
+/// Maps an identifier string to a Symbol.
+struct SymbolTable
+{
+  Symbol[char[]] table; /// The table data structure.
+
+  /// Looks up ident in the table.
+  /// Returns: the symbol if there, otherwise null.
+  Symbol lookup(Identifier* ident)
+  {
+    assert(ident !is null);
+    auto psym = ident.str in table;
+    return psym ? *psym : null;
+  }
+
+  /// Inserts a symbol into the table.
+  void insert(Symbol symbol, Identifier* ident)
+  {
+    table[ident.str] = symbol;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/semantic/Symbols.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,206 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.semantic.Symbols;
+
+import dil.ast.Expression;
+import dil.semantic.Symbol;
+import dil.semantic.SymbolTable;
+import dil.semantic.Types;
+import dil.ast.Node;
+import dil.lexer.IdTable;
+import dil.Enums;
+import common;
+
+/// A symbol that has its own scope with a symbol table.
+class ScopeSymbol : Symbol
+{
+  SymbolTable symbolTable; /// The symbol table.
+  Symbol[] members; /// The member symbols (in lexical order.)
+
+  this(SYM sid, Identifier* name, Node node)
+  {
+    super(sid, name, node);
+  }
+
+  /// Look up name in the table.
+  Symbol lookup(Identifier* name)
+  {
+    return symbolTable.lookup(name);
+  }
+
+  /// Look up name in the table.
+  Symbol lookup(string name)
+  {
+    auto id = IdTable.lookup(name);
+    return id ? symbolTable.lookup(id) : null;
+  }
+
+  /// Insert a symbol into the table.
+  void insert(Symbol s, Identifier* name)
+  {
+    symbolTable.insert(s, name);
+    members ~= s;
+  }
+}
+
+/// Aggregates have function and field members.
+abstract class Aggregate : ScopeSymbol
+{
+  Function[] funcs;
+  Variable[] fields;
+
+  this(SYM sid, Identifier* name, Node node)
+  {
+    super(sid, name, node);
+  }
+
+  override void insert(Symbol s, Identifier* ident)
+  {
+    if (s.isVariable)
+      // Append variable to fields.
+      fields ~= cast(Variable)cast(void*)s;
+    else if (s.isFunction)
+      // Append function to funcs.
+      funcs ~= cast(Function)cast(void*)s;
+    super.insert(s, ident);
+  }
+}
+
+/// A class symbol.
+class Class : Aggregate
+{
+  this(Identifier* name, Node classNode)
+  {
+    super(SYM.Class, name, classNode);
+  }
+}
+
+/// An interface symbol.
+class Interface : Aggregate
+{
+  this(Identifier* name, Node interfaceNode)
+  {
+    super(SYM.Interface, name, interfaceNode);
+  }
+}
+
+/// A union symbol.
+class Union : Aggregate
+{
+  this(Identifier* name, Node unionNode)
+  {
+    super(SYM.Union, name, unionNode);
+  }
+}
+
+/// A struct symbol.
+class Struct : Aggregate
+{
+  this(Identifier* name, Node structNode)
+  {
+    super(SYM.Struct, name, structNode);
+  }
+}
+
+/// An enum symbol.
+class Enum : ScopeSymbol
+{
+  TypeEnum type;
+  this(Identifier* name, Node enumNode)
+  {
+    super(SYM.Enum, name, enumNode);
+  }
+
+  void setType(TypeEnum type)
+  {
+    this.type = type;
+  }
+}
+
+/// A template symbol.
+class Template : ScopeSymbol
+{
+  this(Identifier* name, Node templateNode)
+  {
+    super(SYM.Template, name, templateNode);
+  }
+}
+
+/// A function symbol.
+class Function : ScopeSymbol
+{
+  Protection prot; /// The protection.
+  StorageClass stc; /// The storage classes.
+  LinkageType linkType; /// The linkage type.
+
+  Type returnType;
+  Variable[] params;
+
+  this(Identifier* name, Node functionNode)
+  {
+    super(SYM.Function, name, functionNode);
+  }
+}
+
+/// A variable symbol.
+class Variable : Symbol
+{
+  Protection prot; /// The protection.
+  StorageClass stc; /// The storage classes.
+  LinkageType linkType; /// The linkage type.
+
+  Type type; /// The type of this variable.
+  Expression value; /// The value of this variable.
+
+  this(Identifier* name,
+       Protection prot, StorageClass stc, LinkageType linkType,
+       Node variableNode)
+  {
+    super(SYM.Variable, name, variableNode);
+
+    this.prot = prot;
+    this.stc = stc;
+    this.linkType = linkType;
+  }
+}
+
+/// An enum member symbol.
+class EnumMember : Variable
+{
+  this(Identifier* name,
+       Protection prot, StorageClass stc, LinkageType linkType,
+       Node enumMemberNode)
+  {
+    super(name, prot, stc, linkType, enumMemberNode);
+    this.sid = SYM.EnumMember;
+  }
+}
+
+/// An alias symbol.
+class Alias : Symbol
+{
+  this(Identifier* name, Node aliasNode)
+  {
+    super(SYM.Alias, name, aliasNode);
+  }
+}
+
+/// A list of symbols that share the same identifier.
+///
+/// These can be functions, templates and aggregates with template parameter lists.
+class OverloadSet : Symbol
+{
+  Symbol[] symbols;
+
+  this(Identifier* name, Node node)
+  {
+    super(SYM.OverloadSet, name, node);
+  }
+
+  void add(Symbol s)
+  {
+    symbols ~= s;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/semantic/Types.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,403 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.semantic.Types;
+
+import dil.semantic.Symbol;
+import dil.semantic.TypesEnum;
+import dil.lexer.Identifier;
+import dil.CompilerInfo;
+
+/// The base type for all type structures.
+abstract class Type/* : Symbol*/
+{
+  Type next;     /// The next type in the type structure.
+  TYP tid;       /// The ID of the type.
+  Symbol symbol; /// Not null if this type has a symbol.
+
+  this(){}
+
+  /// Constructs a Type object.
+  /// Params:
+  ///   next = the type's next type.
+  ///   tid = the type's ID.
+  this(Type next, TYP tid)
+  {
+//     this.sid = SYM.Type;
+
+    this.next = next;
+    this.tid = tid;
+  }
+
+  /// Returns a pointer type to this type.
+  TypePointer ptrTo()
+  {
+    return new TypePointer(this);
+  }
+
+  /// Returns a dynamic array type using this type as its base.
+  TypeDArray arrayOf()
+  {
+    return new TypeDArray(this);
+  }
+
+  /// Returns an associative array type using this type as its base.
+  /// Params:
+  ///   key = the key type.
+  TypeAArray arrayOf(Type key)
+  {
+    return new TypeAArray(this, key);
+  }
+
+  /// Returns the byte size of this type.
+  final size_t sizeOf()
+  {
+    return MITable.getSize(this);
+  }
+
+  /// Size is not in MITable. Find out via virtual method.
+  size_t sizeOf_()
+  {
+    return sizeOf();
+  }
+
+  /// Returns true if this type has a symbol.
+  bool hasSymbol()
+  {
+    return symbol !is null;
+  }
+}
+
+/// All basic types. E.g.: int, char, real etc.
+class TypeBasic : Type
+{
+  this(TYP typ)
+  {
+    super(null, typ);
+  }
+}
+
+/// Dynamic array type.
+class TypeDArray : Type
+{
+  this(Type next)
+  {
+    super(next, TYP.DArray);
+  }
+}
+
+/// Associative array type.
+class TypeAArray : Type
+{
+  Type keyType;
+  this(Type next, Type keyType)
+  {
+    super(next, TYP.AArray);
+    this.keyType = keyType;
+  }
+}
+
+/// Static array type.
+class TypeSArray : Type
+{
+  size_t dimension;
+  this(Type next, size_t dimension)
+  {
+    super(next, TYP.SArray);
+    this.dimension = dimension;
+  }
+}
+
+/// Pointer type.
+class TypePointer : Type
+{
+  this(Type next)
+  {
+    super(next, TYP.Pointer);
+  }
+}
+
+/// Reference type.
+class TypeReference : Type
+{
+  this(Type next)
+  {
+    super(next, TYP.Reference);
+  }
+}
+
+/// Enum type.
+class TypeEnum : Type
+{
+  this(Symbol symbol, Type baseType)
+  {
+    super(baseType, TYP.Enum);
+    this.symbol = symbol;
+  }
+
+  Type baseType()
+  {
+    return next;
+  }
+}
+
+/// Struct type.
+class TypeStruct : Type
+{
+  this(Symbol symbol)
+  {
+    super(null, TYP.Struct);
+    this.symbol = symbol;
+  }
+}
+
+/// Class type.
+class TypeClass : Type
+{
+  this(Symbol symbol)
+  {
+    super(null, TYP.Class);
+    this.symbol = symbol;
+  }
+}
+
+/// Typedef type.
+class TypeTypedef : Type
+{
+  this(Type next)
+  {
+    super(next, TYP.Typedef);
+  }
+}
+
+/// Function type.
+class TypeFunction : Type
+{
+  this(Type next)
+  {
+    super(next, TYP.Function);
+  }
+}
+
+/// Delegate type.
+class TypeDelegate : Type
+{
+  this(Type next)
+  {
+    super(next, TYP.Delegate);
+  }
+}
+
+/// Identifier type.
+class TypeIdentifier : Type
+{
+  Identifier* ident;
+  this(Identifier* ident)
+  {
+    super(null, TYP.Identifier);
+  }
+}
+
+/// Template instantiation type.
+class TypeTemplInstance : Type
+{
+  this()
+  {
+    super(null, TYP.TInstance);
+  }
+}
+
+/// Template tuple type.
+class TypeTuple : Type
+{
+  this(Type next)
+  {
+    super(next, TYP.Tuple);
+  }
+}
+
+/// Constant type. D2.0
+class TypeConst : Type
+{
+  this(Type next)
+  {
+    super(next, TYP.Const);
+  }
+}
+
+/// Invariant type. D2.0
+class TypeInvariant : Type
+{
+  this(Type next)
+  {
+    super(next, TYP.Const);
+  }
+}
+
+/// Represents a value related to a Type.
+union Value
+{
+  void*  pvoid;
+  bool   bool_;
+  dchar  dchar_;
+  long   long_;
+  ulong  ulong_;
+  int    int_;
+  uint   uint_;
+  float  float_;
+  double double_;
+  real   real_;
+  creal  creal_;
+}
+
+/// Information related to a Type.
+struct TypeMetaInfo
+{
+  char mangle; /// Mangle character of the type.
+  ushort size; /// Byte size of the type.
+  Value* defaultInit; /// Default initialization value.
+}
+
+/// Namespace for the meta info table.
+struct MITable
+{
+static:
+  const ushort SIZE_NOT_AVAILABLE = 0; /// Size not available.
+  const Value VZERO = {int_:0}; /// Value 0.
+  const Value VNULL = {pvoid:null}; /// Value null.
+  const Value V0xFF = {dchar_:0xFF}; /// Value 0xFF.
+  const Value V0xFFFF = {dchar_:0xFFFF}; /// Value 0xFFFF.
+  const Value VFALSE = {bool_:false}; /// Value false.
+  const Value VNAN = {float_:float.nan}; /// Value NAN.
+  const Value VCNAN = {creal_:creal.nan}; /// Value complex NAN.
+  private alias SIZE_NOT_AVAILABLE SNA;
+  private alias PTR_SIZE PS;
+  /// The meta info table.
+  private const TypeMetaInfo metaInfoTable[] = [
+    {'?', SNA}, // Error
+
+    {'a', 1, &V0xFF},   // Char
+    {'u', 2, &V0xFFFF},   // Wchar
+    {'w', 4, &V0xFFFF},   // Dchar
+    {'b', 1, &VFALSE},   // Bool
+    {'g', 1, &VZERO},   // Byte
+    {'h', 1, &VZERO},   // Ubyte
+    {'s', 2, &VZERO},   // Short
+    {'t', 2, &VZERO},   // Ushort
+    {'i', 4, &VZERO},   // Int
+    {'k', 4, &VZERO},   // Uint
+    {'l', 8, &VZERO},   // Long
+    {'m', 8, &VZERO},   // Ulong
+    {'?', 16, &VZERO},  // Cent
+    {'?', 16, &VZERO},  // Ucent
+    {'f', 4, &VNAN},   // Float
+    {'d', 8, &VNAN},   // Double
+    {'e', 12, &VNAN},  // Real
+    {'o', 4, &VNAN},   // Ifloat
+    {'p', 8, &VNAN},   // Idouble
+    {'j', 12, &VNAN},  // Ireal
+    {'q', 8, &VCNAN},   // Cfloat
+    {'r', 16, &VCNAN},  // Cdouble
+    {'c', 24, &VCNAN},  // Creal
+    {'v', 1},   // void
+
+    {'n', SNA},  // None
+
+    {'A', PS*2, &VNULL}, // Dynamic array
+    {'G', PS*2, &VNULL}, // Static array
+    {'H', PS*2, &VNULL}, // Associative array
+
+    {'E', SNA}, // Enum
+    {'S', SNA}, // Struct
+    {'C', PS, &VNULL},  // Class
+    {'T', SNA}, // Typedef
+    {'F', PS},  // Function
+    {'D', PS*2, &VNULL}, // Delegate
+    {'P', PS, &VNULL},  // Pointer
+    {'R', PS, &VNULL},  // Reference
+    {'I', SNA}, // Identifier
+    {'?', SNA}, // Template instance
+    {'B', SNA}, // Tuple
+    {'x', SNA}, // Const, D2
+    {'y', SNA}, // Invariant, D2
+  ];
+  static assert(metaInfoTable.length == TYP.max+1);
+
+  /// Returns the size of a type.
+  size_t getSize(Type type)
+  {
+    auto size = metaInfoTable[type.tid].size;
+    if (size == SIZE_NOT_AVAILABLE)
+      return type.sizeOf_();
+    return size;
+  }
+}
+
+/// Namespace for a set of predefined types.
+struct Types
+{
+static:
+  /// Predefined basic types.
+  TypeBasic Char,   Wchar,   Dchar, Bool,
+            Byte,   Ubyte,   Short, Ushort,
+            Int,    Uint,    Long,  Ulong,
+            Cent,   Ucent,
+            Float,  Double,  Real,
+            Ifloat, Idouble, Ireal,
+            Cfloat, Cdouble, Creal, Void;
+
+  TypeBasic Size_t; /// The size type.
+  TypeBasic Ptrdiff_t; /// The pointer difference type.
+  TypePointer Void_ptr; /// The void pointer type.
+  TypeBasic Error; /// The error type.
+  TypeBasic Undefined; /// The undefined type.
+
+  /// Allocates an instance of TypeBasic and assigns it to typeName.
+  template newTB(char[] typeName)
+  {
+    const newTB = mixin(typeName~" = new TypeBasic(TYP."~typeName~")");
+  }
+
+  /// Initializes predefined types.
+  static this()
+  {
+    newTB!("Char");
+    newTB!("Wchar");
+    newTB!("Dchar");
+    newTB!("Bool");
+    newTB!("Byte");
+    newTB!("Ubyte");
+    newTB!("Short");
+    newTB!("Ushort");
+    newTB!("Int");
+    newTB!("Uint");
+    newTB!("Long");
+    newTB!("Ulong");
+    newTB!("Cent");
+    newTB!("Ucent");
+    newTB!("Float");
+    newTB!("Double");
+    newTB!("Real");
+    newTB!("Ifloat");
+    newTB!("Idouble");
+    newTB!("Ireal");
+    newTB!("Cfloat");
+    newTB!("Cdouble");
+    newTB!("Creal");
+    newTB!("Void");
+    version(X86_64)
+    {
+      Size_t = Ulong;
+      Ptrdiff_t = Long;
+    }
+    else
+    {
+      Size_t = Uint;
+      Ptrdiff_t = Int;
+    }
+    Void_ptr = Void.ptrTo;
+    Error = new TypeBasic(TYP.Error);
+    Undefined = new TypeBasic(TYP.Error);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/semantic/TypesEnum.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,56 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.semantic.TypesEnum;
+
+/// Enumeration of Type IDs.
+enum TYP
+{
+  Error,
+  // Basic types.
+  Char,    /// char
+  Wchar,   /// wchar
+  Dchar,   /// dchar
+  Bool,    /// bool
+  Byte,    /// int8
+  Ubyte,   /// uint8
+  Short,   /// int16
+  Ushort,  /// uint16
+  Int,     /// int32
+  Uint,    /// uint32
+  Long,    /// int64
+  Ulong,   /// uint64
+  Cent,    /// int128
+  Ucent,   /// uint128
+  Float,   /// float32
+  Double,  /// float64
+  Real,    /// float80
+  Ifloat,  /// imaginary float32
+  Idouble, /// imaginary float64
+  Ireal,   /// imaginary float80
+  Cfloat,  /// complex float32
+  Cdouble, /// complex float64
+  Creal,   /// complex float80
+  Void,    /// void
+
+  None,   /// TypeNone in the specs. Why?
+
+  DArray, /// Dynamic array.
+  SArray, /// Static array.
+  AArray, /// Associative array.
+
+  Enum,       /// An enum.
+  Struct,     /// A struct.
+  Class,      /// A class.
+  Typedef,    /// A typedef.
+  Function,   /// A function.
+  Delegate,   /// A delegate.
+  Pointer,    /// A pointer.
+  Reference,  /// A reference.
+  Identifier, /// An identifier.
+  TInstance,  /// Template instance.
+  Tuple,      /// A template tuple.
+  Const,      /// A constant type. D2.0
+  Invariant,  /// An invariant type. D2.0
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dil/translator/German.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,340 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.translator.German;
+
+import dil.ast.DefaultVisitor;
+import dil.ast.Node;
+import dil.ast.Declarations,
+       dil.ast.Statements,
+       dil.ast.Types,
+       dil.ast.Parameters;
+import tango.io.Print;
+
+private alias Declaration D;
+
+/// Translates a syntax tree into German.
+class GermanTranslator : DefaultVisitor
+{
+  Print!(char) put; /// Output buffer.
+
+  char[] indent; /// Current indendation string.
+  char[] indentStep; /// Appended to indent at each indendation level.
+
+  Declaration inAggregate; /// Current aggregate.
+  Declaration inFunc; /// Current function.
+
+  bool pluralize; /// Whether to use the plural when printing the next types.
+  bool pointer; /// Whether next types should consider the previous pointer.
+
+  /// Construct a GermanTranslator.
+  /// Params:
+  ///   put = buffer to print to.
+  ///   indentStep = added at every indendation step.
+  this(Print!(char) put, char[] indentStep)
+  {
+    this.put = put;
+    this.indentStep = indentStep;
+  }
+
+  /// Start translation.
+  void translate(Node root)
+  {
+    visitN(root);
+  }
+
+  /// Increases the indentation when instantiated.
+  /// The indentation is restored when the instance goes out of scope.
+  scope class Indent
+  {
+    char[] old_indent;
+    this()
+    {
+      old_indent = this.outer.indent;
+      this.outer.indent ~= this.outer.indentStep;
+    }
+
+    ~this()
+    { this.outer.indent = old_indent; }
+
+    char[] toString()
+    { return this.outer.indent; }
+  }
+
+  /// Saves an outer member when instantiated.
+  /// It is restored when the instance goes out of scope.
+  scope class Enter(T)
+  {
+    T t_save;
+    this(T t)
+    {
+      auto t_save = t;
+      static if (is(T == ClassDeclaration) ||
+                 is(T == InterfaceDeclaration) ||
+                 is(T == StructDeclaration) ||
+                 is(T == UnionDeclaration))
+        this.outer.inAggregate = t;
+      static if (is(T == FunctionDeclaration) ||
+                 is(T == ConstructorDeclaration))
+        this.outer.inFunc = t;
+    }
+
+    ~this()
+    {
+      static if (is(T == ClassDeclaration) ||
+                 is(T == InterfaceDeclaration) ||
+                 is(T == StructDeclaration) ||
+                 is(T == UnionDeclaration))
+        this.outer.inAggregate = t_save;
+      static if (is(T == FunctionDeclaration) ||
+                 is(T == ConstructorDeclaration))
+        this.outer.inFunc = t_save;
+    }
+  }
+
+  alias Enter!(ClassDeclaration) EnteredClass;
+  alias Enter!(InterfaceDeclaration) EnteredInterface;
+  alias Enter!(StructDeclaration) EnteredStruct;
+  alias Enter!(UnionDeclaration) EnteredUnion;
+  alias Enter!(FunctionDeclaration) EnteredFunction;
+  alias Enter!(ConstructorDeclaration) EnteredConstructor;
+
+  /// Prints the location of a node: @(lin,col)
+  void printLoc(Node node)
+  {
+    auto loc = node.begin.getRealLocation();
+    put(indent).formatln("@({},{})",/+ loc.filePath,+/ loc.lineNum, loc.colNum);
+  }
+
+override:
+  D visit(ModuleDeclaration n)
+  {
+    printLoc(n);
+    put.format("Dies ist das Modul '{}'", n.moduleName.str);
+    if (n.packages.length)
+      put.format(" im Paket '{}'", n.getPackageName('.'));
+    put(".").newline;
+    return n;
+  }
+
+  D visit(ImportDeclaration n)
+  {
+    printLoc(n);
+    put("Importiert Symbole aus einem anderen Modul bzw. Module.").newline;
+    return n;
+  }
+
+  D visit(ClassDeclaration n)
+  {
+    printLoc(n);
+    scope E = new EnteredClass(n);
+    put(indent).formatln("'{}' is eine Klasse mit den Eigenschaften:", n.name.str);
+    scope I = new Indent();
+    n.decls && visitD(n.decls);
+    return n;
+  }
+
+  D visit(InterfaceDeclaration n)
+  {
+    printLoc(n);
+    scope E = new EnteredInterface(n);
+    put(indent).formatln("'{}' is ein Interface mit den Eigenschaften:", n.name.str);
+    scope I = new Indent();
+    n.decls && visitD(n.decls);
+    return n;
+  }
+
+  D visit(StructDeclaration n)
+  {
+    printLoc(n);
+    scope E = new EnteredStruct(n);
+    put(indent).formatln("'{}' is eine Datenstruktur mit den Eigenschaften:", n.name.str);
+    scope I = new Indent();
+    n.decls && visitD(n.decls);
+    return n;
+  }
+
+  D visit(UnionDeclaration n)
+  {
+    printLoc(n);
+    scope E = new EnteredUnion(n);
+    put(indent).formatln("'{}' is eine Datenunion mit den Eigenschaften:", n.name.str);
+    scope I = new Indent();
+    n.decls && visitD(n.decls);
+    return n;
+  }
+
+  D visit(VariablesDeclaration n)
+  {
+    printLoc(n);
+    char[] was;
+    if (inAggregate)
+      was = "Membervariable";
+    else if (inFunc)
+      was = "lokale Variable";
+    else
+      was = "globale Variable";
+    foreach (name; n.names)
+    {
+      put(indent).format("'{}' ist eine {} des Typs: ", name.str, was);
+      if (n.typeNode)
+        visitT(n.typeNode);
+      else
+        put("auto");
+      put.newline;
+    }
+    return n;
+  }
+
+  D visit(FunctionDeclaration n)
+  {
+    printLoc(n);
+    char[] was;
+    if (inAggregate)
+      was = "Methode";
+    else if(inFunc)
+      was = "geschachtelte Funktion";
+    else
+      was = "Funktion";
+    scope E = new EnteredFunction(n);
+    put(indent).format("'{}' ist eine {} ", n.name.str, was);
+    if (n.params.length == 1)
+      put("mit dem Argument "), visitN(n.params);
+    else if (n.params.length > 1)
+      put("mit den Argumenten "), visitN(n.params);
+    else
+      put("ohne Argumente");
+    put(".").newline;
+    scope I = new Indent();
+    return n;
+  }
+
+  D visit(ConstructorDeclaration n)
+  {
+    printLoc(n);
+    scope E = new EnteredConstructor(n);
+    put(indent)("Ein Konstruktor ");
+    if (n.params.length == 1)
+      put("mit dem Argument "), visitN(n.params);
+    else if (n.params.length > 1)
+      put("mit den Argumenten "), visitN(n.params);
+    else
+      put("ohne Argumente");
+    put(".").newline;
+    return n;
+  }
+
+  D visit(StaticConstructorDeclaration n)
+  {
+    printLoc(n);
+    put(indent)("Ein statischer Konstruktor.").newline;
+    return n;
+  }
+
+  D visit(DestructorDeclaration n)
+  {
+    printLoc(n);
+    put(indent)("Ein Destruktor.").newline;
+    return n;
+  }
+
+  D visit(StaticDestructorDeclaration n)
+  {
+    printLoc(n);
+    put(indent)("Ein statischer Destruktor.").newline;
+    return n;
+  }
+
+  D visit(InvariantDeclaration n)
+  {
+    printLoc(n);
+    put(indent)("Eine Unveränderliche.").newline;
+    return n;
+  }
+
+  D visit(UnittestDeclaration n)
+  {
+    printLoc(n);
+    put(indent)("Ein Komponententest.").newline;
+    return n;
+  }
+
+  Node visit(Parameter n)
+  {
+    put.format("'{}' des Typs \"", n.name ? n.name.str : "unbenannt");
+    n.type && visitN(n.type);
+    put(\");
+    return n;
+  }
+
+  Node visit(Parameters n)
+  {
+    if (n.length > 1)
+    {
+      visitN(n.children[0]);
+      foreach (node; n.children[1..$])
+        put(", "), visitN(node);
+    }
+    else
+      super.visit(n);
+    return n;
+  }
+
+  TypeNode visit(ArrayType n)
+  {
+    char[] c1 = "s", c2 = "";
+    if (pluralize)
+      (c1 = pointer ? ""[] : "n"), (c2 = "s");
+    pointer = false;
+    if (n.assocType)
+      put.format("assoziative{} Array{} von ", c1, c2);
+//       visitT(n.assocType);
+    else if (n.e1)
+    {
+      if (n.e2)
+        put.format("gescheibte{} Array{} von ", c1, c2);
+      else
+        put.format("statische{} Array{} von ", c1, c2);
+//       visitE(n.e), n.e2 && visitE(n.e2);
+    }
+    else
+      put.format("dynamische{} Array{} von ", c1, c2);
+    // Types following arrays should be in plural.
+    pluralize = true;
+    visitT(n.next);
+    pluralize = false;
+    return n;
+  }
+
+  TypeNode visit(PointerType n)
+  {
+    char[] c = pluralize ? (pointer ? ""[] : "n") : "";
+    pointer = true;
+    put.format("Zeiger{} auf ", c), visitT(n.next);
+    return n;
+  }
+
+  TypeNode visit(QualifiedType n)
+  {
+    visitT(n.lhs);
+    put(".");
+    visitT(n.rhs);
+    return n;
+  }
+
+  TypeNode visit(IdentifierType n)
+  {
+    put(n.ident.str);
+    return n;
+  }
+
+  TypeNode visit(IntegralType n)
+  {
+    char[] c = pluralize ? "s"[] : "";
+    if (n.tok == TOK.Void) // Avoid pluralizing "void"
+      c = "";
+    put.format("{}{}", n.begin.srcText, c);
+    return n;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/archdoc.xmi	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,1066 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<XMI xmlns:UML="http://schema.omg.org/spec/UML/1.3" verified="false" timestamp="2007-10-15T23:59:30" xmi.version="1.2" >
+ <XMI.header>
+  <XMI.documentation>
+   <XMI.exporter>umbrello uml modeller http://uml.sf.net</XMI.exporter>
+   <XMI.exporterVersion>1.5.8</XMI.exporterVersion>
+   <XMI.exporterEncoding>UnicodeUTF8</XMI.exporterEncoding>
+  </XMI.documentation>
+  <XMI.metamodel xmi.name="UML" href="UML.xml" xmi.version="1.3" />
+ </XMI.header>
+ <XMI.content>
+  <UML:Model isSpecification="false" isLeaf="false" isRoot="false" xmi.id="m1" isAbstract="false" name="Umbrello UML mallintaja" >
+   <UML:Namespace.ownedElement>
+    <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="folder" isRoot="false" isAbstract="false" name="folder" />
+    <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="datatype" isRoot="false" isAbstract="false" name="datatype" />
+    <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="enum" isRoot="false" isAbstract="false" name="enum" />
+    <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="interface" isRoot="false" isAbstract="false" name="interface" />
+    <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Logical View" isRoot="false" isAbstract="false" name="Logical View" >
+     <UML:Namespace.ownedElement>
+      <UML:Package stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="Datatypes" isRoot="false" isAbstract="false" name="Datatypes" >
+       <UML:Namespace.ownedElement>
+        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="wMWsornjU1NO" isRoot="false" isAbstract="false" name="int" />
+        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="MGwAYPpykhTm" isRoot="false" isAbstract="false" name="char" />
+        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="EaC7G8UkzGbk" isRoot="false" isAbstract="false" name="bool" />
+        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="z3jKRbJnqFxM" isRoot="false" isAbstract="false" name="float" />
+        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="clKKQl7eLHlZ" isRoot="false" isAbstract="false" name="double" />
+        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="NFJMWv4VyoqO" isRoot="false" isAbstract="false" name="short" />
+        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="N7BDN7YzqsIG" isRoot="false" isAbstract="false" name="long" />
+        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="cPuvefV1toMN" isRoot="false" isAbstract="false" name="unsigned int" />
+        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="hQqeEe2cmDn9" isRoot="false" isAbstract="false" name="unsigned short" />
+        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="IL68COOolGjP" isRoot="false" isAbstract="false" name="unsigned long" />
+        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="wERn1lAgB0KQ" isRoot="false" isAbstract="false" name="string" />
+        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="tblJnk8mwuii" isRoot="false" isAbstract="false" name="GraphNode[]" elementReference="FVtbgO8sd2ii" />
+        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="zgj70ST7PbVQ" isRoot="false" isAbstract="false" name="undef" >
+         <UML:GeneralizableElement.generalization>
+          <UML:Generalization xmi.idref="1dmVIJyonUEn" />
+          <UML:Generalization xmi.idref="p27xKs3wyvpN" />
+          <UML:Generalization xmi.idref="lO9c3UK3Ot3L" />
+          <UML:Generalization xmi.idref="ns2H6KLVJ9Xb" />
+         </UML:GeneralizableElement.generalization>
+        </UML:DataType>
+        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="UGpWCc0uWy3g" isRoot="false" isAbstract="false" name="Vertex[]" elementReference="FVtbgO8sd2ii" />
+        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="QXgD4zE4FsCt" isRoot="false" isAbstract="false" name="GraphWriterOptions *" />
+        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="DaFOT7jBVtui" isRoot="false" isAbstract="false" name="CodeListerOptions *" />
+       </UML:Namespace.ownedElement>
+      </UML:Package>
+      <UML:Class comment="CodeLister " isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="gGNje78ValnI" isRoot="false" isAbstract="true" name="AbstractListingWriter" >
+       <UML:Classifier.feature>
+        <UML:Attribute isSpecification="false" visibility="protected" xmi.id="hcALY1fmWlEG" type="DdhFJyNQcQSm" name="factory" />
+        <UML:Attribute isSpecification="false" visibility="protected" xmi.id="9QXgkpqgA1Du" type="3qQutO5Yhxt6" name="outputs" />
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="Aa3THxJUbPoV" isRoot="false" isAbstract="false" isQuery="false" name="this" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="BqUI126Bc7cr" value="" type="DdhFJyNQcQSm" name="factory" />
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="UJXlWuv0im5m" value="" type="3qQutO5Yhxt6" name="outputs" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="UY72E0ULeXyT" isRoot="false" isAbstract="false" name="Parser" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="KASRlJWedAvi" client="gGNje78ValnI" name="" supplier="UY72E0ULeXyT" />
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="OcpJQugxHW8F" isRoot="false" isAbstract="false" name="ListingOptions" >
+       <UML:Classifier.feature>
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="gOHG3iCLbStZ" type="58hyBKGITKzU" name="docFormat" />
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="uYIB5OPcbNSb" client="gGNje78ValnI" name="" supplier="OcpJQugxHW8F" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="dw4fHleozmt5" client="gGNje78ValnI" name="" supplier="zgj70ST7PbVQ" />
+      <UML:Enumeration stereotype="enum" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="58hyBKGITKzU" isRoot="false" isAbstract="false" name="DocFormat" >
+       <UML:EnumerationLiteral comment="LaTeX + listings currently" isSpecification="false" isLeaf="false" visibility="public" namespace="58hyBKGITKzU" xmi.id="jnhozkQ1UqIp" isRoot="false" isAbstract="false" name="LaTeX" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="58hyBKGITKzU" xmi.id="DhN6TjTmtUai" isRoot="false" isAbstract="false" name="XML" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="58hyBKGITKzU" xmi.id="eyKevtlegQQd" isRoot="false" isAbstract="false" name="HTML" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="58hyBKGITKzU" xmi.id="9qedeuTpcot5" isRoot="false" isAbstract="false" name="PlainText" />
+      </UML:Enumeration>
+      <UML:Enumeration stereotype="enum" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="o5RT7D5TyDem" isRoot="false" isAbstract="false" name="CommentFormat" >
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="o5RT7D5TyDem" xmi.id="pCzlo8cW1N0o" isRoot="false" isAbstract="false" name="ddoc" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="o5RT7D5TyDem" xmi.id="FS23UTFrinBx" isRoot="false" isAbstract="false" name="doxygen" />
+      </UML:Enumeration>
+      <UML:Interface stereotype="interface" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="zhVfgpENwAeN" isRoot="false" isAbstract="true" name="ListingWriter" >
+       <UML:Classifier.feature>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="eGKXDits9Kho" isRoot="false" isAbstract="false" isQuery="false" name="generateListing" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="KNIleVffDrUP" value="" type="yBk69LKYzyaX" name="stream" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="fA2So7Re6pf2" isRoot="false" isAbstract="false" isQuery="false" name="generateListing" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="Au5dZofnQ9Fm" value="" type="UY72E0ULeXyT" name="parser" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+       </UML:Classifier.feature>
+      </UML:Interface>
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="qxq04A8rywIb" isRoot="false" isAbstract="false" name="XMLWriter" >
+       <UML:GeneralizableElement.generalization>
+        <UML:Generalization xmi.idref="u534X7uMBIy5" />
+       </UML:GeneralizableElement.generalization>
+       <UML:Classifier.feature>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="KoEO9zJwTXuD" isRoot="false" isAbstract="false" isQuery="false" name="generateListing" />
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="w884b40YcIag" isRoot="false" isAbstract="false" name="HTMLWriter" >
+       <UML:GeneralizableElement.generalization>
+        <UML:Generalization xmi.idref="1tZ6hQ3Znq07" />
+       </UML:GeneralizableElement.generalization>
+       <UML:Classifier.feature>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="mBRaST74dftD" isRoot="false" isAbstract="false" isQuery="false" name="generateListing" />
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="B92ON93E7uE9" isRoot="false" isAbstract="false" name="LatexWriter" >
+       <UML:GeneralizableElement.generalization>
+        <UML:Generalization xmi.idref="FbDTu6ZqYxZ5" />
+       </UML:GeneralizableElement.generalization>
+       <UML:Classifier.feature>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="JpwoOQQ4RzaO" isRoot="false" isAbstract="false" isQuery="false" name="generateListing" />
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2MyyGGXAPfEy" isRoot="false" isAbstract="false" name="PlainTextWriter" >
+       <UML:GeneralizableElement.generalization>
+        <UML:Generalization xmi.idref="jNbdqaYMr5vR" />
+       </UML:GeneralizableElement.generalization>
+       <UML:Classifier.feature>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="VRgNwkJTDt0B" isRoot="false" isAbstract="false" isQuery="false" name="generateListing" />
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="haoxC1oM2QVz" isRoot="false" isAbstract="false" name="DefaultListingFactory" >
+       <UML:GeneralizableElement.generalization>
+        <UML:Generalization xmi.idref="0zf0YojVOJsY" />
+       </UML:GeneralizableElement.generalization>
+       <UML:Classifier.feature>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="2SrUGMptabML" isRoot="false" isAbstract="false" isQuery="false" name="createListingWriter" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter kind="return" xmi.id="TMA6Ge0zQMX6" type="zhVfgpENwAeN" />
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="GYFWlYNnmcE7" value="" type="3qQutO5Yhxt6" name="outputs" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="pOOtPyR4YD1i" client="gGNje78ValnI" name="" supplier="zhVfgpENwAeN" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="Hf6nfAgadb4K" client="gGNje78ValnI" name="" supplier="haoxC1oM2QVz" />
+      <UML:Abstraction isSpecification="false" visibility="public" namespace="Logical View" xmi.id="Zq72H2CSpWXa" client="2MyyGGXAPfEy" name="" supplier="zhVfgpENwAeN" />
+      <UML:Abstraction isSpecification="false" visibility="public" namespace="Logical View" xmi.id="A6N2elCBKnZO" client="B92ON93E7uE9" name="" supplier="zhVfgpENwAeN" />
+      <UML:Abstraction isSpecification="false" visibility="public" namespace="Logical View" xmi.id="eumL2kguvB4r" client="w884b40YcIag" name="" supplier="zhVfgpENwAeN" />
+      <UML:Abstraction isSpecification="false" visibility="public" namespace="Logical View" xmi.id="4EmCZ7If6KdF" client="qxq04A8rywIb" name="" supplier="zhVfgpENwAeN" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="lPLNpCYn0pMy" client="haoxC1oM2QVz" name="" supplier="qxq04A8rywIb" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="vlcHfpQlYKr7" client="haoxC1oM2QVz" name="" supplier="w884b40YcIag" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="Kg5HoKskzFEv" client="haoxC1oM2QVz" name="" supplier="B92ON93E7uE9" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="9Vk40Voo7HZw" client="haoxC1oM2QVz" name="" supplier="2MyyGGXAPfEy" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="PsKBU0u8FFdQ" client="zhVfgpENwAeN" name="" supplier="zgj70ST7PbVQ" />
+      <UML:Abstraction isSpecification="false" visibility="public" namespace="Logical View" xmi.id="xxCyboRg8fju" client="gGNje78ValnI" name="" supplier="zhVfgpENwAeN" />
+      <UML:Generalization isSpecification="false" child="2MyyGGXAPfEy" visibility="public" namespace="Logical View" xmi.id="jNbdqaYMr5vR" parent="gGNje78ValnI" discriminator="" name="" />
+      <UML:Generalization isSpecification="false" child="B92ON93E7uE9" visibility="public" namespace="Logical View" xmi.id="FbDTu6ZqYxZ5" parent="gGNje78ValnI" discriminator="" name="" />
+      <UML:Generalization isSpecification="false" child="w884b40YcIag" visibility="public" namespace="Logical View" xmi.id="1tZ6hQ3Znq07" parent="gGNje78ValnI" discriminator="" name="" />
+      <UML:Generalization isSpecification="false" child="qxq04A8rywIb" visibility="public" namespace="Logical View" xmi.id="u534X7uMBIy5" parent="gGNje78ValnI" discriminator="" name="" />
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="098RWfwZqN4L" isRoot="false" isAbstract="false" name="ModuleGraphFactory" >
+       <UML:Classifier.feature>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="CMMapfT5KiQP" isRoot="false" isAbstract="false" isQuery="false" name="createGraphWriter" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter kind="return" xmi.id="R9UhhTPng6id" type="2Mzl2VgeffI0" />
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="r5Ijnmvx8HYv" value="" type="Ug6grrz7llbI" name="modules" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Enumeration stereotype="enum" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="4F09aHCjljSA" isRoot="false" isAbstract="false" name="GraphFormat" >
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="4F09aHCjljSA" xmi.id="Uhfew917nyad" isRoot="false" isAbstract="false" name="Dot" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="4F09aHCjljSA" xmi.id="Jy1fqRBSwrTe" isRoot="false" isAbstract="false" name="ModuleNames" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="4F09aHCjljSA" xmi.id="aow2SW2oUhRP" isRoot="false" isAbstract="false" name="ModulePaths" />
+      </UML:Enumeration>
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="pwXaDeUXVlRv" isRoot="false" isAbstract="false" name="ClassGraphFactory" >
+       <UML:Classifier.feature>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="RDl3vCbldkit" isRoot="false" isAbstract="false" isQuery="false" name="createGraphWriter" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter kind="return" xmi.id="juNjzfHRzPXE" type="2Mzl2VgeffI0" />
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="eZGRSI3D44ZH" value="" type="Ug6grrz7llbI" name="modules" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="FVtbgO8sd2ii" isRoot="false" isAbstract="false" name="Vertex" >
+       <UML:GeneralizableElement.generalization>
+        <UML:Generalization xmi.idref="rtOV4FVf7iPk" />
+       </UML:GeneralizableElement.generalization>
+       <UML:Classifier.feature>
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="cf98eu4OpFbX" type="cPuvefV1toMN" name="id" />
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="hgsYJ2YnnaVS" type="wERn1lAgB0KQ" name="name" />
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="sBVGlTogVHfE" type="wERn1lAgB0KQ" name="location" />
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="ajeRzBpBzXm2" type="XjtDAoectTTH" name="incomingEdges" />
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="hTSa11gAdwIE" type="XjtDAoectTTH" name="outgoingEdges" />
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="VXmaXhPeKk9I" type="BQqAv02HTM6x" name="type" />
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="2fXtbb2YF7TG" isRoot="false" isAbstract="false" isQuery="false" name="this" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="yejRa2Oznwhc" value="" type="wERn1lAgB0KQ" name="name" />
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="659S1872M8Cd" value="" type="wERn1lAgB0KQ" name="loc" />
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="QSb02dspK6xX" value="" type="cPuvefV1toMN" name="id" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="PX2Y1eFKtaj6" isRoot="false" isAbstract="false" isQuery="false" name="isCyclic" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter kind="return" xmi.id="1XBPtiTIpxzU" type="EaC7G8UkzGbk" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Generalization isSpecification="false" child="zgj70ST7PbVQ" visibility="public" namespace="Logical View" xmi.id="1dmVIJyonUEn" parent="FVtbgO8sd2ii" discriminator="" name="" />
+      <UML:Generalization isSpecification="false" child="zgj70ST7PbVQ" visibility="public" namespace="Logical View" xmi.id="p27xKs3wyvpN" parent="FVtbgO8sd2ii" discriminator="" name="" />
+      <UML:Generalization isSpecification="false" child="zgj70ST7PbVQ" visibility="public" namespace="Logical View" xmi.id="lO9c3UK3Ot3L" parent="FVtbgO8sd2ii" discriminator="" name="" />
+      <UML:Generalization isSpecification="false" child="zgj70ST7PbVQ" visibility="public" namespace="Logical View" xmi.id="ns2H6KLVJ9Xb" parent="FVtbgO8sd2ii" discriminator="" name="" />
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="taceG4p7AY1k" isRoot="false" isAbstract="true" name="AbstractGraphWriter" >
+       <UML:Classifier.feature>
+        <UML:Attribute isSpecification="false" visibility="protected" xmi.id="jYgSGEsqagKv" type="H9NLXsg0Hncp" name="factory" />
+        <UML:Attribute isSpecification="false" visibility="protected" xmi.id="4Bqtwxx8p0pI" type="3qQutO5Yhxt6" name="outputs" />
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="RhFDP34VCWM4" isRoot="false" isAbstract="false" isQuery="false" name="this" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="tBvamRjPCFGt" value="" type="H9NLXsg0Hncp" name="factory" />
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="9EFHJ6ymPiIf" value="" type="3qQutO5Yhxt6" name="outputs" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="672lM6F9KhcI" isRoot="false" isAbstract="false" name="GraphOptions" >
+       <UML:Classifier.feature>
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="zRuotD7A5ZEx" type="4F09aHCjljSA" name="format" />
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="dMwwhlSnUoPh" type="VDAdlQhZ750q" name="imageFormat" />
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="E1vnjmQdHkkv" type="58hyBKGITKzU" name="docFormat" />
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="cGQrznU4axXm" type="cPuvefV1toMN" name="depth" />
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="UirRcvN0JEsV" type="EaC7G8UkzGbk" name="IncludeUnlocatableModules" />
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="AQlvQmLLBkXo" type="EaC7G8UkzGbk" name="GroupByFullPackageName" />
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="vOQEdHhXSPF8" type="EaC7G8UkzGbk" name="GroupByPackageNames" />
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="TrfH97Bbn23Q" type="EaC7G8UkzGbk" name="HighlightCyclicVertices" />
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="uBkkfpbvggDX" type="EaC7G8UkzGbk" name="HighlightCyclicEdges" />
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Interface stereotype="interface" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2Mzl2VgeffI0" isRoot="false" isAbstract="true" name="GraphWriter" >
+       <UML:Classifier.feature>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="kluUKuajlkAu" isRoot="false" isAbstract="false" isQuery="false" name="generateGraph" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="fREmiJ7UKXFJ" value="" type="UGpWCc0uWy3g" name="vertices" />
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="OVLa6NXYfSPa" value="" type="XjtDAoectTTH" name="edges" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+       </UML:Classifier.feature>
+      </UML:Interface>
+      <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="QrZyyaltfezo" name="" >
+       <UML:Association.connection>
+        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="kdwMLV8h83sE" aggregation="composite" type="zgj70ST7PbVQ" name="" />
+        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="Sii687Npp9vE" aggregation="none" type="FVtbgO8sd2ii" name="" />
+       </UML:Association.connection>
+      </UML:Association>
+      <UML:Generalization isSpecification="false" child="FVtbgO8sd2ii" visibility="public" namespace="Logical View" xmi.id="rtOV4FVf7iPk" parent="zgj70ST7PbVQ" discriminator="" name="" />
+      <UML:Abstraction isSpecification="false" visibility="public" namespace="Logical View" xmi.id="YFH3CyxPGsNY" client="taceG4p7AY1k" name="" supplier="2Mzl2VgeffI0" />
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="ZUDChgtO8jSy" isRoot="false" isAbstract="false" name="DotWriter" >
+       <UML:GeneralizableElement.generalization>
+        <UML:Generalization xmi.idref="gO9JCUKh4zz7" />
+       </UML:GeneralizableElement.generalization>
+       <UML:Classifier.feature>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="nXwHg6RtyC4B" isRoot="false" isAbstract="false" isQuery="false" name="generateGraph" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="L3a5zNEcbuwz" value="" type="UGpWCc0uWy3g" name="vertices" />
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="FX185qpx9hBY" value="" type="XjtDAoectTTH" name="edges" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Generalization isSpecification="false" child="ZUDChgtO8jSy" visibility="public" namespace="Logical View" xmi.id="gO9JCUKh4zz7" parent="taceG4p7AY1k" discriminator="" name="" />
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="Ug6grrz7llbI" isRoot="false" isAbstract="false" name="Parser[]" />
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="85ASUVIYu8Rm" isRoot="false" isAbstract="false" name="ClassGraphWriter" />
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="R1LMLXi8zBZD" isRoot="false" isAbstract="false" name="ModuleGraphWriter" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="eIi8xlOA51aq" client="zgj70ST7PbVQ" name="" supplier="ZUDChgtO8jSy" />
+      <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="xcuomSYFMuc3" name="" >
+       <UML:Association.connection>
+        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="Yxf0JQYnYv4n" aggregation="none" type="zgj70ST7PbVQ" name="" />
+        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="CZfvIVeFD72m" aggregation="none" type="ZUDChgtO8jSy" name="" />
+       </UML:Association.connection>
+      </UML:Association>
+      <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="KxhR786WWKiA" name="" >
+       <UML:Association.connection>
+        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="e0bOstNQo1O8" aggregation="none" type="haoxC1oM2QVz" name="" />
+        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="Pwtxqxi0ULvm" aggregation="none" type="2MyyGGXAPfEy" name="" />
+       </UML:Association.connection>
+      </UML:Association>
+      <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="036VnHDG2xBH" name="" >
+       <UML:Association.connection>
+        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="rY12d3mG4Neu" aggregation="none" type="haoxC1oM2QVz" name="" />
+        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="GzI5yhBNb2IP" aggregation="none" type="B92ON93E7uE9" name="" />
+       </UML:Association.connection>
+      </UML:Association>
+      <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="MPnzJ9f0egCU" name="" >
+       <UML:Association.connection>
+        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="xyPRKJE9rFBS" aggregation="none" type="haoxC1oM2QVz" name="" />
+        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="HxgLLIDbGVeE" aggregation="none" type="w884b40YcIag" name="" />
+       </UML:Association.connection>
+      </UML:Association>
+      <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="qQ8ZNcL54wHR" name="" >
+       <UML:Association.connection>
+        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="CnampsBkrbC9" aggregation="none" type="haoxC1oM2QVz" name="" />
+        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="sQIhdT9uOqDj" aggregation="none" type="qxq04A8rywIb" name="" />
+       </UML:Association.connection>
+      </UML:Association>
+      <UML:Enumeration stereotype="enum" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="BQqAv02HTM6x" isRoot="false" isAbstract="false" name="VertexType" >
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="BQqAv02HTM6x" xmi.id="UWXR1uwj6Xht" isRoot="false" isAbstract="false" name="module" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="BQqAv02HTM6x" xmi.id="KZH8gthgkYAr" isRoot="false" isAbstract="false" name="package" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="BQqAv02HTM6x" xmi.id="GvOp2iAWCfvE" isRoot="false" isAbstract="false" name="class" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="BQqAv02HTM6x" xmi.id="XsxdPcUh9joq" isRoot="false" isAbstract="false" name="interface" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="BQqAv02HTM6x" xmi.id="dTUN2eCIZb6Z" isRoot="false" isAbstract="false" name="trait" />
+      </UML:Enumeration>
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="PILb9kCQnOZd" isRoot="false" isAbstract="false" name="Edge" >
+       <UML:Classifier.feature>
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="Aq7LuhClDFeB" type="FVtbgO8sd2ii" name="incoming" />
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="xg3pIv6gVUUO" type="FVtbgO8sd2ii" name="outgoing" />
+        <UML:Attribute isSpecification="false" visibility="private" xmi.id="eaFFJAnvNrxh" type="uzw9DITFgRm2" name="type" />
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="p2AAWOx6E09l" isRoot="false" isAbstract="false" isQuery="false" name="this" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="mN7gwLT6JP4I" value="" type="FVtbgO8sd2ii" name="o" />
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="WNmYYSfW1HTL" value="" type="FVtbgO8sd2ii" name="i" />
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="ITeVbCmrH3BN" value="" type="BQqAv02HTM6x" name="type" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="faPqILFpZIBc" isRoot="false" isAbstract="false" isQuery="false" name="isCyclic" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter kind="return" xmi.id="ONF2RwfAq0sn" type="EaC7G8UkzGbk" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Enumeration stereotype="enum" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="uzw9DITFgRm2" isRoot="false" isAbstract="false" name="EdgeType" >
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="uzw9DITFgRm2" xmi.id="Gv3YsqBCKi6E" isRoot="false" isAbstract="false" name="unspecified" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="uzw9DITFgRm2" xmi.id="A1QhopWR6xzK" isRoot="false" isAbstract="false" name="aggregation" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="uzw9DITFgRm2" xmi.id="OVYO1FWE3aSP" isRoot="false" isAbstract="false" name="association" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="uzw9DITFgRm2" xmi.id="uXTHm0iw18dq" isRoot="false" isAbstract="false" name="composition" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="uzw9DITFgRm2" xmi.id="3Mv6vLTpsw6c" isRoot="false" isAbstract="false" name="cyclicDependency" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="uzw9DITFgRm2" xmi.id="0BPEtKs5X9EB" isRoot="false" isAbstract="false" name="dependency" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="uzw9DITFgRm2" xmi.id="w8F05EKRiqqj" isRoot="false" isAbstract="false" name="generalization" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="uzw9DITFgRm2" xmi.id="OQEcUiDMf7Wr" isRoot="false" isAbstract="false" name="inheritance" />
+      </UML:Enumeration>
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="YjondCVQ8s2U" client="2Mzl2VgeffI0" name="" supplier="zgj70ST7PbVQ" />
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="XjtDAoectTTH" isRoot="false" isAbstract="false" name="Edge[]" />
+      <UML:Interface stereotype="interface" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="H9NLXsg0Hncp" isRoot="false" isAbstract="true" name="GraphWriterFactory" >
+       <UML:Classifier.feature>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="FYgiWJyDqrhK" isRoot="false" isAbstract="false" isQuery="false" name="options" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter kind="return" xmi.id="e9EdXlpWG0u7" type="672lM6F9KhcI" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="L1C3szmMnzpw" isRoot="false" isAbstract="false" isQuery="false" name="createGraphWriter" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="YLOGwvBFuNIk" value="" type="3qQutO5Yhxt6" name="outputs" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+       </UML:Classifier.feature>
+      </UML:Interface>
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="GIPhxHkszygs" isRoot="false" isAbstract="true" name="AbstractGraphWriterFactory" >
+       <UML:Classifier.feature>
+        <UML:Attribute isSpecification="false" visibility="protected" xmi.id="ZmI5M1aN978M" type="672lM6F9KhcI" name="m_options" />
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="liEDYXNQ5pTO" isRoot="false" isAbstract="false" isQuery="false" name="options" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter kind="return" xmi.id="gNPWJNyfiEi9" type="QXgD4zE4FsCt" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="m7wwiwCSxVGR" client="2Mzl2VgeffI0" name="" supplier="FVtbgO8sd2ii" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="R79vj31U6PK0" client="2Mzl2VgeffI0" name="" supplier="PILb9kCQnOZd" />
+      <UML:Abstraction isSpecification="false" visibility="public" namespace="Logical View" xmi.id="Pef9sSrIGFql" client="GIPhxHkszygs" name="" supplier="H9NLXsg0Hncp" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="p0keVPRrye6f" client="H9NLXsg0Hncp" name="" supplier="672lM6F9KhcI" />
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="vJ8WmfZPiVQE" isRoot="false" isAbstract="false" name="DefaultGraphWriterFactory" >
+       <UML:GeneralizableElement.generalization>
+        <UML:Generalization xmi.idref="kOBlgJz6y2Lz" />
+       </UML:GeneralizableElement.generalization>
+       <UML:Classifier.feature>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="rSVt3npBuRwI" isRoot="false" isAbstract="false" isQuery="false" name="this" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="o4PMZ16oEaaK" value="" type="672lM6F9KhcI" name="options" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="qt3yjRHa0HmR" isRoot="false" isAbstract="false" isQuery="false" name="createGraphWriter" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="37SmulDSCnBM" value="" type="3qQutO5Yhxt6" name="outputs" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="leYQpk5LWBlE" isRoot="false" isAbstract="false" name="ModuleNameWriter" >
+       <UML:GeneralizableElement.generalization>
+        <UML:Generalization xmi.idref="51RZVXixdhgF" />
+       </UML:GeneralizableElement.generalization>
+       <UML:Classifier.feature>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="VR6VNEtfCgkY" isRoot="false" isAbstract="false" isQuery="false" name="generateGraph" />
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="cQGGEupKkEKw" isRoot="false" isAbstract="false" name="ModulePathWriter" >
+       <UML:GeneralizableElement.generalization>
+        <UML:Generalization xmi.idref="Z4ZHkEV03W4k" />
+       </UML:GeneralizableElement.generalization>
+       <UML:Classifier.feature>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="wEWZIkURw0Kn" isRoot="false" isAbstract="false" isQuery="false" name="generateGraph" />
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Generalization isSpecification="false" child="cQGGEupKkEKw" visibility="public" namespace="Logical View" xmi.id="Z4ZHkEV03W4k" parent="taceG4p7AY1k" discriminator="" name="" />
+      <UML:Generalization isSpecification="false" child="leYQpk5LWBlE" visibility="public" namespace="Logical View" xmi.id="51RZVXixdhgF" parent="taceG4p7AY1k" discriminator="" name="" />
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="3qQutO5Yhxt6" isRoot="false" isAbstract="false" name="OutputStream[]" />
+      <UML:Interface stereotype="interface" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="QbirDWtuKiBS" isRoot="false" isAbstract="true" name="OutputStream" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="0e7qU7vxuugt" client="H9NLXsg0Hncp" name="" supplier="QbirDWtuKiBS" />
+      <UML:Generalization isSpecification="false" child="vJ8WmfZPiVQE" visibility="public" namespace="Logical View" xmi.id="kOBlgJz6y2Lz" parent="GIPhxHkszygs" discriminator="" name="" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="jUfTITIIjhSw" client="vJ8WmfZPiVQE" name="" supplier="leYQpk5LWBlE" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="ntBujkSHp8rF" client="vJ8WmfZPiVQE" name="" supplier="cQGGEupKkEKw" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="oG7IcloUW5iz" client="vJ8WmfZPiVQE" name="" supplier="ZUDChgtO8jSy" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="6E5Os60E5bNw" client="taceG4p7AY1k" name="" supplier="QbirDWtuKiBS" />
+      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="m1ftLgsc5LXQ" isRoot="false" isAbstract="true" name="AbstractListingFactory" >
+       <UML:Classifier.feature>
+        <UML:Attribute isSpecification="false" visibility="protected" xmi.id="xswAJre2CrPi" type="OcpJQugxHW8F" name="m_options" />
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="mZ1wtQujXunn" isRoot="false" isAbstract="false" isQuery="false" name="options" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter kind="return" xmi.id="ANIyMAl0H0bm" type="DaFOT7jBVtui" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+       </UML:Classifier.feature>
+      </UML:Class>
+      <UML:Interface stereotype="interface" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="DdhFJyNQcQSm" isRoot="false" isAbstract="true" name="ListingFactory" >
+       <UML:Classifier.feature>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="QR4frQ4pllIy" isRoot="false" isAbstract="false" isQuery="false" name="options" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter kind="return" xmi.id="jPJ0PB74YVap" type="OcpJQugxHW8F" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="GL3CAg7Qy0PF" isRoot="false" isAbstract="false" isQuery="false" name="createListingWriter" >
+         <UML:BehavioralFeature.parameter>
+          <UML:Parameter kind="return" xmi.id="qWVYkDfsYxos" type="zhVfgpENwAeN" />
+          <UML:Parameter isSpecification="false" visibility="private" xmi.id="rlp4XIxd1W9V" value="" type="3qQutO5Yhxt6" name="outputs" />
+         </UML:BehavioralFeature.parameter>
+        </UML:Operation>
+       </UML:Classifier.feature>
+      </UML:Interface>
+      <UML:Abstraction isSpecification="false" visibility="public" namespace="Logical View" xmi.id="M1DRAGcxqQmM" client="m1ftLgsc5LXQ" name="" supplier="DdhFJyNQcQSm" />
+      <UML:Generalization isSpecification="false" child="haoxC1oM2QVz" visibility="public" namespace="Logical View" xmi.id="0zf0YojVOJsY" parent="m1ftLgsc5LXQ" discriminator="" name="" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="6bs0V3Pr6aVg" client="DdhFJyNQcQSm" name="" supplier="OcpJQugxHW8F" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="yQFLdIs4FB5E" client="DdhFJyNQcQSm" name="" supplier="3qQutO5Yhxt6" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="ykj8Siycsv3x" client="gGNje78ValnI" name="" supplier="3qQutO5Yhxt6" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="YFeUspY6csTF" client="zhVfgpENwAeN" name="" supplier="UY72E0ULeXyT" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="8nWBoU6zOpZ6" client="gGNje78ValnI" name="" supplier="QbirDWtuKiBS" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="0RBqSjye7dsd" client="DdhFJyNQcQSm" name="" supplier="QbirDWtuKiBS" />
+      <UML:Interface stereotype="interface" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="yBk69LKYzyaX" isRoot="false" isAbstract="true" name="InputStream" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="veycFmCVOnie" client="zhVfgpENwAeN" name="" supplier="yBk69LKYzyaX" />
+      <UML:Enumeration stereotype="enum" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="VDAdlQhZ750q" isRoot="false" isAbstract="false" name="ImageFormat" >
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="VDAdlQhZ750q" xmi.id="NPNgtZqJFAtE" isRoot="false" isAbstract="false" name="PNG" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="VDAdlQhZ750q" xmi.id="2W24K4edixcf" isRoot="false" isAbstract="false" name="SVG" />
+       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="VDAdlQhZ750q" xmi.id="kjad3bVP0s5s" isRoot="false" isAbstract="false" name="GIF" />
+      </UML:Enumeration>
+     </UML:Namespace.ownedElement>
+     <XMI.extension xmi.extender="umbrello" >
+      <diagrams>
+       <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1042" snapy="10" showatts="1" xmi.id="VfRLtV4Z9Ptg" documentation="" type="1" showops="1" showpackage="0" name="Source listing classes" localid="" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="860" >
+        <widgets>
+         <classwidget usesdiagramfillcolor="0" width="428" showattsigs="601" x="504" fillcolor="#ffffc0" y="464" drawascircle="0" showopsigs="601" linewidth="none" height="72" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="gGNje78ValnI" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
+         <classwidget usesdiagramfillcolor="1" width="62" showattsigs="601" x="862" fillcolor="none" y="200" showopsigs="601" linewidth="none" height="36" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="UY72E0ULeXyT" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+         <classwidget usesdiagramfillcolor="0" width="175" showattsigs="601" x="135" fillcolor="#ffffc0" y="236" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="OcpJQugxHW8F" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
+         <interfacewidget usesdiagramfillcolor="0" width="368" x="643" fillcolor="#ffffc0" y="291" drawascircle="0" showopsigs="601" linewidth="none" height="81" usefillcolor="1" showpubliconly="0" isinstance="0" xmi.id="zhVfgpENwAeN" showoperations="1" showpackage="0" showscope="1" showstereotype="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
+         <classwidget usesdiagramfillcolor="0" width="145" showattsigs="601" x="404" fillcolor="#ffffc0" y="747" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="qxq04A8rywIb" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
+         <classwidget usesdiagramfillcolor="0" width="145" showattsigs="601" x="559" fillcolor="#ffffc0" y="747" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="w884b40YcIag" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
+         <classwidget usesdiagramfillcolor="0" width="145" showattsigs="601" x="714" fillcolor="#ffffc0" y="747" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="B92ON93E7uE9" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
+         <classwidget usesdiagramfillcolor="0" width="145" showattsigs="601" x="869" fillcolor="#ffffc0" y="747" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="2MyyGGXAPfEy" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
+         <classwidget usesdiagramfillcolor="0" width="411" showattsigs="601" x="17" fillcolor="#ffffc0" y="582" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="haoxC1oM2QVz" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
+         <classwidget usesdiagramfillcolor="0" width="226" showattsigs="601" x="109" fillcolor="#ffffc0" y="482" drawascircle="0" showopsigs="601" linewidth="none" height="54" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="m1ftLgsc5LXQ" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
+         <interfacewidget usesdiagramfillcolor="0" width="411" x="17" fillcolor="#ffffc0" y="355" drawascircle="0" showopsigs="601" linewidth="none" height="81" usefillcolor="1" showpubliconly="0" isinstance="0" xmi.id="DdhFJyNQcQSm" showoperations="1" showpackage="0" showscope="1" showstereotype="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
+         <interfacewidget usesdiagramfillcolor="1" width="127" x="498" fillcolor="none" y="324" drawascircle="0" showopsigs="601" linewidth="none" height="54" usefillcolor="1" showpubliconly="0" isinstance="0" xmi.id="QbirDWtuKiBS" showoperations="1" showpackage="0" showscope="1" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+         <interfacewidget usesdiagramfillcolor="1" width="113" x="690" fillcolor="none" y="182" drawascircle="0" showopsigs="601" linewidth="none" height="54" usefillcolor="1" showpubliconly="0" isinstance="0" xmi.id="yBk69LKYzyaX" showoperations="1" showpackage="0" showscope="1" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+        </widgets>
+        <messages/>
+        <associations>
+         <assocwidget totalcounta="4" indexa="3" totalcountb="2" indexb="1" linewidth="none" widgetbid="zhVfgpENwAeN" widgetaid="gGNje78ValnI" xmi.id="xxCyboRg8fju" type="511" linecolor="none" >
+          <linepath>
+           <startpoint startx="825" starty="464" />
+           <endpoint endx="827" endy="372" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="2" totalcountb="5" indexb="4" linewidth="none" widgetbid="gGNje78ValnI" widgetaid="2MyyGGXAPfEy" xmi.id="jNbdqaYMr5vR" type="500" linecolor="none" >
+          <linepath>
+           <startpoint startx="965" starty="747" />
+           <endpoint endx="846" endy="536" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="2" totalcountb="5" indexb="3" linewidth="none" widgetbid="gGNje78ValnI" widgetaid="B92ON93E7uE9" xmi.id="FbDTu6ZqYxZ5" type="500" linecolor="none" >
+          <linepath>
+           <startpoint startx="810" starty="747" />
+           <endpoint endx="760" endy="536" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="2" totalcountb="5" indexb="2" linewidth="none" widgetbid="gGNje78ValnI" widgetaid="w884b40YcIag" xmi.id="1tZ6hQ3Znq07" type="500" linecolor="none" >
+          <linepath>
+           <startpoint startx="655" starty="747" />
+           <endpoint endx="675" endy="536" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="2" totalcountb="5" indexb="1" linewidth="none" widgetbid="gGNje78ValnI" widgetaid="qxq04A8rywIb" xmi.id="u534X7uMBIy5" type="500" linecolor="none" >
+          <linepath>
+           <startpoint startx="500" starty="747" />
+           <endpoint endx="589" endy="536" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="5" indexa="4" totalcountb="3" indexb="1" linewidth="none" widgetbid="2MyyGGXAPfEy" widgetaid="haoxC1oM2QVz" xmi.id="KxhR786WWKiA" type="512" linecolor="none" >
+          <linepath>
+           <startpoint startx="345" starty="627" />
+           <endpoint endx="917" endy="747" />
+           <point x="846" y="686" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="5" indexa="3" totalcountb="3" indexb="1" linewidth="none" widgetbid="B92ON93E7uE9" widgetaid="haoxC1oM2QVz" xmi.id="036VnHDG2xBH" type="512" linecolor="none" >
+          <linepath>
+           <startpoint startx="263" starty="627" />
+           <endpoint endx="762" endy="747" />
+           <point x="693" y="689" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="5" indexa="2" totalcountb="3" indexb="1" linewidth="none" widgetbid="w884b40YcIag" widgetaid="haoxC1oM2QVz" xmi.id="MPnzJ9f0egCU" type="512" linecolor="none" >
+          <linepath>
+           <startpoint startx="181" starty="627" />
+           <endpoint endx="607" endy="747" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="5" indexa="1" totalcountb="3" indexb="1" linewidth="none" widgetbid="qxq04A8rywIb" widgetaid="haoxC1oM2QVz" xmi.id="qQ8ZNcL54wHR" type="512" linecolor="none" >
+          <linepath>
+           <startpoint startx="99" starty="627" />
+           <endpoint endx="452" endy="747" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="4" indexa="1" visibilityB="200" totalcountb="3" indexb="2" linewidth="none" widgetbid="DdhFJyNQcQSm" widgetaid="gGNje78ValnI" xmi.id="hcALY1fmWlEG" type="510" changeabilityA="900" changeabilityB="900" linecolor="none" visibilityA="200" >
+          <linepath>
+           <startpoint startx="611" starty="464" />
+           <endpoint endx="428" endy="409" />
+           <point x="541" y="409" />
+          </linepath>
+          <floatingtext usesdiagramfillcolor="1" width="66" x="448" fillcolor="none" y="410" linewidth="none" posttext="" role="710" height="22" usefillcolor="1" pretext="#" isinstance="0" xmi.id="vasmP4T4bt7x" text="factory" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+         </assocwidget>
+         <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="DdhFJyNQcQSm" widgetaid="m1ftLgsc5LXQ" xmi.id="M1DRAGcxqQmM" type="511" linecolor="none" >
+          <linepath>
+           <startpoint startx="222" starty="482" />
+           <endpoint endx="222" endy="436" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="m1ftLgsc5LXQ" widgetaid="haoxC1oM2QVz" xmi.id="0zf0YojVOJsY" type="500" linecolor="none" >
+          <linepath>
+           <startpoint startx="222" starty="582" />
+           <endpoint endx="222" endy="536" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="OcpJQugxHW8F" widgetaid="DdhFJyNQcQSm" xmi.id="6bs0V3Pr6aVg" type="502" linecolor="none" >
+          <linepath>
+           <startpoint startx="222" starty="355" />
+           <endpoint endx="222" endy="281" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="2" totalcountb="2" indexb="1" linewidth="none" widgetbid="UY72E0ULeXyT" widgetaid="zhVfgpENwAeN" xmi.id="YFeUspY6csTF" type="502" linecolor="none" >
+          <linepath>
+           <startpoint startx="888" starty="291" />
+           <endpoint endx="893" endy="236" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="4" indexa="2" totalcountb="2" indexb="1" linewidth="none" widgetbid="QbirDWtuKiBS" widgetaid="gGNje78ValnI" xmi.id="8nWBoU6zOpZ6" type="502" linecolor="none" >
+          <linepath>
+           <startpoint startx="718" starty="464" />
+           <endpoint endx="561" endy="378" />
+           <point x="604" y="432" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="QbirDWtuKiBS" widgetaid="DdhFJyNQcQSm" xmi.id="0RBqSjye7dsd" type="502" linecolor="none" >
+          <linepath>
+           <startpoint startx="428" starty="382" />
+           <endpoint endx="498" endy="351" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="yBk69LKYzyaX" widgetaid="zhVfgpENwAeN" xmi.id="veycFmCVOnie" type="502" linecolor="none" >
+          <linepath>
+           <startpoint startx="765" starty="291" />
+           <endpoint endx="746" endy="236" />
+          </linepath>
+         </assocwidget>
+        </associations>
+       </diagram>
+       <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1042" snapy="10" showatts="1" xmi.id="BbQfy5JEWUGf" documentation="" type="1" showops="1" showpackage="0" name="Class graph classes" localid="" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="860" >
+        <widgets>
+         <classwidget usesdiagramfillcolor="0" width="386" showattsigs="601" x="304" fillcolor="#ffffc0" y="533" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="pwXaDeUXVlRv" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
+         <classwidget usesdiagramfillcolor="0" width="168" showattsigs="601" x="201" fillcolor="#ffffc0" y="283" showopsigs="601" linewidth="none" height="36" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="85ASUVIYu8Rm" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
+        </widgets>
+        <messages/>
+        <associations/>
+       </diagram>
+       <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1042" snapy="10" showatts="1" xmi.id="PnEBEL9IihdQ" documentation="" type="1" showops="1" showpackage="0" name="Module doc classes" localid="" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="860" >
+        <widgets/>
+        <messages/>
+        <associations/>
+       </diagram>
+       <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1042" snapy="10" showatts="1" xmi.id="i9im14LKfTmZ" documentation="" type="1" showops="1" showpackage="0" name="Module graph classes" localid="" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="860" >
+        <widgets>
+         <classwidget usesdiagramfillcolor="0" width="386" showattsigs="601" x="307" fillcolor="#ffffc0" y="545" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="098RWfwZqN4L" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
+         <classwidget usesdiagramfillcolor="0" width="194" showattsigs="601" x="197" fillcolor="#ffffc0" y="276" showopsigs="601" linewidth="none" height="36" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="R1LMLXi8zBZD" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
+        </widgets>
+        <messages/>
+        <associations/>
+       </diagram>
+       <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1042" snapy="10" showatts="1" xmi.id="HBjs7fL0WfO5" documentation="" type="1" showops="1" showpackage="0" name="General classes" localid="" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="860" >
+        <widgets>
+         <enumwidget usesdiagramfillcolor="0" width="162" x="98" fillcolor="#ffffc0" y="44" linewidth="none" height="108" usefillcolor="1" isinstance="0" xmi.id="58hyBKGITKzU" showpackage="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
+         <enumwidget usesdiagramfillcolor="0" width="183" x="300" fillcolor="#ffffc0" y="44" linewidth="none" height="72" usefillcolor="1" isinstance="0" xmi.id="o5RT7D5TyDem" showpackage="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
+        </widgets>
+        <messages/>
+        <associations/>
+       </diagram>
+       <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1042" snapy="10" showatts="1" xmi.id="37Q7pvtspjUI" documentation="" type="1" showops="1" showpackage="0" name="Graph classes" localid="" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="860" >
+        <widgets>
+         <classwidget usesdiagramfillcolor="0" width="330" showattsigs="601" x="324" fillcolor="#ffffc0" y="228" showopsigs="601" linewidth="none" height="162" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="FVtbgO8sd2ii" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
+         <enumwidget usesdiagramfillcolor="0" width="172" x="62" fillcolor="#ffffc0" y="90" linewidth="none" height="90" usefillcolor="1" isinstance="0" xmi.id="4F09aHCjljSA" showpackage="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
+         <interfacewidget usesdiagramfillcolor="0" width="375" x="622" fillcolor="#ffffc0" y="433" drawascircle="0" showopsigs="601" linewidth="none" height="63" usefillcolor="1" showpubliconly="0" isinstance="0" xmi.id="2Mzl2VgeffI0" showoperations="1" showpackage="0" showscope="1" showstereotype="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
+         <classwidget usesdiagramfillcolor="0" width="436" showattsigs="601" x="481" fillcolor="#ffffc0" y="546" drawascircle="0" showopsigs="601" linewidth="none" height="72" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="taceG4p7AY1k" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
+         <classwidget usesdiagramfillcolor="0" width="236" showattsigs="601" x="70" fillcolor="#ffffc0" y="228" showopsigs="601" linewidth="none" height="189" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="672lM6F9KhcI" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
+         <classwidget usesdiagramfillcolor="0" width="375" showattsigs="601" x="623" fillcolor="#ffffc0" y="766" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="ZUDChgtO8jSy" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
+         <enumwidget usesdiagramfillcolor="0" width="110" x="434" fillcolor="#ffffc0" y="54" linewidth="none" height="126" usefillcolor="1" isinstance="0" xmi.id="BQqAv02HTM6x" showpackage="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
+         <classwidget usesdiagramfillcolor="0" width="309" showattsigs="601" x="729" fillcolor="#ffffc0" y="234" showopsigs="601" linewidth="none" height="108" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="PILb9kCQnOZd" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
+         <enumwidget usesdiagramfillcolor="0" width="136" x="815" fillcolor="#ffffc0" y="0" linewidth="none" height="180" usefillcolor="1" isinstance="0" xmi.id="uzw9DITFgRm2" showpackage="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
+         <interfacewidget usesdiagramfillcolor="0" width="338" x="19" fillcolor="#ffffc0" y="440" drawascircle="0" showopsigs="601" linewidth="none" height="81" usefillcolor="1" showpubliconly="0" isinstance="0" xmi.id="H9NLXsg0Hncp" showoperations="1" showpackage="0" showscope="1" showstereotype="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
+         <classwidget usesdiagramfillcolor="0" width="250" showattsigs="601" x="63" fillcolor="#ffffc0" y="554" drawascircle="0" showopsigs="601" linewidth="none" height="54" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="GIPhxHkszygs" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
+         <classwidget usesdiagramfillcolor="0" width="319" showattsigs="601" x="29" fillcolor="#ffffc0" y="646" showopsigs="601" linewidth="none" height="63" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="vJ8WmfZPiVQE" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
+         <classwidget usesdiagramfillcolor="0" width="156" showattsigs="601" x="296" fillcolor="#ffffc0" y="766" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="leYQpk5LWBlE" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
+         <classwidget usesdiagramfillcolor="0" width="147" showattsigs="601" x="464" fillcolor="#ffffc0" y="766" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="cQGGEupKkEKw" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
+         <interfacewidget usesdiagramfillcolor="1" width="127" x="426" fillcolor="none" y="423" drawascircle="0" showopsigs="601" linewidth="none" height="54" usefillcolor="1" showpubliconly="0" isinstance="0" xmi.id="QbirDWtuKiBS" showoperations="1" showpackage="0" showscope="1" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+         <enumwidget usesdiagramfillcolor="0" width="112" x="259" fillcolor="#ffffc0" y="90" linewidth="none" height="90" usefillcolor="1" isinstance="0" xmi.id="VDAdlQhZ750q" showpackage="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
+        </widgets>
+        <messages/>
+        <associations>
+         <assocwidget totalcounta="4" indexa="3" totalcountb="2" indexb="1" linewidth="none" widgetbid="2Mzl2VgeffI0" widgetaid="taceG4p7AY1k" xmi.id="YFH3CyxPGsNY" type="511" linecolor="none" >
+          <linepath>
+           <startpoint startx="808" starty="546" />
+           <endpoint endx="809" endy="496" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="2" totalcountb="4" indexb="3" linewidth="none" widgetbid="taceG4p7AY1k" widgetaid="ZUDChgtO8jSy" xmi.id="gO9JCUKh4zz7" type="500" linecolor="none" >
+          <linepath>
+           <startpoint startx="873" starty="766" />
+           <endpoint endx="808" endy="618" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="1" visibilityB="200" totalcountb="4" indexb="1" linewidth="none" widgetbid="FVtbgO8sd2ii" widgetaid="PILb9kCQnOZd" xmi.id="Aq7LuhClDFeB" type="510" changeabilityA="900" changeabilityB="900" linecolor="none" visibilityA="200" >
+          <linepath>
+           <startpoint startx="729" starty="270" />
+           <endpoint endx="654" endy="268" />
+          </linepath>
+          <floatingtext usesdiagramfillcolor="1" width="76" x="653" fillcolor="none" y="246" linewidth="none" posttext="" role="710" height="22" usefillcolor="1" pretext="-" isinstance="0" xmi.id="6iFUQNA8O29G" text="incoming" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+         </assocwidget>
+         <assocwidget totalcounta="2" indexa="1" visibilityB="200" totalcountb="2" indexb="1" linewidth="none" widgetbid="uzw9DITFgRm2" widgetaid="PILb9kCQnOZd" xmi.id="eaFFJAnvNrxh" type="510" changeabilityA="900" changeabilityB="900" linecolor="none" visibilityA="200" >
+          <linepath>
+           <startpoint startx="883" starty="234" />
+           <endpoint endx="883" endy="180" />
+          </linepath>
+          <floatingtext usesdiagramfillcolor="1" width="43" x="838" fillcolor="none" y="182" linewidth="none" posttext="" role="710" height="22" usefillcolor="1" pretext="-" isinstance="0" xmi.id="37WQwMtpwlbJ" text="type" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="2" visibilityB="200" totalcountb="4" indexb="2" linewidth="none" widgetbid="FVtbgO8sd2ii" widgetaid="PILb9kCQnOZd" xmi.id="xg3pIv6gVUUO" type="510" changeabilityA="900" changeabilityB="900" linecolor="none" visibilityA="200" >
+          <linepath>
+           <startpoint startx="729" starty="306" />
+           <endpoint endx="654" endy="309" />
+          </linepath>
+          <floatingtext usesdiagramfillcolor="1" width="75" x="649" fillcolor="none" y="309" linewidth="none" posttext="" role="710" height="22" usefillcolor="1" pretext="-" isinstance="0" xmi.id="n4MMwRI29XWX" text="outgoing" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="1" totalcountb="4" indexb="3" linewidth="none" widgetbid="FVtbgO8sd2ii" widgetaid="2Mzl2VgeffI0" xmi.id="m7wwiwCSxVGR" type="502" linecolor="none" >
+          <linepath>
+           <startpoint startx="747" starty="433" />
+           <endpoint endx="654" endy="349" />
+           <point x="714" y="385" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="2" totalcountb="2" indexb="1" linewidth="none" widgetbid="PILb9kCQnOZd" widgetaid="2Mzl2VgeffI0" xmi.id="R79vj31U6PK0" type="502" linecolor="none" >
+          <linepath>
+           <startpoint startx="872" starty="433" />
+           <endpoint endx="883" endy="342" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="H9NLXsg0Hncp" widgetaid="GIPhxHkszygs" xmi.id="Pef9sSrIGFql" type="511" linecolor="none" >
+          <linepath>
+           <startpoint startx="188" starty="554" />
+           <endpoint endx="188" endy="521" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="4" indexa="1" visibilityB="200" totalcountb="3" indexb="2" linewidth="none" widgetbid="H9NLXsg0Hncp" widgetaid="taceG4p7AY1k" xmi.id="jYgSGEsqagKv" type="510" changeabilityA="900" changeabilityB="900" linecolor="none" visibilityA="200" >
+          <linepath>
+           <startpoint startx="590" starty="546" />
+           <endpoint endx="357" endy="494" />
+           <point x="516" y="494" />
+          </linepath>
+          <floatingtext usesdiagramfillcolor="1" width="66" x="359" fillcolor="none" y="496" linewidth="none" posttext="" role="710" height="22" usefillcolor="1" pretext="#" isinstance="0" xmi.id="uefHfmXit36n" text="factory" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+         </assocwidget>
+         <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="672lM6F9KhcI" widgetaid="H9NLXsg0Hncp" xmi.id="p0keVPRrye6f" type="502" linecolor="none" >
+          <linepath>
+           <startpoint startx="188" starty="440" />
+           <endpoint endx="188" endy="417" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="2" totalcountb="4" indexb="2" linewidth="none" widgetbid="taceG4p7AY1k" widgetaid="cQGGEupKkEKw" xmi.id="Z4ZHkEV03W4k" type="500" linecolor="none" >
+          <linepath>
+           <startpoint startx="562" starty="766" />
+           <endpoint endx="699" endy="618" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="2" totalcountb="4" indexb="1" linewidth="none" widgetbid="taceG4p7AY1k" widgetaid="leYQpk5LWBlE" xmi.id="51RZVXixdhgF" type="500" linecolor="none" >
+          <linepath>
+           <startpoint startx="400" starty="766" />
+           <endpoint endx="590" endy="618" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="QbirDWtuKiBS" widgetaid="H9NLXsg0Hncp" xmi.id="0e7qU7vxuugt" type="502" linecolor="none" >
+          <linepath>
+           <startpoint startx="357" starty="467" />
+           <endpoint endx="426" endy="450" />
+           <point x="409" y="467" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="GIPhxHkszygs" widgetaid="vJ8WmfZPiVQE" xmi.id="kOBlgJz6y2Lz" type="500" linecolor="none" >
+          <linepath>
+           <startpoint startx="188" starty="646" />
+           <endpoint endx="188" endy="608" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="1" totalcountb="3" indexb="1" linewidth="none" widgetbid="leYQpk5LWBlE" widgetaid="vJ8WmfZPiVQE" xmi.id="jUfTITIIjhSw" type="502" linecolor="none" >
+          <linepath>
+           <startpoint startx="135" starty="709" />
+           <endpoint endx="348" endy="766" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="2" totalcountb="3" indexb="1" linewidth="none" widgetbid="cQGGEupKkEKw" widgetaid="vJ8WmfZPiVQE" xmi.id="ntBujkSHp8rF" type="502" linecolor="none" >
+          <linepath>
+           <startpoint startx="241" starty="709" />
+           <endpoint endx="513" endy="766" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="2" indexa="1" totalcountb="3" indexb="1" linewidth="none" widgetbid="ZUDChgtO8jSy" widgetaid="vJ8WmfZPiVQE" xmi.id="oG7IcloUW5iz" type="502" linecolor="none" >
+          <linepath>
+           <startpoint startx="348" starty="677" />
+           <endpoint endx="748" endy="766" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="4" indexa="2" totalcountb="2" indexb="1" linewidth="none" widgetbid="QbirDWtuKiBS" widgetaid="taceG4p7AY1k" xmi.id="6E5Os60E5bNw" type="502" linecolor="none" >
+          <linepath>
+           <startpoint startx="699" starty="546" />
+           <endpoint endx="553" endy="450" />
+           <point x="679" y="524" />
+           <point x="597" y="524" />
+           <point x="597" y="494" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="2" indexa="1" visibilityB="200" totalcountb="2" indexb="1" linewidth="none" widgetbid="BQqAv02HTM6x" widgetaid="FVtbgO8sd2ii" xmi.id="VXmaXhPeKk9I" type="510" changeabilityA="900" changeabilityB="900" linecolor="none" visibilityA="200" >
+          <linepath>
+           <startpoint startx="489" starty="228" />
+           <endpoint endx="489" endy="180" />
+          </linepath>
+          <floatingtext usesdiagramfillcolor="1" width="41" x="446" fillcolor="none" y="182" linewidth="none" posttext="" role="710" height="22" usefillcolor="1" pretext="-" isinstance="0" xmi.id="PzcKiCdTExqA" text="type" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="1" visibilityB="200" totalcountb="2" indexb="1" linewidth="none" widgetbid="4F09aHCjljSA" widgetaid="672lM6F9KhcI" xmi.id="zRuotD7A5ZEx" type="510" changeabilityA="900" changeabilityB="900" linecolor="none" visibilityA="200" >
+          <linepath>
+           <startpoint startx="148" starty="228" />
+           <endpoint endx="148" endy="180" />
+          </linepath>
+          <floatingtext usesdiagramfillcolor="1" width="56" x="150" fillcolor="none" y="182" linewidth="none" posttext="" role="710" height="22" usefillcolor="1" pretext="-" isinstance="0" xmi.id="O8CVfg2XLio0" text="format" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="2" visibilityB="200" totalcountb="2" indexb="1" linewidth="none" widgetbid="VDAdlQhZ750q" widgetaid="672lM6F9KhcI" xmi.id="dMwwhlSnUoPh" type="510" changeabilityA="900" changeabilityB="900" linecolor="none" visibilityA="200" >
+          <linepath>
+           <startpoint startx="227" starty="228" />
+           <endpoint endx="315" endy="180" />
+          </linepath>
+          <floatingtext usesdiagramfillcolor="1" width="99" x="273" fillcolor="none" y="196" linewidth="none" posttext="" role="710" height="22" usefillcolor="1" pretext="-" isinstance="0" xmi.id="SJgKMk7kki2Q" text="imageFormat" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+         </assocwidget>
+        </associations>
+       </diagram>
+       <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1042" snapy="10" showatts="1" xmi.id="cZsSOYL0vMYc" documentation="" type="3" showops="1" showpackage="0" name="Graph generation" localid="fNm3GNcdo5oo" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="860" >
+        <widgets>
+         <objectwidget usesdiagramfillcolor="0" width="191" x="432" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="vJ8WmfZPiVQE" decon="0" localid="xkkShjnglZDn" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+         <objectwidget usesdiagramfillcolor="0" width="82" x="846" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="ZUDChgtO8jSy" decon="0" localid="5sYVesgRYawR" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+         <objectwidget usesdiagramfillcolor="0" width="144" x="37" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="R1LMLXi8zBZD" decon="0" localid="8k1etAbDCjb4" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+         <notewidget usesdiagramfillcolor="1" width="130" x="558" fillcolor="none" y="105" linewidth="none" height="63" usefillcolor="1" isinstance="0" xmi.id="mi9i1VrBEe8P" text="Common graph settings are bound first." usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+         <notewidget usesdiagramfillcolor="1" width="205" x="241" fillcolor="none" y="207" linewidth="none" height="50" usefillcolor="1" isinstance="0" xmi.id="AvASsvve1luo" text="A new writer is usually created for each graph file." usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+         <notewidget usesdiagramfillcolor="1" width="194" x="214" fillcolor="none" y="455" linewidth="none" height="50" usefillcolor="1" isinstance="0" xmi.id="pnt8L3mW94H6" text="Writer can be used to generate several graphs." usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+        </widgets>
+        <messages>
+         <messagewidget usesdiagramfillcolor="1" width="426" x="123" fillcolor="none" y="98" operation="rSVt3npBuRwI" linewidth="none" widgetbid="xkkShjnglZDn" height="32" usefillcolor="1" seqnum="" textid="17kr4cTMN71P" widgetaid="8k1etAbDCjb4" isinstance="0" xmi.id="rSVt3npBuRwI" sequencemessagetype="1000" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+          <floatingtext usesdiagramfillcolor="1" width="233" x="128" fillcolor="none" y="76" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="17kr4cTMN71P" text=": this(options : GraphOptions)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+         </messagewidget>
+         <messagewidget usesdiagramfillcolor="1" width="426" x="123" fillcolor="none" y="284" operation="qt3yjRHa0HmR" linewidth="none" widgetbid="xkkShjnglZDn" height="73" usefillcolor="1" seqnum="" textid="8R7413dyF3lY" widgetaid="8k1etAbDCjb4" isinstance="0" xmi.id="qt3yjRHa0HmR" sequencemessagetype="1000" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+          <floatingtext usesdiagramfillcolor="1" width="306" x="128" fillcolor="none" y="262" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="8R7413dyF3lY" text=": createGraphWriter(outputs : OutputStream[])" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+         </messagewidget>
+         <messagewidget usesdiagramfillcolor="1" width="368" x="527" fillcolor="none" y="304" operation="RhFDP34VCWM4" linewidth="none" widgetbid="5sYVesgRYawR" height="32" usefillcolor="1" seqnum="" textid="KpN7JYvOVJ7T" widgetaid="xkkShjnglZDn" isinstance="0" xmi.id="RhFDP34VCWM4" sequencemessagetype="1000" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+          <floatingtext usesdiagramfillcolor="1" width="399" x="532" fillcolor="none" y="282" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="KpN7JYvOVJ7T" text=": this(factory : GraphWriterFactory, outputs : OutputStream[])" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+         </messagewidget>
+         <messagewidget usesdiagramfillcolor="1" width="786" x="123" fillcolor="none" y="537" operation="nXwHg6RtyC4B" linewidth="none" widgetbid="5sYVesgRYawR" height="32" usefillcolor="1" seqnum="" textid="CUWS73hkulgU" widgetaid="8k1etAbDCjb4" isinstance="0" xmi.id="nXwHg6RtyC4B" sequencemessagetype="1000" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+          <floatingtext usesdiagramfillcolor="1" width="338" x="249" fillcolor="none" y="515" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="CUWS73hkulgU" text=": generateGraph(vertices : Vertex[], edges : Edge[])" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+         </messagewidget>
+        </messages>
+        <associations/>
+       </diagram>
+      </diagrams>
+     </XMI.extension>
+    </UML:Model>
+    <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Use Case View" isRoot="false" isAbstract="false" name="Use Case View" >
+     <UML:Namespace.ownedElement/>
+    </UML:Model>
+    <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Component View" isRoot="false" isAbstract="false" name="Component View" >
+     <UML:Namespace.ownedElement>
+      <UML:Component executable="0" isSpecification="false" isLeaf="false" visibility="public" namespace="Component View" xmi.id="3XF2INiTN1r0" isRoot="false" isAbstract="false" name="DocumentGenerator" />
+      <UML:Component executable="0" isSpecification="false" isLeaf="false" visibility="public" namespace="Component View" xmi.id="JrRpdxcmaX5Z" isRoot="false" isAbstract="false" name="ModuleDoc" />
+      <UML:Component executable="0" isSpecification="false" isLeaf="false" visibility="public" namespace="Component View" xmi.id="oCHM2Pm3w15E" isRoot="false" isAbstract="false" name="SourceListing" />
+      <UML:Component executable="0" isSpecification="false" isLeaf="false" visibility="public" namespace="Component View" xmi.id="OmgklXk4NCu0" isRoot="false" isAbstract="false" name="ModuleGraph" />
+      <UML:Component executable="0" isSpecification="false" isLeaf="false" visibility="public" namespace="Component View" xmi.id="9Wmh3pGp1WC1" isRoot="false" isAbstract="false" name="ClassGraph" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Component View" xmi.id="9zv0am0s4p3H" client="3XF2INiTN1r0" name="" supplier="9Wmh3pGp1WC1" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Component View" xmi.id="7Qg9DhQeLLiC" client="3XF2INiTN1r0" name="" supplier="OmgklXk4NCu0" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Component View" xmi.id="TCboYJyLq3UQ" client="3XF2INiTN1r0" name="" supplier="JrRpdxcmaX5Z" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Component View" xmi.id="3BrrELHlDrWv" client="3XF2INiTN1r0" name="" supplier="oCHM2Pm3w15E" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Component View" xmi.id="G51CBWFaF9t3" client="3XF2INiTN1r0" name="" supplier="9Wmh3pGp1WC1" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Component View" xmi.id="sgHau3wyChzY" client="3XF2INiTN1r0" name="" supplier="OmgklXk4NCu0" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Component View" xmi.id="8Xdyj7yz61iY" client="3XF2INiTN1r0" name="" supplier="JrRpdxcmaX5Z" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Component View" xmi.id="YbwqcMQKAE7f" client="3XF2INiTN1r0" name="" supplier="oCHM2Pm3w15E" />
+      <UML:Component executable="0" isSpecification="false" isLeaf="false" visibility="public" namespace="Component View" xmi.id="JeCajbMGRVUn" isRoot="false" isAbstract="false" name="Parser&amp;Lexer" />
+      <UML:Dependency isSpecification="false" visibility="public" namespace="Component View" xmi.id="ZZ3AIK4OAcIw" client="3XF2INiTN1r0" name="" supplier="JeCajbMGRVUn" />
+     </UML:Namespace.ownedElement>
+     <XMI.extension xmi.extender="umbrello" >
+      <diagrams>
+       <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1042" snapy="10" showatts="1" xmi.id="9cvLzH7kYq8S" documentation="" type="7" showops="1" showpackage="0" name="high level components" localid="" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="860" >
+        <widgets>
+         <componentwidget usesdiagramfillcolor="1" width="223" x="380" fillcolor="none" y="310" linewidth="none" height="66" usefillcolor="1" isinstance="0" xmi.id="3XF2INiTN1r0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,75,0,0,0,0,0" linecolor="none" />
+         <componentwidget usesdiagramfillcolor="0" width="230" x="183" fillcolor="#ffffc0" y="447" linewidth="none" height="66" usefillcolor="1" isinstance="0" xmi.id="JrRpdxcmaX5Z" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
+         <componentwidget usesdiagramfillcolor="0" width="201" x="568" fillcolor="#ffffc0" y="447" linewidth="none" height="66" usefillcolor="1" isinstance="0" xmi.id="oCHM2Pm3w15E" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
+         <componentwidget usesdiagramfillcolor="0" width="247" x="166" fillcolor="#ffffc0" y="158" linewidth="none" height="66" usefillcolor="1" isinstance="0" xmi.id="OmgklXk4NCu0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
+         <componentwidget usesdiagramfillcolor="0" width="279" x="568" fillcolor="#ffffc0" y="158" linewidth="none" height="66" usefillcolor="1" isinstance="0" xmi.id="9Wmh3pGp1WC1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
+         <componentwidget usesdiagramfillcolor="1" width="159" x="98" fillcolor="none" y="310" linewidth="none" height="66" usefillcolor="1" isinstance="0" xmi.id="JeCajbMGRVUn" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,75,0,0,0,0,0" linecolor="none" />
+        </widgets>
+        <messages/>
+        <associations>
+         <assocwidget totalcounta="3" indexa="2" totalcountb="2" indexb="1" linewidth="none" widgetbid="9Wmh3pGp1WC1" widgetaid="3XF2INiTN1r0" xmi.id="G51CBWFaF9t3" type="502" linecolor="none" >
+          <linepath>
+           <startpoint startx="528" starty="310" />
+           <endpoint endx="707" endy="224" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="OmgklXk4NCu0" widgetaid="3XF2INiTN1r0" xmi.id="sgHau3wyChzY" type="502" linecolor="none" >
+          <linepath>
+           <startpoint startx="454" starty="310" />
+           <endpoint endx="289" endy="224" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="JrRpdxcmaX5Z" widgetaid="3XF2INiTN1r0" xmi.id="8Xdyj7yz61iY" type="502" linecolor="none" >
+          <linepath>
+           <startpoint startx="454" starty="376" />
+           <endpoint endx="298" endy="447" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="3" indexa="2" totalcountb="2" indexb="1" linewidth="none" widgetbid="oCHM2Pm3w15E" widgetaid="3XF2INiTN1r0" xmi.id="YbwqcMQKAE7f" type="502" linecolor="none" >
+          <linepath>
+           <startpoint startx="528" starty="376" />
+           <endpoint endx="668" endy="447" />
+          </linepath>
+         </assocwidget>
+         <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="JeCajbMGRVUn" widgetaid="3XF2INiTN1r0" xmi.id="ZZ3AIK4OAcIw" type="502" linecolor="none" >
+          <linepath>
+           <startpoint startx="380" starty="343" />
+           <endpoint endx="257" endy="343" />
+          </linepath>
+         </assocwidget>
+        </associations>
+       </diagram>
+      </diagrams>
+     </XMI.extension>
+    </UML:Model>
+    <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Deployment View" isRoot="false" isAbstract="false" name="Deployment View" >
+     <UML:Namespace.ownedElement/>
+    </UML:Model>
+    <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Entity Relationship Model" isRoot="false" isAbstract="false" name="Entity Relationship Model" >
+     <UML:Namespace.ownedElement/>
+    </UML:Model>
+   </UML:Namespace.ownedElement>
+  </UML:Model>
+ </XMI.content>
+ <XMI.extensions xmi.extender="umbrello" >
+  <docsettings viewid="37Q7pvtspjUI" documentation="" uniqueid="qWVYkDfsYxos" />
+  <listview>
+   <listitem open="1" type="800" label="Näytöt" >
+    <listitem open="1" type="801" id="Logical View" >
+     <listitem open="0" type="807" id="BbQfy5JEWUGf" label="Class graph classes" />
+     <listitem open="0" type="807" id="HBjs7fL0WfO5" label="General classes" />
+     <listitem open="0" type="807" id="37Q7pvtspjUI" label="Graph classes" />
+     <listitem open="0" type="807" id="PnEBEL9IihdQ" label="Module doc classes" />
+     <listitem open="0" type="807" id="i9im14LKfTmZ" label="Module graph classes" />
+     <listitem open="0" type="807" id="VfRLtV4Z9Ptg" label="Source listing classes" />
+     <listitem open="0" type="810" id="cZsSOYL0vMYc" label="Graph generation" />
+     <listitem open="0" type="813" id="taceG4p7AY1k" >
+      <listitem open="0" type="814" id="jYgSGEsqagKv" />
+      <listitem open="0" type="814" id="4Bqtwxx8p0pI" />
+      <listitem open="0" type="815" id="RhFDP34VCWM4" />
+     </listitem>
+     <listitem open="0" type="813" id="GIPhxHkszygs" >
+      <listitem open="0" type="814" id="ZmI5M1aN978M" />
+      <listitem open="0" type="815" id="liEDYXNQ5pTO" />
+     </listitem>
+     <listitem open="0" type="813" id="m1ftLgsc5LXQ" >
+      <listitem open="0" type="814" id="xswAJre2CrPi" />
+      <listitem open="0" type="815" id="mZ1wtQujXunn" />
+     </listitem>
+     <listitem open="0" type="813" id="gGNje78ValnI" >
+      <listitem open="0" type="814" id="hcALY1fmWlEG" />
+      <listitem open="0" type="814" id="9QXgkpqgA1Du" />
+      <listitem open="0" type="815" id="Aa3THxJUbPoV" />
+     </listitem>
+     <listitem open="0" type="813" id="pwXaDeUXVlRv" >
+      <listitem open="0" type="815" id="RDl3vCbldkit" />
+     </listitem>
+     <listitem open="0" type="813" id="85ASUVIYu8Rm" />
+     <listitem open="1" type="813" id="vJ8WmfZPiVQE" >
+      <listitem open="0" type="815" id="rSVt3npBuRwI" />
+      <listitem open="0" type="815" id="qt3yjRHa0HmR" />
+     </listitem>
+     <listitem open="0" type="813" id="haoxC1oM2QVz" >
+      <listitem open="0" type="815" id="2SrUGMptabML" />
+     </listitem>
+     <listitem open="0" type="813" id="ZUDChgtO8jSy" >
+      <listitem open="0" type="815" id="nXwHg6RtyC4B" />
+     </listitem>
+     <listitem open="1" type="813" id="PILb9kCQnOZd" >
+      <listitem open="0" type="814" id="Aq7LuhClDFeB" />
+      <listitem open="0" type="814" id="xg3pIv6gVUUO" />
+      <listitem open="0" type="814" id="eaFFJAnvNrxh" />
+      <listitem open="0" type="815" id="p2AAWOx6E09l" />
+      <listitem open="0" type="815" id="faPqILFpZIBc" />
+     </listitem>
+     <listitem open="0" type="813" id="XjtDAoectTTH" />
+     <listitem open="1" type="813" id="672lM6F9KhcI" >
+      <listitem open="0" type="814" id="zRuotD7A5ZEx" />
+      <listitem open="0" type="814" id="dMwwhlSnUoPh" />
+      <listitem open="0" type="814" id="E1vnjmQdHkkv" />
+      <listitem open="0" type="814" id="cGQrznU4axXm" />
+      <listitem open="0" type="814" id="UirRcvN0JEsV" />
+      <listitem open="0" type="814" id="AQlvQmLLBkXo" />
+      <listitem open="0" type="814" id="vOQEdHhXSPF8" />
+      <listitem open="0" type="814" id="TrfH97Bbn23Q" />
+      <listitem open="0" type="814" id="uBkkfpbvggDX" />
+     </listitem>
+     <listitem open="0" type="813" id="w884b40YcIag" >
+      <listitem open="0" type="815" id="mBRaST74dftD" />
+     </listitem>
+     <listitem open="0" type="813" id="B92ON93E7uE9" >
+      <listitem open="0" type="815" id="JpwoOQQ4RzaO" />
+     </listitem>
+     <listitem open="1" type="813" id="OcpJQugxHW8F" >
+      <listitem open="0" type="814" id="gOHG3iCLbStZ" />
+     </listitem>
+     <listitem open="0" type="813" id="098RWfwZqN4L" >
+      <listitem open="0" type="815" id="CMMapfT5KiQP" />
+     </listitem>
+     <listitem open="0" type="813" id="R1LMLXi8zBZD" />
+     <listitem open="1" type="813" id="leYQpk5LWBlE" >
+      <listitem open="0" type="815" id="VR6VNEtfCgkY" />
+     </listitem>
+     <listitem open="1" type="813" id="cQGGEupKkEKw" >
+      <listitem open="0" type="815" id="wEWZIkURw0Kn" />
+     </listitem>
+     <listitem open="0" type="813" id="3qQutO5Yhxt6" />
+     <listitem open="0" type="813" id="UY72E0ULeXyT" />
+     <listitem open="0" type="813" id="Ug6grrz7llbI" />
+     <listitem open="0" type="813" id="2MyyGGXAPfEy" >
+      <listitem open="0" type="815" id="VRgNwkJTDt0B" />
+     </listitem>
+     <listitem open="1" type="813" id="FVtbgO8sd2ii" >
+      <listitem open="0" type="814" id="cf98eu4OpFbX" />
+      <listitem open="0" type="814" id="hgsYJ2YnnaVS" />
+      <listitem open="0" type="814" id="sBVGlTogVHfE" />
+      <listitem open="0" type="814" id="ajeRzBpBzXm2" />
+      <listitem open="0" type="814" id="hTSa11gAdwIE" />
+      <listitem open="0" type="814" id="VXmaXhPeKk9I" />
+      <listitem open="0" type="815" id="2fXtbb2YF7TG" />
+      <listitem open="0" type="815" id="PX2Y1eFKtaj6" />
+     </listitem>
+     <listitem open="0" type="813" id="qxq04A8rywIb" >
+      <listitem open="0" type="815" id="KoEO9zJwTXuD" />
+     </listitem>
+     <listitem open="0" type="817" id="2Mzl2VgeffI0" >
+      <listitem open="0" type="815" id="kluUKuajlkAu" />
+     </listitem>
+     <listitem open="0" type="817" id="H9NLXsg0Hncp" >
+      <listitem open="0" type="815" id="FYgiWJyDqrhK" />
+      <listitem open="0" type="815" id="L1C3szmMnzpw" />
+     </listitem>
+     <listitem open="0" type="817" id="yBk69LKYzyaX" />
+     <listitem open="0" type="817" id="DdhFJyNQcQSm" >
+      <listitem open="0" type="815" id="QR4frQ4pllIy" />
+      <listitem open="0" type="815" id="GL3CAg7Qy0PF" />
+     </listitem>
+     <listitem open="0" type="817" id="zhVfgpENwAeN" >
+      <listitem open="0" type="815" id="eGKXDits9Kho" />
+      <listitem open="0" type="815" id="fA2So7Re6pf2" />
+     </listitem>
+     <listitem open="0" type="817" id="QbirDWtuKiBS" />
+     <listitem open="0" type="830" id="Datatypes" >
+      <listitem open="1" type="829" id="DaFOT7jBVtui" />
+      <listitem open="1" type="829" id="tblJnk8mwuii" />
+      <listitem open="1" type="829" id="QXgD4zE4FsCt" />
+      <listitem open="1" type="829" id="UGpWCc0uWy3g" />
+      <listitem open="1" type="829" id="EaC7G8UkzGbk" />
+      <listitem open="1" type="829" id="MGwAYPpykhTm" />
+      <listitem open="1" type="829" id="clKKQl7eLHlZ" />
+      <listitem open="1" type="829" id="z3jKRbJnqFxM" />
+      <listitem open="1" type="829" id="wMWsornjU1NO" />
+      <listitem open="1" type="829" id="N7BDN7YzqsIG" />
+      <listitem open="1" type="829" id="NFJMWv4VyoqO" />
+      <listitem open="1" type="829" id="wERn1lAgB0KQ" />
+      <listitem open="0" type="829" id="zgj70ST7PbVQ" />
+      <listitem open="1" type="829" id="cPuvefV1toMN" />
+      <listitem open="1" type="829" id="IL68COOolGjP" />
+      <listitem open="1" type="829" id="hQqeEe2cmDn9" />
+     </listitem>
+     <listitem open="0" type="831" id="o5RT7D5TyDem" >
+      <listitem open="0" type="839" id="pCzlo8cW1N0o" />
+      <listitem open="0" type="839" id="FS23UTFrinBx" />
+     </listitem>
+     <listitem open="0" type="831" id="58hyBKGITKzU" >
+      <listitem open="0" type="839" id="jnhozkQ1UqIp" />
+      <listitem open="0" type="839" id="DhN6TjTmtUai" />
+      <listitem open="0" type="839" id="eyKevtlegQQd" />
+      <listitem open="0" type="839" id="9qedeuTpcot5" />
+     </listitem>
+     <listitem open="0" type="831" id="uzw9DITFgRm2" >
+      <listitem open="0" type="839" id="Gv3YsqBCKi6E" />
+      <listitem open="0" type="839" id="A1QhopWR6xzK" />
+      <listitem open="0" type="839" id="OVYO1FWE3aSP" />
+      <listitem open="0" type="839" id="uXTHm0iw18dq" />
+      <listitem open="0" type="839" id="3Mv6vLTpsw6c" />
+      <listitem open="0" type="839" id="0BPEtKs5X9EB" />
+      <listitem open="0" type="839" id="w8F05EKRiqqj" />
+      <listitem open="0" type="839" id="OQEcUiDMf7Wr" />
+     </listitem>
+     <listitem open="0" type="831" id="4F09aHCjljSA" >
+      <listitem open="0" type="839" id="Uhfew917nyad" />
+      <listitem open="0" type="839" id="Jy1fqRBSwrTe" />
+      <listitem open="0" type="839" id="aow2SW2oUhRP" />
+     </listitem>
+     <listitem open="1" type="831" id="VDAdlQhZ750q" >
+      <listitem open="0" type="839" id="NPNgtZqJFAtE" />
+      <listitem open="0" type="839" id="2W24K4edixcf" />
+      <listitem open="0" type="839" id="kjad3bVP0s5s" />
+     </listitem>
+     <listitem open="0" type="831" id="BQqAv02HTM6x" >
+      <listitem open="0" type="839" id="UWXR1uwj6Xht" />
+      <listitem open="0" type="839" id="KZH8gthgkYAr" />
+      <listitem open="0" type="839" id="GvOp2iAWCfvE" />
+      <listitem open="0" type="839" id="XsxdPcUh9joq" />
+      <listitem open="0" type="839" id="dTUN2eCIZb6Z" />
+     </listitem>
+    </listitem>
+    <listitem open="1" type="802" id="Use Case View" />
+    <listitem open="1" type="821" id="Component View" >
+     <listitem open="0" type="819" id="9cvLzH7kYq8S" label="high level components" />
+     <listitem open="1" type="822" id="9Wmh3pGp1WC1" />
+     <listitem open="1" type="822" id="3XF2INiTN1r0" />
+     <listitem open="1" type="822" id="JrRpdxcmaX5Z" />
+     <listitem open="1" type="822" id="OmgklXk4NCu0" />
+     <listitem open="1" type="822" id="JeCajbMGRVUn" />
+     <listitem open="1" type="822" id="oCHM2Pm3w15E" />
+    </listitem>
+    <listitem open="1" type="827" id="Deployment View" />
+    <listitem open="1" type="836" id="Entity Relationship Model" />
+   </listitem>
+  </listview>
+  <codegeneration>
+   <codegenerator language="C++" />
+  </codegeneration>
+ </XMI.extensions>
+</XMI>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/config/configurator.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,81 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.config.configurator;
+
+import docgen.config.reader;
+import docgen.config.reflection;
+import docgen.misc.options;
+
+import Integer = tango.text.convert.Integer;
+import tango.io.stream.FileStream;
+import tango.io.Stdout;
+
+/**
+ * Class for handling and merging doc generator options.
+ */
+interface Configurator {
+  /**
+   * Merges configuration options from the given file.
+   */
+  void mergeConfiguration(char[] cfgFile);
+  
+  /**
+   * Returns a hierarchical structure of configuration options.
+   */
+  DocGeneratorOptions *getConfiguration();
+}
+
+private DocGeneratorOptions options;
+private Struct!(options) opt;
+private const cases = makeTypeStringForStruct!(opt);
+
+class DefaultConfigurator : Configurator {
+  private:
+    
+  DocGeneratorOptions options;
+
+  public:
+
+  const defaultProfileLocation = "docgen/config/default.cfg";
+
+  this() {
+    mergeConfiguration(defaultProfileLocation);
+  }
+
+  this(char[] cfgFile) {
+    this();
+    mergeConfiguration(cfgFile);
+  }
+
+  void mergeConfiguration(char[] cfgFile) {
+    
+    auto inputStream = new FileInput(cfgFile);
+    auto content = new char[inputStream.length];
+    auto bytesRead = inputStream.read (content);
+    
+    assert(bytesRead == inputStream.length, "Error reading configuration file");
+
+    auto tokens = lex(content);
+    auto configuration = parse(tokens);
+
+    foreach(key, val; configuration) {
+      bool err() {
+        throw new Exception(
+          "Configurator: Invalid key-val pair " ~ key ~
+          "=" ~ (val.length ? val[0] : "null"));
+      }
+
+      // cuteness, lul
+      mixin(_switch(
+        mixin(cases) ~
+        `default: throw new Exception("Illegal configuration key " ~ key);`
+      ));
+    }
+  }
+
+  DocGeneratorOptions *getConfiguration() {
+    return &options;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/config/default.cfg	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,49 @@
+#
+# This file contains the default configuration. You don't need to
+# worry about this, the system will load the settings automatically.
+#
+# If you need to customize settings, just take a copy of this or
+# write one from scratch and pass the new file location as a
+# command line parameter.
+#
+
+
+(options
+  (graph
+    (imageFormat PNG)
+    (depth -1)
+    (nodeColor white)
+    (cyclicNodeColor tomato)
+    (unlocatableNodeColor gray)
+    (depColor black)
+    (cyclicDepColor red)
+    (publicDepColor blue)
+    (clusterColor blue)
+    (includeUnlocatableModules true)
+    (highlightCyclicEdges true)
+    (highlightCyclicVertices true)
+    (groupByPackageNames true)
+    (groupByFullPackageName false)
+  )
+  (listing
+    (literateStyle true)
+    (enableListings true)
+  )
+  (templates
+    (title "Test project")
+    (versionString 1.0)
+    (copyright "Crashtest dummy")
+    (paperSize a4paper)
+    (shortFileNames false)
+    (templateStyle default)
+  )
+  (parser
+    (importPaths)
+    (rootPaths)
+    (strRegexps)
+    (commentFormat Doxygen)
+    (depth -1)
+  )
+  (outputFormats LaTeX HTML PlainText)
+  (outputDir tmp/)
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/config/reader.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,144 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.config.reader;
+
+debug import tango.io.Stdout;
+
+/**
+ * Lexes a s-exp like input
+ */
+char[][] lex(char[] input) {
+  char[][] tokens;
+
+  uint state = 0, level = 0;
+  size_t sidx = 0;
+
+  void err(size_t i, int type = 0) {
+    auto b = input[i<20 ? 0 : i-20..i];
+    auto e = input[i+1..i+21>$ ? $ : i+21];
+
+    throw new Exception("Lex: " ~ 
+      (type == 0 ? "Illegal character" :
+      type == 1 ? "Wrong number of parenthesis" :
+      "Unexpected end of input") ~
+      ": " ~ b ~ "  >>>" ~ input[i] ~ "<<<  " ~ e ~ "."
+    );
+  }
+  void begin(size_t i) { sidx = i; }
+  void end(size_t i) { tokens ~= input[sidx..i]; }
+
+  foreach(size_t i, c; input) {
+    if (sidx > i) continue;
+    switch(c) { // states space, token, textEnd
+      case '"': // starts a ""-string
+        switch(state) {
+          case 0:
+            char[] buf;
+            bool escape;
+            char d;
+            sidx = i;
+            while(!((d = input[++sidx]) == '"' && !escape) && sidx<input.length)
+              if (escape) {
+                if (d != '"' && d != '\\') buf ~= '\\';
+                buf ~= d;
+                escape = false;
+              } else if (d == '\\')
+                escape = true;
+              else
+                buf ~= d;
+
+            sidx++;
+            tokens ~= buf;
+            state = 2;
+            continue;
+          default: err(i);
+        }
+      case '\\':
+        switch(state) {
+          case 0: begin(i); state = 1; continue;
+          case 1: continue;
+          case 2: err(i);
+        }
+      case '#': // starts a comment
+        sidx = i;
+        while (++sidx<input.length && input[sidx] != '\n') {}
+        continue;
+      case ' ': // whitespace
+      case '\t':
+      case '\n':
+      case '(': // begins a block
+      case ')': // ends a block
+        switch(state) {
+          case 1: end(i);
+          case 0:
+          case 2:
+            switch(c) {
+              case '(': tokens ~= "("; level++; state = 0; break;
+              case ')': tokens ~= ")"; if (!level--) err(i,1);
+              default: state = 0;
+            }
+        }
+        break;
+      default:
+        switch(state) {
+          case 0: begin(i);
+          case 1: state = 1; continue;
+          case 2: err(i);
+        }
+     }
+  }
+
+  if (state == 3 || level != 0) err(input.length-1,2);
+  if (state > 0) end(input.length);
+
+  debug {
+    foreach(i, tok; tokens)
+      Stdout.format("{}{}", tok, (i != tokens.length-1 ? " " : ""));
+    Stdout.newline;
+  }
+
+  return tokens;
+}
+
+/**
+ * Parser a s-exp like input used by the config files.
+ */
+char[][][char[]] parse(char[][] tokens) {
+  char[][][char[]] values;
+  size_t i = 1;
+
+  void err(size_t j) {
+    auto b = tokens[j < 5 ? 0 : j-5..j];
+    auto e = tokens[j+1..j+6>$ ? $ : j+6];
+    char[] tmp;
+    foreach(t; b) tmp ~= t ~ " ";
+    tmp ~= ">>>" ~ tokens[j] ~ "<<< ";
+    foreach(t; e) tmp ~= t ~ " ";
+
+    throw new Exception(
+      "Parse: Illegal token: " ~ tmp ~ "."
+    );
+  }
+
+  if (tokens[0] != "(") err(0);
+
+  void doParse(char[] prefix = null) {
+    if (tokens[i] == "(" ||
+        tokens[i] == ")") err(i);
+    if (prefix) prefix ~= ".";
+    auto v = prefix ~ tokens[i++];
+    //values[v] = null;
+    while (tokens[i] != ")")
+      if (tokens[i++] == "(")
+        doParse(v);
+      else
+        values[v] ~= tokens[i-1];
+    i++;
+  }
+
+  doParse();
+
+  return values;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/config/reflection.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,275 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.config.reflection;
+
+import docgen.misc.meta;
+import docgen.misc.options;
+
+////
+//
+// Macros for reading input
+//
+////
+
+char[] _wrong(char[] key) {
+  return `if (val.length != 1) throw new Exception(
+    "Wrong number of arguments for `~key~`");`;
+}
+
+char[] _switch(char[] stuff) {
+  return "switch(key) {" ~ stuff ~ "}";
+}
+
+char[] _parseI(char[] key) {
+  return `case "` ~ key ~ `":` ~ _wrong(key) ~ key ~
+    `= Integer.parse(val[0]); continue;`;
+}
+
+char[] _parseS(char[] key) {
+  return `case "` ~ key ~ `":` ~ _wrong(key) ~ key ~
+    `= val[0]; continue;`;
+}
+
+char[] _parseB(char[] key) {
+  return `case "` ~ key ~ `":` ~ _wrong(key) ~ key ~
+    `= val[0] == "true" ? true : val[0] == "false" ? false : err(); continue;`;
+}
+
+char[] _parseList(char[] key) {
+  return `case "` ~ key ~ `":foreach(v; val) ` ~
+    key ~ `~= v; continue;`;
+}
+
+template _parseEnum_(bool list, char[] key, V...) {
+  static if (V.length>1)
+    const char[] _parseEnum_ =
+      `case "` ~ V[0] ~ `":` ~ key ~ (list ? "~" : "") ~ `=` ~ V[1] ~ `; continue;` \n ~
+      _parseEnum_!(list, key, V[2..$]);
+  else
+    const char[] _parseEnum_ = "";
+}
+
+template _parseEnum(char[] key, V...) {
+  const char[] _parseEnum = `case "` ~ key ~
+    `":` ~ _wrong(key) ~ `switch(val[0]) {` ~
+    _parseEnum_!(false, key, V) ~
+      `default: err(); } continue;`;
+}
+
+template _parseEnumList(char[] key, V...) {
+  const char[] _parseEnumList = `case "` ~ key ~
+    `":` ~ `foreach (item; val) switch(item) {` ~
+    _parseEnum_!(true, key, V) ~
+      `default: err(); } continue;`;
+}
+
+////
+//
+// Reflection for properties. This code will hopefully get better when the dmdfe bugs get fixed.
+//
+////
+
+// dmdfe bug -- Seriously WTF?
+char[] fixType(char[] type) {
+  return type[$-1] == ' ' ? type[0..$-1] : type;
+}
+
+// take the last part of field name
+char[] getLastName(char[] field) {
+  if (field.length == 0) return "";
+  int t = 0;
+  // dmdfe bug: a while loop causes index out of bounds error
+  for (int i=field.length-1; i >= 0; i--)
+    if (field[i] == '.') { t = i+1; break; }
+  return field[t..$];
+}
+
+// dmdfe bug: cannot return evalType alias
+template _evalType(char[] type) {
+  mixin("alias "~type~" value;");
+}
+
+// Note: stuple wrappers needed for tuples, otherwise:
+// dmdfe bug: cc1d: ../.././gcc/d/dmd/expression.c:4865: virtual Expression* DotIdExp::semantic(Scope*): Assertion `0' failed.
+template evalType(char[] type) {
+  alias _evalType!(type).value evalType;
+}
+
+// wraps the reflected struct and enum data inside struct because otherwise the handling becomes impossibly hard
+template getType(T) {
+  static if(is(T == struct))
+    alias Struct!(T) getType;
+  else static if(is(T == enum))
+    alias Enum!(T) getType;
+  else static if(isEnumList!(T))
+    alias Enum!(enumListType!(T), true) getType;
+  else
+    alias T getType;
+}
+
+template getTypes(alias S, int idx = S.tupleof.length) {
+  static if(idx)
+    alias Tuple!(getTypes!(S, idx-1), getType!(typeof(S.tupleof[idx-1]))) getTypes;
+  else
+    alias Tuple!() getTypes;
+}
+
+/**
+ * Extracts the comma separated struct field names using .tupleof.stringof.
+ * This is needed since the struct.tupleof[n].stringof is broken for enums and tuples in dmdfe.
+ *
+ * Bugs: handling of tuples
+ */
+char[] __getNames(char[] type) {
+  char[] tmp;
+  bool end = false;
+
+  foreach(c; type[5..$]) {
+    if (c != ' ' && c != '(' && c != ')' && end) tmp ~= c;
+    if (c == ',') end = false;
+    if (c == '.') end = true;
+  }
+
+  return tmp;
+}
+
+template _getNames(char[] str, T...) {
+  static if (str.length) {
+    static if (str[0] == ',')
+      alias _getNames!(str[1..$], T, "") _getNames;
+    else
+      alias _getNames!(str[1..$], T[0..$-1], T[$-1] ~ str[0]) _getNames;
+  } else
+    alias T _getNames;
+}
+
+template getNames(char[] str) {
+  alias _getNames!(__getNames(str), "") getNames;
+}
+
+struct Struct(alias T) {
+  const type = "struct"; // used for pattern matching... apparently there's no other way
+  const name = fixType(T.stringof); // dmdfe bug: trailing space
+  alias STuple!(getNames!(T.tupleof.stringof)) names;
+  alias STuple!(getTypes!(T)) types;
+}
+
+struct Enum(alias T, bool list = false) {
+  const type = list ? "enumlist" : "enum"; // used for pattern matching... apparently there's no other way
+  const name =  T.stringof[1..$]; // dmdfe bug: returns enum base type instead enum type
+  alias evalType!("___"~name).tuple elements;
+}
+
+// determines the enumtype[] type
+template isEnumList(T : T[]) {
+  const isEnumList = T.stringof[0] == '_';
+}
+
+template isEnumList(T) {
+  const isEnumList = false;
+}
+
+template enumListType(T : T[]) {
+  alias T enumListType;
+}
+
+template enumListType(T) {
+  static assert(false, "Not enum list type!");
+}
+
+char[] createIParser(char[] field) {
+  return `_parseI("` ~ field ~ `") ~` \n;
+}
+
+char[] createBParser(char[] field) {
+  return `_parseB("` ~ field ~ `") ~` \n;
+}
+ 
+char[] createSParser(char[] field) {
+  return `_parseS("` ~ field ~ `") ~` \n;
+}
+ 
+char[] createLParser(char[] field) {
+  return `_parseList("` ~ field ~ `") ~` \n;
+}
+
+char[] createEParser(char[] field, char[] contents) {
+  return `_parseEnum!("` ~ field ~ `",` ~ contents ~ `) ~` \n;
+}
+
+char[] createELParser(char[] field, char[] contents) {
+  return `_parseEnumList!("` ~ field ~ `",` ~ contents ~ `) ~` \n;
+}
+
+template _makeEnumString(char[] t, E...) {
+  static if (E.length)
+    const _makeEnumString = `"` ~ E[0] ~ `", "` ~ t ~ "." ~ E[0] ~ `",` ~
+                            _makeEnumString!(t, E[1..$]);
+  else
+    const _makeEnumString = "";
+}
+
+// avoids the following dmdfe bugs:
+//  - Error: elements is not a type (typeof(T).elements)
+//  - Error: tuple is not a valid template value argument (T.elements where T is the complex type def)
+template makeEnumString(char[] t, T) {
+  const makeEnumString = _makeEnumString!(t, T.elements);
+}
+
+/**
+ * Generates code for parsing data from the configuration data structure.
+ */
+template makeTypeString(int i, N, T, char[] prefix) {
+  static assert(N.tuple.length == T.tuple.length);
+  static if (i < N.tuple.length) {
+    static if (is(T.tuple[i] == bool))
+      const makeTypeString = createBParser(prefix ~ N.tuple[i]) ~ makeTypeString!(i+1, N, T, prefix);
+    else static if (is(T.tuple[i] : int))
+      const makeTypeString = createIParser(prefix ~ N.tuple[i]) ~ makeTypeString!(i+1, N, T, prefix);
+    else static if (is(T.tuple[i] == char[]))
+      const makeTypeString = createSParser(prefix ~ N.tuple[i]) ~ makeTypeString!(i+1, N, T, prefix);
+    else static if (is(T.tuple[i] == char[][]))
+      const makeTypeString = createLParser(prefix ~ N.tuple[i]) ~ makeTypeString!(i+1, N, T, prefix);
+    else static if (is(T.tuple[i] == struct)) {
+      static if (T.tuple[i].type == "struct")
+        const makeTypeString = makeTypeString!(0, typeof(T.tuple[i].names),
+                               typeof(T.tuple[i].types), prefix~N.tuple[i]~".") ~
+                               makeTypeString!(i+1, N, T, prefix);
+      else static if (T.tuple[i].type == "enum")
+        const makeTypeString = createEParser(prefix ~ N.tuple[i],
+                               makeEnumString!(T.tuple[i].name, T.tuple[i])[0..$-1]) ~
+                               makeTypeString!(i+1, N, T, prefix);
+      else static if (T.tuple[i].type == "enumlist")
+        const makeTypeString = createELParser(prefix ~ N.tuple[i],
+                               makeEnumString!(T.tuple[i].name, T.tuple[i])[0..$-1]) ~
+                               makeTypeString!(i+1, N, T, prefix);
+      else {
+        const makeTypeString = "?" ~ makeTypeString!(i+1, N, T, prefix);
+        static assert(false, "Unknown type");
+      }
+    } else {
+      const makeTypeString = "?" ~ makeTypeString!(i+1, N, T, prefix);
+      static assert(false, "Unknown type");
+    }
+  } else
+    const makeTypeString = "";
+}
+
+template makeTypeStringForStruct(alias opt) {
+  const makeTypeStringForStruct = makeTypeString!(0, opt.names, opt.types, opt.name~".")[0..$-2];
+}
+
+/* some leftovers 
+template handleType(T, char[] prefix="") {
+  static if(is(typeof(T) == struct)) {
+    static if(T.type == "enum")
+      // another dmdfe weirdness: T.stringof == "Enum!(Type)" here, but if do
+      // alias T handleType;, the result.stringof is "struct Enum".
+      alias T handleType;
+  } else
+    alias T handleType;
+}
+*/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/docgen.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,131 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.docgen;
+
+import docgen.graphutils.writers;
+import docgen.config.configurator;
+import docgen.document.latexgenerator;
+import docgen.document.htmlgenerator;
+import docgen.document.xmlgenerator;
+import docgen.document.plaintextgenerator;
+
+//import dil.Settings;
+import dil.SettingsLoader;
+
+import tango.core.Array;
+import tango.text.Text;
+import tango.io.Stdout;
+
+void usage() {
+  Stdout(
+    "Usage: docgen rootpath importpath_1 ... importpath_n outputdir"
+  ).newline;
+}
+
+void main(char[][] args) {
+  dil.SettingsLoader.loadSettings();
+
+  Stdout(docgen_version).newline.newline;
+
+  if (args.length<3) {
+    usage();
+    return;
+  }
+
+  Configurator config = new DefaultConfigurator();
+
+  auto options = config.getConfiguration();
+  options.parser.rootPaths = [ args[1] ];
+  options.parser.importPaths = args[2..$-1];
+  options.outputDir = args[$-1];
+
+  alias DepGraph.Vertex Vertex;
+  alias DepGraph.Edge Edge;
+
+  Module[] cachedModules;
+  DepGraph cachedGraph;
+
+  void parser(ref Module[] modules, ref DepGraph depGraph) {
+    Edge[] edges;
+    Vertex[char[]] vertices;
+
+    if (cachedGraph !is null) {
+      modules = cachedModules;
+      depGraph = cachedGraph;
+      return;
+    }
+
+    int id = 1;
+
+    Parser.loadModules(
+      options.parser.rootPaths,
+      options.parser.importPaths,
+      options.parser.strRegexps,
+      options.graph.includeUnlocatableModules,
+      options.parser.depth,
+      (char[] fqn, char[] path, Module m) {
+        if (m is null) {
+          if (fqn in vertices) {
+            debug Stdout.format("{} already set.\n", fqn);
+            return;
+          }
+          auto vertex = new Vertex(fqn, path, id++);
+          vertices[fqn] = vertex;
+          debug Stdout.format("Setting {} = {}.\n", fqn, path);
+        } else {
+          vertices[m.moduleFQN] = new Vertex(m.moduleFQN, m.filePath, id++);
+          debug Stdout.format("Setting {} = {}.\n", m.moduleFQN, m.filePath);
+        }
+      },
+      (Module imported, Module importer, bool isPublic, bool isStatic) {
+        debug Stdout.format("Connecting {} - {}.\n", imported.moduleFQN, importer.moduleFQN);
+        auto edge = vertices[imported.moduleFQN].addChild(vertices[importer.moduleFQN]);
+        edge.isPublic = isPublic;
+        edge.isStatic = isStatic;
+        edges ~= edge;
+      },
+      modules
+    );
+
+    modules.sort(
+      (Module a, Module b) { return ((new Text!(char)(a.moduleFQN)).compare(b.moduleFQN)) < 0; }
+    );
+
+    depGraph.edges = edges;
+    depGraph.vertices = vertices.values;
+
+    cachedGraph = depGraph;
+    cachedModules = modules;
+  }
+  
+  GraphCache graphcache = new DefaultGraphCache();
+
+  foreach(format; options.outputFormats) {
+    DocGenerator generator;
+
+    switch(format) {
+      case DocFormat.LaTeX:
+        Stdout("Generating LaTeX docs..");
+        generator = new LaTeXDocGenerator(*options, &parser, graphcache);
+        break;
+      case DocFormat.HTML:
+        Stdout("Generating HTML docs..");
+        generator = new HTMLDocGenerator(*options, &parser, graphcache);
+        break;
+      case DocFormat.XML:
+        Stdout("Generating XML docs..");
+        generator = new XMLDocGenerator(*options, &parser);
+        break;
+      case DocFormat.PlainText:
+        Stdout("Generating plain text docs..");
+        generator = new PlainTextDocGenerator(*options, &parser, graphcache);
+        break;
+      default: throw new Exception("Format not supported");
+    }
+
+    generator.generate();
+    Stdout("done.").newline;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/document/generator.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,147 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.document.generator;
+
+import docgen.misc.misc;
+import docgen.misc.parser;
+public import docgen.misc.options;
+import docgen.page.writers;
+import docgen.moduledoc.writers;
+import docgen.graphutils.writers;
+import docgen.sourcelisting.writers;
+import docgen.config.configurator;
+import tango.io.stream.FileStream;
+import tango.io.FilePath;
+import tango.io.FileScan;
+debug import tango.io.Stdout;
+
+
+alias void delegate(ref Module[], ref DepGraph) ParserDg;
+
+abstract class DefaultDocGenerator : DocGenerator {
+  protected:
+
+  DocFormat docFormat;
+  auto makeFile = "make.sh";
+  char[] genDir;
+
+  DocGeneratorOptions m_options;
+  ParserDg m_parser;
+  PageWriter docWriter;
+
+  GraphWriterFactory graphFactory;
+  PageWriterFactory pageFactory;
+  ListingWriterFactory listingFactory;
+  ModuleDocWriterFactory moduleDocFactory;
+  
+  Module[] modules;
+  DepGraph depGraph;
+
+  public:
+
+  this(DocGeneratorOptions options, ParserDg parser) {
+    m_options = options;
+    m_parser = parser;
+
+    createGraphWriterFactory();
+    createPageWriterFactory();
+    createListingWriterFactory();
+    createModuleDocWriterFactory();
+
+    // create output dir
+    (new FilePath(options.outputDir ~ "/" ~ genDir)).create();
+
+    // copy static files
+    copyStaticContent();
+  }
+
+  DocGeneratorOptions *options() {
+    return &m_options;
+  }
+
+  protected:
+
+  void createGraphWriterFactory() {
+    graphFactory = new DefaultGraphWriterFactory(this);
+  }
+
+  void createPageWriterFactory() {
+    pageFactory = new DefaultPageWriterFactory(this);
+  }
+
+  void createListingWriterFactory() {
+    listingFactory = new DefaultListingWriterFactory(this);
+  }
+
+  void createModuleDocWriterFactory() {
+    moduleDocFactory = new DefaultModuleDocWriterFactory(this);
+  }
+
+  char[] outPath(char[] file) {
+    return options.outputDir ~ "/" ~ genDir ~ "/" ~ file;
+  }
+
+  void copyStaticContent() {
+    auto scan = new FileScan();
+    scan(templateDir~options.templates.templateStyle~"/"~formatDirs[docFormat]~"/static/");
+
+    foreach(filePath; scan.files) {
+      (new FilePath(outPath(filePath.file))).copy(filePath.toString());
+    }
+
+    debug Stdout(scan.files.length)(" static files copied.\n");
+  }
+
+  FileOutput outputFile(char[] fname) {
+    return new FileOutput(outPath(fname));
+  }
+
+  void parseSources() {
+    depGraph = new DepGraph();
+    m_parser(modules, depGraph);
+  }
+
+  //---
+
+  void writeSimpleFile(char[] fname, void delegate() dg) {
+    auto docFile = outputFile(fname);
+
+    docWriter.setOutput([docFile]);
+    dg();
+
+    docFile.close();
+  }
+
+  /**
+   * Generates "makefile" for processing e.g. .dot files.
+   */
+  void generateMakeFile(char[][] args ...) {
+    writeSimpleFile(makeFile, { docWriter.generateCustomPage("makefile", args); } );
+  }
+  
+}
+
+abstract class DefaultCachingDocGenerator : DefaultDocGenerator, CachingDocGenerator {
+  private:
+    
+  GraphCache m_graphCache;
+
+  public:
+
+  this(DocGeneratorOptions options, ParserDg parser, GraphCache graphCache) {
+    super(options, parser);
+    m_graphCache = graphCache;
+  }
+  
+  GraphCache graphCache() {
+    return m_graphCache;
+  }
+
+  protected:
+
+  void createGraphWriterFactory() {
+    graphFactory = new DefaultCachingGraphWriterFactory(this);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/document/htmlgenerator.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,156 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.document.htmlgenerator;
+
+import docgen.document.generator;
+import docgen.misc.misc;
+import tango.io.stream.FileStream;
+import tango.text.Util : replace;
+
+class HTMLDocGenerator : DefaultCachingDocGenerator {
+  private:
+
+  auto docFileNames = [
+    "index.html"[], "toc.html"[], "classes.html"[],
+    "modules.html"[], "files.html"[]
+  ];
+
+  auto depGraphFile = "depgraph.dot";
+  auto depGraphDocFile = "depgraph.html";
+  auto styleSheetFile = "default.css";
+
+  public:
+
+  this(DocGeneratorOptions options, ParserDg parser, GraphCache graphcache) {
+    genDir = "html";
+    docFormat = DocFormat.HTML;
+    super(options, parser, graphcache);
+  }
+
+  /**
+   * Generates the documentation.
+   */
+  void generate() {
+    parseSources();
+
+    docWriter = pageFactory.createPageWriter( null, docFormat );
+
+    // stylesheet needs to be created first to propagate the css file name
+    generateStyleSheet();
+
+    generateDoc();
+
+    if (options.listing.enableListings)
+      generateListings();
+
+    generateClasses();
+    generateModules();
+    generateDependencies();
+    generateMakeFile(imageFormatExts[options.graph.imageFormat]);
+  }
+
+  protected:
+
+  /**
+   * Generates document skeleton.
+   */
+  void generateDoc() {
+    writeSimpleFile(docFileNames[0], {
+      docWriter.generateFirstPage();
+    });
+    /*
+    writeSimpleFile(docFileNames[1], {
+      docWriter.generateTOC(modules);
+      docWriter.generateCustomPage("pagetemplate2", docgen_version);
+    });*/
+  }
+
+  /**
+   * Generates a global style sheet.
+   */
+  void generateStyleSheet() {
+    writeSimpleFile(styleSheetFile, {
+      docWriter.generateCustomPage("stylesheet");
+    });
+  }
+
+  /**
+   * Generates documentation for classes.
+   */
+  void generateClasses() {
+    writeSimpleFile(docFileNames[2], {
+      docWriter.generateClassSection();
+      docWriter.generateCustomPage("pagetemplate2", docgen_version);
+    });
+  }
+
+  /**
+   * Generates documentation for modules.
+   */
+  void generateModules() {
+    writeSimpleFile(docFileNames[3], {
+      docWriter.generateModuleSection(modules);
+      docWriter.generateCustomPage("pagetemplate2", docgen_version);
+    });
+    
+//    auto mdw = moduleDocFactory.createModuleDocWriter(docWriter, docFormat);
+
+  }
+
+  /**
+   * Generates source file listings.
+   */
+  void generateListings() {
+    writeSimpleFile(docFileNames[4], {
+      docWriter.generateListingSection(modules);
+
+      char[][] contents;
+
+      contents ~= "(";
+
+      foreach(mod; modules) {
+        auto FQN = mod.moduleFQN;
+        auto dstFname = replace(mod.moduleFQN.dup, '.', '_') ~ ".html";
+        contents ~= `<a href="` ~ dstFname ~ `">` ~ FQN ~ "</a>";
+      }
+
+      contents ~= ")";
+
+      docWriter.addList(contents, false);
+
+      docWriter.generateCustomPage("pagetemplate2", docgen_version);
+    });
+
+    auto writer = listingFactory.createListingWriter(docWriter, docFormat);
+
+    foreach(mod; modules) {
+      auto dstFname = replace(mod.moduleFQN.dup, '.', '_') ~ ".html";
+
+      writeSimpleFile(dstFname, {
+        auto srcFile = new FileInput(mod.filePath);
+        writer.generateListing(srcFile, null, mod.moduleFQN);
+        srcFile.close();
+      });
+    }
+  }
+
+  /**
+   * Generates dependency graphs.
+   */
+  void generateDependencies() {
+    writeSimpleFile(depGraphDocFile, {
+      docWriter.generateDepGraphSection();
+
+      auto imgFile = outputFile(depGraphFile);
+
+      auto writer = graphFactory.createGraphWriter( docWriter, GraphFormat.Dot );
+      writer.generateDepGraph(depGraph, imgFile);
+
+      imgFile.close();
+
+      docWriter.generateCustomPage("pagetemplate2", docgen_version);
+    });
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/document/latexgenerator.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,121 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.document.latexgenerator;
+
+import docgen.document.generator;
+import docgen.misc.misc;
+import tango.io.stream.FileStream;
+import tango.text.Util : replace;
+
+/**
+ * Main routine for LaTeX doc generation.
+ */
+class LaTeXDocGenerator : DefaultCachingDocGenerator {
+  private:
+
+  auto docFileName = "document.tex";
+  auto depGraphDocFile = "dependencies.tex";
+  auto depGraphFile = "depgraph.dot";
+  auto listingFile = "files.tex";
+  auto modulesFile = "modules.tex";
+
+  public:
+
+  this(DocGeneratorOptions options, ParserDg parser, GraphCache graphcache) {
+    genDir = "latex";
+    docFormat = DocFormat.LaTeX;
+
+    super(options, parser, graphcache);
+  }
+
+  /**
+   * Generates the documentation.
+   */
+  void generate() {
+    parseSources();
+
+    generateDoc();
+
+    if (options.listing.enableListings)
+      generateListings();
+
+    generateClasses();
+    generateModules();
+    generateDependencies();
+    generateMakeFile(docFileName, "pdf");
+  }
+
+  protected:
+
+  /**
+   * Generates document skeleton.
+   */
+  void generateDoc() {
+    auto docFile = outputFile(docFileName);
+    docWriter = pageFactory.createPageWriter( [ docFile ], docFormat );
+
+    docWriter.generateFirstPage();
+    docWriter.generateTOC(modules);
+    docWriter.generateClassSection();
+    docWriter.generateModuleSection(modules);
+    docWriter.generateListingSection(modules);
+    docWriter.generateDepGraphSection();
+    docWriter.generateIndexSection();
+    docWriter.generateLastPage();
+
+    docFile.close();
+  }
+
+  /**
+   * Generates documentation for classes.
+   */
+  void generateClasses() {
+    auto docFile = outputFile(modulesFile);
+    docFile.close();
+  }
+
+  /**
+   * Generates documentation for modules.
+   */
+  void generateModules() {
+    auto docFile = outputFile(modulesFile);
+    docFile.close();
+  }
+
+  /**
+   * Generates source file listings.
+   */
+  void generateListings() {
+    writeSimpleFile(listingFile, {
+      auto writer = listingFactory.createListingWriter(docWriter, docFormat);
+
+      foreach(mod; modules) {
+        auto dstFname = replace(mod.moduleFQN.dup, '.', '_') ~ ".d";
+        
+        auto srcFile = new FileInput(mod.filePath);
+        auto dstFile = outputFile(dstFname);
+        
+        writer.generateListing(srcFile, dstFile, mod.moduleFQN);
+
+        srcFile.close();
+        dstFile.close();
+      }
+    });
+  }
+
+  /**
+   * Generates dependency graphs.
+   */
+  void generateDependencies() {
+    writeSimpleFile(depGraphDocFile, {
+      auto imgFile = outputFile(depGraphFile);
+
+      auto writer = graphFactory.createGraphWriter( docWriter, GraphFormat.Dot );
+      writer.generateDepGraph(depGraph, imgFile);
+
+      imgFile.close();
+    });
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/document/plaintextgenerator.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,121 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.document.plaintextgenerator;
+
+import docgen.document.generator;
+import docgen.misc.misc;
+import tango.io.stream.FileStream;
+import tango.io.FilePath;
+import tango.text.Util : replace;
+
+class PlainTextDocGenerator : DefaultCachingDocGenerator {
+  private:
+
+  auto docFileNames = [
+    "index.txt"[], "toc.txt"[], "classes.txt"[],
+    "modules.txt"[], "files.txt"[]
+  ];
+
+  auto depGraphFile = "depgraph.dot";
+  auto depGraphDocFile = "depgraph.txt";
+
+  public:
+
+  this(DocGeneratorOptions options, ParserDg parser, GraphCache graphcache) {
+    genDir = "txt";
+    docFormat = DocFormat.PlainText;
+    
+    super(options, parser, graphcache);
+  }
+
+  /**
+   * Generates the documentation.
+   */
+  void generate() {
+    parseSources();
+
+    docWriter = pageFactory.createPageWriter( null, docFormat );
+
+    generateDoc();
+
+    if (options.listing.enableListings)
+      generateListings();
+
+    generateClasses();
+    generateModules();
+    generateDependencies();
+    generateMakeFile(imageFormatExts[options.graph.imageFormat]);
+  }
+
+  protected:
+
+  /**
+   * Generates document skeleton.
+   */
+  void generateDoc() {
+    writeSimpleFile(docFileNames[0], {
+      docWriter.generateFirstPage();
+    });
+    
+    writeSimpleFile(docFileNames[1], {
+      docWriter.generateTOC(modules);
+    });
+  }
+
+  /**
+   * Generates documentation for classes.
+   */
+  void generateClasses() {
+    writeSimpleFile(docFileNames[2], {
+      docWriter.generateClassSection();
+    });
+  }
+
+  /**
+   * Generates documentation for modules.
+   */
+  void generateModules() {
+    writeSimpleFile(docFileNames[3], {
+      docWriter.generateModuleSection(modules);
+    });
+  }
+
+  /**
+   * Generates source file listings.
+   */
+  void generateListings() {
+    writeSimpleFile(docFileNames[4], {
+      docWriter.generateListingSection(modules);
+
+      char[][] contents;
+
+      foreach(mod; modules) {
+        auto FQN = mod.moduleFQN;
+        contents ~= FQN ~ " (see " ~ replace(FQN.dup, '.', '_') ~ ".d)";
+      }
+
+      docWriter.addList(contents, false);
+    });
+
+    foreach(mod; modules)
+      (new FilePath(outPath(replace(mod.moduleFQN.dup, '.', '_') ~ ".d"))).copy(mod.filePath);
+  }
+
+  /**
+   * Generates dependency graphs.
+   */
+  void generateDependencies() {
+    writeSimpleFile(depGraphDocFile, {
+      docWriter.generateDepGraphSection();
+
+      auto imgFile = outputFile(depGraphFile);
+
+      auto writer = graphFactory.createGraphWriter( docWriter, GraphFormat.Dot );
+      writer.generateDepGraph(depGraph, imgFile);
+
+      imgFile.close();
+    });
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/document/xmlgenerator.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,23 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.document.xmlgenerator;
+
+import docgen.document.generator;
+import docgen.misc.misc;
+import tango.io.stream.FileStream;
+import tango.text.Util : replace;
+
+class XMLDocGenerator : DefaultDocGenerator {
+  public:
+
+  this(DocGeneratorOptions options, ParserDg parser) {
+    genDir = "xml";
+    docFormat = DocFormat.XML;
+
+    super(options, parser);
+  }
+
+  void generate() { /* TODO */ }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/graphutils/dotwriter.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,170 @@
+/**
+ * Author: Aziz Köksal & Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.graphutils.dotwriter;
+import docgen.graphutils.writer;
+
+import tango.io.Print: Print;
+import tango.text.convert.Layout : Layout;
+import tango.io.FilePath;
+import tango.text.Util;
+import tango.text.convert.Sprint;
+debug import tango.io.Stdout;
+
+/**
+ * Creates a graph rule file for the dot utility.
+ */
+class DotWriter : AbstractGraphWriter {
+  public:
+
+  this(GraphWriterFactory factory, PageWriter writer) {
+    super(factory, writer);
+  }
+
+  void generateDepGraph(DepGraph depGraph, OutputStream imageFile) {
+    generateImageTag(imageFile);
+    
+    auto image = generateDepImageFile(depGraph);
+    auto printer = new Print!(char)(new Layout!(char), imageFile);
+    printer(image);
+  }
+
+  protected:
+
+  char[] generateDepImageFile(DepGraph depGraph) {
+    char[] image;
+    auto sprint = new Sprint!(char);
+    
+    auto edges = depGraph.edges;
+    auto vertices = depGraph.vertices;
+
+    DepGraph.Vertex[][char[]] verticesByPckgName;
+    if (factory.options.graph.groupByFullPackageName ||
+        factory.options.graph.groupByPackageNames) {
+      foreach (mod; vertices) {
+        auto parts = mod.name.delimit(".");
+
+        if (parts.length>1) {
+          auto pkg = parts[0..$-1].join(".");
+          verticesByPckgName[pkg] ~= mod;
+        }
+      }
+    }
+
+    if (factory.options.graph.highlightCyclicVertices ||
+        factory.options.graph.highlightCyclicEdges)
+      depGraph.markCycles();
+
+    image ~= "Digraph ModuleDependencies {\n";
+
+    foreach (module_; vertices) {
+      auto nodeName = 
+        factory.options.graph.groupByPackageNames ?
+        module_.name.split(".")[$-1] :
+        module_.name;
+
+      image ~= sprint.format(
+        `  n{} [label="{}",style=filled,fillcolor={}];`\n,
+        module_.id,
+        nodeName,
+        module_.cyclic && factory.options.graph.highlightCyclicVertices ?
+          factory.options.graph.cyclicNodeColor :
+        module_.incoming.length == 0 && module_.outgoing.length == 0 ?
+          factory.options.graph.unlocatableNodeColor :
+          factory.options.graph.nodeColor
+      );
+    }
+
+    foreach (edge; edges)
+      image ~= sprint.format(
+        `  n{} -> n{}[color={}];`\n,
+        edge.outgoing.id,
+        edge.incoming.id,
+        edge.cyclic ?
+          factory.options.graph.cyclicDepColor :
+        edge.isPublic ?
+          factory.options.graph.publicDepColor ~ ",style=bold" :
+          factory.options.graph.depColor
+      );
+
+    if (factory.options.graph.groupByPackageNames)
+
+      if (!factory.options.graph.groupByFullPackageName) {
+        foreach (packageName, vertices; verticesByPckgName) {
+          auto name = packageName.split(".");
+
+          if (name.length > 1) {
+            char[] pkg;
+            foreach(part; name) {
+              pkg ~= part ~ ".";
+              image ~= sprint.format(
+                `subgraph "cluster_{0}" {{`\n`  label="{0}"`\n,
+                pkg[0..$-1],
+                pkg[0..$-1]
+              );
+            }
+            for (int i=0; i< name.length; i++) {
+              image ~= "}\n";
+            }
+          }
+        }
+      }
+      foreach (packageName, vertices; verticesByPckgName) {
+        image ~= sprint.format(
+          `  subgraph "cluster_{0}" {{`\n`  label="{0}";color=`
+          ~ factory.options.graph.clusterColor ~ `;`\n`  `,
+          packageName,
+          packageName
+        );
+
+        foreach (module_; vertices)
+          image ~= sprint.format(`n{0};`, module_.id);
+        image ~= "\n  }\n";
+      }
+
+    image ~= "}";
+
+    return image;
+  }
+        
+  void generateImageTag(OutputStream imageFile) {
+    // name of the .dot file
+    char[] fn = (cast(Object)imageFile.conduit).toString();
+    fn = FilePath(fn).file;
+
+    fn = fn[0..$-3] ~ imageFormatExts[factory.options.graph.imageFormat];
+    
+    writer.addGraphics(fn);
+  } 
+}
+
+class CachingDotWriter : DotWriter {
+  private:
+
+  CachingGraphWriterFactory factory;
+
+  public:
+
+  this(CachingGraphWriterFactory factory, PageWriter writer) {
+    super(factory, writer);
+    this.factory = factory;
+  }
+
+  override void generateDepGraph(DepGraph depGraph, OutputStream imageFile) {
+    generateImageTag(imageFile);
+
+    auto cached = factory.graphCache.getCachedGraph(depGraph, GraphFormat.Dot);
+
+    auto printer = new Print!(char)(new Layout!(char), imageFile);
+    
+    if (cached) {
+      printer(cached);
+    } else {
+      auto image = generateDepImageFile(depGraph);
+      factory.graphCache.setCachedGraph(depGraph, GraphFormat.Dot, image);
+      printer(image);
+    }
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/graphutils/modulenamewriter.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,42 @@
+/**
+ * Author: Aziz Köksal & Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.graphutils.modulenamewriter;
+import docgen.graphutils.writer;
+
+import tango.io.Print: Print;
+import tango.text.convert.Layout : Layout;
+
+class ModuleNameWriter : AbstractGraphWriter {
+  public:
+
+  this(GraphWriterFactory factory, PageWriter writer) {
+    super(factory, writer);
+  }
+
+  void generateDepGraph(DepGraph depGraph, OutputStream imageFile) {
+    char[][] contents;
+
+    auto edges = depGraph.edges;
+    auto vertices = depGraph.vertices;
+
+    void doList(DepGraph.Vertex[] v, uint level) {
+      if (!level) return;
+
+      contents ~= "(";
+
+      foreach (vertex; v) {
+        contents ~= vertex.name;
+        if (vertex.outgoing.length)
+          doList(vertex.outgoing, level-1);
+      }
+
+      contents ~= ")";
+    }
+
+    doList(vertices, factory.options.graph.depth);
+
+    writer.addList(contents, false);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/graphutils/modulepathwriter.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,42 @@
+/**
+ * Author: Aziz Köksal & Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.graphutils.modulepathwriter;
+import docgen.graphutils.writer;
+
+import tango.io.Print: Print;
+import tango.text.convert.Layout : Layout;
+
+class ModulePathWriter : AbstractGraphWriter {
+  public:
+
+  this(GraphWriterFactory factory, PageWriter writer) {
+    super(factory, writer);
+  }
+
+  void generateDepGraph(DepGraph depGraph, OutputStream imageFile) {
+    char[][] contents;
+
+    auto edges = depGraph.edges;
+    auto vertices = depGraph.vertices;
+
+    void doList(DepGraph.Vertex[] v, uint level) {
+      if (!level) return;
+
+      contents ~= "(";
+
+      foreach (vertex; v) {
+        contents ~= vertex.location;
+        if (vertex.outgoing.length)
+          doList(vertex.outgoing, level-1);
+      }
+
+      contents ~= ")";
+    }
+
+    doList(vertices, factory.options.graph.depth);
+
+    writer.addList(contents, false);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/graphutils/primitives.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,142 @@
+/**
+ * Author: Aziz Köksal & Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.graphutils.primitives;
+
+/**
+ * Extendible graph class. Should support separation of concerns now better with mixins.
+ * Provides a method for cycle marking.
+ */
+class Graph(alias V, alias E, int capacity = 1) {
+  static class Edge {
+    Vertex outgoing, incoming;
+    //bool cyclic = true;
+
+    this(Vertex o, Vertex i) {
+      outgoing = o;
+      incoming = i;
+      o.outgoingEdges ~= this;
+      i.incomingEdges ~= this;
+    }
+
+    bool cyclic() {
+      return outgoing.cyclic && incoming.cyclic;
+    }
+
+    mixin E;
+  }
+
+  static class Vertex {
+    Edge[] incomingEdges;
+    Edge[] outgoingEdges;
+    bool cyclic = true;
+
+    Edge addChild(Vertex v) {
+      return new Edge(v, this);
+    }
+
+    Edge addParent(Vertex v) {
+      return v.addChild(this);
+    }
+
+    Vertex[] incoming() {
+      Vertex[] tmp;
+
+      foreach(edge; incomingEdges)
+        tmp ~= edge.outgoing;
+
+      return tmp;
+    }
+
+    Vertex[] outgoing() {
+      Vertex[] tmp;
+
+      foreach(edge; outgoingEdges)
+        tmp ~= edge.incoming;
+
+      return tmp;
+    }
+
+    mixin V;
+  }
+
+  Vertex[] vertices;
+  Edge[] edges;
+
+  this() {
+    vertices.length = capacity;
+    vertices.length = 0;
+    edges.length = capacity;
+    edges.length = 0;
+  }
+
+  void add(Vertex vertex) { vertices ~= vertex; }
+
+  void add(Edge edge) { edges ~= edge; }
+
+  void connect(Vertex from, Vertex to) { edges ~= from.addParent(to); }
+
+  void connect(int from, int to) { connect(vertices[from], vertices[to]); }
+
+  /**
+   * Starts from non-cyclic nodes and propagates two both directions.
+   * Bugs: marks non-cyclic imports between two cycles as cyclic. Could be fixed later if it's really needed (slow)
+   */
+  void markCycles() {
+    void mark(Vertex v) {
+      v.cyclic = false;
+      foreach(o; v.outgoing) {
+        if (!o.cyclic) continue;
+
+        // propagate
+        bool cyclic = false;
+        foreach(p; o.incoming) if (p.cyclic) { cyclic = true; break; }
+        if (!cyclic) mark(o);
+      }
+    }
+
+    void mark2(Vertex v) {
+      v.cyclic = false;
+      foreach(o; v.incoming) {
+        if (!o.cyclic) continue;
+
+        // propagate
+        bool cyclic = false;
+        foreach(p; o.outgoing) if (p.cyclic) { cyclic = true; break; }
+        if (!cyclic) mark2(o);
+      }
+    }
+
+    foreach(e; vertices)
+      if (e.cyclic) {
+        if (!e.incoming.length) mark(e);
+        if (!e.outgoing.length) mark2(e);
+      }
+  }
+}
+
+template Empty() {}
+
+
+// graph elements used in dep graphs
+
+
+template DepEdge() {
+  bool isPublic; /// Public import.
+  bool isStatic; /// Static import.
+}
+
+template DepVertex() {
+  char[] name;
+  char[] location;
+  uint id;
+
+  this(char[] name, char[] location, uint id = 0) {
+    this.name = name;
+    this.location = location;
+    this.id = id;
+  }
+}
+
+alias Graph!(DepVertex, DepEdge, 100) DepGraph;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/graphutils/writer.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,113 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.graphutils.writer;
+
+public import docgen.misc.misc;
+public import docgen.graphutils.primitives;
+public import docgen.page.writer;
+debug import tango.io.Stdout;
+
+interface GraphWriter {
+  void generateDepGraph(DepGraph depGraph, OutputStream imageFile);
+}
+
+interface GraphWriterFactory : WriterFactory {
+  GraphWriter createGraphWriter(PageWriter writer, GraphFormat outputFormat);
+}
+
+interface CachingGraphWriterFactory : GraphWriterFactory {
+  GraphCache graphCache();
+}
+/+
+/**
+ * Marks all cycles in the graph.
+ *
+ * May have bugs, but is a bit simpler than the previous version.
+ */
+void findCycles(Vertex[] vertices, Edge[] edges) {
+  debug void p() {
+    foreach(e; edges) Stderr(e.type)(" "c);
+    Stderr.newline;
+  }
+
+  bool visit(Edge edge) {
+    if (edge.cycleType == CycleType.Reserved) {
+      edge.cycleType = CycleType.Cyclic;
+      version(VerboseDebug) p();
+      return true;
+    }
+
+    bool wasCyclic = edge.isCyclic();
+    edge.cycleType = CycleType.Reserved;
+    version(VerboseDebug) p();
+
+    foreach(edge2; edge.incoming.outgoingEdges)
+      if (visit(edge2)) {
+        if (edge.isCyclic()) {
+          edge.cycleType = CycleType.Reserved;
+          wasCyclic = true;
+          version(VerboseDebug) p();
+          continue;
+        }
+        edge.cycleType = CycleType.Cyclic;
+        return true;
+      }
+
+    edge.cycleType = wasCyclic ? CycleType.Cyclic : CycleType.Cyclefree;
+    version(VerboseDebug) p();
+    return false;
+  }
+
+  foreach(vertex; vertices)
+    foreach(edge; vertex.outgoingEdges)
+      if (edge.cycleType == CycleType.Unspecified) {
+        visit(edge);
+        debug Stderr("*\n");
+      }
+}
++/
+
+abstract class AbstractGraphWriter : AbstractWriter!(GraphWriterFactory), GraphWriter {
+  protected:
+
+  PageWriter writer;
+  
+  public:
+
+  this(GraphWriterFactory factory, PageWriter writer) {
+    super(factory);
+    this.writer = writer;
+  }
+}
+
+class DefaultGraphCache : GraphCache {
+  private:
+    
+  char[][Object][GraphFormat] m_graphCache;
+
+  public:
+
+  char[] getCachedGraph(Object graph, GraphFormat format) {
+    debug Stdout("Starting graph lookup\n");
+    debug Stdout(&graph, format).newline;
+    debug Stdout(&m_graphCache).newline;
+    
+    auto lookup1 = format in m_graphCache;
+    if (lookup1) {
+      auto lookup2 = graph in *lookup1;
+      if (lookup2) {
+          return *lookup2;
+      }
+    }
+    debug Stdout("Graph cache miss!\n");
+    return null;
+  }
+
+  void setCachedGraph(Object graph, GraphFormat format, char[]
+      contents) {
+    m_graphCache[format][graph] = contents;
+    debug Stdout("Graph cache updated!\n");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/graphutils/writers.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,59 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.graphutils.writers;
+
+public import docgen.graphutils.writer;
+import docgen.graphutils.dotwriter;
+import docgen.graphutils.modulepathwriter;
+import docgen.graphutils.modulenamewriter;
+
+class DefaultGraphWriterFactory : AbstractWriterFactory, GraphWriterFactory {
+  public:
+
+  this(DocGenerator generator) {
+    super(generator);
+  }
+
+  GraphWriter createGraphWriter(PageWriter writer, GraphFormat outputFormat) {
+    switch (outputFormat) {
+      case GraphFormat.Dot:
+        return new DotWriter(this, writer);
+      case GraphFormat.ModuleNames:
+        return new ModuleNameWriter(this, writer);
+      case GraphFormat.ModulePaths:
+        return new ModulePathWriter(this, writer);
+      default:
+        throw new Exception("Graph writer type does not exist!");
+    }
+  }
+}
+
+class DefaultCachingGraphWriterFactory : AbstractWriterFactory, CachingGraphWriterFactory {
+  public:
+
+  CachingDocGenerator generator;
+
+  this(CachingDocGenerator generator) {
+    super(generator);
+    this.generator = generator;
+  }
+
+  GraphCache graphCache() {
+    return generator.graphCache;
+  }
+
+  override GraphWriter createGraphWriter(PageWriter writer, GraphFormat outputFormat) {
+    switch (outputFormat) {
+      case GraphFormat.Dot:
+        return new CachingDotWriter(this, writer);
+      case GraphFormat.ModuleNames:
+        return new ModuleNameWriter(this, writer);
+      case GraphFormat.ModulePaths:
+        return new ModulePathWriter(this, writer);
+      default:
+        throw new Exception("Graph writer type does not exist!");
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/lstlang0.sty	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,21 @@
+%%
+%% D definition (c) 2007 Jari-Matti Mäkelä
+%%
+\lst@definelanguage{D}%
+  {morekeywords={abstract,alias,align,asm,assert,auto,body,bool,break,%
+      byte,case,cast,catch,cdouble,cent,cfloat,char,class,const,continue,%
+      creal,dchar,debug,default,delegate,delete,deprecated,do,double,%
+      else,enum,export,extern,false,final,finally,float,for,foreach,%
+      foreach_reverse,function,goto,idouble,if,ifloat,import,in,inout,%
+      int,interface,invariant,ireal,is,lazy,long,macro,mixin,module,new,%
+      null,out,override,package,pragma,private,protected,public,real,ref,%
+      return,scope,short,static,struct,super,switch,synchronized,template,%
+      this,throw,true,try,typedef,typeid,typeof,ubyte,ucent,uint,ulong,%
+      union,unittest,ushort,version,void,volatile,wchar,while,with},%
+   sensitive,%
+   morecomment=[s]{/*}{*/},%
+   morecomment=[n]{/+}{+/},%
+   morecomment=[l]//,%
+   morestring=[b]",%
+   morestring=[b]`%
+  }[keywords,comments,strings]%
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/misc/meta.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,98 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.misc.meta;
+
+/// tuple literal workaround
+template Tuple(T...) { alias T Tuple; }
+
+/// another tuple literal workaround (can be nested & avoids at least one dmdfe bug)
+struct STuple(T...) { alias T tuple; }
+
+
+// (a -> b), [a] -> [b]
+template map(alias S, T...) {
+  static if (T.length)
+    alias Tuple!(S!(T[0]), map!(S, T[1..$])) map;
+  else
+    alias T map;
+}
+
+/// (a -> Bool), [a] -> [a]
+template filter(alias S, T...) {
+  static if (!T.length)
+    alias Tuple!() filter;
+  else static if (S!(T[0]))
+    alias Tuple!(T[0], filter!(S, T[1..$])) filter;
+  else
+    alias filter!(S, T[1..$]) filter;
+}
+
+/// Int -> Bool
+template odd(int T) {
+  const odd = T%2 == 1;
+}
+
+/// Int -> Bool
+template even(int T) {
+  const even = !odd!(T);
+}
+
+/// a [a] -> a  -- max x y = max2 x (max y)
+T max(T, U...)(T a, U b) {
+  static if (b.length)
+    return a > max(b) ? a : max(b);
+  else
+    return a;
+}
+
+/// a [a] -> a  -- min x y = min2 x (min y)
+T min(T, U...)(T a, U b) {
+  static if (b.length)
+    return a < min(b) ? a : min(b);
+  else
+    return a;
+}
+
+/// Upcasts derivatives of B to B
+template UpCast(B, T) { alias T UpCast; }
+template UpCast(B, T : B) { alias B UpCast; }
+
+/// converts integer to ascii, base 10
+char[] itoa(int i) {
+  char[] ret;
+  auto numbers = "0123456789ABCDEF";
+
+  do {
+    ret = numbers[i%10] ~ ret;
+    i /= 10;
+  } while (i)
+
+  return ret;
+}
+
+/// Enum stuff
+
+template _genList(char[] pre, char[] post, T...) {
+  static if (T.length)
+    const _genList = pre ~ T[0] ~ post ~ (T.length>1 ? "," : "") ~
+                     _genList!(pre, post, T[1..$]);
+  else
+    const _genList = ``;
+}
+
+/**
+ * Creates
+ *   - a typedef for enum (workaround for .tupleof.stringof)
+ *   - the enum structure
+ *   - string array of enum items (for runtime programming)
+ *   - string tuple of enum items (for metaprogramming - char[][] doesn't work)
+ */
+template createEnum(char[] tName, char[] eName, char[] arName, char[] alName, T...) {
+  const createEnum =
+    "typedef int " ~ tName ~ ";" ~
+    "enum " ~ eName ~ ":" ~ tName ~ "{" ~ _genList!("", "", T) ~ "};" ~
+    "char[][] " ~ arName ~ "=[" ~ _genList!(`"`, `"[]`, T) ~ "];" ~
+    "alias STuple!(" ~ _genList!(`"`, `"`, T) ~ ") " ~ alName ~ ";";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/misc/misc.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,61 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.misc.misc;
+import docgen.misc.options;
+import tango.io.model.IConduit : OutputStream;
+
+char[] docgen_version = "Dil document generator 0.1";
+
+interface DocGenerator {
+  DocGeneratorOptions *options();
+  void generate();
+}
+
+interface GraphCache {  
+  char[] getCachedGraph(Object graph, GraphFormat format);
+  void setCachedGraph(Object graph, GraphFormat format, char[] contents);
+}
+
+interface CachingDocGenerator : DocGenerator {
+  GraphCache graphCache();
+}
+
+interface WriterFactory {
+  DocGeneratorOptions *options();
+}
+
+abstract class AbstractWriterFactory : WriterFactory {
+  protected DocGenerator generator;
+
+  public:
+  
+  DocGeneratorOptions *options() {
+    return generator.options;
+  }
+
+  this(DocGenerator generator) {
+    this.generator = generator;
+  }
+}
+
+
+template AbstractWriter(T, int n = 0) {
+  abstract class AbstractWriter {
+    protected T factory;
+    protected OutputStream[] outputs;
+  
+    static if (n > 0) {
+      this(T factory, OutputStream[] outputs) {
+        this.factory = factory;
+        this.outputs = outputs;
+        assert(outputs.length == n, "Incorrect number of outputs");
+      }
+    }
+
+    this(T factory) {
+      this.factory = factory;
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/misc/options.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,112 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.misc.options;
+
+import docgen.misc.meta;
+
+/** creates reflective enums, syntax: enum name + list of elements */
+template optionEnum(char[] name, T...) {
+  const optionEnum = createEnum!("_" ~ name, name, "__" ~ name, "___" ~ name, T);
+}
+
+/** Supported document output formats. */
+mixin(optionEnum!("DocFormat", "LaTeX", "XML", "HTML", "PlainText"));
+
+/**
+ * Supported comment formats.
+ * 
+ * http://www.stack.nl/~dimitri/doxygen/docblocks.html
+ * http://www.digitalmars.com/d/ddoc.html
+ */
+mixin(optionEnum!("CommentFormat", "Ddoc", "Doxygen"));
+
+/** Supported image formats. */
+mixin(optionEnum!("ImageFormat", "PNG", "SVG", "GIF", "PDF"));
+
+/** Image format extensions. */
+const imageFormatExts = [ "png", "svg", "gif", "pdf" ];
+
+/** Supported graph writers. */
+mixin(optionEnum!("GraphFormat", "Dot", "ModuleNames", "ModulePaths"));
+
+struct GraphOptions {
+  /// image format to use for graphs
+  ImageFormat imageFormat;
+  /// maximum depth of dependencies in graphs
+  uint depth;
+  /// color of normal modules
+  char[] nodeColor;
+  /// color of the modules in cyclic dep relation
+  char[] cyclicNodeColor;
+  /// unlocatable module color
+  char[] unlocatableNodeColor;
+  /// color of the dependencies
+  char[] depColor;
+  /// color of the dependencies in cyclic dep relation
+  char[] cyclicDepColor;
+  /// color of the public dependencies
+  char[] publicDepColor;
+  /// package color
+  char[] clusterColor;
+  /// include unlocatable modules to the dep graph
+  bool includeUnlocatableModules;
+  /// highlight imports in cyclic dep relation
+  bool highlightCyclicEdges;
+  /// highlight modules in cyclic dep relation
+  bool highlightCyclicVertices;
+  /// group modules by package names in dep graph
+  bool groupByPackageNames;
+  /// group modules hierarchically or by full package name
+  bool groupByFullPackageName;
+}
+
+struct ListingOptions {
+  /// use literate programming symbols [LaTeX]
+  bool literateStyle;
+  /// enable source code listings
+  bool enableListings;
+}
+
+struct TemplateOptions {
+  /// project title
+  char[] title;
+  /// project version
+  char[] versionString;
+  /// copyright notice
+  char[] copyright;
+  /// paper size [LaTeX]
+  char[] paperSize;
+  /// use short file names [HTML]
+  bool shortFileNames;
+  /// page template style to use, customizable via docgen/templates
+  char[] templateStyle;
+}
+
+struct ParserOptions {
+  /// paths to search for imports 
+  char[][] importPaths;
+  /// paths to "root files"
+  char[][] rootPaths;
+  /// regexps for excluding modules
+  char[][] strRegexps;
+  /// comment format [comment parser]
+  CommentFormat commentFormat;
+  /// maximum depth of dependencies
+  uint depth;
+}
+
+struct DocGeneratorOptions {
+  /// location for the generated output
+  char[] outputDir;
+
+  /// list of document formats to be generated
+  DocFormat[] outputFormats;
+ 
+  GraphOptions graph;
+  ListingOptions listing;
+  TemplateOptions templates;
+  ParserOptions parser;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/misc/parser.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,210 @@
+/**
+ * Author: Aziz Köksal & Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.misc.parser;
+
+import dil.parser.Parser;
+import dil.parser.ImportParser;
+import dil.File;
+import dil.Settings;
+public import dil.semantic.Module;
+import tango.text.Regex : RegExp = Regex;
+import tango.io.FilePath;
+import tango.io.FileSystem;
+import tango.core.Array : remove;
+import tango.text.Util;
+import docgen.misc.meta;
+debug import tango.io.Stdout;
+
+alias void delegate (char[] fqn, char[] path, Module module_) modDg;
+alias void delegate (Module imported, Module importer, bool isPublic, bool isStatic) importDg;
+
+class Parser {
+  protected:
+
+//  ParserOptions m_options;
+
+    
+  static char[] findModuleFilePath(char[] moduleFQNPath, char[][] importPaths) {
+    auto filePath = new FilePath();
+    foreach (importPath; importPaths) {
+      filePath.set(importPath);
+      filePath.append(moduleFQNPath);
+
+      foreach (moduleSuffix; [".d", ".di"/*interface file*/])
+      {
+        filePath.suffix(moduleSuffix);
+        debug Stdout("Trying ")(filePath.toString()).newline;
+        if (filePath.exists())
+          return filePath.toString();
+      }
+    }
+
+    debug Stdout("  * ")(moduleFQNPath)(" does not exist in imports\n")();
+    return null;
+  }
+
+  public:
+
+  /**
+   * Imports the transitive closure of imports starting from "filePath",
+   * limited by recursionDepth.
+   *
+   * The search can be filtered by providing a list of regexps that match the
+   * FQNs of modules to be ignored.
+   *
+   * Params:
+   *     filePath = Path of the file to parse
+   *     importPaths = Directories to look for imports
+   *     strRegexps = Filter regexps
+   *     IncludeUnlocatableModules = Call the delegate also for unlocatable files
+   *     recursionDepth = How many levels of imports to follow (-1 = no limit)
+   *     mdg = Delegate that gets called for every module found
+   *     idg = Delegate that gets called for every import found
+   *     modules = List of parsed modules
+   */
+  static void loadModules(char[] filePath, char[][] importPaths, char[][] strRegexps,
+                          bool IncludeUnlocatableModules, int recursionDepth,
+                          modDg mdg, importDg idg, out Module[] modules) {
+
+    loadModules([filePath], importPaths, strRegexps, IncludeUnlocatableModules,
+      recursionDepth, mdg, idg, modules);
+  }
+
+  /**
+   * Imports the transitive closure of imports starting from "filePath",
+   * limited by recursionDepth.
+   *
+   * The search can be filtered by providing a list of regexps that match the
+   * FQNs of modules to be ignored.
+   *
+   * Params:
+   *     filePaths = Paths of the files to parse
+   *     importPaths = Directories to look for imports
+   *     strRegexps = Filter regexps
+   *     IncludeUnlocatableModules = Call the delegate also for unlocatable files
+   *     recursionDepth = How many levels of imports to follow (-1 = no limit)
+   *     mdg = Delegate that gets called for every module found
+   *     idg = Delegate that gets called for every import found
+   *     modules = List of parsed modules
+   */
+  static void loadModules(char[][] filePaths, char[][] importPaths, char[][] strRegexps,
+                          bool IncludeUnlocatableModules, int recursionDepth,
+                          modDg mdg, importDg idg, out Module[] modules) {
+
+    // Initialize regular expressions.
+    RegExp[] regexps;
+    foreach (strRegexp; strRegexps)
+      regexps ~= new RegExp(strRegexp);
+
+    importPaths ~= ".";
+
+    // Add directory of file and global directories to import paths.
+    foreach(filePath; filePaths) {
+      auto fileDir = (new FilePath(filePath)).folder();
+      if (fileDir.length)
+        importPaths ~= fileDir;
+    }
+
+//    importPaths ~= GlobalSettings.importPaths;
+
+    debug foreach(path; importPaths) {
+      Stdout("Import path: ")(path).newline;
+    }
+
+    Module[char[]] loadedModules;
+
+    Module loadModule(char[] moduleFQNPath, int depth) {
+      if (depth == 0) return null;
+      
+      debug Stdout("Loading ")(moduleFQNPath).newline;
+
+      // Return already loaded module.
+      auto mod_ = moduleFQNPath in loadedModules;
+      if (mod_ !is null) {
+        debug Stdout("  Already loaded.")(moduleFQNPath).newline;
+        return *mod_;
+      }
+
+      auto FQN = replace(moduleFQNPath.dup, dirSep, '.');
+      
+      // Ignore module names matching regular expressions.
+      foreach (rx; regexps)
+        if (rx.test(FQN)) return null;
+
+      auto moduleFilePath = findModuleFilePath(moduleFQNPath, importPaths);
+
+      debug Stdout("  FQN ")(FQN).newline;
+      debug Stdout("  Module path ")(moduleFilePath).newline;
+
+      Module mod = null;
+
+      if (moduleFilePath is null) {
+        if (IncludeUnlocatableModules)
+          mdg(FQN, moduleFQNPath, null);
+      } else {
+        mod = new Module(moduleFilePath);
+        
+        // Use lightweight ImportParser.
+//        mod.parser = new ImportParser(loadFile(moduleFilePath), moduleFilePath);
+        mod.parse();
+
+        debug Stdout("  Parsed FQN ")(mod.getFQN()).newline;
+
+        // autoinclude dirs (similar to Java)
+        // running docgen in foo/bar/abc/ also finds foo/xyz/zzz.d if module names are right
+        {
+          // foo.bar.mod -> [ "foo", "bar" ]
+          auto modPackage = split(mod.getFQN, ".")[0..$-1];
+          auto modDir = split(FileSystem.toAbsolute(new FilePath(moduleFilePath)).standard().folder(), "/");
+          auto modLocation = modDir[0..modDir.remove(".")];
+
+          bool matches = false;
+          int i;
+
+          for(i = 1; i <= min(modPackage.length, modLocation.length); i++) {
+            matches = true;
+            debug Stdout("  Decl: ")(modPackage[$-i]).newline;
+            debug Stdout("  Path: ")(modLocation[$-i]).newline;
+            if (modPackage[$-i] != modLocation[$-i]) {
+              matches = false;
+              break;
+            }
+          }
+          if (matches) {
+            auto loc = modLocation[0..$-i+1].join("/");
+            debug Stdout("  Autoadding import: ")(loc).newline;
+            importPaths ~= loc;
+          }
+        }
+
+        mdg(FQN, moduleFQNPath, mod);
+        loadedModules[moduleFQNPath] = mod;
+
+        foreach (importDecl; mod.imports)
+          foreach(moduleFQN_; importDecl.getModuleFQNs(dirSep)) {
+            auto loaded_mod = loadModule(moduleFQN_, depth == -1 ? depth : depth-1);
+
+            if (loaded_mod !is null) {
+              idg(loaded_mod, mod, importDecl.isPublic(), importDecl.isStatic());
+            } else if (IncludeUnlocatableModules) {
+              auto tmp = new Module(null);
+              tmp.setFQN(replace(moduleFQN_.dup, dirSep, '.'));
+              idg(tmp, mod, importDecl.isPublic(), importDecl.isStatic());
+            }
+          }
+      }
+
+      return mod;
+    } // loadModule
+
+    foreach(filePath; filePaths)
+      loadModule(filePath, recursionDepth);
+
+    // Finished loading modules.
+
+    // Ordered list of loaded modules.
+    modules = loadedModules.values;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/misc/textutils.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,38 @@
+/**
+ * Author: Aziz Köksal & Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.misc.textutils;
+
+// copied from Generate.d
+char[] xml_escape(char[] text)
+{
+  char[] result;
+  result.length = text.length;
+  result.length = 0;
+  foreach(c; text)
+    switch(c)
+    {
+      case '<': result ~= "&lt;";  break;
+      case '>': result ~= "&gt;";  break;
+      case '&': result ~= "&amp;"; break;
+      default:  result ~= c;
+    }
+  return result;
+}
+
+char[] plainTextHeading(char[] s) {
+  char[] line;
+  line.length = 80;
+  line[] = '=';
+
+  return s ~ \n ~ line[0..s.length].dup ~ \n ~ \n;
+}
+
+char[] plainTextHorizLine(int l = 80) {
+  char[] line;
+  line.length = 80;
+  line[] = '-';
+  
+  return line[0..l].dup ~ \n;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/moduledoc/htmlwriter.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,38 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.moduledoc.htmlwriter;
+
+import docgen.moduledoc.writer;
+import docgen.misc.textutils;
+
+
+/**
+ * TODO
+ */
+class HTMLWriter : AbstractWriter!(ModuleDocWriterFactory), ModuleDocWriter {
+  PageWriter writer;
+  
+  this(ModuleDocWriterFactory factory, PageWriter writer) {
+    super(factory);
+    this.writer = writer;
+  }
+  
+  void generateModuleDoc(Module mod, OutputStream output) {
+    
+					/*
+    auto inputStream = cast(FileInput)input;
+    auto content = new char[inputStream.length];
+    auto bytesRead = inputStream.read (content);
+    
+    assert(bytesRead == inputStream.length, "Error reading source file");
+    assert(output == null);
+    
+    writer.addListing(
+      moduleName,
+      xml_escape(content)
+    );*/
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/moduledoc/writer.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,17 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.moduledoc.writer;
+
+import docgen.misc.misc;
+public import docgen.page.writer;
+import tango.io.model.IConduit : OutputStream, InputStream;
+
+interface ModuleDocWriter {
+  void generateModuleDoc(Module mod, OutputStream output);
+}
+
+interface ModuleDocWriterFactory : WriterFactory {
+  ModuleDocWriter createModuleDocWriter(PageWriter writer, DocFormat outputFormat);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/moduledoc/writers.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,30 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.moduledoc.writers;
+
+public import docgen.moduledoc.writer;
+//import docgen.moduledoc.latexwriter;
+import docgen.moduledoc.htmlwriter;
+//import docgen.moduledoc.xmlwriter;
+
+class DefaultModuleDocWriterFactory : AbstractWriterFactory, ModuleDocWriterFactory {
+  this(DocGenerator generator) {
+    super(generator);
+  }
+
+  ModuleDocWriter createModuleDocWriter(PageWriter writer, DocFormat outputFormat) {
+    switch (outputFormat) {/*
+      case DocFormat.LaTeX:
+        return new LaTeXWriter(this, writer);
+      case DocFormat.XML:
+        return new XMLWriter(this, writer);*/
+      case DocFormat.HTML:
+        return new HTMLWriter(this, writer);
+      default:
+        throw new Exception("Moduledoc writer type does not exist!");
+    }
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/page/htmlwriter.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,121 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.page.htmlwriter;
+
+import docgen.page.writer;
+import docgen.misc.textutils;
+import tango.io.FileConduit : FileConduit;
+import tango.text.convert.Sprint;
+import tango.io.FilePath;
+
+/**
+ * Writes a HTML document skeleton.
+ */
+class HTMLWriter : AbstractPageWriter!("html") {
+  private:
+
+  char[] styleSheetFile;
+
+  public:
+  
+  this(PageWriterFactory factory, OutputStream[] outputs) {
+    super(factory);
+  }
+
+  override void generateClassSection() {
+    print.format(getTemplate("classes"), factory.options.templates.title);
+  }
+
+  override void generateModuleSection(Module[] modules) {
+    print.format(getTemplate("modules"), factory.options.templates.title);
+  }
+
+  override void generateListingSection(Module[] modules) {
+    print.format(getTemplate("listings"), factory.options.templates.title);
+  }
+
+  override void generateDepGraphSection() {
+    print.format(getTemplate("dependencies"), factory.options.templates.title);
+  }
+
+  void generateFirstPage() {
+    print.format(
+      getTemplate("firstpage"),
+      factory.options.templates.title,
+      factory.options.templates.versionString,
+      factory.options.templates.copyright
+    );
+
+    footer();
+  }
+  
+  /**
+   * A hack for figuring out the stylesheet file name.
+   */
+  override void generateCustomPage(char[] name, char[][] args ...) {
+    super.generateCustomPage(name, args);
+
+    if (name == "stylesheet") {
+      styleSheetFile = (new FilePath(
+        (cast(Object)outputs[0].conduit).toString())).file();
+    }
+  }
+
+  /**
+   * Overrides the default template fetcher in order to
+   * provide a consistent layout for all pages.
+   */
+  override char[] getTemplate(char[] name) {
+    auto content = super.getTemplate(name);
+
+    foreach(pageName; [
+      "firstpage"[], "toc"[], "classes"[], "modules"[], "listing"[],
+      "listings"[], "dependencies"[], "lastpage"[] ]) {
+      if (name == pageName) {
+        auto sprint = new Sprint!(char)(5120);
+        char[] title = factory.options.templates.title ~ " ";
+        switch(name) {
+          case "firstpage": title ~= "Documentation"; break;
+          case "toc": title ~= "TOC"; break;
+          case "classes": title ~= "Class index"; break;
+          case "modules": title ~= "Module index"; break;
+          case "listing": title ~= "File contents"; break;
+          case "listings": title ~= "File index"; break;
+          case "dependencies": title ~="Dependencies"; break;
+        }
+        return
+          sprint.format(super.getTemplate("pagetemplate"), styleSheetFile, title) ~
+          content;
+      }
+    }
+
+    return content;
+  }
+
+  void addList(char[][] contents, bool ordered) {
+    foreach(item; contents) {
+      switch(item) {
+        case "(": print(ordered ? "<ol>" : "<ul>"); continue;
+        case ")": print(ordered ? "</ol>" : "</ul>"); continue;
+        default: print("<li>")(item)("</li>");
+      }
+    }
+  }
+
+  override void addListing(char[] moduleName, char[] contents, bool inline) {
+    print.format(getTemplate("listing"), moduleName, contents);
+
+    footer();
+  }
+
+  protected:
+
+  /**
+   * Writes the page footer.
+   */
+  void footer() {
+    print.format(getTemplate("pagetemplate2"), docgen_version);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/page/latexwriter.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,39 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.page.latexwriter;
+
+import docgen.page.writer;
+import tango.io.FileConduit : FileConduit;
+
+/**
+ * Writes a LaTeX document skeleton.
+ */
+class LaTeXWriter : AbstractPageWriter!("latex", 1) {
+  this(PageWriterFactory factory, OutputStream[] outputs) {
+    super(factory, outputs);
+  }
+
+  void generateFirstPage() {
+    print.format(
+      getTemplate("firstpage"),
+      factory.options.templates.paperSize,
+      factory.options.templates.title,
+      factory.options.templates.versionString,
+      docgen_version,
+      timeNow(),
+      factory.options.listing.literateStyle ? "" : "%"
+    );
+  }
+
+  void addList(char[][] contents, bool ordered) {
+    foreach(item; contents) {
+      switch(item) {
+        case "(": print(ordered ? "\\begin{enumerate}" : "\\begin{itemize}"); continue;
+        case ")": print(ordered ? "\\end{enumerate}" : "\\end{itemize}"); continue;
+        default: print("\\item")(item)(\n);
+      }
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/page/plaintextwriter.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,61 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.page.plaintextwriter;
+
+import docgen.page.writer;
+import docgen.misc.textutils;
+import tango.io.FileConduit : FileConduit;
+
+/**
+ * Writes a plain text document skeleton.
+ */
+class PlainTextWriter : AbstractPageWriter!("plaintext") {
+  this(PageWriterFactory factory, OutputStream[] outputs) {
+    super(factory);
+  }
+
+  override void generateTOC(Module[] modules) {
+    print.format(getTemplate("toc"));
+  }
+
+  override void generateModuleSection(Module[] modules) {
+    print.format(getTemplate("modules"));
+  }
+
+  override void generateListingSection(Module[] modules) {
+    print.format(getTemplate("listings"));
+  }
+
+  void generateDepGraphSection() {
+    print.format(getTemplate("dependencies"));
+  }
+
+  void generateFirstPage() {
+    print.format(getTemplate("firstpage"),
+      plainTextHeading(factory.options.templates.title ~ " Reference Manual"),
+      factory.options.templates.versionString,
+      docgen_version,
+      timeNow()
+    );
+  }
+
+  void addList(char[][] contents, bool ordered) {
+    uint[] counters;
+    foreach(item; contents) {
+      switch(item) {
+        case "(": counters ~= 1; continue;
+        case ")": counters.length = counters.length - 1; continue;
+        default:
+        if (counters.length>0)
+          for (int i=0; i <= counters.length; i++)
+            print(" ");
+        if (ordered)
+          print(++counters[$-1])(". ")(item)(\n);
+        else
+          print("* ")(item)(\n);
+      }
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/page/writer.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,231 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.page.writer;
+
+public import docgen.misc.misc;
+public import docgen.misc.options;
+public import docgen.misc.parser;
+import tango.io.model.IConduit : OutputStream;
+import tango.time.chrono.Gregorian;
+import tango.text.locale.Core;
+import tango.time.WallClock;
+import tango.text.convert.Sprint;
+import tango.io.stream.FileStream;
+import tango.io.Stdout;
+import tango.io.Print: Print;
+import tango.text.convert.Layout : Layout;
+import tango.io.FilePath;
+import tango.io.FileScan;
+
+const templateDir = "docgen/templates/";
+
+const formatDirs = [ "latex"[], "xml"[], "html"[], "plaintext"[] ];
+
+/**
+ * Writes the logical subcomponents of a document,
+ * e.g. sections, embedded graphics, lists
+ */
+interface PageWriter {
+  /**
+   * Updates the outputstreams.
+   */
+  void setOutput(OutputStream[] outputs);
+
+  /**
+   * Generates the first page(s).
+   */
+  void generateFirstPage();
+
+  /**
+   * Generates table of contents.
+   */
+  void generateTOC(Module[] modules);
+
+  /**
+   * Generates class documentation section.
+   */
+  void generateClassSection();
+
+  /**
+   * Generates module documentation section.
+   */
+  void generateModuleSection(Module[] modules);
+
+  /**
+   * Generates source code listing section.
+   */
+  void generateListingSection(Module[] modules);
+
+  /**
+   * Generates dependency graph section.
+   */
+  void generateDepGraphSection();
+
+  /**
+   * Generates an index section.
+   */
+  void generateIndexSection();
+
+  /**
+   * Generates the last page(s).
+   */
+  void generateLastPage();
+
+  /**
+   * Generates a page using a custom template file.
+   *
+   * Some examples: style sheet, DTD files, makefiles.
+   */
+  void generateCustomPage(char[] name, char[][] args ...);
+  
+  // --- page components
+  //
+  /*
+   * Adds an external graphics file. 
+   */
+  void addGraphics(char[] imageFile);
+  
+  /**
+   * Adds a source code listing.
+   */
+  void addListing(char[] moduleName, char[] contents, bool inline = true);
+
+  /**
+   * Adds a list of items.
+   */
+  void addList(char[][] contents, bool ordered);
+}
+
+interface PageWriterFactory : WriterFactory {
+  PageWriter createPageWriter(OutputStream[] outputs, DocFormat outputFormat);
+}
+
+template AbstractPageWriter(char[] format, int n = 0) {
+  abstract class AbstractPageWriter : AbstractWriter!(PageWriterFactory, n), PageWriter {
+    protected:
+
+    char[][char[]] m_templates;
+    Print!(char) print;
+
+    public:
+         
+    this(PageWriterFactory factory, OutputStream[] outputs) {
+      this(factory);
+      setOutput(outputs);
+    }
+
+    void setOutput(OutputStream[] outputs) {
+      this.outputs = outputs;
+      static if (n > 0)
+        assert(outputs.length == n, "Incorrect number of outputs");
+
+      print = new Print!(char)(new Layout!(char), outputs[0]);
+    }
+
+    void generateTOC(Module[] modules) {
+      print.format(getTemplate("toc"));
+    }
+
+    void generateClassSection() {
+      print.format(getTemplate("classes"));
+    }
+
+    void generateModuleSection(Module[] modules) {
+      print.format(getTemplate("modules"));
+    }
+
+    void generateListingSection(Module[] modules) {
+      print.format(getTemplate("listings"));
+    }
+
+    void generateDepGraphSection() {
+      print.format(getTemplate("dependencies"));
+    }
+
+    void generateIndexSection() {
+      print.format(getTemplate("index"));
+    }
+
+    void generateLastPage() {
+      print.format(getTemplate("lastpage"));
+    }
+
+    void generateCustomPage(char[] name, char[][] args ...) {
+      switch(args.length) {
+        case 0: print.format(getTemplate(name)); break;
+        case 1: print.format(getTemplate(name), args[0]); break;
+        case 2: print.format(getTemplate(name), args[0], args[1]); break;
+        case 3: print.format(getTemplate(name), args[0], args[1], args[2]); break;
+        default: throw new Exception("Too many arguments");
+      }
+    }
+
+    //---
+
+    void addGraphics(char[] imageFile) {
+      print.format(getTemplate("graphics"), imageFile);
+    }
+    
+    void addListing(char[] moduleName, char[] contents, bool inline) {
+      print.format(getTemplate("listing"), moduleName, contents);
+    }
+
+    protected:
+
+    this(PageWriterFactory factory) {
+      super(factory);
+    
+      auto scan = new FileScan();
+      scan(templateDir~factory.options.templates.templateStyle~"/"~format~"/", ".tpl");
+
+      debug Stdout(scan.files.length)(" template files loaded.\n");
+
+      foreach(tpl; scan.files) {
+        m_templates[tpl.name] = loadTemplate(tpl.toString());
+      }
+    }
+
+    char[] getTemplate(char[] name) {
+      auto tpl = name in m_templates;
+      assert(tpl, "Error: template ["~format~"/"~name~"] not found!");
+      return *tpl;
+    }
+
+    char[] loadTemplate(char[] fn) {
+      scope(failure) {
+        Stderr("Warning: error opening template "~fn~".");
+        return null;
+      }
+
+      auto file = new FileInput(fn);
+      auto content = new char[file.length];
+      auto bytesRead = file.read(content);
+      
+      assert(bytesRead == file.length, "Error reading template");
+      
+      file.close();
+      
+      return content;
+    }
+    
+    char[] timeNow() {
+      auto n = WallClock.now;
+      auto c = Gregorian.generic;
+      auto d = c.toDate(n);
+      auto sprint = new Sprint!(char);
+
+      auto culture = new Culture("en-GB");
+      auto dateTimeFormat = culture.dateTimeFormat();
+
+      return sprint.format("{} {} {} {}",
+        dateTimeFormat.getAbbreviatedDayName(c.getDayOfWeek(n)),
+        1,//d.day(),
+        //dateTimeFormat.getAbbreviatedMonthName(d.month()),
+        2,//d.month(),
+        3//d.year()) //FIXME: something is broken here (Error: function expected before (), not *(&d + 8u) of type uint)
+        ).dup;
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/page/writers.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,32 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.page.writers;
+
+public import docgen.page.writer;
+import docgen.page.htmlwriter;
+import docgen.page.xmlwriter;
+import docgen.page.plaintextwriter;
+import docgen.page.latexwriter;
+
+class DefaultPageWriterFactory : AbstractWriterFactory, PageWriterFactory {
+  this(DocGenerator generator) {
+    super(generator);
+  }
+
+  PageWriter createPageWriter(OutputStream[] outputs, DocFormat outputFormat) {
+    switch (outputFormat) {
+      case DocFormat.LaTeX:
+        return new LaTeXWriter(this, outputs);
+      case DocFormat.XML:
+        return new XMLWriter(this, outputs);
+      case DocFormat.HTML:
+        return new HTMLWriter(this, outputs);
+      case DocFormat.PlainText:
+        return new PlainTextWriter(this, outputs);
+      default:
+        throw new Exception("Document writer type does not exist!");
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/page/xmlwriter.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,56 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.page.xmlwriter;
+
+import docgen.page.writer;
+import docgen.misc.textutils;
+import tango.io.FileConduit : FileConduit;
+
+//TODO: this is mostly broken now
+
+/**
+ * TODO
+ */
+class XMLWriter : AbstractPageWriter!("xml", 1) {
+  this(PageWriterFactory factory, OutputStream[] outputs) {
+    super(factory, outputs);
+  }
+
+  void generateTOC(Module[] modules) {
+    // TODO
+    print.format(getTemplate("toc"));
+  }
+
+  void generateModuleSection() {
+    // TODO
+    print.format(getTemplate("modules"));
+  }
+
+  void generateListingSection() {
+    // TODO
+    print.format(getTemplate("listings"));
+  }
+
+  void generateDepGraphSection() {
+    // TODO
+    print.format(getTemplate("dependencies"));
+  }
+
+  void generateIndexSection() { }
+
+  void generateLastPage() { }
+
+  void generateFirstPage() { }
+
+  void addList(char[][] contents, bool ordered) {
+    foreach(item; contents) {
+      switch(item) {
+        case "(": print(ordered ? "<ol>" : "<ul>"); continue;
+        case ")": print(ordered ? "</ol>" : "</ul>"); continue;
+        default: print("<li>")(xml_escape(item))("</li>");
+      }
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/sourcelisting/htmlwriter.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,39 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.sourcelisting.htmlwriter;
+
+import docgen.sourcelisting.writer;
+import docgen.misc.textutils;
+//import dil.Parser;
+import tango.io.stream.FileStream;
+
+
+/**
+ * TODO
+ */
+class HTMLWriter : AbstractWriter!(ListingWriterFactory), ListingWriter {
+  PageWriter writer;
+  
+  this(ListingWriterFactory factory, PageWriter writer) {
+    super(factory);
+    this.writer = writer;
+  }
+  
+  //void generateListing(Parser parser) { /* TODO */ }
+  
+  void generateListing(InputStream input, OutputStream output, char[] moduleName) {
+    auto inputStream = cast(FileInput)input;
+    auto content = new char[inputStream.length];
+    auto bytesRead = inputStream.read (content);
+    
+    assert(bytesRead == inputStream.length, "Error reading source file");
+    assert(output == null);
+    
+    writer.addListing(
+      moduleName,
+      xml_escape(content)
+    );
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/sourcelisting/latexwriter.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,32 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.sourcelisting.latexwriter;
+
+import docgen.sourcelisting.writer;
+//import dil.Parser;
+import tango.io.FilePath;
+
+/**
+ * Adds a code listing section for the given file. 
+ */
+class LaTeXWriter : AbstractWriter!(ListingWriterFactory), ListingWriter {
+  PageWriter writer;
+  
+  this(ListingWriterFactory factory, PageWriter writer) {
+    super(factory);
+    this.writer = writer;
+  }
+
+  //void generateListing(Parser parser) { /* TODO */ }
+  
+  void generateListing(InputStream input, OutputStream output, char[] moduleName) {
+    output.copy(input);
+    
+    writer.addListing(
+      moduleName,
+      FilePath((cast(Object)output.conduit).toString()).file
+    );
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/sourcelisting/writer.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,19 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.sourcelisting.writer;
+
+import docgen.misc.misc;
+public import docgen.page.writer;
+//import dil.Parser;
+import tango.io.model.IConduit : OutputStream, InputStream;
+
+interface ListingWriter {
+  //void generateListing(Parser parser);
+  void generateListing(InputStream input, OutputStream output, char[] moduleName);
+}
+
+interface ListingWriterFactory : WriterFactory {
+  ListingWriter createListingWriter(PageWriter writer, DocFormat outputFormat);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/sourcelisting/writers.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,29 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.sourcelisting.writers;
+
+public import docgen.sourcelisting.writer;
+import docgen.sourcelisting.latexwriter;
+import docgen.sourcelisting.htmlwriter;
+import docgen.sourcelisting.xmlwriter;
+
+class DefaultListingWriterFactory : AbstractWriterFactory, ListingWriterFactory {
+  this(DocGenerator generator) {
+    super(generator);
+  }
+
+  ListingWriter createListingWriter(PageWriter writer, DocFormat outputFormat) {
+    switch (outputFormat) {
+      case DocFormat.LaTeX:
+        return new LaTeXWriter(this, writer);
+      case DocFormat.XML:
+        return new XMLWriter(this, writer);
+      case DocFormat.HTML:
+        return new HTMLWriter(this, writer);
+      default:
+        throw new Exception("Listing writer type does not exist!");
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/sourcelisting/xmlwriter.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,23 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.sourcelisting.xmlwriter;
+
+import docgen.sourcelisting.writer;
+//import dil.Parser;
+
+/**
+ * TODO
+ */
+class XMLWriter : AbstractWriter!(ListingWriterFactory), ListingWriter {
+  PageWriter writer;
+  
+  this(ListingWriterFactory factory, PageWriter writer) {
+    super(factory);
+    this.writer = writer;
+  }
+
+  //void generateListing(Parser parser) { /* TODO */ }
+  void generateListing(InputStream input, OutputStream output, char[] moduleName) { /* TODO */ }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/README	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,14 @@
+The docgen uses the following template file names by default
+
+firstpage
+toc
+classes
+modules
+listings
+dependencies
+index
+lastpage
+langdef
+makefile
+graphics
+listing
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/html/classes.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,1 @@
+<h1>{0} Class List</h1>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/html/dependencies.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,1 @@
+<h1>{} Dependencies</h1>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/html/firstpage.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,3 @@
+<h1>{0} Documentation</h1>
+<h2 id="version">{1}</h2>
+<h2>© {2}</h2>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/html/graphics.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,1 @@
+<p><img src="{}" /></p>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/html/listing.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,2 @@
+<h1>{0} Contents</h1>
+<pre style="dcode">{1}</pre>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/html/listings.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,1 @@
+<h1>{0} File List</h1>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/html/makefile.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+for i in *.dot; do
+  F=`echo $i|sed 's/dot/{0}/'`
+  dot $i -T{0} -o$F
+done
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/html/modules.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,1 @@
+<h1>{0} Module List</h1>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/html/pagetemplate.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,18 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+  <title>{1}</title>
+  <meta name="author" content="TODO" />
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <link rel="stylesheet" href="{0}" media="all" title="default" />
+</head>
+<body>
+<div class="tabs">
+  <ul>
+    <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
+    <li><a href="classes.html"><span>Classes</span></a></li>
+    <li><a href="modules.html"><span>Modules</span></a></li>
+    <li><a href="files.html"><span>Files</span></a></li>
+    <li><a href="depgraph.html"><span>Dependencies</span></a></li>
+  </ul>
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/html/pagetemplate2.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,4 @@
+<hr />
+<p id="generator">Generated by {0}</p>
+</body>
+</html>
Binary file src/docgen/templates/default/html/static/tab_b.gif has changed
Binary file src/docgen/templates/default/html/static/tab_l.gif has changed
Binary file src/docgen/templates/default/html/static/tab_r.gif has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/html/static/tabs.css	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,102 @@
+/* tabs styles, based on http://www.alistapart.com/articles/slidingdoors */
+
+DIV.tabs
+{
+   float            : left;
+   width            : 100%;
+   background       : url("tab_b.gif") repeat-x bottom;
+   margin-bottom    : 4px;
+}
+
+DIV.tabs UL
+{
+   margin           : 0px;
+   padding-left     : 10px;
+   list-style       : none;
+}
+
+DIV.tabs LI, DIV.tabs FORM
+{
+   display          : inline;
+   margin           : 0px;
+   padding          : 0px;
+}
+
+DIV.tabs FORM
+{
+   float            : right;
+}
+
+DIV.tabs A
+{
+   float            : left;
+   background       : url("tab_r.gif") no-repeat right top;
+   border-bottom    : 1px solid #84B0C7;
+   font-size        : x-small;
+   font-weight      : bold;
+   text-decoration  : none;
+}
+
+DIV.tabs A:hover
+{
+   background-position: 100% -150px;
+}
+
+DIV.tabs A:link, DIV.tabs A:visited,
+DIV.tabs A:active, DIV.tabs A:hover
+{
+       color: #1A419D;
+}
+
+DIV.tabs SPAN
+{
+   float            : left;
+   display          : block;
+   background       : url("tab_l.gif") no-repeat left top;
+   padding          : 5px 9px;
+   white-space      : nowrap;
+}
+
+DIV.tabs INPUT
+{
+   float            : right;
+   display          : inline;
+   font-size        : 1em;
+}
+
+DIV.tabs TD
+{
+   font-size        : x-small;
+   font-weight      : bold;
+   text-decoration  : none;
+}
+
+
+
+/* Commented Backslash Hack hides rule from IE5-Mac \*/
+DIV.tabs SPAN {float : none;}
+/* End IE5-Mac hack */
+
+DIV.tabs A:hover SPAN
+{
+   background-position: 0% -150px;
+}
+
+DIV.tabs LI.current A
+{
+   background-position: 100% -150px;
+   border-width     : 0px;
+}
+
+DIV.tabs LI.current SPAN
+{
+   background-position: 0% -150px;
+   padding-bottom   : 6px;
+}
+
+DIV.nav
+{
+   background       : none;
+   border           : none;
+   border-bottom    : 1px solid #84B0C7;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/html/stylesheet.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,33 @@
+@import "tabs.css";
+
+body {{
+background: #fff;
+}
+
+h1, h2 {{
+text-align: center;
+}
+
+h1 {{
+font-size: 1.5em;
+}
+
+h2#version {{
+font-size: 0.8em;
+}
+
+h2 {{
+font-size: 1.1em;
+}
+
+hr {{
+height: 0;
+border: 0;
+border-bottom: 1px solid black;
+}
+
+#generator {{
+text-align: right;
+font-size: small;
+font-style: italic;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/html/toc.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,15 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+  <title>{0} Reference Manual</title>
+  <meta name="author" content="{1}" />
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <link rel="stylesheet" href="style.css" media="all" title="default" />
+  <link rel="stylesheet" href="print.css" media="print" />
+</head>
+<body>
+<h2>Table of Contents</h2>
+<hr />
+{0}
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/latex/classes.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,2 @@
+\chapter{{Class documentation}
+\input{{classes}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/latex/dependencies.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,2 @@
+\chapter{{Dependency diagram}
+\input{{dependencies}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/latex/firstpage.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,50 @@
+\documentclass[{0}]{{book}
+\usepackage{{a4wide}
+\usepackage{{makeidx}
+\usepackage{{fancyhdr}
+\usepackage{{graphicx}
+\usepackage{{hyperref}
+\usepackage{{multicol}
+\usepackage{{float}
+\usepackage{{textcomp}
+\usepackage{{alltt}
+\usepackage[utf8]{{inputenc}
+\usepackage{{listings}
+\lstnewenvironment{{dcode}
+{{ \lstset{{language=d} }
+{{}
+\lstset{{
+  {5} literate=
+  {5}          {{<=}{{{{$\leq$}}1
+  {5}          {{>=}{{{{$\geq$}}1
+  {5}          {{!=}{{{{$\neq$}}1
+  {5}          {{...}{{{{$\dots$}}1
+  {5}          {{~}{{{{$\sim$}}1,
+  stringstyle=\ttfamily,
+  inputencoding=utf8,
+  extendedchars=false,
+  columns=fixed,
+  basicstyle=\small
+}
+\hypersetup{{backref,colorlinks=true}
+\makeindex
+\setcounter{{tocdepth}{{1}
+\newcommand{{\clearemptydoublepage}{{\newpage{{\pagestyle{{empty}\cleardoublepage}}
+\def\thechapter{{\Roman{{chapter}}
+\def\thesection{{\arabic{{chapter}.\arabic{{section}}
+% \renewcommand{{\footrulewidth}{{0.4pt}
+
+\begin{{document}
+
+\begin{{titlepage}
+\vspace*{{7cm}
+\begin{{center}
+{{\Large {1} Reference Manual\\[1ex]\large {2} }\\
+\vspace*{{1cm}
+{{\large Generated by {3} }\\
+\vspace*{{0.5cm}
+{{\small {4} }\\
+\end{{center}
+\end{{titlepage}
+
+\clearemptydoublepage
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/latex/graphics.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,1 @@
+\includegraphics[width=1\textwidth,height=1\textheight,keepaspectratio]{{{0}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/latex/index.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,1 @@
+\printindex
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/latex/lastpage.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,1 @@
+\end{{document}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/latex/listing.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,3 @@
+\section{{Module {0}}
+\lstinputlisting[language=d]{{{1}}
+\clearpage
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/latex/listings.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,2 @@
+\chapter{{File listings}
+\input{{files}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/latex/makefile.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+for i in *.dot; do
+  F=`echo $i|sed 's/dot/{1}/'`
+  dot $i -T{1} -o$F
+done
+
+pdflatex {0}
+makeindex document
+pdflatex {0}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/latex/modules.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,2 @@
+\chapter{{Module documentation}
+\input{{modules}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/latex/static/lstlang0.sty	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,22 @@
+%%
+%% D definition (c) 2007 Jari-Matti Mäkelä
+%%
+\lst@definelanguage{D}%
+  {morekeywords={abstract,alias,align,asm,assert,auto,body,bool,break,%
+      byte,case,cast,catch,cdouble,cent,cfloat,char,class,const,continue,%
+      creal,dchar,debug,default,delegate,delete,deprecated,do,double,%
+      else,enum,export,extern,false,final,finally,float,for,foreach,%
+      foreach_reverse,function,goto,idouble,if,ifloat,import,in,inout,%
+      int,interface,invariant,ireal,is,lazy,long,macro,mixin,module,new,%
+      null,out,override,package,pragma,private,protected,public,real,ref,%
+      return,scope,short,static,struct,super,switch,synchronized,template,%
+      this,throw,true,try,typedef,typeid,typeof,ubyte,ucent,uint,ulong,%
+      union,unittest,ushort,version,void,volatile,wchar,while,with},%
+   sensitive,%
+
+   morecomment=[s]{/*}{*/},%
+   morecomment=[n]{/+}{+/},%
+   morecomment=[l]//,%
+   morestring=[b]",%
+   morestring=[b]`%
+  }[keywords,comments,strings]%
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/latex/toc.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,6 @@
+\tableofcontents
+\thispagestyle{{empty}
+
+\clearemptydoublepage
+
+\setcounter{{page}{{1}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/plaintext/classes.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,3 @@
+Class List
+----------
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/plaintext/dependencies.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,3 @@
+Module Dependencies
+-------------------
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/plaintext/firstpage.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,7 @@
+{0}
+
+Version {1}
+
+Generated by {2}
+
+{3}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/plaintext/graphics.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,1 @@
+See {}.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/plaintext/listing.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,3 @@
+Module {0}
+See {1}.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/plaintext/listings.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,3 @@
+File listings
+-------------
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/plaintext/makefile.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+for i in *.dot; do
+  F=`echo $i|sed 's/dot/{0}/'`
+  dot $i -T{0} -o$F
+done
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/plaintext/modules.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,3 @@
+Module List
+-----------
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/templates/default/plaintext/toc.tpl	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,10 @@
+Table of Contents
+-----------------
+
+1. Class documentation
+
+2. Module documentation
+
+3. File listings
+
+4. Dependency diagram
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/tests/common.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,25 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.tests.common;
+
+import docgen.misc.misc;
+import docgen.misc.options;
+import docgen.config.configurator;
+
+class TestDocGenerator : DocGenerator {
+  Configurator config;
+
+  this() {
+    config = new DefaultConfigurator();
+  }
+
+  public void generate() {
+
+  }
+  
+  public DocGeneratorOptions *options() {
+    return config.getConfiguration();
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/tests/doctemplate.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,30 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.tests.doctemplate;
+
+import docgen.tests.common;
+import docgen.page.writers;
+import tango.io.FileConduit;
+
+// doc template
+//@unittest
+void doctemplate1() {
+  auto gen = new TestDocGenerator;
+  auto fname = "doctemplate.tex";
+  
+  auto gwf = new DefaultPageWriterFactory(gen);
+  auto file = new FileConduit("docgen/teststuff/" ~ fname, FileConduit.WriteCreate);
+  auto writer = gwf.createPageWriter( [ file ], DocFormat.LaTeX );
+  
+  writer.generateFirstPage();
+  writer.generateTOC(null);
+  writer.generateModuleSection(null);
+  writer.generateListingSection(null);
+  writer.generateDepGraphSection();
+  writer.generateIndexSection();
+  writer.generateLastPage();
+  
+  file.close();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/tests/graphs.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,160 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.tests.graphs;
+
+import docgen.tests.common;
+import docgen.misc.parser;
+import docgen.graphutils.writers;
+import docgen.page.writers;
+import tango.io.FileConduit;
+import dil.semantic.Module;
+
+alias DepGraph.Edge Edge;
+alias DepGraph.Vertex Vertex;
+
+void saveDefaultGraph(DepGraph depGraph, char[] fname) {
+  auto gen = new TestDocGenerator;
+  gen.options.graph.highlightCyclicVertices = true;
+  gen.options.graph.imageFormat = ImageFormat.SVG;
+  //gen.options.graph.graphFormat = GraphFormat.ModuleNames;
+  //gen.options.graph.graphFormat = GraphFormat.ModulePaths;
+  gen.options.graph.depth = 5;
+  auto ddf = new DefaultPageWriterFactory(gen);
+  auto gwf = new DefaultGraphWriterFactory(gen);
+  auto file = new FileConduit("docgen/teststuff/" ~ fname, FileConduit.WriteCreate);
+  auto file2 = new FileConduit("docgen/teststuff/" ~ fname ~ "-2", FileConduit.WriteCreate);
+
+  auto writer = gwf.createGraphWriter(
+    ddf.createPageWriter( [ file2 ], DocFormat.LaTeX),
+    GraphFormat.Dot
+  );
+  
+  writer.generateDepGraph(depGraph, file);
+  
+  file.close();
+  file2.close();
+}
+
+// no edges
+//@unittest
+void graph1() {
+  auto g = new DepGraph;
+  g.add(new Vertex("mod_a", "path.to.mod_a", 1));
+  g.add(new Vertex("mod_b", "path.to.mod_b", 2));
+  g.add(new Vertex("mod_c", "path.to.mod_c", 3));
+  
+  saveDefaultGraph(g, "graph1.dot");
+}
+
+
+// simple tree structure
+//@unittest
+void graph2() {
+  auto g = new DepGraph;
+  g.add(new Vertex("mod_a", "path.to.mod_a", 1));
+  g.add(new Vertex("mod_b", "path.to.mod_b", 2));
+  g.add(new Vertex("mod_c", "path.to.mod_c", 3));
+  g.add(new Vertex("mod_d", "path.to.mod_d", 4));
+
+  g.connect(1, 0);
+  g.connect(2, 0);
+  g.connect(3, 2);
+  
+  saveDefaultGraph(g, "graph2.dot");
+}
+
+// circular imports
+//@unittest
+void graph3() {
+  auto g = new DepGraph;
+  g.add(new Vertex("mod_a", "path.to.mod_a", 1));
+  g.add(new Vertex("mod_b", "path.to.mod_b", 2));
+  g.add(new Vertex("mod_c", "path.to.mod_c", 3));
+  g.add(new Vertex("mod_d", "path.to.mod_d", 4));
+
+  g.connect(1, 0);
+  g.connect(2, 1);
+  g.connect(0, 2);
+  
+  saveDefaultGraph(g, "graph3.dot");
+}
+
+// more complex graph
+//@unittest
+void graph4() {
+  auto g = new DepGraph;
+  g.add(new Vertex("mod_a", "path.to.mod_a", 1));
+  g.add(new Vertex("mod_b", "path.to.mod_b", 2));
+  g.add(new Vertex("mod_c", "path.to.mod_c", 3));
+  g.add(new Vertex("mod_d", "path.to.mod_d", 4));
+  g.add(new Vertex("mod_e", "path.to.mod_e", 5));
+  g.add(new Vertex("mod_f", "path.to.mod_f", 6));
+  g.add(new Vertex("mod_g", "path.to.mod_g", 7));
+
+  g.connect(1, 0);
+  g.connect(2, 1);
+  g.connect(0, 2); 
+  g.connect(0, 3);
+  g.connect(0, 4);
+  g.connect(3, 1);
+  g.connect(4, 1);
+  g.connect(0, 6);
+  g.connect(5, 1);
+  g.connect(5, 6);
+  g.connect(6, 0);
+
+  saveDefaultGraph(g, "graph4.dot");
+}
+
+
+// parses the test modules and creates a dep graph
+//@unittest
+void graph5() {
+  auto gen = new TestDocGenerator;
+  gen.options.graph.highlightCyclicVertices = true;
+  gen.options.graph.imageFormat = ImageFormat.PDF;
+  gen.options.outputFormats = [ DocFormat.LaTeX ];
+  auto fname = "dependencies.tex";
+  auto imgFname = "depgraph.dot";
+  
+  auto ddf = new DefaultPageWriterFactory(gen);
+  auto gwf = new DefaultGraphWriterFactory(gen);
+  auto file = new FileConduit("docgen/teststuff/" ~ fname, FileConduit.WriteCreate);
+  auto imgFile = new FileConduit("docgen/teststuff/" ~ imgFname, FileConduit.WriteCreate);
+  
+  Module[] modules;
+  Edge[] edges;
+  Vertex[char[]] vertices;
+  int id = 1;
+  
+  Parser.loadModules(
+    [ "c" ], [ "docgen/teststuff/" ],
+    null, true, -1,
+    (char[] fqn, char[] path, Module m) {
+      vertices[m.moduleFQN] = new DepGraph.Vertex(m.moduleFQN, m.filePath, id++);
+    },
+    (Module imported, Module importer, bool isPublic, bool isStatic) {
+      auto edge = vertices[imported.moduleFQN].addChild(vertices[importer.moduleFQN]);
+      edge.isPublic = isPublic;
+      edge.isStatic = isStatic;
+      edges ~= edge;
+    },
+    modules
+  );
+
+  auto writer = gwf.createGraphWriter(
+    ddf.createPageWriter( [ file ], DocFormat.LaTeX ),
+    GraphFormat.Dot
+  );
+  
+  auto graph = new DepGraph;
+  graph.edges = edges;
+  graph.vertices = vertices.values;
+
+  writer.generateDepGraph(graph, imgFile);
+  
+  file.close();
+  imgFile.close();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/tests/listing.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,51 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.tests.listing;
+
+import docgen.misc.parser;
+import docgen.tests.common;
+import docgen.sourcelisting.writers;
+import docgen.page.writers;
+import tango.io.FileConduit;
+import tango.text.Util;
+
+// doc template
+//@unittest
+void listing1() {
+  auto gen = new TestDocGenerator;
+  gen.options.outputFormats = [ DocFormat.LaTeX ];
+  auto fname = "files.tex";
+  
+  auto ddf = new DefaultPageWriterFactory(gen);
+  auto dlwf = new DefaultListingWriterFactory(gen);
+  auto file = new FileConduit("docgen/teststuff/" ~ fname, FileConduit.WriteCreate);
+  
+
+  Module[] modules;
+
+  Parser.loadModules(
+    [ "c" ], [ "docgen/teststuff/" ],
+    null, true, -1,
+    (char[] fqn, char[] path, Module m) {},
+    (Module imported, Module importer, bool isPublic, bool isStatic) {},
+    modules
+  );
+  
+  foreach(mod; modules) {
+    auto dstFname = replace(mod.moduleFQN.dup, '.', '_');
+    
+    auto srcFile = new FileConduit(mod.filePath);
+    auto dstFile = new FileConduit("docgen/teststuff/_" ~ dstFname ~ ".d", FileConduit.WriteCreate);
+    auto writer = dlwf.createListingWriter( ddf.createPageWriter( [ file ],
+          DocFormat.LaTeX ), DocFormat.LaTeX );
+    
+    writer.generateListing(srcFile, dstFile, mod.moduleFQN);
+
+    srcFile.close();
+    dstFile.close();
+  }
+  
+  file.close();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/tests/parse.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,65 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.tests.parse;
+
+import docgen.misc.parser;
+import tango.io.FileConduit;
+import tango.io.Print: Print;
+import tango.text.convert.Layout : Layout;
+
+void saveToFile(char[] fname, void delegate(Print!(char) file) foo) {
+  auto file = new FileConduit("docgen/teststuff/" ~ fname, FileConduit.WriteCreate);
+  auto output = new Print!(char)(new Layout!(char), file);
+  
+  foo(output);
+  
+  file.close();
+}
+
+// load some test files
+//@unittest
+void parse1() {
+  saveToFile("parse1.txt", (Print!(char) file){
+    Module[] modules;
+  
+    Parser.loadModules(
+      [ "c" ], [ "docgen/teststuff/" ],
+      null, true, -1,
+      (char[] fqn, char[] path, Module m) {
+        file.format("{0} = {1}\n", fqn, path);
+      },
+      (Module imported, Module importer, bool isPublic, bool isStatic) {
+        file.format("{0} <- {1}\n",
+          imported ? imported.moduleFQN : "null"[],
+          importer ? importer.moduleFQN : "null"[]
+        );
+      },
+      modules
+    );
+  });
+}
+
+// load the imports of dil
+//@unittest
+void parse2() {
+  saveToFile("parse2.txt", (Print!(char) file){
+    Module[] modules;
+    
+    Parser.loadModules(
+      [ "docgen/testsuite" ], [".", "/home/jm/d/tango/"],
+      null, true, -1,
+      (char[] fqn, char[] path, Module m) {
+        file.format("{0} = {1}\n", fqn, path);
+      },
+      (Module imported, Module importer, bool isPublic, bool isStatic) {
+        file.format("{0} <- {1}\n",
+          imported ? imported.moduleFQN : "null"[],
+          importer ? importer.moduleFQN : "null"[]
+        );
+      },
+      modules
+    );
+  });
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/teststuff/a.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,4 @@
+module a;
+
+void foo() {}
+void bar() {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/teststuff/b.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,4 @@
+module b;
+
+import a;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/teststuff/c.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,4 @@
+module c;
+
+import a;
+import b;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/teststuff/clean.sh	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,7 @@
+rm _*
+rm dep*
+rm doc*
+rm *.tex
+rm graph*
+rm parse*
+touch modules.tex
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/teststuff/lstlang0.sty	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,21 @@
+%%
+%% D definition (c) 2007 Jari-Matti Mäkelä
+%%
+\lst@definelanguage{D}%
+  {morekeywords={abstract,alias,align,asm,assert,auto,body,bool,break,%
+      byte,case,cast,catch,cdouble,cent,cfloat,char,class,const,continue,%
+      creal,dchar,debug,default,delegate,delete,deprecated,do,double,%
+      else,enum,export,extern,false,final,finally,float,for,foreach,%
+      foreach_reverse,function,goto,idouble,if,ifloat,import,in,inout,%
+      int,interface,invariant,ireal,is,lazy,long,macro,mixin,module,new,%
+      null,out,override,package,pragma,private,protected,public,real,ref,%
+      return,scope,short,static,struct,super,switch,synchronized,template,%
+      this,throw,true,try,typedef,typeid,typeof,ubyte,ucent,uint,ulong,%
+      union,unittest,ushort,version,void,volatile,wchar,while,with},%
+   sensitive,%
+   morecomment=[s]{/*}{*/},%
+   morecomment=[n]{/+}{+/},%
+   morecomment=[l]//,%
+   morestring=[b]",%
+   morestring=[b]`%
+  }[keywords,comments,strings]%
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/docgen/testsuite.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,42 @@
+/**
+ * Author: Jari-Matti Mäkelä
+ * License: GPL3
+ */
+module docgen.testsuite;
+
+import docgen.tests.graphs;
+import docgen.tests.parse;
+import docgen.tests.doctemplate;
+import docgen.tests.listing;
+//import docgen.tests.sexp;
+import tango.io.Stdout;
+
+/**
+ * A temporary test program for the docgen package.
+ * I'll replace this with proper unittests in the future.
+ *
+ */
+void main() {
+  Stdout("Running..\n")();
+
+  Stdout(" Test1\n")();
+  graph1();
+  Stdout(" Test2\n")();
+  graph2();
+  Stdout(" Test3\n")();
+  graph3();
+  Stdout(" Test4\n")();
+  graph4();
+  Stdout(" Test5\n")();
+  graph5();
+  Stdout(" Test6\n")();
+  parse1();
+  Stdout(" Test7\n")();
+  parse2();
+  Stdout(" Test8\n")();
+  doctemplate1();
+  Stdout(" Test9\n")();
+  listing1();
+//  loadConfig();
+  Stdout("done.\n")();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/html.css	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,70 @@
+@charset "utf-8";
+.compilerinfo, .sourcecode, .linescolumn {
+  white-space: pre;
+  font-family: Monospace;
+  font-size: 0.8em;
+  margin:0;
+  padding:0;
+}
+.compilerinfo {
+  white-space: normal;
+  border: 1px solid #A22;
+  padding: 0.5em;
+  margin: 1em;
+}
+.compilerinfo .error { display: block; }
+.linescolumn {
+  text-align: right;
+  padding-right: 0.3em;
+  border-right: 1px dotted gray;
+}
+.linescolumn a {
+  display: block;
+  color: #44B;
+  text-decoration: none;
+}
+/* Number */
+.n { color: teal; }
+/* Keyword */
+.k { color: darkblue; font-weight: bold; }
+/* Line, block and nested comments */
+.lc, .bc, .nc { color: green; }
+/* Identifier */
+.i { color: black; }
+/* String literal */
+.sl { color: red; }
+/* Character literal */
+.cl { color: purple; }
+/* All bracket types */
+.br { color: orange; }
+/* Special tokens */
+.st { color: green; font-weight: bold; }
+/* #line, hash line */
+.hl { color: green; }
+/* filespec (e.g. #line number [filespec]) */
+.fs { color: purple;}
+/* When the first line starts with #! it's a "shebang" */
+.shebang { color: gray; }
+/* Operator */
+/*.op { color: royalblue; }*/
+/* Particular operators */
+/*.opaa { content: "and"; }*/ /*&& ∧*/
+/*.opoo { content: "or"; }*/ /*|| ∨*/
+/*.opn { content: "¬"; }*/ /*!*/
+/*.opne { content: "≠"; }*/ /*!=*/
+/*.ople { content: "≤"; }*/ /*<=*/
+/*.opge { content: "≥"; }*/ /*>=*/
+/*.oplg { content: "≶"; }*/ /*<>*/
+/*
+d = Declaration
+s = Statement
+e = Expression
+t = Type
+o = Other
+*/
+/* .d { background-color: #FFDDDD; } */
+/* .e { background-color: #DDDDFF; } */
+.d.Module .i, .d.Import .i { color: blue; }
+ /*.t .i,*/ .t.Identifier .i, .TemplateTypeParameter .i { color: #911; } 
+.t .br, .t .op { color: #911; }
+.t .k { color: #911; font-weight: normal; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/html_map.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,117 @@
+/// A map of document elements and D tokens to format strings.
+string[string] map = [
+  "DocHead" : `<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">`\n
+              `<html>`\n
+              `<head>`\n
+              `  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">`\n
+              `  <link href="html.css" rel="stylesheet" type="text/css">`\n
+              `</head>`\n
+              `<body>`\n
+              `<table><tr>`\n,
+  "CompBegin"   : `<td><div class="compilerinfo">`\n,
+  "CompEnd"     : "</div>\n</td></tr><tr>",
+  "LexerError"  : `<p class="error L">{0}({1},{2})L: {3}</p>`\n,
+  "ParserError" : `<p class="error P">{0}({1},{2})P: {3}</p>`\n,
+
+  "LineNumberBegin" : `<td class="linescolumn">`,
+  "LineNumberEnd"   : "</td>\n<td>",
+  "LineNumber"      : `<a id="L{0}" href="#L{0}">{0}</a>`,
+
+  "SourceBegin" : `<td><pre class="sourcecode">`\n,
+  "SourceEnd"   : "\n</pre></td>",
+
+  "DocEnd"  : "\n</tr></table>"
+              "\n</body>"
+              "\n</html>",
+
+  // Node categories:
+  "Declaration" : "d",
+  "Statement"   : "s",
+  "Expression"  : "e",
+  "Type"        : "t",
+  "Other"       : "o",
+
+  // {0} = node category.
+  // {1} = node class name: "Call", "If", "Class" etc.
+  // E.g.: <span class="d Struct">...</d>
+  "NodeBegin" : `<span class="{0} {1}">`,
+  "NodeEnd"   : `</span>`,
+
+  "Identifier" : `<span class="i">{0}</span>`,
+  "String"     : `<span class="sl">{0}</span>`,
+  "Char"       : `<span class="cl">{0}</span>`,
+  "Number"     : `<span class="n">{0}</span>`,
+  "Keyword"    : `<span class="k">{0}</span>`,
+
+  "LineC"   : `<span class="lc">{0}</span>`,
+  "BlockC"  : `<span class="bc">{0}</span>`,
+  "NestedC" : `<span class="nc">{0}</span>`,
+
+  "Shebang"  : `<span class="shebang">{0}</span>`,
+  "HLine"    : `<span class="hl">{0}</span>`, // #line
+  "Filespec" : `<span class="fs">{0}</span>`, // #line N "filespec"
+  "Newline"  : "{0}", // \n | \r | \r\n | LS | PS
+  "Illegal"  : `<span class="ill">{0}</span>`, // A character not recognized by the lexer.
+
+  "SpecialToken" : `<span class="st">{0}</span>`, // __FILE__, __LINE__ etc.
+
+  "("    : "(",
+  ")"    : ")",
+  "["    : "[",
+  "]"    : "]",
+  "{"    : "{",
+  "}"    : "}",
+  "."    : ".",
+  ".."   : "..",
+  "..."  : "...",
+  "!<>=" : "!&lt;&gt;=", // Unordered
+  "!<>"  : "!&lt;&gt;",  // UorE
+  "!<="  : "!&lt;=",     // UorG
+  "!<"   : "!&lt;",      // UorGorE
+  "!>="  : "!&gt;=",     // UorL
+  "!>"   : "!&gt;",      // UorLorE
+  "<>="  : "&lt;&gt;=",  // LorEorG
+  "<>"   : "&lt;&gt;",   // LorG
+  "="    : "=",
+  "=="   : "==",
+  "!"    : "!",
+  "!="   : "!=",
+  "<="   : "&lt;=",
+  "<"    : "&lt;",
+  ">="   : "&gt;=",
+  ">"    : "&gt;",
+  "<<="  : "&lt;&lt;=",
+  "<<"   : "&lt;&lt;",
+  ">>="  : "&gt;&gt;=",
+  ">>"   : "&gt;&gt;",
+  ">>>=" : "&gt;&gt;&gt;=",
+  ">>>"  : "&gt;&gt;&gt;",
+  "|"    : "|",
+  "||"   : "||",
+  "|="   : "|=",
+  "&"    : "&amp;",
+  "&&"   : "&amp;&amp;",
+  "&="   : "&amp;=",
+  "+"    : "+",
+  "++"   : "++",
+  "+="   : "+=",
+  "-"    : "-",
+  "--"   : "--",
+  "-="   : "-=",
+  "/"    : "/",
+  "/="   : "/=",
+  "*"    : "*",
+  "*="   : "*=",
+  "%"    : "%",
+  "%="   : "%=",
+  "^"    : "^",
+  "^="   : "^=",
+  "~"    : "~",
+  "~="   : "~=",
+  ":"    : ":",
+  ";"    : ";",
+  "?"    : "?",
+  ","    : ",",
+  "$"    : "$",
+  "EOF"  : ""
+];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lang_de.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,91 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+
+string lang_code = "de";
+
+string[] messages = [
+  // Lexer messages:
+  "illegales Zeichen gefunden: '{0}'",
+//   "ungültiges Unicodezeichen.",
+  "ungültige UTF-8-Sequenz: '{0}'",
+  // ''
+  "unterminiertes Zeichenliteral.",
+  "leeres Zeichenliteral.",
+  // #line
+  "erwartete 'line' nach '#'.",
+  "Ganzzahl nach #line erwartet.",
+//   `erwartete Dateispezifikation (z.B. "pfad\zur\datei".)`,
+  "unterminierte Dateispezifikation (filespec.)",
+  "ein Special Token muss mit einem Zeilenumbruch abgeschlossen werden.",
+  // ""
+  "unterminiertes Zeichenkettenliteral.",
+  // x""
+  "Nicht-Hexzeichen '{0}' in Hexzeichenkette gefunden.",
+  "ungerade Anzahl von Hexziffern in Hexzeichenkette.",
+  "unterminierte Hexzeichenkette.",
+  // /* */ /+ +/
+  "unterminierter Blockkommentar (/* */).",
+  "unterminierter verschachtelter Kommentar (/+ +/).",
+  // `` r""
+  "unterminierte rohe Zeichenkette.",
+  "unterminierte Backquote-Zeichenkette.",
+  // \x \u \U
+  "undefinierte Escapesequenz '{0}' gefunden.",
+  "ungültige Unicode-Escapesequenz '{0}' gefunden.",
+  "unzureichende Anzahl von Hexziffern in Escapesequenz: '{0}'",
+  // \&[a-zA-Z][a-zA-Z0-9]+;
+  "undefinierte HTML-Entität '{0}'",
+  "unterminierte HTML-Entität '{0}'.",
+  "HTML-Entitäten müssen mit einem Buchstaben beginnen.",
+  // integer overflows
+  "Dezimalzahl überläuft im Vorzeichenbit.",
+  "Überlauf in Dezimalzahl.",
+  "Überlauf in Hexadezimalzahl.",
+  "Überlauf in Binärzahl.",
+  "Überlauf in Oktalzahl.",
+  "Überlauf in Fließkommazahl.",
+  "die Ziffern 8 und 9 sind in Oktalzahlen unzulässig.",
+  "ungültige Hexzahl; mindestens eine Hexziffer erforderlich.",
+  "ungültige Binärzahl; mindestens eine Binärziffer erforderlich.",
+  "der Exponent einer hexadezimalen Fließkommazahl ist erforderlich.",
+  "Hexadezimal-Exponenten müssen mit einer Dezimalziffer anfangen.",
+  "Exponenten müssen mit einer Dezimalziffer anfangen.",
+
+  // Parser messages:
+  "erwartete '{0}', fand aber '{1}'.",
+  "'{0}' ist redundant.",
+  "Template-Tupel-Parameter dürfen nur am Ende auftreten.",
+  "der 'in'-Vertrag der Funktion wurde bereits geparsed.",
+  "der 'out'-Vertrag der Funktion wurde bereits geparsed.",
+  "es wurde kein Verbindungstyp angegeben.",
+  "unbekannter Verbindungstyp '{0}'; gültig sind C, C++, D, Windows, Pascal und System.",
+  "erwartete eine oder mehrere Basisklassen, nicht '{0}'.",
+  "Basisklassen sind in Vorwärtsdeklarationen nicht erlaubt.",
+
+  // Help messages:
+  `dil v{0}
+Copyright (c) 2007-2008, Aziz Köksal. Lizensiert unter der GPL3.
+
+Befehle:
+{1}
+Geben Sie 'dil help <Befehl>' ein, um mehr Hilfe zu einem bestimmten Befehl zu
+erhalten.
+
+Kompiliert mit {2} v{3} am {4}.`,
+
+  `Generiere ein XML- oder HTML-Dokument aus einer D-Quelltextdatei.
+Verwendung:
+  dil gen datei.d [Optionen]
+
+Optionen:
+  --syntax         : generiere Elemente für den Syntaxbaum
+  --xml            : verwende XML-Format (voreingestellt)
+  --html           : verwende HTML-Format
+
+Beispiel:
+  dil gen Parser.d --html --syntax > Parser.html`,
+
+  ``,
+];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lang_en.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,118 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+
+string lang_code = "en";
+
+string[] messages = [
+  // Lexer messages:
+  "illegal character found: '{0}'",
+//   "invalid Unicode character.",
+  "invalid UTF-8 sequence: '{0}'",
+  // ''
+  "unterminated character literal.",
+  "empty character literal.",
+  // #line
+  "expected 'line' after '#'.",
+  "integer expected after #line",
+//   `expected filespec string (e.g. "path\to\file".)`,
+  "unterminated filespec string.",
+  "expected a terminating newline after special token.",
+  // ""
+  "unterminated string literal.",
+  // x""
+  "non-hex character '{0}' found in hex string.",
+  "odd number of hex digits in hex string.",
+  "unterminated hex string.",
+  // /* */ /+ +/
+  "unterminated block comment (/* */).",
+  "unterminated nested comment (/+ +/).",
+  // `` r""
+  "unterminated raw string.",
+  "unterminated back quote string.",
+  // \x \u \U
+  "found undefined escape sequence '{0}'.",
+  "found invalid Unicode escape sequence '{0}'.",
+  "insufficient number of hex digits in escape sequence: '{0}'",
+  // \&[a-zA-Z][a-zA-Z0-9]+;
+  "undefined HTML entity '{0}'",
+  "unterminated HTML entity '{0}'.",
+  "HTML entities must begin with a letter.",
+  // integer overflows
+  "decimal number overflows sign bit.",
+  "overflow in decimal number.",
+  "overflow in hexadecimal number.",
+  "overflow in binary number.",
+  "overflow in octal number.",
+  "overflow in float number.",
+  "digits 8 and 9 are not allowed in octal numbers.",
+  "invalid hex number; at least one hex digit expected.",
+  "invalid binary number; at least one binary digit expected.",
+  "the exponent of a hexadecimal float number is required.",
+  "hexadecimal float exponents must start with a digit.",
+  "exponents must start with a digit.",
+
+  // Parser messages
+  "expected '{0}', but found '{1}'.",
+  "'{0}' is redundant.",
+  "template tuple parameters can only be last.",
+  "the functions 'in' contract was already parsed.",
+  "the functions 'out' contract was already parsed.",
+  "no linkage type was specified.",
+  "unrecognized linkage type '{0}'; valid types are C, C++, D, Windows, Pascal und System.",
+  "expected one or more base classes, not '{0}'.",
+  "base classes are not allowed in forward declarations.",
+
+  // Help messages:
+  `dil v{0}
+Copyright (c) 2007-2008 by Aziz Köksal. Licensed under the GPL3.
+
+Subcommands:
+{1}
+Type 'dil help <subcommand>' for more help on a particular subcommand.
+
+Compiled with {2} v{3} on {4}.`,
+
+  `Generate an XML or HTML document from a D source file.
+Usage:
+  dil gen file.d [Options]
+
+Options:
+  --syntax         : generate tags for the syntax tree
+  --xml            : use XML format (default)
+  --html           : use HTML format
+
+Example:
+  dil gen Parser.d --html --syntax > Parser.html`,
+
+  `Parse a module and extract information from the resulting module dependency graph.
+Usage:
+  dil igraph file.d Format [Options]
+
+  The directory of file.d is implicitly added to the list of import paths.
+
+Format:
+  --dot            : generate a dot document
+  Further options for --dot:
+  -gbp             : Group modules by package names
+  -gbf             : Group modules by full package name
+  -hle             : highlight cyclic edges in the graph
+  -hlv             : highlight modules in cyclic relationship
+
+  --paths          : print a list of paths to the modules imported by file.d
+  --list           : print a list of the module names imported by file.d
+  Options common to --paths and --list:
+  -lN              : print N levels.
+  -m               : mark modules in cyclic relationships with a star.
+
+Options:
+  -Ipath           : add 'path' to the list of import paths where modules are
+                     looked for
+  -rREGEXP         : exclude modules whose names match the regular expression
+                     REGEXP
+  -i               : include unlocatable modules
+
+Example:
+  dil igraph src/main.d`,
+];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lang_fi.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,91 @@
+/++
+  Author: Jari-Matti Mäkelä <jmjm@iki.fi>
+  License: GPL3
++/
+
+string lang_code = "fi";
+
+string[] messages = [
+  // Lexer messages:
+  "virheellinen merkki: '{0}'",
+//   "virheellinen Unicode-merkki.",
+  "virheellinen UTF-8-merkkijono: '{0}'",
+  // ''
+  "päättämätön merkkiliteraali.",
+  "tyhjä merkkiliteraali.",
+  // #line
+  "odotettiin rivinumeroa '#':n jälkeen.",
+  "odotettiin kokonaislukua #line:n jälkeen",
+//   `odotettiin tiedostomäärittelyn merkkijonoa (esim. "polku\tiedostoon")`,
+  "päättämätön tiedostomäärittely.",
+  "odotettiin päättävää rivinvaihtoa erikoismerkin jälkeen.",
+  // ""
+  "päättämätön merkkijonoliteraali.",
+  // x""
+  "ei-heksamerkki '{0}' heksajonossa.",
+  "pariton määrä heksanumeroita heksajonossa.",
+  "päättämätön heksajono.",
+  // /* */ /+ +/
+  "päättämätön lohkokommentti (/* */).",
+  "päättämätön sisäkkäinen kommentti (/+ +/).",
+  // `` r""
+  "päättämätön raakamerkkijono.",
+  "päättämätön gravisaksenttimerkkijono.",
+  // \x \u \U
+  "määrittelemätön escape-sekvenssi {0}.",
+  "virheellinen Unicode escape-merkki '{0}'.",
+  "riittämätön määrä heksanumeroita escape-sekvenssissä: '{0}'",
+  // \&[a-zA-Z][a-zA-Z0-9]+;
+  "määrittelemätön HTML-entiteetti '{0}'",
+  "päättämätön HTML-entiteetti {0}.",
+  "HTML-entiteettien tulee alkaa kirjaimella.",
+  // integer overflows
+  "desimaaliluku ylivuotaa etumerkin.",
+  "desimaaliluvun ylivuoto.",
+  "heksadesimaaliluvun ylivuoto.",
+  "binääriluvun ylivuoto.",
+  "oktaaliluvun ylivuoto.",
+  "liukuluvun ylivuoto.",
+  "numerot 8 ja 9 eivät ole sallittuja oktaaliluvuissa.",
+  "virheellinen heksaluku; odotettiin vähintään yhtä heksanumeroa.",
+  "virheellinen binääriluku; odotettiin vähintään yhtä binäärinumeroa.",
+  "heksadesimaalisen liukuluvun eksponentti vaaditaan.",
+  "heksadesimaalisen liukuluvun eksponentin tulee alkaa numerolla.",
+  "eksponenttien tulee alkaa numerolla.",
+
+  // Parser messages
+  "odotettiin '{0}':a, mutta luettiin '{1}'.",
+  "'{0}' on redundantti.",
+  "tupla voi esiintyä ainoastaan mallin viimeisenä parametrina.",
+  "funktion alkuehto jäsennettiin jo.",
+  "funktion loppuehto jäsennettiin jo.",
+  "linkitystyyppiä ei määritelty.",
+  "tunnistamaton linkitystyyppi '{0}'; sallittuja tyyppejä ovat C, C++, D, Windows, Pascal ja System.",
+  "odotettiin yhtä tai useampaa luokkaa, ei '{0}':ta.",
+  "kantaluokat eivät ole sallittuja etukäteismäärittelyissä.",
+
+  // Help messages:
+  `dil v{0}
+Copyright (c) 2007-2008, Aziz Köksal. GPL3-lisensöity.
+
+Alikomennot:
+{1}
+Lisäohjeita tietystä alitoiminnosta saa kirjoittamalla 'dil help <toiminto>'.
+
+Käännetty {2}:n versiolla {3} {4}.`,
+
+  `Luo XML- tai HTML-dokumentti D-lähdekoodista.
+
+Käyttö:
+  dil gen tiedosto.d [Valinnat]
+
+Valinnat:
+  --syntax         : luo elementtejä syntaksipuun mukaisesti
+  --xml            : käytä XML-muotoa (oletus)
+  --html           : käytä HTML-muotoa
+
+Esimerkki:
+  dil gen Parser.d --html --syntax > Parser.html`,
+
+  ``,
+];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lang_tr.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,90 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+
+string lang_code = "tr";
+
+string[] messages = [
+  // Lexer messages:
+  "illegal karakter bulundu: '{0}'",
+//   "geçersiz Unikod karakteri.",
+  "geçersiz UTF-8 serisi: '{0}'",
+  // ''
+  "kapanmamış karakter sabiti.",
+  "boş karakter sabiti.",
+  // #line
+  "'#' karakter'den sonra 'line' beklendi.",
+  "'#line''den sonra rakam beklendi.",
+//   `filespec dizgisi beklendi (e.g. "yol\dosya".)`,
+  "kapanmamış filespec dizgisi.",
+  "özel belirtici'den (special token) sonra yeni bir satır beklendi.",
+  // ""
+  "kapanmamış çift tırnak dizgisi.",
+  // x""
+  "heks sayı olmayan karakter '{0}' heks dizgisi içinde bulundu.",
+  "heks dizginin içindeki sayılar çifter çifter olmalıdır.",
+  "kapanmamış heks dizgisi.",
+  // /* */ /+ +/
+  "kapanmamış blok açıklaması (/* */).",
+  "kapanmamış iç içe koyulabilen açıklaması (/+ +/).",
+  // `` r""
+  "kapanmamış çiğ dizgisi.",
+  "kapanmamış ters tırnak dizgisi.",
+  // \x \u \U
+  "tanımlanmamış çıkış serisi '{0}' bulundu.",
+  "geçersiz Unikod çıkış serisi '{0}' bulundu.",
+  "heksadesimal çıkış serisi sayıları yeterli değil: '{0}'",
+  // \&[a-zA-Z][a-zA-Z0-9]+;
+  "tanımlanmamış HTML varlık '{0}'",
+  "kapanmamış HTML varlık '{0}'.",
+  "HTML varlık bir harf ile başlamalı.",
+  // integer overflows
+  "desimal rakamın bit işareti taşdı.",
+  "desimal rakam taşması.",
+  "heksadesimal rakam taşması.",
+  "binari rakam taşması.",
+  "oktal rakam taşması.",
+  "float rakam taşması.",
+  "8 ve 9 sayılar oktal rakamlar'da geçersizdir.",
+  "geçersiz heks rakam; minimum bir heks sayı gereklidir.",
+  "geçersiz binari rakam; minimum bir binari sayı gereklidir.",
+  "bir heksadesimal float rakamın üsü gereklidir.",
+  "heksadesimal float üsler desimal sayı ile başlamalı.",
+  "üsler desimal sayı ile başlamalı.",
+
+  // Parser messages
+  "'{0}' beklendi, ama '{1}' bulundu.",
+  "'{0}' lüzumsuz.",
+  "şablon tuple parametre son sırada olmalı.",
+  "fonksiyonun 'in' kontratı daha önceden ayrıştırılmış.",
+  "fonksiyonun 'out' kontratı daha önceden ayrıştırılmış.",
+  "bağlantı tüp (linkage type) belirtilmedi.",
+  "bilinmeyen bağlantı tüpü (linkage type) '{0}'; geçerli olanlar C, C++, D, Windows, Pascal ve System.",
+  "expected one or more base classes, not '{0}'.", // TODO: translate
+  "base classes are not allowed in forward declarations.", // TODO: translate
+
+  // Help messages:
+  `dil v{0}
+Copyright (c) 2007-2008, Aziz Köksal. Lisans GPL3.
+
+Komutlar:
+{1}
+Belirli komut'a yardım edinmek için 'dil help <komut>' yazınız.
+
+Bu yazılım {2} v{3} ile {4} tarihinde derletilmiş.`,
+
+  `Bir D kaynak kodundan XML veya HTML dosyası oluştur.
+Kullanım:
+  dil gen dosya.d [Seçenekler]
+
+Seçenekler:
+  --syntax         : söz dizimi için etiketler yazdır
+  --xml            : XML biçimi kullan (varsayılır)
+  --html           : HTML biçimi kullan
+
+Örnek:
+  dil gen Parser.d --html --syntax > Parser.html`,
+
+  ``,
+];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/macros_dil.ddoc	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,22 @@
+DDOC = <html>
+<head>
+  <META http-equiv="content-type" content="text/html; charset=utf-8">
+  <title>$(TITLE)</title>
+</head>
+<body>
+<h1><a href="$(SRCFILE)">$(TITLE)</a></h1>
+$(BODY)
+<hr>
+<p class="footer">$(COPYRIGHT) Page generated by $(LINK2 http://code.google.com/p/dil, dil) on $(DATETIME).</p>
+</body>
+</html>
+
+MODFQN = $(TITLE)
+SRCFILE = ./htmlsrc/$(MODFQN).html
+COPYRIGHT = Copyright © 2007-$(YEAR), Aziz Köksal. All rights reserved.
+SYMBOL_ = <a href="http://hg.sharesource.org/dil/file/tip/trunk/src/$(MODPATH)#L$2">$1</a>
+SYMBOL = <a href="$(SRCFILE)#L$2">$1</a>
+
+PRE = <pre>$0</pre>
+DDD = ---
+DMDBUG = $(LINK2 http://d.puremagic.com/issues/show_bug.cgi?id=$1, $2)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,576 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module main;
+
+import dil.parser.Parser;
+import dil.lexer.Lexer,
+       dil.lexer.Token;
+import dil.ast.Declarations,
+       dil.ast.Expressions,
+       dil.ast.Node,
+       dil.ast.Visitor;
+import dil.semantic.Module;
+import dil.semantic.Symbols;
+import dil.semantic.Pass1,
+       dil.semantic.Pass2,
+       dil.semantic.Interpreter;
+import dil.translator.German;
+import dil.doc.Doc;
+import dil.Messages;
+import dil.CompilerInfo;
+import dil.Information;
+import dil.SourceText;
+import dil.Compilation;
+
+import cmd.Generate;
+import cmd.Statistics;
+import cmd.ImportGraph;
+import cmd.DDoc;
+
+import Settings;
+import SettingsLoader;
+// import TypeRules;
+import common;
+
+import Integer = tango.text.convert.Integer;
+import tango.stdc.stdio;
+import tango.io.File;
+import tango.text.Util;
+import tango.time.StopWatch;
+import tango.text.Ascii : icompare;
+
+/// Entry function of dil.
+void main(char[][] args)
+{
+  auto infoMan = new InfoManager();
+  SettingsLoader.SettingsLoader(infoMan).load();
+  if (infoMan.hasInfo)
+    return printErrors(infoMan);
+
+  if (args.length <= 1)
+    return Stdout(helpMain()).newline;
+
+  string command = args[1];
+  switch (command)
+  {
+  case "c", "compile":
+    if (args.length < 2)
+      return printHelp("compile");
+
+    string[] filePaths;
+    auto context = newCompilationContext();
+    foreach (arg; args[2..$])
+    {
+      if (parseDebugOrVersion(arg, context))
+      {}
+      else
+        filePaths ~= arg;
+    }
+    infoMan = new InfoManager();
+    foreach (filePath; filePaths)
+    {
+      auto mod = new Module(filePath, infoMan);
+      // Parse the file.
+      mod.parse();
+      if (mod.hasErrors)
+        continue;
+
+      // Start semantic analysis.
+      auto pass1 = new SemanticPass1(mod, context);
+      pass1.start();
+
+      void printSymbolTable(ScopeSymbol scopeSym, char[] indent)
+      {
+        foreach (member; scopeSym.members)
+        {
+          auto tokens = getDocTokens(member.node);
+          char[] docText;
+          foreach (token; tokens)
+            docText ~= token.srcText;
+          Stdout(indent).formatln("Id:{}, Symbol:{}, DocText:{}", member.name.str, member.classinfo.name, docText);
+          if (auto s = cast(ScopeSymbol)member)
+            printSymbolTable(s, indent ~ "→ ");
+        }
+      }
+
+      printSymbolTable(mod, "");
+    }
+
+    infoMan.hasInfo && printErrors(infoMan);
+    break;
+  case "ddoc", "d":
+    if (args.length < 4)
+      return printHelp("ddoc");
+
+    auto destination = args[2];
+    auto macroPaths = GlobalSettings.ddocFilePaths;
+    char[][] filePaths;
+    bool incUndoc;
+    bool writeXML;
+    bool verbose;
+    // Parse arguments.
+    auto context = newCompilationContext();
+    foreach (arg; args[3..$])
+    {
+      if (parseDebugOrVersion(arg, context))
+      {}
+      else if (arg == "--xml")
+        writeXML = true;
+      else if (arg == "-i")
+        incUndoc = true;
+      else if (arg == "-v")
+        verbose = true;
+      else if (arg.length > 5 && icompare(arg[$-4..$], "ddoc") == 0)
+        macroPaths ~= arg;
+      else
+        filePaths ~= arg;
+    }
+
+    infoMan = new InfoManager();
+    // Execute command.
+    cmd.DDoc.execute(filePaths, destination, macroPaths, writeXML,
+                     incUndoc, verbose, context, infoMan);
+    infoMan.hasInfo && printErrors(infoMan);
+    break;
+  case "gen", "generate":
+    char[] fileName;
+    GenOption options = GenOption.Tokens;
+    foreach (arg; args[2..$])
+    {
+      switch (arg)
+      {
+      case "--syntax":
+        options |= GenOption.Syntax; break;
+      case "--xml":
+        options |= GenOption.XML; break;
+      case "--html":
+        options |= GenOption.HTML; break;
+      case "--lines":
+        options |= GenOption.PrintLines; break;
+      default:
+        fileName = arg;
+      }
+    }
+    if (!(options & (GenOption.XML | GenOption.HTML)))
+      options |= GenOption.XML; // Default to XML.
+    cmd.Generate.execute(fileName, options, infoMan);
+    infoMan.hasInfo && printErrors(infoMan);
+    break;
+  case "importgraph", "igraph":
+    string filePath;
+    string[] regexps;
+    string siStyle = "dashed"; // static import style
+    string piStyle = "bold";   // public import style
+    uint levels;
+    IGraphOption options;
+    auto context = newCompilationContext();
+    foreach (arg; args[2..$])
+    {
+      if (parseDebugOrVersion(arg, context))
+      {}
+      else if (strbeg(arg, "-I"))
+        context.importPaths ~= arg[2..$];
+      else if(strbeg(arg, "-r"))
+        regexps ~= arg[2..$];
+      else if(strbeg(arg, "-l"))
+        levels = Integer.toInt(arg[2..$]);
+      else if(strbeg(arg, "-si"))
+        siStyle = arg[3..$];
+      else if(strbeg(arg, "-pi"))
+        piStyle = arg[3..$];
+      else
+        switch (arg)
+        {
+        case "--dot":
+          options |= IGraphOption.PrintDot; break;
+        case "--paths":
+          options |= IGraphOption.PrintPaths; break;
+        case "--list":
+          options |= IGraphOption.PrintList; break;
+        case "-i":
+          options |= IGraphOption.IncludeUnlocatableModules; break;
+        case "-hle":
+          options |= IGraphOption.HighlightCyclicEdges; break;
+        case "-hlv":
+          options |= IGraphOption.HighlightCyclicVertices; break;
+        case "-gbp":
+          options |= IGraphOption.GroupByPackageNames; break;
+        case "-gbf":
+          options |= IGraphOption.GroupByFullPackageName; break;
+        case "-m":
+          options |= IGraphOption.MarkCyclicModules; break;
+        default:
+          filePath = arg;
+        }
+    }
+    cmd.ImportGraph.execute(filePath, context, regexps, levels, siStyle, piStyle, options);
+    break;
+  case "stats", "statistics":
+    char[][] filePaths;
+    bool printTokensTable;
+    bool printNodesTable;
+    foreach (arg; args[2..$])
+      if (arg == "--toktable")
+        printTokensTable = true;
+      else if (arg == "--asttable")
+        printNodesTable = true;
+      else
+        filePaths ~= arg;
+    cmd.Statistics.execute(filePaths, printTokensTable, printNodesTable);
+    break;
+  case "tok", "tokenize":
+    SourceText sourceText;
+    char[] filePath;
+    char[] separator;
+    bool ignoreWSToks;
+    bool printWS;
+
+    foreach (arg; args[2..$])
+    {
+      if (strbeg(arg, "-s"))
+        separator = arg[2..$];
+      else if (arg == "-")
+        sourceText = new SourceText("stdin", readStdin());
+      else if (arg == "-i")
+        ignoreWSToks = true;
+      else if (arg == "-ws")
+        printWS = true;
+      else
+        filePath = arg;
+    }
+
+    separator || (separator = "\n");
+    if (!sourceText)
+      sourceText = new SourceText(filePath, true);
+
+    infoMan = new InfoManager();
+    auto lx = new Lexer(sourceText, infoMan);
+    lx.scanAll();
+    auto token = lx.firstToken();
+
+    for (; token.kind != TOK.EOF; token = token.next)
+    {
+      if (token.kind == TOK.Newline || ignoreWSToks && token.isWhitespace)
+        continue;
+      if (printWS && token.ws)
+        Stdout(token.wsChars);
+      Stdout(token.srcText)(separator);
+    }
+
+    infoMan.hasInfo && printErrors(infoMan);
+    break;
+  case "trans", "translate":
+    if (args.length < 3)
+      return printHelp("trans");
+
+    if (args[2] != "German")
+      return Stdout.formatln("Error: unrecognized target language \"{}\"", args[2]);
+
+    infoMan = new InfoManager();
+    auto filePath = args[3];
+    auto mod = new Module(filePath, infoMan);
+    // Parse the file.
+    mod.parse();
+    if (!mod.hasErrors)
+    { // Translate
+      auto german = new GermanTranslator(Stdout, "  ");
+      german.translate(mod.root);
+    }
+    printErrors(infoMan);
+    break;
+  case "profile":
+    if (args.length < 3)
+      break;
+    char[][] filePaths;
+    if (args[2] == "dstress")
+    {
+      auto text = cast(char[])(new File("dstress_files")).read();
+      filePaths = split(text, "\0");
+    }
+    else
+      filePaths = args[2..$];
+
+    StopWatch swatch;
+    swatch.start;
+
+    foreach (filePath; filePaths)
+      (new Lexer(new SourceText(filePath, true))).scanAll();
+
+    Stdout.formatln("Scanned in {:f10}s.", swatch.stop);
+    break;
+  // case "parse":
+  //   if (args.length == 3)
+  //     parse(args[2]);
+  //   break;
+  case "?", "help":
+    printHelp(args.length >= 3 ? args[2] : "");
+    break;
+  // case "typerules":
+  //   genHTMLTypeRulesTables();
+  //   break;
+  default:
+  }
+}
+
+char[] readStdin()
+{
+  char[] text;
+  while (1)
+  {
+    auto c = getc(stdin);
+    if (c == EOF)
+      break;
+    text ~= c;
+  }
+  return text;
+}
+
+/// Available commands.
+const char[] COMMANDS =
+  "  compile (c)\n"
+  "  ddoc (d)\n"
+  "  generate (gen)\n"
+  "  help (?)\n"
+  "  importgraph (igraph)\n"
+  "  statistics (stats)\n"
+  "  tokenize (tok)\n"
+  "  translate (trans)\n";
+
+bool strbeg(char[] str, char[] begin)
+{
+  if (str.length >= begin.length)
+  {
+    if (str[0 .. begin.length] == begin)
+      return true;
+  }
+  return false;
+}
+
+/// Creates the global compilation context.
+CompilationContext newCompilationContext()
+{
+  auto cc = new CompilationContext;
+  cc.importPaths = GlobalSettings.importPaths;
+  cc.addVersionId("dil");
+  cc.addVersionId("all");
+version(D2)
+  cc.addVersionId("D_Version2");
+  foreach (versionId; GlobalSettings.versionIds)
+    if (!Lexer.isReservedIdentifier(versionId))
+      cc.versionIds[versionId] = true;
+  return cc;
+}
+
+bool parseDebugOrVersion(string arg, CompilationContext context)
+{
+  if (strbeg(arg, "-debug"))
+  {
+    if (arg.length > 7)
+    {
+      auto val = arg[7..$];
+      if (isdigit(val[0]))
+        context.debugLevel = Integer.toInt(val);
+      else if (!Lexer.isReservedIdentifier(val))
+        context.addDebugId(val);
+    }
+    else
+      context.debugLevel = 1;
+  }
+  else if (arg.length > 9 && strbeg(arg, "-version="))
+  {
+    auto val = arg[9..$];
+    if (isdigit(val[0]))
+      context.versionLevel = Integer.toInt(val);
+    else if (!Lexer.isReservedIdentifier(val))
+      context.addVersionId(val);
+  }
+  else
+    return false;
+  return true;
+}
+
+/// Prints the errors collected in infoMan.
+void printErrors(InfoManager infoMan)
+{
+  foreach (info; infoMan.info)
+  {
+    char[] errorFormat;
+    if (info.classinfo is LexerError.classinfo)
+      errorFormat = GlobalSettings.lexerErrorFormat;
+    else if (info.classinfo is ParserError.classinfo)
+      errorFormat = GlobalSettings.parserErrorFormat;
+    else if (info.classinfo is SemanticError.classinfo)
+      errorFormat = GlobalSettings.semanticErrorFormat;
+    else if (info.classinfo is Warning.classinfo)
+      errorFormat = "{0}: Warning: {3}";
+    else
+      continue;
+    auto err = cast(Problem)info;
+    Stderr.formatln(errorFormat, err.filePath, err.loc, err.col, err.getMsg);
+  }
+}
+
+/// Prints the compiler's main help message.
+char[] helpMain()
+{
+  auto COMPILED_WITH = __VENDOR__;
+  auto COMPILED_VERSION = Format("{}.{,:d3}", __VERSION__/1000, __VERSION__%1000);
+  auto COMPILED_DATE = __TIMESTAMP__;
+  return FormatMsg(MID.HelpMain, VERSION, COMMANDS, COMPILED_WITH,
+                   COMPILED_VERSION, COMPILED_DATE);
+}
+
+/// Prints a help message for command.
+void printHelp(char[] command)
+{
+  char[] msg;
+  switch (command)
+  {
+  case "c", "compile":
+    msg = `Compile D source files.
+Usage:
+  dil compile file.d [file2.d, ...] [Options]
+
+  This command only parses the source files and does little semantic analysis.
+  Errors are printed to standard error output.
+
+Options:
+  -debug           : include debug code
+  -debug=level     : include debug(l) code where l <= level
+  -debug=ident     : include debug(ident) code
+  -version=level   : include version(l) code where l >= level
+  -version=ident   : include version(ident) code
+
+Example:
+  dil c src/main.d`;
+    break;
+  case "ddoc", "d":
+    msg = `Generate documentation from DDoc comments in D source files.
+Usage:
+  dil ddoc Destination file.d [file2.d, ...] [Options]
+
+  Destination is the folder where the documentation files are written to.
+  Files with the extension .ddoc are recognized as macro definition files.
+
+Options:
+  --xml            : write XML instead of HTML documents
+  -i               : include undocumented symbols
+  -v               : verbose output
+
+Example:
+  dil d doc/ src/main.d src/macros_dil.ddoc -i`;
+    break;
+  case "gen", "generate":
+//     msg = GetMsg(MID.HelpGenerate);
+    msg = `Generate an XML or HTML document from a D source file.
+Usage:
+  dil gen file.d [Options]
+
+Options:
+  --syntax         : generate tags for the syntax tree
+  --xml            : use XML format (default)
+  --html           : use HTML format
+  --lines          : print line numbers
+
+Example:
+  dil gen Parser.d --html --syntax > Parser.html`;
+    break;
+  case "importgraph", "igraph":
+//     msg = GetMsg(MID.HelpImportGraph);
+    msg = `Parse a module and build a module dependency graph based on its imports.
+Usage:
+  dil igraph file.d Format [Options]
+
+  The directory of file.d is implicitly added to the list of import paths.
+
+Format:
+  --dot            : generate a dot document (default)
+  Options related to --dot:
+  -gbp             : Group modules by package names
+  -gbf             : Group modules by full package name
+  -hle             : highlight cyclic edges in the graph
+  -hlv             : highlight modules in cyclic relationships
+  -siSTYLE         : the edge style to use for static imports
+  -piSTYLE         : the edge style to use for public imports
+  STYLE can be: "dashed", "dotted", "solid", "invis" or "bold"
+
+  --paths          : print the file paths of the modules in the graph
+
+  --list           : print the names of the module in the graph
+  Options common to --paths and --list:
+  -lN              : print N levels.
+  -m               : use '*' to mark modules in cyclic relationships
+
+Options:
+  -Ipath           : add 'path' to the list of import paths where modules are
+                     looked for
+  -rREGEXP         : exclude modules whose names match the regular expression
+                     REGEXP
+  -i               : include unlocatable modules
+
+Example:
+  dil igraph src/main.d --list
+  dil igraph src/main.d | dot -Tpng > main.png`;
+    break;
+  case "tok", "tokenize":
+    msg = `Print the tokens of a D source file.
+Usage:
+  dil tok file.d [Options]
+
+Options:
+  -               : reads text from the standard input.
+  -sSEPARATOR     : print SEPARATOR instead of newline between tokens.
+  -i              : ignore whitespace tokens (e.g. comments, shebang etc.)
+  -ws             : print a token's preceding whitespace characters.
+
+Example:
+  echo "module foo; void func(){}" | dil tok -
+  dil tok main.d | grep ^[0-9]`;
+    break;
+  case "stats", "statistics":
+    msg = "Gather statistics about D source files.
+Usage:
+  dil stat file.d [file2.d, ...] [Options]
+
+Options:
+  --toktable      : print the count of all kinds of tokens in a table.
+  --asttable      : print the count of all kinds of nodes in a table.
+
+Example:
+  dil stat src/dil/Parser.d src/dil/Lexer.d";
+    break;
+  case "trans", "translate":
+    msg = `Translate a D source file to another language.
+Usage:
+  dil translate Language file.d
+
+  Languages that are supported:
+    *) German
+
+Example:
+  dil trans German src/main.d`;
+    break;
+  default:
+    msg = helpMain();
+  }
+  Stdout(msg).newline;
+}
+
+/+void parse(string fileName)
+{
+  auto mod = new Module(fileName);
+  mod.parse();
+
+  void print(Node[] decls, char[] indent)
+  {
+    foreach(decl; decls)
+    {
+      assert(decl !is null);
+      Stdout.formatln("{}{}: begin={} end={}", indent, decl.classinfo.name, decl.begin ? decl.begin.srcText : "\33[31mnull\33[0m", decl.end ? decl.end.srcText : "\33[31mnull\33[0m");
+      print(decl.children, indent ~ "  ");
+    }
+  }
+  print(mod.root.children, "");
+}+/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/predefined.ddoc	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,109 @@
+DDOC = <html>
+<head>
+  <META http-equiv="content-type" content="text/html; charset=utf-8">
+  <title>$(TITLE)</title>
+</head>
+<body>
+<h1>$(TITLE)</h1>
+$(BODY)
+<hr>
+<p class="footer">$(COPYRIGHT) | Page generated by $(LINK2 http://code.google.com/p/dil, dil) on $(DATETIME).</p>
+</body>
+</html>
+
+B = <b>$0</b>
+I = <i>$0</i>
+U = <u>$0</u>
+P = <p>$0</p>
+DL = <dl>$0</dl>
+DT = <dt>$0</dt>
+DD = <dd>$0</dd>
+TABLE = <table>$0</table>
+TR = <tr>$0</tr>
+TH = <th>$0</th>
+TD = <td>$0</td>
+OL = <ol>$0</ol>
+UL = <ul>$0</ul>
+LI = <li>$0</li>
+BIG = <big>$0</big>
+SMALL = <small>$0</small>
+BR = <br>
+LINK = <a href="$0">$0</a>
+LINK2 = <a href="$1">$+</a>
+
+RED = <font color="red">$0</font>
+BLUE = <font color="blue">$0</font>
+GREEN = <font color="green">$0</font>
+YELLOW = <font color="yellow">$0</font>
+BLACK = <font color="black">$0</font>
+WHITE = <font color="white">$0</font>
+
+D_CODE    = <pre class="d_code">$0</pre>
+D_COMMENT = $(GREEN $0)
+D_STRING  = $(RED $0)
+D_KEYWORD = $(BLUE $0)
+D_PSYMBOL = $(U $0)
+D_PARAM   = $(I $0)
+
+DDOC_COMMENT   = <!-- $0 -->
+DDOC_DECL      = $(DT $(BIG $0))
+DDOC_DECL_DD   = $(DD $0)
+DDOC_DITTO     = $(BR)$0
+
+DDOC_SECTIONS  = $0
+DDOC_SUMMARY   = $0$(BR)$(BR)
+DDOC_DESCRIPTION = $0$(BR)$(BR)
+DDOC_AUTHORS   = $(B Authors:)$(BR)
+$0$(BR)$(BR)
+DDOC_BUGS      = $(RED BUGS:)$(BR)
+$0$(BR)$(BR)
+DDOC_COPYRIGHT = $(B Copyright:)$(BR)
+$0$(BR)$(BR)
+DDOC_DATE      = $(B Date:)$(BR)
+$0$(BR)$(BR)
+DDOC_DEPRECATED = $(RED Deprecated:)$(BR)
+$0$(BR)$(BR)
+DDOC_EXAMPLES  = $(B Examples:)$(BR)
+$0$(BR)$(BR)
+DDOC_HISTORY   = $(B History:)$(BR)
+$0$(BR)$(BR)
+DDOC_LICENSE   = $(B License:)$(BR)
+$0$(BR)$(BR)
+DDOC_RETURNS   = $(B Returns:)$(BR)
+$0$(BR)$(BR)
+DDOC_SEE_ALSO  = $(B See Also:)$(BR)
+$0$(BR)$(BR)
+DDOC_STANDARDS = $(B Standards:)$(BR)
+$0$(BR)$(BR)
+DDOC_THROWS    = $(B Throws:)$(BR)
+$0$(BR)$(BR)
+DDOC_VERSION   = $(B Version:)$(BR)
+$0$(BR)$(BR)
+DDOC_SECTION_H = $(B $0)$(BR)
+DDOC_SECTION   = $0$(BR)$(BR)
+
+DDOC_MEMBERS   = $(DL $0)
+DDOC_MODULE_MEMBERS    = $(DDOC_MEMBERS $0)
+DDOC_CLASS_MEMBERS     = $(DDOC_MEMBERS $0)
+DDOC_INTERFACE_MEMBERS = $(DDOC_MEMBERS $0)
+DDOC_STRUCT_MEMBERS    = $(DDOC_MEMBERS $0)
+DDOC_UNION_MEMBERS     = $(DDOC_MEMBERS $0)
+DDOC_TEMPLATE_MEMBERS  = $(DDOC_MEMBERS $0)
+DDOC_ENUM_MEMBERS      = $(DDOC_MEMBERS $0)
+
+DDOC_PARAMS = $(B Params:)$(BR)
+$(TABLE $0)$(BR)
+DDOC_PARAM_ROW = $(TR $0)
+DDOC_PARAM_ID = $(TD $0)
+DDOC_PARAM_DESC = $(TD $0)
+DDOC_BLANKLINE = $(BR)$(BR)
+
+DDOC_PSYMBOL = $(U $0)
+DDOC_KEYWORD = $(B $0)
+DDOC_PARAM = $(I $0)
+
+ATTRIBUTES = [$0]
+PROT = $0
+STC = $0
+LINKAGE = $0
+SYMBOL = $1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/predefined_xml.ddoc	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,98 @@
+DDOC = <root>
+<module>$(TITLE)</module>
+$(BODY)
+<copyright>$(COPYRIGHT)</copyright>
+<generator>dil $(DDOC_VERSION) $(LINK http://code.google.com/p/dil)
+  <date>$(DATETIME)</date>
+</generator>
+</root>
+
+B = <b>$0</b>
+I = <i>$0</i>
+U = <u>$0</u>
+P = <p>$0</p>
+DL = <dl>$0</dl>
+DT = <dt>$0</dt>
+DD = <dd>$0</dd>
+TABLE = <table>$0</table>
+TR = <tr>$0</tr>
+TH = <th>$0</th>
+TD = <td>$0</td>
+OL = <ol>$0</ol>
+UL = <ul>$0</ul>
+LI = <li>$0</li>
+BIG = <big>$0</big>
+SMALL = <small>$0</small>
+BR = <br />
+LINK = <link href="$0">$0</link>
+LINK2 = <link href="$1">$+</link>
+
+RED = <font color="red">$0</font>
+BLUE = <font color="blue">$0</font>
+GREEN = <font color="green">$0</font>
+YELLOW = <font color="yellow">$0</font>
+BLACK = <font color="black">$0</font>
+WHITE = <font color="white">$0</font>
+
+D_CODE    = <dcode>$0</dcode>
+D_COMMENT = <dcomment>$0</dcomment>
+D_STRING  = <dstring>$0</dstring>
+D_COMMENT = <dkeyword>$0</dkeyword>
+D_PSYMBOL = <dpsymbol>$0</dpsymbol>
+D_PARAM   = <dparam>$0</dparam>
+
+DDOC_COMMENT   = <!-- $0 -->
+DDOC_DECL      = <declaration type="$1">$2</declaration>
+DDOC_DECL_DD   = $0
+DDOC_DITTO     = $0
+
+DDOC_SECTIONS    = <description>$0</description>
+DDOC_SECTION_T   = <section name="$1">$2</section>
+DDOC_SUMMARY     = $(DDOC_SECTION_T summary, $0)
+DDOC_DESCRIPTION = $(DDOC_SECTION_T description, $0)
+DDOC_AUTHORS     = $(DDOC_SECTION_T authors, $0)
+DDOC_BUGS        = $(DDOC_SECTION_T bugs, $0)
+DDOC_COPYRIGHT   = $(DDOC_SECTION_T copyright, $0)
+DDOC_DATE        = $(DDOC_SECTION_T date, $0)
+DDOC_DEPRECATED  = $(DDOC_SECTION_T deprecated, $0)
+DDOC_EXAMPLES    = $(DDOC_SECTION_T examples, $0)
+DDOC_HISTORY     = $(DDOC_SECTION_T history, $0)
+DDOC_LICENSE     = $(DDOC_SECTION_T license, $0)
+DDOC_RETURNS     = $(DDOC_SECTION_T returns, $0)
+DDOC_SEE_ALSO    = $(DDOC_SECTION_T seealso, $0)
+DDOC_STANDARDS   = $(DDOC_SECTION_T standards, $0)
+DDOC_THROWS      = $(DDOC_SECTION_T throws, $0)
+DDOC_VERSION     = $(DDOC_SECTION_T version, $0)
+DDOC_SECTION_H   = $(B $0)$(BR)
+DDOC_SECTION     = $0
+
+DDOC_MEMBERS           = <members>$0</members>
+DDOC_MODULE_MEMBERS    = $(DDOC_MEMBERS $0)
+DDOC_CLASS_MEMBERS     = $(DDOC_MEMBERS $0)
+DDOC_INTERFACE_MEMBERS = $(DDOC_MEMBERS $0)
+DDOC_STRUCT_MEMBERS    = $(DDOC_MEMBERS $0)
+DDOC_UNION_MEMBERS     = $(DDOC_MEMBERS $0)
+DDOC_TEMPLATE_MEMBERS  = $(DDOC_MEMBERS $0)
+DDOC_ENUM_MEMBERS      = $(DDOC_MEMBERS $0)
+
+DDOC_PARAMS     = <params>$0</params>
+DDOC_PARAM_ROW  = <param>$0</param>
+DDOC_PARAM_ID   = <name>$0</name>
+DDOC_PARAM_DESC = <description>$0</description>
+DDOC_BLANKLINE  = <newline />
+
+DDOC_PSYMBOL = $(U $0)
+DDOC_KEYWORD = $(B $0)
+DDOC_PARAM   = $0
+
+ATTRIBUTES      = <attributes>$0</attributes>
+ATTRIBUTE       = <attribute type="$1">$2</attribute>
+PROT            = $(ATTRIBUTE protection, $0)
+STC             = $(ATTRIBUTE storage, $0)
+LINKAGE         = $(ATTRIBUTE linkage, $0)
+SYMBOL          = $1
+PARENTS         = <parents>$0</parents>
+TYPE            = <type>$0</type>
+PARAMS          = <params>$0</params>
+RETURNS         = <returns>$0</returns>
+TEMPLATE_PARAMS = <templateparams>$0</templateparams>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tests/forward01.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,7 @@
+/++
+  Author: Jari-Matti Mäkelä
++/
+
+// Impossible circular composition.
+struct A { B b; }
+struct B { A a; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tests/forward02.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,13 @@
+/++
+  Author: Jari-Matti Mäkelä
++/
+
+// Valid circular composition because of pointer.
+struct A { B* b; }
+struct B { A a; }
+// Equivalent to:
+struct A { A* a; }
+
+// Valid circular composition because classes are reference types.
+class C { D d; }
+class D { C c; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tests/forward03.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,18 @@
+/++
+  Author: Aziz Köksal
++/
+
+// Impossible static circular reference.
+const x = y;
+const y = x;
+
+// Impossible static circular reference.
+struct A
+{ const int a = B.b; }
+struct B
+{ const int b = A.a; }
+
+struct C
+{
+  const x = C.x;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tests/forward04.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,6 @@
+/++
+  Author: Aziz Köksal
++/
+
+class A { auto x = pi; }
+mixin("const pi = 3.14;");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tests/forward05.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,9 @@
+/++
+  Author: Aziz Köksal
++/
+
+struct A
+{ int a = B.x; }
+
+struct B
+{ const int x = 1; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/about.ui	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,70 @@
+<ui version="4.0" >
+ <class>AboutDialog</class>
+ <widget class="QDialog" name="AboutDialog" >
+  <property name="windowModality" >
+   <enum>Qt::WindowModal</enum>
+  </property>
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>414</width>
+    <height>157</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>About</string>
+  </property>
+  <layout class="QVBoxLayout" >
+   <item>
+    <widget class="QLabel" name="label1" >
+     <property name="text" >
+      <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
+p, li { white-space: pre-wrap; }
+&lt;/style>&lt;/head>&lt;body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
+&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">A tool for managing message catalogues in different languages.&lt;/p>
+&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">These catalogues can be used to make an application multilingual.&lt;/p>
+&lt;p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">&lt;/p>
+&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007 by Aziz Köksal &amp;lt;aziz.koeksal@gmail.com&amp;gt;&lt;/p>
+&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Licensed under the GPL2.&lt;/p>&lt;/body>&lt;/html></string>
+     </property>
+     <property name="textFormat" >
+      <enum>Qt::RichText</enum>
+     </property>
+     <property name="alignment" >
+      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+     </property>
+     <property name="wordWrap" >
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox" >
+     <property name="standardButtons" >
+      <set>QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>AboutDialog</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>346</x>
+     <y>274</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>317</x>
+     <y>256</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/closing_project.ui	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,125 @@
+<ui version="4.0" >
+ <class>ClosingProjectDialog</class>
+ <widget class="QDialog" name="ClosingProjectDialog" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Closing Project</string>
+  </property>
+  <layout class="QVBoxLayout" >
+   <item>
+    <widget class="QLabel" name="label" >
+     <property name="text" >
+      <string>The following documents have been modified:</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QTreeWidget" name="treeWidget" >
+     <column>
+      <property name="text" >
+       <string>Title</string>
+      </property>
+     </column>
+     <column>
+      <property name="text" >
+       <string>Full Path</string>
+      </property>
+     </column>
+    </widget>
+   </item>
+   <item>
+    <spacer>
+     <property name="orientation" >
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" >
+      <size>
+       <width>382</width>
+       <height>33</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" >
+     <item>
+      <spacer>
+       <property name="orientation" >
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" >
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="button_Save_Selected" >
+       <property name="text" >
+        <string>&amp;Save Selected</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="button_Discard_All" >
+       <property name="text" >
+        <string>&amp;Discard All Changes</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="button_Cancel" >
+       <property name="text" >
+        <string>&amp;Cancel</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>button_Save_Selected</sender>
+   <signal>clicked()</signal>
+   <receiver>ClosingProjectDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>144</x>
+     <y>269</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>179</x>
+     <y>238</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>button_Cancel</sender>
+   <signal>clicked()</signal>
+   <receiver>ClosingProjectDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>337</x>
+     <y>268</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>328</x>
+     <y>248</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/errors.py	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+# Author: Aziz Köksal
+# License: GPL2
+import exceptions
+
+class LoadingError(exceptions.Exception):
+  def __init__(self, msg):
+    self.msg = msg
+    return
+  def __str__(self):
+    return self.msg
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/langfile.py	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,112 @@
+# -*- coding: utf-8 -*-
+# Author: Aziz Köksal
+# License: GPL2
+import yaml
+from errors import LoadingError
+
+# Avoid that all unicode strings are tagged with "!!python/unicode".
+def unicode_representer(dumper, data):
+  return dumper.represent_scalar(u'tag:yaml.org,2002:str', data)
+yaml.add_representer(unicode, unicode_representer)
+
+def newLangFile(langCode, authors, license):
+  return {
+    "LangCode":langCode,
+    "Authors":authors,
+    "License":license,
+    "Messages":[]
+  }
+
+class LangFile:
+  def __init__(self, filePath):
+    from os import path
+    self.filePath = path.abspath(filePath)
+    self.isSource = False
+    self.source = None
+    # Load language file and check data integrity.
+    try:
+      self.doc = yaml.load(open(filePath, "r"))
+    except yaml.YAMLError, e:
+      raise LoadingError(str(e))
+    self.verify()
+
+  def verify(self):
+    doc = self.doc
+    self.checkType(doc, dict)
+    try:
+      self.langCode = str(doc["LangCode"])
+      self.authors = list(doc["Authors"])
+      self.license = unicode(doc["License"])
+      self.messages = list(doc["Messages"])
+    except KeyError, e:
+      raise LoadingError("Missing member '%s' in '%s'" % (e.message, filePath))
+
+    authors = []
+    for author in self.authors:
+      self.checkType(author, dict, "LangFile: author must be of type dict.")
+      try:
+        author["Name"] = unicode(author["Name"])
+        author["EMail"] = str(author["EMail"])
+        authors += [author]
+      except KeyError, e:
+        raise LoadingError("Author is missing '%s' in '%s'" % (e.message, filePath))
+    self.authors = authors
+
+    self.msgDict = {} # {ID : msg, ...}
+    for msg in self.messages:
+      self.checkType(msg, dict, "LangFile: messages must be of type dict.")
+      try:
+        msg["ID"] = int(msg["ID"])
+        msg["Text"] = unicode(msg["Text"])
+        msg["Annot"] = unicode(msg["Annot"])
+        msg["LastEd"] = int(msg["LastEd"])
+      except KeyError, e:
+        raise LoadingError("LangFile: a message is missing the '%s' key." % str(e))
+      self.msgDict[msg["ID"]] = msg
+
+  def checkType(self, var, type_, msg=""):
+    if not isinstance(var, type_):
+      raise LoadingError(msg)
+
+  def setSource(self, sourceLangFile):
+    self.source = sourceLangFile
+
+  def getMsg(self, ID):
+    for msg in self.messages:
+      if msg["ID"] == ID:
+        return msg
+    return None
+
+  def createMissingMessages(self, IDs):
+    for ID in IDs:
+      if not self.msgDict.has_key(ID):
+        msg = self.createEmptyMsg(ID)
+        self.msgDict[ID] = msg
+        self.messages += [msg]
+
+  def createEmptyMsg(self, ID):
+    return {"ID":ID,"Text":"","Annot":"","LastEd":""}
+
+  def save(self):
+    self.doc["LangCode"] = self.langCode
+    self.doc["License"] = self.license
+    self.doc["Authors"] = self.authors
+    langFile = open(self.filePath, "w")
+    yaml.dump(self.doc, stream=langFile, allow_unicode=True)
+    langFile.close()
+
+  def setLangCode(self, langCode):
+    self.langCode = langCode
+
+  def setLicense(self, license):
+    self.license = license
+
+  def setAuthors(self, authors):
+    self.authors = authors
+
+  def getFileName(self):
+    from os import path
+    return path.basename(self.filePath)
+
+  def getFilePath(self):
+    return self.filePath
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/langfile_properties.ui	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,128 @@
+<ui version="4.0" >
+ <class>LangFilePropertiesDialog</class>
+ <widget class="QDialog" name="LangFilePropertiesDialog" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>228</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Language File Properties</string>
+  </property>
+  <layout class="QVBoxLayout" >
+   <item>
+    <layout class="QGridLayout" >
+     <item row="1" column="0" >
+      <widget class="QLabel" name="label_2" >
+       <property name="text" >
+        <string>Language code:</string>
+       </property>
+       <property name="alignment" >
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+       <property name="buddy" >
+        <cstring>langCodeField</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1" >
+      <widget class="QLineEdit" name="langCodeField" />
+     </item>
+     <item row="2" column="0" >
+      <widget class="QLabel" name="label" >
+       <property name="text" >
+        <string>Creation date:</string>
+       </property>
+       <property name="alignment" >
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+       <property name="buddy" >
+        <cstring>creationDateField</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1" >
+      <widget class="QLineEdit" name="creationDateField" />
+     </item>
+     <item row="0" column="1" >
+      <widget class="QTextEdit" name="authorsField" />
+     </item>
+     <item row="0" column="0" >
+      <widget class="QLabel" name="label_3" >
+       <property name="text" >
+        <string>Author(s):</string>
+       </property>
+       <property name="alignment" >
+        <set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <spacer>
+     <property name="orientation" >
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeType" >
+      <enum>QSizePolicy::Fixed</enum>
+     </property>
+     <property name="sizeHint" >
+      <size>
+       <width>20</width>
+       <height>10</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox" >
+     <property name="orientation" >
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons" >
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>LangFilePropertiesDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>227</x>
+     <y>278</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>LangFilePropertiesDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>295</x>
+     <y>284</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/make_ui.sh	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+ui_file=$1
+echo $ui_file \> ui_`basename $ui_file .ui`.py
+pyuic4 $ui_file > ui_`basename $ui_file .ui`.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/make_uis.sh	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+for ui_file in *.ui; do
+  ./make_ui.sh $ui_file
+done
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/msg_form.ui	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,107 @@
+<ui version="4.0" >
+ <class>MsgForm</class>
+ <widget class="QWidget" name="MsgForm" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>456</width>
+    <height>512</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" >
+   <item>
+    <widget class="QSplitter" name="splitter" >
+     <property name="orientation" >
+      <enum>Qt::Vertical</enum>
+     </property>
+     <widget class="QWidget" name="layoutWidget" >
+      <layout class="QVBoxLayout" >
+       <item>
+        <widget class="QLabel" name="label" >
+         <property name="text" >
+          <string>Messages:</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QTreeWidget" name="treeWidget" >
+         <column>
+          <property name="text" >
+           <string>1</string>
+          </property>
+         </column>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="layoutWidget" >
+      <layout class="QGridLayout" >
+       <item row="0" column="0" >
+        <layout class="QVBoxLayout" >
+         <item>
+          <widget class="QLabel" name="label_2" >
+           <property name="text" >
+            <string>Source string:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QTextEdit" name="sourceEdit" />
+         </item>
+        </layout>
+       </item>
+       <item row="0" column="1" >
+        <layout class="QVBoxLayout" >
+         <item>
+          <widget class="QLabel" name="label_3" >
+           <property name="text" >
+            <string>Source annotation:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QTextEdit" name="sourceAnnotEdit" />
+         </item>
+        </layout>
+       </item>
+       <item row="1" column="0" >
+        <layout class="QVBoxLayout" >
+         <item>
+          <widget class="QLabel" name="label_4" >
+           <property name="text" >
+            <string>Translation:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QTextEdit" name="translEdit" />
+         </item>
+        </layout>
+       </item>
+       <item row="1" column="1" >
+        <layout class="QVBoxLayout" >
+         <item>
+          <widget class="QLabel" name="label_5" >
+           <property name="text" >
+            <string>Translator's annotation:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QTextEdit" name="translAnnotEdit" />
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </widget>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/new_project.ui	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,127 @@
+<ui version="4.0" >
+ <class>NewProjectDialog</class>
+ <widget class="QDialog" name="NewProjectDialog" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>401</width>
+    <height>131</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Create New Project</string>
+  </property>
+  <layout class="QVBoxLayout" >
+   <item>
+    <layout class="QGridLayout" >
+     <item row="0" column="0" >
+      <layout class="QGridLayout" >
+       <item row="0" column="0" >
+        <widget class="QLabel" name="label" >
+         <property name="text" >
+          <string>Project name:</string>
+         </property>
+         <property name="alignment" >
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+         <property name="buddy" >
+          <cstring>projectName</cstring>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="1" >
+        <widget class="QLineEdit" name="projectName" />
+       </item>
+       <item row="1" column="0" >
+        <widget class="QLabel" name="label_2" >
+         <property name="text" >
+          <string>Project file:</string>
+         </property>
+         <property name="alignment" >
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+         <property name="buddy" >
+          <cstring>projectFilePath</cstring>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="1" >
+        <layout class="QHBoxLayout" >
+         <item>
+          <widget class="QLineEdit" name="projectFilePath" />
+         </item>
+         <item>
+          <widget class="QToolButton" name="pickFileButton" >
+           <property name="text" >
+            <string>...</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </item>
+     <item row="1" column="0" >
+      <spacer>
+       <property name="orientation" >
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeHint" >
+        <size>
+         <width>20</width>
+         <height>40</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item row="2" column="0" >
+      <widget class="QDialogButtonBox" name="buttonBox" >
+       <property name="orientation" >
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="standardButtons" >
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>NewProjectDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>228</x>
+     <y>108</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>157</x>
+     <y>130</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>NewProjectDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>296</x>
+     <y>114</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>286</x>
+     <y>130</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/project.py	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,109 @@
+# -*- coding: utf-8 -*-
+# Author: Aziz Köksal
+# License: GPL2
+import os
+from errors import LoadingError
+import langfile
+import datetime
+import yaml
+
+def newProjectData(projectName):
+  return {
+    "Name":projectName,
+    "LangFiles":[],
+    "SourceLangFile":'',
+    "MsgIDs":[],
+    "CreationDate":str(datetime.datetime.utcnow()),
+    "BuildScript":''
+  }
+
+class Project:
+  # Members:
+  # name
+  # source
+  # langFilePaths
+  # langFile
+  # msgids
+  # creationDate
+  def __init__(self, projectPath):
+    self.projectPath = projectPath
+    # Load project file and check data integrity.
+    try:
+      self.doc = yaml.load(open(projectPath, "r"))
+    except yaml.YAMLError, e:
+      raise LoadingError(str(e))
+    self.verify()
+
+  def verify(self):
+    doc = self.doc
+    self.checkType(doc, dict)
+    try:
+      self.name = unicode(doc["Name"])
+      self.srcLangFilePath = str(doc["SourceLangFile"])
+      self.langFilePaths = list(doc["LangFiles"])
+      self.msgIDs = list(doc["MsgIDs"])
+      self.creationDate = str(doc["CreationDate"])
+      self.buildScript = str(doc["BuildScript"])
+    except KeyError, e:
+      raise LoadingError("Missing member '%s' in '%s'" % (e.message, projectPath))
+
+    for path in self.langFilePaths:
+      self.checkType(path, str)
+
+    msgIDs = []
+    for msg in self.msgIDs:
+      self.checkType(msg, dict)
+      try:
+         msg["ID"]  = int(msg["ID"])
+         msg["Name"] = unicode(msg["Name"])
+         msg["Order"] = int(msg["Order"])
+      except KeyError, e:
+        raise LoadingError("Project: a message is missing the '%s' key." % str(e))
+      msgIDs += [msg]
+    self.msgIDs = msgIDs
+
+    # Load language files.
+    self.langFiles = []
+    IDList = [msg["ID"] for msgID in self.msgIDs]
+    for filePath in self.langFilePaths:
+      langFile = self.loadLangFile(filePath)
+      langFile.createMissingMessages(IDList)
+      self.langFiles += [langFile]
+    self.srcLangFile = self.loadLangFile(self.srcLangFilePath)
+    self.srcLangFile.createMissingMessages(IDList)
+    self.srcLangFile.isSource = True
+    self.langFiles += [self.srcLangFile]
+
+    for langFile in self.langFiles:
+      langFile.setSource(self.srcLangFile)
+
+  def checkType(self, var, type_):
+    if not isinstance(var, type_):
+      raise LoadingException("%s is not of type %s" % (str(var), str(type_)))
+
+  def loadLangFile(self, filePath):
+    if not os.path.exists(filePath):
+      # Look in project directory.
+      projectDir = os.path.dirname(self.projectPath)
+      filePath2 = os.path.join(projectDir, filePath)
+      if not os.path.exists(filePath2):
+        raise LoadingError("Project: Language file '%s' doesn't exist"%filePath)
+      filePath = filePath2
+    return langfile.LangFile(filePath)
+
+  def setName(self, name):
+    self.name = name
+
+  def setBuildScript(self, filePath):
+    self.buildScript = filePath
+
+  def setCreationDate(self, date):
+    self.creationDate = date
+
+  def save(self):
+    self.doc["Name"] = self.name
+    self.doc["BuildScript"] = self.buildScript
+    self.doc["CreationDate"] = self.creationDate
+    file_ = open(self.projectPath, "w")
+    yaml.dump(self.doc, stream=file_, allow_unicode=True)
+    file_.close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/project_properties.ui	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,136 @@
+<ui version="4.0" >
+ <class>ProjectPropertiesDialog</class>
+ <widget class="QDialog" name="ProjectPropertiesDialog" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>152</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Project Properties</string>
+  </property>
+  <layout class="QVBoxLayout" >
+   <item>
+    <layout class="QGridLayout" >
+     <item row="0" column="0" >
+      <widget class="QLabel" name="label_2" >
+       <property name="text" >
+        <string>Project name:</string>
+       </property>
+       <property name="alignment" >
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+       <property name="buddy" >
+        <cstring>projectNameField</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1" >
+      <widget class="QLineEdit" name="projectNameField" />
+     </item>
+     <item row="1" column="0" >
+      <widget class="QLabel" name="label" >
+       <property name="text" >
+        <string>Build script:</string>
+       </property>
+       <property name="alignment" >
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+       <property name="buddy" >
+        <cstring>buildScriptField</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1" >
+      <layout class="QHBoxLayout" >
+       <item>
+        <widget class="QLineEdit" name="buildScriptField" />
+       </item>
+       <item>
+        <widget class="QToolButton" name="pickFileButton" >
+         <property name="text" >
+          <string>...</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item row="2" column="1" >
+      <widget class="QLineEdit" name="creationDateField" />
+     </item>
+     <item row="2" column="0" >
+      <widget class="QLabel" name="label_3" >
+       <property name="text" >
+        <string>Creation date:</string>
+       </property>
+       <property name="alignment" >
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <spacer>
+     <property name="orientation" >
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" >
+      <size>
+       <width>20</width>
+       <height>40</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox" >
+     <property name="orientation" >
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons" >
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>ProjectPropertiesDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>227</x>
+     <y>278</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>ProjectPropertiesDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>295</x>
+     <y>284</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/translator.py	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,685 @@
+#! /usr/bin/python
+# -*- coding: utf-8 -*-
+# Author: Aziz Köksal
+# License: GPL2
+import sys, os
+import yaml
+
+from PyQt4 import QtCore, QtGui
+# User interface modules
+from ui_translator import Ui_MainWindow
+from ui_about import Ui_AboutDialog
+from ui_new_project import Ui_NewProjectDialog
+from ui_project_properties import Ui_ProjectPropertiesDialog
+from ui_msg_form import Ui_MsgForm
+from ui_closing_project import Ui_ClosingProjectDialog
+
+from project import Project, newProjectData
+
+g_scriptDir = sys.path[0]
+g_CWD = os.getcwd()
+g_projectExt = ".tproj"
+g_catExt = ".cat"
+g_settingsFile = os.path.join(g_scriptDir, "settings.yaml")
+g_settings = {}
+
+Qt = QtCore.Qt
+Qt.connect = QtCore.QObject.connect
+Qt.disconnect = QtCore.QObject.disconnect
+Qt.SIGNAL = QtCore.SIGNAL
+Qt.SLOT = QtCore.SLOT
+
+def QTabWidgetCloseAll(self):
+ for i in range(self.count()-1,-1,-1):
+   widget = self.widget(i)
+   self.removeTab(i)
+   widget.close()
+QtGui.QTabWidget.closeAll = QTabWidgetCloseAll
+
+class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
+  def __init__(self):
+    QtGui.QMainWindow.__init__(self)
+    self.setupUi(self)
+
+    self.project = None
+    # Modifications
+    self.pages = QtGui.QTabWidget()
+    self.setCentralWidget(self.pages)
+    self.disableMenuItems()
+    self.projectDock = QtGui.QDockWidget("Project", self)
+    self.projectTree = ProjectTree(self.projectDock, self)
+    self.projectDock.setWidget(self.projectTree)
+    self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.projectDock)
+    # Custom connections
+    triggered = Qt.SIGNAL("triggered()")
+    Qt.connect(self.action_About, triggered, self.showAboutDialog)
+    Qt.connect(self.action_New_Project, triggered, self.createNewProject)
+    Qt.connect(self.action_Open_Project, triggered, self.openProjectAction)
+    Qt.connect(self.action_Close_Project, triggered, self.closeProjectAction)
+    Qt.connect(self.action_Save, triggered, self.saveForm)
+    Qt.connect(self.action_Save_All, triggered, self.saveAllForms)
+    Qt.connect(self.action_Close, triggered, self.closeForm)
+    Qt.connect(self.action_Close_All, triggered, self.closeAllForms)
+    Qt.connect(self.action_Properties, triggered, self.showProjectProperties)
+    Qt.connect(self.action_Add_Catalogue, triggered, self.addCatalogue)
+    Qt.connect(self.action_Add_New_Catalogue, triggered, self.addNewCatalogue)
+    Qt.connect(self.projectTree, Qt.SIGNAL("itemDoubleClicked(QTreeWidgetItem*,int)"), self.projectTreeItemDblClicked)
+    Qt.connect(self.projectTree, Qt.SIGNAL("onKeyEnter"), self.projectTreeItemActivated)
+    Qt.connect(self.projectTree, Qt.SIGNAL("onKeyDelete"), self.projectTreeItemDeleted)
+
+    shortcut = QtGui.QShortcut(QtGui.QKeySequence(Qt.CTRL+Qt.Key_Tab), self)
+    Qt.connect(shortcut, Qt.SIGNAL("activated()"), self.nextDocument)
+    shortcut = QtGui.QShortcut(QtGui.QKeySequence(Qt.CTRL+Qt.SHIFT+Qt.Key_Tab), self)
+    Qt.connect(shortcut, Qt.SIGNAL("activated()"), self.prevDocument)
+
+    self.readSettings()
+
+  def nextDocument(self):
+    count = self.pages.count()
+    if count < 1: return
+    index = self.pages.currentIndex()+1
+    if index == count: index = 0
+    self.pages.setCurrentIndex(index)
+
+  def prevDocument(self):
+    count = self.pages.count()
+    if count < 1: return
+    index = self.pages.currentIndex()-1
+    if index == -1: index = count-1
+    self.pages.setCurrentIndex(index)
+
+  def showAboutDialog(self):
+    about = QtGui.QDialog()
+    Ui_AboutDialog().setupUi(about)
+    about.exec_()
+
+  def showProjectProperties(self):
+    dialog = ProjectPropertiesDialog(self.project)
+    dialog.exec_()
+    self.projectTree.updateProjectName()
+
+  def createNewProject(self):
+    if self.rejectClosingProject():
+      return
+    dialog = NewProjectDialog()
+    code = dialog.exec_()
+    if code == QtGui.QDialog.Accepted:
+      self.closeProject()
+      self.openProject(str(dialog.projectFilePath.text()))
+
+  def openProjectAction(self):
+    if self.rejectClosingProject():
+      return
+    filePath = QtGui.QFileDialog.getOpenFileName(self, "Select Project File", g_CWD, "Translator Project (*%s)" % g_projectExt);
+    filePath = str(filePath)
+    if filePath:
+      self.closeProject()
+      self.openProject(filePath)
+
+  def openProject(self, filePath):
+    from errors import LoadingError
+    try:
+      self.project = Project(filePath)
+    except LoadingError, e:
+      QtGui.QMessageBox.critical(self, "Error", u"Couldn't load project file:\n\n"+str(e))
+      return
+    self.enableMenuItems()
+    self.projectTree.setProject(self.project)
+
+  def closeProjectAction(self):
+    if not self.rejectClosingProject():
+      self.closeProject()
+
+  def addCatalogue(self):
+    filePath = QtGui.QFileDialog.getOpenFileName(self, "Select Project File", g_CWD, "Catalogue (*%s)" % g_catExt);
+    filePath = str(filePath)
+    # TODO:
+    #self.project.addLangFile(filePath)
+
+  def addNewCatalogue(self):
+    pass
+
+  def rejectClosingProject(self):
+    if self.project == None:
+      return False
+
+    modifiedDocs = []
+    # Check if any open document is modified.
+    for i in range(0, self.pages.count()):
+      if self.pages.widget(i).isModified:
+        modifiedDocs += [self.pages.widget(i)]
+    # Display dialog if so.
+    if len(modifiedDocs):
+      dialog = ClosingProjectDialog(modifiedDocs)
+      code = dialog.exec_()
+      if code == dialog.Accepted:
+        for doc in dialog.getSelectedDocs():
+          self.saveDocument(doc)
+      elif code == dialog.Rejected:
+        return True
+      elif code == dialog.DiscardAll:
+        pass
+
+    return False
+
+  def closeProject(self):
+    if self.project == None:
+      return
+    self.project.save()
+    del self.project
+    self.project = None
+    self.disableMenuItems()
+    self.projectTree.clear()
+    self.pages.closeAll()
+
+  def enableMenuItems(self):
+    #self.action_Close_Project.setEnabled(True)
+    for action in [ self.action_Save,
+                    self.action_Save_All,
+                    self.action_Close,
+                    self.action_Close_All ]:
+      action.setEnabled(True)
+    self.menubar.insertMenu(self.menu_Help.menuAction(), self.menu_Project)
+
+  def disableMenuItems(self):
+    #self.action_Close_Project.setEnabled(False)
+    for action in [ self.action_Save,
+                    self.action_Save_All,
+                    self.action_Close,
+                    self.action_Close_All ]:
+      action.setEnabled(False)
+    self.menubar.removeAction(self.menu_Project.menuAction())
+
+  def projectTreeItemDblClicked(self, item, int):
+    self.projectTreeItemActivated(item)
+
+  def projectTreeItemActivated(self, item):
+    if item == None:
+      return
+
+    if isinstance(item, LangFileItem):
+      msgForm = None
+      if not item.isDocOpen():
+        msgForm = item.openDoc()
+        msgForm.setModifiedCallback(self.formModified)
+      else:
+        msgForm = item.openDoc()
+      index = self.pages.indexOf(msgForm)
+      if index == -1:
+        index = self.pages.addTab(msgForm, msgForm.getDocumentTitle())
+      self.pages.setCurrentIndex(index)
+      msgForm.updateData()
+
+  def projectTreeItemDeleted(self, item):
+    pass
+
+  def formModified(self, form):
+    # Append an asterisk to the tab label
+    index = self.pages.indexOf(form)
+    text = form.getDocumentTitle() + "*"
+    self.pages.setTabText(index, text)
+
+  def saveForm(self):
+    self.saveDocument(self.pages.currentWidget())
+
+  def saveAllForms(self):
+    for i in range(0, self.pages.count()):
+      self.saveDocument(self.pages.widget(i))
+
+  def saveDocument(self, form):
+    if form.isModified:
+      # Reset tab text.
+      index = self.pages.indexOf(form)
+      text = form.getDocumentTitle()
+      self.pages.setTabText(index, text)
+
+      form.save()
+
+  def closeForm(self):
+    if self.pages.currentWidget():
+      self.closeDocument(self.pages.currentWidget())
+
+  def closeAllForms(self):
+    for i in range(self.pages.count()-1, -1, -1):
+      self.closeDocument(self.pages.widget(i))
+
+  def closeDocument(self, form):
+    if form.isModified:
+      MB = QtGui.QMessageBox
+      button = MB.question(self, "Closing Document", "The document '%s' has been modified.\nDo you want to save the changes?" % form.getDocumentFullPath(), MB.Save | MB.Discard | MB.Cancel, MB.Cancel)
+      if button == MB.Cancel:
+        return False
+      if button == MB.Save:
+        self.saveDocument(form)
+    index = self.pages.indexOf(form)
+    self.pages.removeTab(index)
+    form.close()
+    return True
+
+  def closeEvent(self, event):
+    if self.rejectClosingProject():
+      event.ignore()
+      return
+    self.closeProject()
+    self.writeSettings()
+    # Closing application
+
+  def moveToCenterOfDesktop(self):
+    rect = QtGui.QApplication.desktop().geometry()
+    self.move(rect.center() - self.rect().center())
+
+  def readSettings(self):
+    # Set default size
+    self.resize(QtCore.QSize(500, 400))
+    doc = {}
+    try:
+      doc = yaml.load(open(g_settingsFile, "r"))
+    except:
+      self.moveToCenterOfDesktop()
+      return
+
+    g_settings = doc
+    if not isinstance(doc, dict):
+      g_settings = {}
+
+    try:
+      coord = doc["Window"]
+      size = QtCore.QSize(coord["Size"][0], coord["Size"][1])
+      point = QtCore.QPoint(coord["Pos"][0], coord["Pos"][1])
+      self.resize(size)
+      self.move(point)
+    except:
+      self.moveToCenterOfDesktop()
+
+  def writeSettings(self):
+    # Save window coordinates
+    g_settings["Window"] = {
+      "Pos" : [self.pos().x(), self.pos().y()],
+      "Size" : [self.size().width(), self.size().height()]
+    }
+    yaml.dump(g_settings, open(g_settingsFile, "w")) #default_flow_style=False
+
+
+class Document(QtGui.QWidget):
+  def __init__(self):
+    QtGui.QWidget.__init__(self)
+    self.isModified = False
+    self.modifiedCallback = None
+    self.documentTitle = ""
+    self.documentFullPath = ""
+
+  def modified(self):
+    if not self.isModified:
+      self.isModified = True
+      self.modifiedCallback(self)
+
+  def setModifiedCallback(self, func):
+    self.modifiedCallback = func
+
+  def save(self):
+    self.isModified = False
+
+  def close(self):
+    self.emit(Qt.SIGNAL("closed()"))
+    QtGui.QWidget.close(self)
+
+  def getDocumentTitle(self):
+    return self.documentTitle
+
+  def getDocumentFullPath(self):
+    return self.documentFullPath
+
+
+class MessageItem(QtGui.QTreeWidgetItem):
+  def __init__(self, msg):
+    QtGui.QTreeWidgetItem.__init__(self, [str(msg["ID"]), msg["Text"], "Done"])
+    self.msg = msg
+
+  def getID(self):
+    return self.msg["ID"]
+
+  def setMsgText(self, text):
+    self.msg["Text"] = text
+
+  def setMsgAnnot(self, text):
+    self.msg["Annot"] = text
+
+
+class MsgForm(Document, Ui_MsgForm):
+  def __init__(self, langFile):
+    Document.__init__(self)
+    self.documentTitle = langFile.getFileName()
+    self.documentFullPath = langFile.getFilePath()
+    self.setupUi(self)
+    self.vboxlayout.setMargin(0)
+
+    self.langFile = langFile
+    self.currentItem = None
+    self.colID = 0
+    self.colText = 1
+    #self.colStat = 2
+    #self.treeWidget.setColumnCount(3)
+    self.treeWidget.setColumnCount(2)
+    self.treeWidget.setHeaderLabels(["ID", "Text"]) #, "Status"
+    self.msgItemDict = {} # Maps msg IDs to msg items.
+    for msg in self.langFile.messages:
+      item = MessageItem(msg)
+      self.msgItemDict[msg["ID"]] = item
+      self.treeWidget.addTopLevelItem(item)
+
+    Qt.connect(self.treeWidget, Qt.SIGNAL("currentItemChanged (QTreeWidgetItem *,QTreeWidgetItem *)"), self.treeItemChanged)
+    Qt.connect(self.translEdit, Qt.SIGNAL("textChanged()"), self.translEditTextChanged)
+    Qt.connect(self.translAnnotEdit, Qt.SIGNAL("textChanged()"), self.translAnnotEditTextChanged)
+
+    #self.translEdit.focusOutEvent = self.translEditFocusOut
+
+  def sourceMsgChanged(self, msg):
+    # TODO:
+    pass
+
+  def treeItemChanged(self, current, previous):
+    if current == None:
+      self.setTranslMsg("")
+      self.setSourceMsg("")
+      return
+    ID = current.getID()
+    # Set the text controls.
+    # The slots receiving text changed signals do nothing if self.currentItem is None.
+    self.currentItem = None
+    self.setTranslMsg(self.langFile.getMsg(ID))
+    self.setSourceMsg(self.langFile.source.getMsg(ID))
+    self.currentItem = current
+
+  def setTranslMsg(self, msg):
+    self.translEdit.setText(msg["Text"])
+    self.translAnnotEdit.setText(msg["Annot"])
+
+  def setSourceMsg(self, msg):
+    self.sourceEdit.setText(msg["Text"])
+    self.sourceAnnotEdit.setText(msg["Annot"])
+
+  #def translEditFocusOut(self, event):
+    #if self.currentItem:
+      #print self.currentItem.text(self.colText)
+      #if self.translEdit.document().isModified():
+        #self.translEdit.document().setModified(False)
+        #print "translEdit was modified"
+    #QtGui.QTextEdit.focusOutEvent(self.translEdit, event)
+
+  def translEditTextChanged(self):
+    if self.currentItem:
+      text = unicode(self.translEdit.toPlainText())
+      self.currentItem.setText(self.colText, text)
+      self.currentItem.setMsgText(text)
+      self.modified()
+
+  def translAnnotEditTextChanged(self):
+    if self.currentItem:
+      text = unicode(self.translAnnotEdit.toPlainText())
+      self.currentItem.setMsgAnnot(text)
+      self.modified()
+
+  def updateData(self):
+    if self.currentItem == None:
+      return
+    ID = self.currentItem.getID()
+    msg = self.langFile.source.getMsg(ID)
+    text = self.sourceEdit.toPlainText()
+    if text != msg["Text"]:
+      self.sourceEdit.setText(msg["Text"])
+    text = self.sourceAnnotEdit.toPlainText()
+    if text != msg["Annot"]:
+      self.sourceAnnotEdit.setText(msg["Annot"])
+
+  def save(self):
+    Document.save(self)
+    self.langFile.save()
+
+
+class MsgFormSource(MsgForm):
+  def __init__(self, langFile):
+    MsgForm.__init__(self, langFile)
+
+    for x in [self.translEdit,
+              self.translAnnotEdit,
+              self.label_4,
+              self.label_5]:
+      x.close()
+
+    Qt.connect(self.sourceEdit, Qt.SIGNAL("textChanged()"), self.sourceEditTextChanged)
+    Qt.connect(self.sourceAnnotEdit, Qt.SIGNAL("textChanged()"), self.sourceAnnotEditTextChanged)
+
+  def treeItemChanged(self, current, previous):
+    if current == None:
+      self.setSourceMsg("")
+      return
+    ID = current.getID()
+    self.currentItem = None
+    self.setSourceMsg(self.langFile.getMsg(ID))
+    self.currentItem = current
+
+  def sourceEditTextChanged(self):
+    if self.currentItem:
+      text = unicode(self.sourceEdit.toPlainText())
+      self.currentItem.setText(self.colText, text)
+      self.currentItem.setMsgText(text)
+      self.modified()
+
+  def sourceAnnotEditTextChanged(self):
+    if self.currentItem:
+      text = unicode(self.sourceAnnotEdit.toPlainText())
+      #self.currentItem.setText(self.colAnnot, text)
+      self.currentItem.setMsgAnnot(text)
+      self.modified()
+
+
+class MsgIDItem(QtGui.QTreeWidgetItem):
+  def __init__(self, parent, text):
+    QtGui.QTreeWidgetItem.__init__(self, parent, [text])
+    self.setFlags(self.flags()|Qt.ItemIsEditable);
+
+class LangFileItem(QtGui.QTreeWidgetItem):
+  def __init__(self, parent, langFile):
+    QtGui.QTreeWidgetItem.__init__(self, parent, [langFile.langCode])
+    self.langFile = langFile
+    self.msgForm = None
+
+  def isDocOpen(self):
+    return self.msgForm != None
+
+  def openDoc(self):
+    if self.msgForm == None:
+      if self.langFile.isSource:
+        self.msgForm = MsgFormSource(self.langFile)
+      else:
+        self.msgForm = MsgForm(self.langFile)
+      Qt.connect(self.msgForm, Qt.SIGNAL("closed()"), self.docClosed)
+    return self.msgForm
+
+  def docClosed(self):
+    self.msgForm = None
+
+class ProjectItem(QtGui.QTreeWidgetItem):
+  def __init__(self, text):
+    QtGui.QTreeWidgetItem.__init__(self, [text])
+    self.setFlags(self.flags()|Qt.ItemIsEditable);
+
+class ProjectTree(QtGui.QTreeWidget):
+  def __init__(self, parent, mainWindow):
+    QtGui.QTreeWidget.__init__(self, parent)
+    self.mainWindow = mainWindow
+    self.project = None
+    self.topItem = None
+    self.msgIDsItem = None
+    self.headerItem().setHidden(True)
+    self.ignoreItemChanged = False
+
+  def itemChanged(self, item, column):
+    if self.ignoreItemChanged:
+      return
+    text = unicode(item.text(0))
+    #if hasattr(item, "textChanged"):
+      #item.textChanged(text)
+    if isinstance(item, ProjectItem):
+      self.project.setName(text)
+      print text
+
+  def keyReleaseEvent(self, event):
+    Qt = QtCore.Qt
+    key = event.key()
+    if key in [Qt.Key_Enter, Qt.Key_Return]:
+      self.emit(Qt.SIGNAL("onKeyEnter"), self.currentItem())
+    elif key == Qt.Key_Delete:
+      self.emit(Qt.SIGNAL("onKeyDelete"), self.currentItem())
+
+  def setProject(self, project):
+    self.project = project
+
+    self.topItem = ProjectItem(self.project.name)
+    self.addTopLevelItem(self.topItem)
+
+    for langFile in self.project.langFiles:
+      langFileItem = LangFileItem(self.topItem, langFile)
+
+    self.msgIDsItem = QtGui.QTreeWidgetItem(self.topItem, ["Message IDs"])
+    for msgID in self.project.msgIDs:
+      MsgIDItem(self.msgIDsItem, msgID["Name"])
+
+    for x in [self.topItem, self.msgIDsItem]:
+      x.setExpanded(True)
+
+    Qt.connect(self, Qt.SIGNAL("itemChanged(QTreeWidgetItem*,int)"), self.itemChanged)
+
+  def contextMenuEvent(self, event):
+    item = self.itemAt(event.pos())
+    func_map = {
+      None : lambda item: None,
+      QtGui.QTreeWidgetItem : lambda item: None,
+      ProjectItem : self.showMenuProjectItem,
+      LangFileItem : self.showMenuLangFileItem,
+      MsgIDItem : self.showMenuMsgIDItem
+    }
+    func_map[type(item)](item)
+
+  def showMenuProjectItem(self, item):
+    mousePos = QtGui.QCursor.pos()
+    menu = QtGui.QMenu()
+    actions = {}
+    actions[menu.addAction("Build")] = lambda: None
+    actions[menu.addAction("Properties")] = lambda: self.mainWindow.showProjectProperties()
+    actions[menu.exec_(mousePos)]()
+
+  def showMenuLangFileItem(self, item):
+    print "LangFileItem"
+
+  def showMenuMsgIDItem(self, item):
+    print "MsgIDItem"
+
+  def updateProjectName(self):
+    self.ignoreItemChanged = True
+    self.topItem.setText(0, self.project.name)
+    self.ignoreItemChanged = False
+
+  def clear(self):
+    self.project = None
+    self.topItem = None
+    self.msgIDsItem = None
+    Qt.disconnect(self, Qt.SIGNAL("itemChanged(QTreeWidgetItem*,int)"), self.itemChanged)
+    QtGui.QTreeWidget.clear(self)
+
+
+class ClosingProjectDialog(QtGui.QDialog, Ui_ClosingProjectDialog):
+  DiscardAll = 2
+  def __init__(self, docs):
+    QtGui.QDialog.__init__(self)
+    self.setupUi(self)
+    Qt.connect(self.button_Discard_All, Qt.SIGNAL("clicked()"),   self.discardAll)
+
+    self.items = []
+    for doc in docs:
+      title = doc.getDocumentTitle()
+      path = doc.getDocumentFullPath()
+      item = QtGui.QTreeWidgetItem([title, path])
+      item.doc = doc
+      item.setFlags(item.flags()|Qt.ItemIsUserCheckable);
+      item.setCheckState(0, Qt.Checked)
+      self.items += [item]
+    self.treeWidget.addTopLevelItems(self.items)
+
+    self.button_Cancel.setFocus()
+
+  def getSelectedDocs(self):
+    return [item.doc for item in self.items if item.checkState(0)]
+
+  def discardAll(self):
+    self.done(self.DiscardAll)
+
+
+class ProjectPropertiesDialog(QtGui.QDialog, Ui_ProjectPropertiesDialog):
+  def __init__(self, project):
+    QtGui.QDialog.__init__(self)
+    self.setupUi(self)
+    Qt.connect(self.pickFileButton, Qt.SIGNAL("clicked()"), self.pickFilePath)
+
+    self.project = project
+    self.projectNameField.setText(self.project.name)
+    self.buildScriptField.setText(self.project.buildScript)
+    self.creationDateField.setText(self.project.creationDate)
+
+  def pickFilePath(self):
+    filePath = QtGui.QFileDialog.getOpenFileName(self, "Select Build Script File", g_CWD, "Python Script (*.py)");
+    if filePath:
+      self.buildScriptField.setText(str(filePath))
+
+  def accept(self):
+    self.project.setName(unicode(self.projectNameField.text()))
+    self.project.setBuildScript(unicode(self.buildScriptField.text()))
+    self.project.setCreationDate(str(self.creationDateField.text()))
+    QtGui.QDialog.accept(self)
+
+
+class NewProjectDialog(QtGui.QDialog, Ui_NewProjectDialog):
+  def __init__(self):
+    QtGui.QDialog.__init__(self)
+    self.setupUi(self)
+    Qt.connect(self.pickFileButton, Qt.SIGNAL("clicked()"), self.pickFilePath)
+
+  def pickFilePath(self):
+    filePath = QtGui.QFileDialog.getSaveFileName(self, "New Project File", g_CWD, "Translator Project (*%s)" % g_projectExt);
+    if filePath:
+      filePath = str(filePath) # Convert QString
+      if os.path.splitext(filePath)[1] != g_projectExt:
+        filePath += g_projectExt
+      self.projectFilePath.setText(filePath)
+
+  def accept(self):
+    projectName = str(self.projectName.text())
+    filePath = str(self.projectFilePath.text())
+
+    MB = QtGui.QMessageBox
+    if projectName == "":
+      MB.warning(self, "Warning", "Please, enter a name for the project.")
+      return
+    if filePath == "":
+      MB.warning(self, "Warning", "Please, choose or enter a path for the project file.")
+      return
+
+    projectData = newProjectData(projectName)
+
+    if os.path.splitext(filePath)[1] != g_projectExt:
+      filePath += g_projectExt
+
+    try:
+      yaml.dump(projectData, open(filePath, "w"), default_flow_style=False)
+    except Exception, e:
+      MB.critical(self, "Error", str(e))
+      return
+
+    # Accept and close dialog.
+    QtGui.QDialog.accept(self)
+
+if __name__ == "__main__":
+  app = QtGui.QApplication(sys.argv)
+  main = MainWindow()
+  main.show()
+  sys.exit(app.exec_())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/translator.ui	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,174 @@
+<ui version="4.0" >
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>608</width>
+    <height>464</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Translator</string>
+  </property>
+  <widget class="QWidget" name="centralwidget" >
+   <layout class="QVBoxLayout" />
+  </widget>
+  <widget class="QMenuBar" name="menubar" >
+   <property name="geometry" >
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>608</width>
+     <height>29</height>
+    </rect>
+   </property>
+   <widget class="QMenu" name="menu_File" >
+    <property name="title" >
+     <string>&amp;File</string>
+    </property>
+    <addaction name="action_Open_Project" />
+    <addaction name="action_New_Project" />
+    <addaction name="separator" />
+    <addaction name="action_Save" />
+    <addaction name="action_Save_All" />
+    <addaction name="separator" />
+    <addaction name="action_Close" />
+    <addaction name="action_Close_All" />
+    <addaction name="separator" />
+    <addaction name="action_Quit" />
+   </widget>
+   <widget class="QMenu" name="menu_Help" >
+    <property name="title" >
+     <string>&amp;Help</string>
+    </property>
+    <addaction name="action_About" />
+   </widget>
+   <widget class="QMenu" name="menu_Project" >
+    <property name="title" >
+     <string>&amp;Project</string>
+    </property>
+    <addaction name="action_Add_Catalogue" />
+    <addaction name="action_Add_New_Catalogue" />
+    <addaction name="action_Build_Project" />
+    <addaction name="separator" />
+    <addaction name="action_Properties" />
+    <addaction name="separator" />
+    <addaction name="action_Close_Project" />
+   </widget>
+   <addaction name="menu_File" />
+   <addaction name="menu_Project" />
+   <addaction name="menu_Help" />
+  </widget>
+  <widget class="QStatusBar" name="statusbar" />
+  <action name="action_Quit" >
+   <property name="text" >
+    <string>&amp;Quit</string>
+   </property>
+   <property name="shortcut" >
+    <string>Ctrl+Q</string>
+   </property>
+  </action>
+  <action name="action_About" >
+   <property name="text" >
+    <string>&amp;About</string>
+   </property>
+  </action>
+  <action name="action_New_Project" >
+   <property name="text" >
+    <string>&amp;New Project...</string>
+   </property>
+   <property name="shortcut" >
+    <string>Ctrl+N</string>
+   </property>
+  </action>
+  <action name="action_Add_Catalogue" >
+   <property name="text" >
+    <string>&amp;Add catalogue...</string>
+   </property>
+  </action>
+  <action name="action_Properties" >
+   <property name="text" >
+    <string>&amp;Properties</string>
+   </property>
+  </action>
+  <action name="action_Build_Project" >
+   <property name="text" >
+    <string>&amp;Build Project</string>
+   </property>
+  </action>
+  <action name="action_Open_Project" >
+   <property name="text" >
+    <string>&amp;Open Project...</string>
+   </property>
+   <property name="shortcut" >
+    <string>Ctrl+O</string>
+   </property>
+  </action>
+  <action name="action_Close" >
+   <property name="text" >
+    <string>&amp;Close</string>
+   </property>
+   <property name="shortcut" >
+    <string>Ctrl+W</string>
+   </property>
+  </action>
+  <action name="action_Add_New_Catalogue" >
+   <property name="text" >
+    <string>Add new catalogue...</string>
+   </property>
+  </action>
+  <action name="action_Close_Project" >
+   <property name="text" >
+    <string>&amp;Close Project</string>
+   </property>
+   <property name="shortcut" >
+    <string>Ctrl+F4</string>
+   </property>
+  </action>
+  <action name="action_Save" >
+   <property name="text" >
+    <string>&amp;Save</string>
+   </property>
+   <property name="shortcut" >
+    <string>Ctrl+S</string>
+   </property>
+  </action>
+  <action name="action_Save_All" >
+   <property name="text" >
+    <string>Save &amp;All</string>
+   </property>
+   <property name="shortcut" >
+    <string>Ctrl+Shift+S</string>
+   </property>
+  </action>
+  <action name="action_Close_All" >
+   <property name="text" >
+    <string>Clos&amp;e All</string>
+   </property>
+   <property name="shortcut" >
+    <string>Ctrl+Shift+W</string>
+   </property>
+  </action>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>action_Quit</sender>
+   <signal>triggered()</signal>
+   <receiver>MainWindow</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>-1</x>
+     <y>-1</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>303</x>
+     <y>231</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/ui_about.py	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'about.ui'
+#
+# Created: Sun Oct 21 17:33:29 2007
+#      by: PyQt4 UI code generator 4.1
+#
+# WARNING! All changes made in this file will be lost!
+
+import sys
+from PyQt4 import QtCore, QtGui
+
+class Ui_AboutDialog(object):
+    def setupUi(self, AboutDialog):
+        AboutDialog.setObjectName("AboutDialog")
+        AboutDialog.setWindowModality(QtCore.Qt.WindowModal)
+        AboutDialog.resize(QtCore.QSize(QtCore.QRect(0,0,414,157).size()).expandedTo(AboutDialog.minimumSizeHint()))
+
+        self.vboxlayout = QtGui.QVBoxLayout(AboutDialog)
+        self.vboxlayout.setObjectName("vboxlayout")
+
+        self.label1 = QtGui.QLabel(AboutDialog)
+        self.label1.setTextFormat(QtCore.Qt.RichText)
+        self.label1.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
+        self.label1.setWordWrap(True)
+        self.label1.setObjectName("label1")
+        self.vboxlayout.addWidget(self.label1)
+
+        self.buttonBox = QtGui.QDialogButtonBox(AboutDialog)
+        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok)
+        self.buttonBox.setObjectName("buttonBox")
+        self.vboxlayout.addWidget(self.buttonBox)
+
+        self.retranslateUi(AboutDialog)
+        QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("accepted()"),AboutDialog.close)
+        QtCore.QMetaObject.connectSlotsByName(AboutDialog)
+
+    def retranslateUi(self, AboutDialog):
+        AboutDialog.setWindowTitle(QtGui.QApplication.translate("AboutDialog", "About", None, QtGui.QApplication.UnicodeUTF8))
+        self.label1.setText(QtGui.QApplication.translate("AboutDialog", "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
+        "p, li { white-space: pre-wrap; }\n"
+        "</style></head><body style=\" font-family:\'Sans Serif\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
+        "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">A tool for managing message catalogues in different languages.</p>\n"
+        "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">These catalogues can be used to make an application multilingual.</p>\n"
+        "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
+        "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Copyright © 2007 by Aziz Köksal &lt;aziz.koeksal@gmail.com&gt;</p>\n"
+        "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Licensed under the GPL2.</p></body></html>", None, QtGui.QApplication.UnicodeUTF8))
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/ui_closing_project.py	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'closing_project.ui'
+#
+# Created: Sun Nov 11 23:01:28 2007
+#      by: PyQt4 UI code generator 4.1
+#
+# WARNING! All changes made in this file will be lost!
+
+import sys
+from PyQt4 import QtCore, QtGui
+
+class Ui_ClosingProjectDialog(object):
+    def setupUi(self, ClosingProjectDialog):
+        ClosingProjectDialog.setObjectName("ClosingProjectDialog")
+        ClosingProjectDialog.resize(QtCore.QSize(QtCore.QRect(0,0,400,300).size()).expandedTo(ClosingProjectDialog.minimumSizeHint()))
+
+        self.vboxlayout = QtGui.QVBoxLayout(ClosingProjectDialog)
+        self.vboxlayout.setObjectName("vboxlayout")
+
+        self.label = QtGui.QLabel(ClosingProjectDialog)
+        self.label.setObjectName("label")
+        self.vboxlayout.addWidget(self.label)
+
+        self.treeWidget = QtGui.QTreeWidget(ClosingProjectDialog)
+        self.treeWidget.setObjectName("treeWidget")
+        self.vboxlayout.addWidget(self.treeWidget)
+
+        spacerItem = QtGui.QSpacerItem(382,33,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Expanding)
+        self.vboxlayout.addItem(spacerItem)
+
+        self.hboxlayout = QtGui.QHBoxLayout()
+        self.hboxlayout.setObjectName("hboxlayout")
+
+        spacerItem1 = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum)
+        self.hboxlayout.addItem(spacerItem1)
+
+        self.button_Save_Selected = QtGui.QPushButton(ClosingProjectDialog)
+        self.button_Save_Selected.setObjectName("button_Save_Selected")
+        self.hboxlayout.addWidget(self.button_Save_Selected)
+
+        self.button_Discard_All = QtGui.QPushButton(ClosingProjectDialog)
+        self.button_Discard_All.setObjectName("button_Discard_All")
+        self.hboxlayout.addWidget(self.button_Discard_All)
+
+        self.button_Cancel = QtGui.QPushButton(ClosingProjectDialog)
+        self.button_Cancel.setDefault(True)
+        self.button_Cancel.setObjectName("button_Cancel")
+        self.hboxlayout.addWidget(self.button_Cancel)
+        self.vboxlayout.addLayout(self.hboxlayout)
+
+        self.retranslateUi(ClosingProjectDialog)
+        QtCore.QObject.connect(self.button_Save_Selected,QtCore.SIGNAL("clicked()"),ClosingProjectDialog.accept)
+        QtCore.QObject.connect(self.button_Cancel,QtCore.SIGNAL("clicked()"),ClosingProjectDialog.reject)
+        QtCore.QMetaObject.connectSlotsByName(ClosingProjectDialog)
+
+    def retranslateUi(self, ClosingProjectDialog):
+        ClosingProjectDialog.setWindowTitle(QtGui.QApplication.translate("ClosingProjectDialog", "Closing Project", None, QtGui.QApplication.UnicodeUTF8))
+        self.label.setText(QtGui.QApplication.translate("ClosingProjectDialog", "The following documents have been modified:", None, QtGui.QApplication.UnicodeUTF8))
+        self.treeWidget.headerItem().setText(0,QtGui.QApplication.translate("ClosingProjectDialog", "Title", None, QtGui.QApplication.UnicodeUTF8))
+        self.treeWidget.headerItem().setText(1,QtGui.QApplication.translate("ClosingProjectDialog", "Full Path", None, QtGui.QApplication.UnicodeUTF8))
+        self.button_Save_Selected.setText(QtGui.QApplication.translate("ClosingProjectDialog", "&Save Selected", None, QtGui.QApplication.UnicodeUTF8))
+        self.button_Discard_All.setText(QtGui.QApplication.translate("ClosingProjectDialog", "&Discard All Changes", None, QtGui.QApplication.UnicodeUTF8))
+        self.button_Cancel.setText(QtGui.QApplication.translate("ClosingProjectDialog", "&Cancel", None, QtGui.QApplication.UnicodeUTF8))
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/ui_langfile_properties.py	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'langfile_properties.ui'
+#
+# Created: Sat Nov 17 23:14:57 2007
+#      by: PyQt4 UI code generator 4.1
+#
+# WARNING! All changes made in this file will be lost!
+
+import sys
+from PyQt4 import QtCore, QtGui
+
+class Ui_LangFilePropertiesDialog(object):
+    def setupUi(self, LangFilePropertiesDialog):
+        LangFilePropertiesDialog.setObjectName("LangFilePropertiesDialog")
+        LangFilePropertiesDialog.resize(QtCore.QSize(QtCore.QRect(0,0,400,228).size()).expandedTo(LangFilePropertiesDialog.minimumSizeHint()))
+
+        self.vboxlayout = QtGui.QVBoxLayout(LangFilePropertiesDialog)
+        self.vboxlayout.setObjectName("vboxlayout")
+
+        self.gridlayout = QtGui.QGridLayout()
+        self.gridlayout.setObjectName("gridlayout")
+
+        self.label_2 = QtGui.QLabel(LangFilePropertiesDialog)
+        self.label_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
+        self.label_2.setObjectName("label_2")
+        self.gridlayout.addWidget(self.label_2,1,0,1,1)
+
+        self.langCodeField = QtGui.QLineEdit(LangFilePropertiesDialog)
+        self.langCodeField.setObjectName("langCodeField")
+        self.gridlayout.addWidget(self.langCodeField,1,1,1,1)
+
+        self.label = QtGui.QLabel(LangFilePropertiesDialog)
+        self.label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
+        self.label.setObjectName("label")
+        self.gridlayout.addWidget(self.label,2,0,1,1)
+
+        self.creationDateField = QtGui.QLineEdit(LangFilePropertiesDialog)
+        self.creationDateField.setObjectName("creationDateField")
+        self.gridlayout.addWidget(self.creationDateField,2,1,1,1)
+
+        self.authorsField = QtGui.QTextEdit(LangFilePropertiesDialog)
+        self.authorsField.setObjectName("authorsField")
+        self.gridlayout.addWidget(self.authorsField,0,1,1,1)
+
+        self.label_3 = QtGui.QLabel(LangFilePropertiesDialog)
+        self.label_3.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTop|QtCore.Qt.AlignTrailing)
+        self.label_3.setObjectName("label_3")
+        self.gridlayout.addWidget(self.label_3,0,0,1,1)
+        self.vboxlayout.addLayout(self.gridlayout)
+
+        spacerItem = QtGui.QSpacerItem(20,10,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Fixed)
+        self.vboxlayout.addItem(spacerItem)
+
+        self.buttonBox = QtGui.QDialogButtonBox(LangFilePropertiesDialog)
+        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
+        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Ok)
+        self.buttonBox.setObjectName("buttonBox")
+        self.vboxlayout.addWidget(self.buttonBox)
+        self.label_2.setBuddy(self.langCodeField)
+        self.label.setBuddy(self.creationDateField)
+
+        self.retranslateUi(LangFilePropertiesDialog)
+        QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("accepted()"),LangFilePropertiesDialog.accept)
+        QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("rejected()"),LangFilePropertiesDialog.reject)
+        QtCore.QMetaObject.connectSlotsByName(LangFilePropertiesDialog)
+
+    def retranslateUi(self, LangFilePropertiesDialog):
+        LangFilePropertiesDialog.setWindowTitle(QtGui.QApplication.translate("LangFilePropertiesDialog", "Language File Properties", None, QtGui.QApplication.UnicodeUTF8))
+        self.label_2.setText(QtGui.QApplication.translate("LangFilePropertiesDialog", "Language code:", None, QtGui.QApplication.UnicodeUTF8))
+        self.label.setText(QtGui.QApplication.translate("LangFilePropertiesDialog", "Creation date:", None, QtGui.QApplication.UnicodeUTF8))
+        self.label_3.setText(QtGui.QApplication.translate("LangFilePropertiesDialog", "Author(s):", None, QtGui.QApplication.UnicodeUTF8))
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/ui_msg_form.py	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,105 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'msg_form.ui'
+#
+# Created: Fri Nov  9 15:38:32 2007
+#      by: PyQt4 UI code generator 4.1
+#
+# WARNING! All changes made in this file will be lost!
+
+import sys
+from PyQt4 import QtCore, QtGui
+
+class Ui_MsgForm(object):
+    def setupUi(self, MsgForm):
+        MsgForm.setObjectName("MsgForm")
+        MsgForm.resize(QtCore.QSize(QtCore.QRect(0,0,456,512).size()).expandedTo(MsgForm.minimumSizeHint()))
+
+        self.vboxlayout = QtGui.QVBoxLayout(MsgForm)
+        self.vboxlayout.setObjectName("vboxlayout")
+
+        self.splitter = QtGui.QSplitter(MsgForm)
+        self.splitter.setOrientation(QtCore.Qt.Vertical)
+        self.splitter.setObjectName("splitter")
+
+        self.layoutWidget = QtGui.QWidget(self.splitter)
+        self.layoutWidget.setObjectName("layoutWidget")
+
+        self.vboxlayout1 = QtGui.QVBoxLayout(self.layoutWidget)
+        self.vboxlayout1.setObjectName("vboxlayout1")
+
+        self.label = QtGui.QLabel(self.layoutWidget)
+        self.label.setObjectName("label")
+        self.vboxlayout1.addWidget(self.label)
+
+        self.treeWidget = QtGui.QTreeWidget(self.layoutWidget)
+        self.treeWidget.setObjectName("treeWidget")
+        self.vboxlayout1.addWidget(self.treeWidget)
+
+        self.layoutWidget1 = QtGui.QWidget(self.splitter)
+        self.layoutWidget1.setObjectName("layoutWidget1")
+
+        self.gridlayout = QtGui.QGridLayout(self.layoutWidget1)
+        self.gridlayout.setObjectName("gridlayout")
+
+        self.vboxlayout2 = QtGui.QVBoxLayout()
+        self.vboxlayout2.setObjectName("vboxlayout2")
+
+        self.label_2 = QtGui.QLabel(self.layoutWidget1)
+        self.label_2.setObjectName("label_2")
+        self.vboxlayout2.addWidget(self.label_2)
+
+        self.sourceEdit = QtGui.QTextEdit(self.layoutWidget1)
+        self.sourceEdit.setObjectName("sourceEdit")
+        self.vboxlayout2.addWidget(self.sourceEdit)
+        self.gridlayout.addLayout(self.vboxlayout2,0,0,1,1)
+
+        self.vboxlayout3 = QtGui.QVBoxLayout()
+        self.vboxlayout3.setObjectName("vboxlayout3")
+
+        self.label_3 = QtGui.QLabel(self.layoutWidget1)
+        self.label_3.setObjectName("label_3")
+        self.vboxlayout3.addWidget(self.label_3)
+
+        self.sourceAnnotEdit = QtGui.QTextEdit(self.layoutWidget1)
+        self.sourceAnnotEdit.setObjectName("sourceAnnotEdit")
+        self.vboxlayout3.addWidget(self.sourceAnnotEdit)
+        self.gridlayout.addLayout(self.vboxlayout3,0,1,1,1)
+
+        self.vboxlayout4 = QtGui.QVBoxLayout()
+        self.vboxlayout4.setObjectName("vboxlayout4")
+
+        self.label_4 = QtGui.QLabel(self.layoutWidget1)
+        self.label_4.setObjectName("label_4")
+        self.vboxlayout4.addWidget(self.label_4)
+
+        self.translEdit = QtGui.QTextEdit(self.layoutWidget1)
+        self.translEdit.setObjectName("translEdit")
+        self.vboxlayout4.addWidget(self.translEdit)
+        self.gridlayout.addLayout(self.vboxlayout4,1,0,1,1)
+
+        self.vboxlayout5 = QtGui.QVBoxLayout()
+        self.vboxlayout5.setObjectName("vboxlayout5")
+
+        self.label_5 = QtGui.QLabel(self.layoutWidget1)
+        self.label_5.setObjectName("label_5")
+        self.vboxlayout5.addWidget(self.label_5)
+
+        self.translAnnotEdit = QtGui.QTextEdit(self.layoutWidget1)
+        self.translAnnotEdit.setObjectName("translAnnotEdit")
+        self.vboxlayout5.addWidget(self.translAnnotEdit)
+        self.gridlayout.addLayout(self.vboxlayout5,1,1,1,1)
+        self.vboxlayout.addWidget(self.splitter)
+
+        self.retranslateUi(MsgForm)
+        QtCore.QMetaObject.connectSlotsByName(MsgForm)
+
+    def retranslateUi(self, MsgForm):
+        MsgForm.setWindowTitle(QtGui.QApplication.translate("MsgForm", "Form", None, QtGui.QApplication.UnicodeUTF8))
+        self.label.setText(QtGui.QApplication.translate("MsgForm", "Messages:", None, QtGui.QApplication.UnicodeUTF8))
+        self.treeWidget.headerItem().setText(0,QtGui.QApplication.translate("MsgForm", "1", None, QtGui.QApplication.UnicodeUTF8))
+        self.label_2.setText(QtGui.QApplication.translate("MsgForm", "Source string:", None, QtGui.QApplication.UnicodeUTF8))
+        self.label_3.setText(QtGui.QApplication.translate("MsgForm", "Source annotation:", None, QtGui.QApplication.UnicodeUTF8))
+        self.label_4.setText(QtGui.QApplication.translate("MsgForm", "Translation:", None, QtGui.QApplication.UnicodeUTF8))
+        self.label_5.setText(QtGui.QApplication.translate("MsgForm", "Translator\'s annotation:", None, QtGui.QApplication.UnicodeUTF8))
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/ui_new_project.py	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,76 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'new_project.ui'
+#
+# Created: Sun Oct 21 17:33:29 2007
+#      by: PyQt4 UI code generator 4.1
+#
+# WARNING! All changes made in this file will be lost!
+
+import sys
+from PyQt4 import QtCore, QtGui
+
+class Ui_NewProjectDialog(object):
+    def setupUi(self, NewProjectDialog):
+        NewProjectDialog.setObjectName("NewProjectDialog")
+        NewProjectDialog.resize(QtCore.QSize(QtCore.QRect(0,0,401,131).size()).expandedTo(NewProjectDialog.minimumSizeHint()))
+
+        self.vboxlayout = QtGui.QVBoxLayout(NewProjectDialog)
+        self.vboxlayout.setObjectName("vboxlayout")
+
+        self.gridlayout = QtGui.QGridLayout()
+        self.gridlayout.setObjectName("gridlayout")
+
+        self.gridlayout1 = QtGui.QGridLayout()
+        self.gridlayout1.setObjectName("gridlayout1")
+
+        self.label = QtGui.QLabel(NewProjectDialog)
+        self.label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
+        self.label.setObjectName("label")
+        self.gridlayout1.addWidget(self.label,0,0,1,1)
+
+        self.projectName = QtGui.QLineEdit(NewProjectDialog)
+        self.projectName.setObjectName("projectName")
+        self.gridlayout1.addWidget(self.projectName,0,1,1,1)
+
+        self.label_2 = QtGui.QLabel(NewProjectDialog)
+        self.label_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
+        self.label_2.setObjectName("label_2")
+        self.gridlayout1.addWidget(self.label_2,1,0,1,1)
+
+        self.hboxlayout = QtGui.QHBoxLayout()
+        self.hboxlayout.setObjectName("hboxlayout")
+
+        self.projectFilePath = QtGui.QLineEdit(NewProjectDialog)
+        self.projectFilePath.setObjectName("projectFilePath")
+        self.hboxlayout.addWidget(self.projectFilePath)
+
+        self.pickFileButton = QtGui.QToolButton(NewProjectDialog)
+        self.pickFileButton.setObjectName("pickFileButton")
+        self.hboxlayout.addWidget(self.pickFileButton)
+        self.gridlayout1.addLayout(self.hboxlayout,1,1,1,1)
+        self.gridlayout.addLayout(self.gridlayout1,0,0,1,1)
+
+        spacerItem = QtGui.QSpacerItem(20,40,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Expanding)
+        self.gridlayout.addItem(spacerItem,1,0,1,1)
+
+        self.buttonBox = QtGui.QDialogButtonBox(NewProjectDialog)
+        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
+        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Ok)
+        self.buttonBox.setObjectName("buttonBox")
+        self.gridlayout.addWidget(self.buttonBox,2,0,1,1)
+        self.vboxlayout.addLayout(self.gridlayout)
+        self.label.setBuddy(self.projectName)
+        self.label_2.setBuddy(self.projectFilePath)
+
+        self.retranslateUi(NewProjectDialog)
+        QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("accepted()"),NewProjectDialog.accept)
+        QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("rejected()"),NewProjectDialog.reject)
+        QtCore.QMetaObject.connectSlotsByName(NewProjectDialog)
+
+    def retranslateUi(self, NewProjectDialog):
+        NewProjectDialog.setWindowTitle(QtGui.QApplication.translate("NewProjectDialog", "Create New Project", None, QtGui.QApplication.UnicodeUTF8))
+        self.label.setText(QtGui.QApplication.translate("NewProjectDialog", "Project name:", None, QtGui.QApplication.UnicodeUTF8))
+        self.label_2.setText(QtGui.QApplication.translate("NewProjectDialog", "Project file:", None, QtGui.QApplication.UnicodeUTF8))
+        self.pickFileButton.setText(QtGui.QApplication.translate("NewProjectDialog", "...", None, QtGui.QApplication.UnicodeUTF8))
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/ui_project_properties.py	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,82 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'project_properties.ui'
+#
+# Created: Sat Nov 17 23:14:55 2007
+#      by: PyQt4 UI code generator 4.1
+#
+# WARNING! All changes made in this file will be lost!
+
+import sys
+from PyQt4 import QtCore, QtGui
+
+class Ui_ProjectPropertiesDialog(object):
+    def setupUi(self, ProjectPropertiesDialog):
+        ProjectPropertiesDialog.setObjectName("ProjectPropertiesDialog")
+        ProjectPropertiesDialog.resize(QtCore.QSize(QtCore.QRect(0,0,400,152).size()).expandedTo(ProjectPropertiesDialog.minimumSizeHint()))
+
+        self.vboxlayout = QtGui.QVBoxLayout(ProjectPropertiesDialog)
+        self.vboxlayout.setObjectName("vboxlayout")
+
+        self.gridlayout = QtGui.QGridLayout()
+        self.gridlayout.setObjectName("gridlayout")
+
+        self.label_2 = QtGui.QLabel(ProjectPropertiesDialog)
+        self.label_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
+        self.label_2.setObjectName("label_2")
+        self.gridlayout.addWidget(self.label_2,0,0,1,1)
+
+        self.projectNameField = QtGui.QLineEdit(ProjectPropertiesDialog)
+        self.projectNameField.setObjectName("projectNameField")
+        self.gridlayout.addWidget(self.projectNameField,0,1,1,1)
+
+        self.label = QtGui.QLabel(ProjectPropertiesDialog)
+        self.label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
+        self.label.setObjectName("label")
+        self.gridlayout.addWidget(self.label,1,0,1,1)
+
+        self.hboxlayout = QtGui.QHBoxLayout()
+        self.hboxlayout.setObjectName("hboxlayout")
+
+        self.buildScriptField = QtGui.QLineEdit(ProjectPropertiesDialog)
+        self.buildScriptField.setObjectName("buildScriptField")
+        self.hboxlayout.addWidget(self.buildScriptField)
+
+        self.pickFileButton = QtGui.QToolButton(ProjectPropertiesDialog)
+        self.pickFileButton.setObjectName("pickFileButton")
+        self.hboxlayout.addWidget(self.pickFileButton)
+        self.gridlayout.addLayout(self.hboxlayout,1,1,1,1)
+
+        self.creationDateField = QtGui.QLineEdit(ProjectPropertiesDialog)
+        self.creationDateField.setObjectName("creationDateField")
+        self.gridlayout.addWidget(self.creationDateField,2,1,1,1)
+
+        self.label_3 = QtGui.QLabel(ProjectPropertiesDialog)
+        self.label_3.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
+        self.label_3.setObjectName("label_3")
+        self.gridlayout.addWidget(self.label_3,2,0,1,1)
+        self.vboxlayout.addLayout(self.gridlayout)
+
+        spacerItem = QtGui.QSpacerItem(20,40,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Expanding)
+        self.vboxlayout.addItem(spacerItem)
+
+        self.buttonBox = QtGui.QDialogButtonBox(ProjectPropertiesDialog)
+        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
+        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Ok)
+        self.buttonBox.setObjectName("buttonBox")
+        self.vboxlayout.addWidget(self.buttonBox)
+        self.label_2.setBuddy(self.projectNameField)
+        self.label.setBuddy(self.buildScriptField)
+
+        self.retranslateUi(ProjectPropertiesDialog)
+        QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("accepted()"),ProjectPropertiesDialog.accept)
+        QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("rejected()"),ProjectPropertiesDialog.reject)
+        QtCore.QMetaObject.connectSlotsByName(ProjectPropertiesDialog)
+
+    def retranslateUi(self, ProjectPropertiesDialog):
+        ProjectPropertiesDialog.setWindowTitle(QtGui.QApplication.translate("ProjectPropertiesDialog", "Project Properties", None, QtGui.QApplication.UnicodeUTF8))
+        self.label_2.setText(QtGui.QApplication.translate("ProjectPropertiesDialog", "Project name:", None, QtGui.QApplication.UnicodeUTF8))
+        self.label.setText(QtGui.QApplication.translate("ProjectPropertiesDialog", "Build script:", None, QtGui.QApplication.UnicodeUTF8))
+        self.pickFileButton.setText(QtGui.QApplication.translate("ProjectPropertiesDialog", "...", None, QtGui.QApplication.UnicodeUTF8))
+        self.label_3.setText(QtGui.QApplication.translate("ProjectPropertiesDialog", "Creation date:", None, QtGui.QApplication.UnicodeUTF8))
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translator/ui_translator.py	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,133 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'translator.ui'
+#
+# Created: Fri Nov  9 20:02:57 2007
+#      by: PyQt4 UI code generator 4.1
+#
+# WARNING! All changes made in this file will be lost!
+
+import sys
+from PyQt4 import QtCore, QtGui
+
+class Ui_MainWindow(object):
+    def setupUi(self, MainWindow):
+        MainWindow.setObjectName("MainWindow")
+        MainWindow.resize(QtCore.QSize(QtCore.QRect(0,0,608,464).size()).expandedTo(MainWindow.minimumSizeHint()))
+
+        self.centralwidget = QtGui.QWidget(MainWindow)
+        self.centralwidget.setObjectName("centralwidget")
+
+        self.vboxlayout = QtGui.QVBoxLayout(self.centralwidget)
+        self.vboxlayout.setObjectName("vboxlayout")
+        MainWindow.setCentralWidget(self.centralwidget)
+
+        self.menubar = QtGui.QMenuBar(MainWindow)
+        self.menubar.setGeometry(QtCore.QRect(0,0,608,29))
+        self.menubar.setObjectName("menubar")
+
+        self.menu_File = QtGui.QMenu(self.menubar)
+        self.menu_File.setObjectName("menu_File")
+
+        self.menu_Help = QtGui.QMenu(self.menubar)
+        self.menu_Help.setObjectName("menu_Help")
+
+        self.menu_Project = QtGui.QMenu(self.menubar)
+        self.menu_Project.setObjectName("menu_Project")
+        MainWindow.setMenuBar(self.menubar)
+
+        self.statusbar = QtGui.QStatusBar(MainWindow)
+        self.statusbar.setObjectName("statusbar")
+        MainWindow.setStatusBar(self.statusbar)
+
+        self.action_Quit = QtGui.QAction(MainWindow)
+        self.action_Quit.setObjectName("action_Quit")
+
+        self.action_About = QtGui.QAction(MainWindow)
+        self.action_About.setObjectName("action_About")
+
+        self.action_New_Project = QtGui.QAction(MainWindow)
+        self.action_New_Project.setObjectName("action_New_Project")
+
+        self.action_Add_Catalogue = QtGui.QAction(MainWindow)
+        self.action_Add_Catalogue.setObjectName("action_Add_Catalogue")
+
+        self.action_Properties = QtGui.QAction(MainWindow)
+        self.action_Properties.setObjectName("action_Properties")
+
+        self.action_Build_Project = QtGui.QAction(MainWindow)
+        self.action_Build_Project.setObjectName("action_Build_Project")
+
+        self.action_Open_Project = QtGui.QAction(MainWindow)
+        self.action_Open_Project.setObjectName("action_Open_Project")
+
+        self.action_Close = QtGui.QAction(MainWindow)
+        self.action_Close.setObjectName("action_Close")
+
+        self.action_Add_New_Catalogue = QtGui.QAction(MainWindow)
+        self.action_Add_New_Catalogue.setObjectName("action_Add_New_Catalogue")
+
+        self.action_Close_Project = QtGui.QAction(MainWindow)
+        self.action_Close_Project.setObjectName("action_Close_Project")
+
+        self.action_Save = QtGui.QAction(MainWindow)
+        self.action_Save.setObjectName("action_Save")
+
+        self.action_Save_All = QtGui.QAction(MainWindow)
+        self.action_Save_All.setObjectName("action_Save_All")
+
+        self.action_Close_All = QtGui.QAction(MainWindow)
+        self.action_Close_All.setObjectName("action_Close_All")
+        self.menu_File.addAction(self.action_Open_Project)
+        self.menu_File.addAction(self.action_New_Project)
+        self.menu_File.addSeparator()
+        self.menu_File.addAction(self.action_Save)
+        self.menu_File.addAction(self.action_Save_All)
+        self.menu_File.addSeparator()
+        self.menu_File.addAction(self.action_Close)
+        self.menu_File.addAction(self.action_Close_All)
+        self.menu_File.addSeparator()
+        self.menu_File.addAction(self.action_Quit)
+        self.menu_Help.addAction(self.action_About)
+        self.menu_Project.addAction(self.action_Add_Catalogue)
+        self.menu_Project.addAction(self.action_Add_New_Catalogue)
+        self.menu_Project.addAction(self.action_Build_Project)
+        self.menu_Project.addSeparator()
+        self.menu_Project.addAction(self.action_Properties)
+        self.menu_Project.addSeparator()
+        self.menu_Project.addAction(self.action_Close_Project)
+        self.menubar.addAction(self.menu_File.menuAction())
+        self.menubar.addAction(self.menu_Project.menuAction())
+        self.menubar.addAction(self.menu_Help.menuAction())
+
+        self.retranslateUi(MainWindow)
+        QtCore.QObject.connect(self.action_Quit,QtCore.SIGNAL("triggered()"),MainWindow.close)
+        QtCore.QMetaObject.connectSlotsByName(MainWindow)
+
+    def retranslateUi(self, MainWindow):
+        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "Translator", None, QtGui.QApplication.UnicodeUTF8))
+        self.menu_File.setTitle(QtGui.QApplication.translate("MainWindow", "&File", None, QtGui.QApplication.UnicodeUTF8))
+        self.menu_Help.setTitle(QtGui.QApplication.translate("MainWindow", "&Help", None, QtGui.QApplication.UnicodeUTF8))
+        self.menu_Project.setTitle(QtGui.QApplication.translate("MainWindow", "&Project", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_Quit.setText(QtGui.QApplication.translate("MainWindow", "&Quit", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_Quit.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+Q", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_About.setText(QtGui.QApplication.translate("MainWindow", "&About", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_New_Project.setText(QtGui.QApplication.translate("MainWindow", "&New Project...", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_New_Project.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+N", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_Add_Catalogue.setText(QtGui.QApplication.translate("MainWindow", "&Add catalogue...", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_Properties.setText(QtGui.QApplication.translate("MainWindow", "&Properties", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_Build_Project.setText(QtGui.QApplication.translate("MainWindow", "&Build Project", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_Open_Project.setText(QtGui.QApplication.translate("MainWindow", "&Open Project...", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_Open_Project.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+O", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_Close.setText(QtGui.QApplication.translate("MainWindow", "&Close", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_Close.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+W", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_Add_New_Catalogue.setText(QtGui.QApplication.translate("MainWindow", "Add new catalogue...", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_Close_Project.setText(QtGui.QApplication.translate("MainWindow", "&Close Project", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_Close_Project.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+F4", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_Save.setText(QtGui.QApplication.translate("MainWindow", "&Save", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_Save.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+S", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_Save_All.setText(QtGui.QApplication.translate("MainWindow", "Save &All", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_Save_All.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+Shift+S", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_Close_All.setText(QtGui.QApplication.translate("MainWindow", "Clos&e All", None, QtGui.QApplication.UnicodeUTF8))
+        self.action_Close_All.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+Shift+W", None, QtGui.QApplication.UnicodeUTF8))
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/util/uni.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,632 @@
+
+// Written in the D programming language.
+
+/*
+ * Placed into the Public Domain.
+ * Digital Mars, www.digitalmars.com
+ * Written by Walter Bright
+ */
+
+/**
+ * Simple Unicode character classification functions.
+ * For ASCII classification, see $(LINK2 std_ctype.html, std.ctype).
+ * Macros:
+ *	WIKI=Phobos/StdUni
+ * References:
+ *	$(LINK2 http://www.digitalmars.com/d/ascii-table.html, ASCII Table),
+ *	$(LINK2 http://en.wikipedia.org/wiki/Unicode, Wikipedia),
+ *	$(LINK2 http://www.unicode.org, The Unicode Consortium)
+ * Trademarks:
+ *	Unicode(tm) is a trademark of Unicode, Inc.
+ * Copyright:
+ *	Public Domain.
+ */
+
+
+module util.uni;
+
+/**
+ * Returns !=0 if c is a Unicode lower case character.
+ */
+int isUniLower(dchar c)
+{
+    if (c <= 0x7F)
+	return (c >= 'a' && c <= 'z');
+
+    return isUniAlpha(c) && c == toUniLower(c);
+}
+
+/**
+ * Returns !=0 if c is a Unicode upper case character.
+ */
+int isUniUpper(dchar c)
+{
+    if (c <= 0x7F)
+	return (c >= 'A' && c <= 'Z');
+
+    return isUniAlpha(c) && c == toUniUpper(c);
+}
+
+/**
+ * If c is a Unicode upper case character, return the lower case
+ * equivalent, otherwise return c.
+ */
+dchar toUniLower(dchar c)
+{
+    if (c >= 'A' && c <= 'Z')
+    {
+        c += 32;
+    }
+    else if (c >= 0x00C0)
+    {
+	if ((c >= 0x00C0 && c <= 0x00D6) || (c >= 0x00D8 && c<=0x00DE))
+	{
+	    c += 32;
+	}
+	else if ((c >= 0x0100 && c < 0x0138) || (c > 0x0149 && c < 0x0178))
+	{
+	    if (c == 0x0130)
+		c = 0x0069;
+	    else if ((c & 1) == 0)
+		c += 1;
+	}
+	else if (c == 0x0178)
+	{
+	    c = 0x00FF;
+	}
+	else if ((c >= 0x0139 && c < 0x0149) || (c > 0x0178 && c < 0x017F))
+	{
+	    if (c & 1)
+		c += 1;
+	}
+	else if (c >= 0x0200 && c <= 0x0217)
+	{
+	    if ((c & 1) == 0)
+		c += 1;
+	}
+	else if ((c >= 0x0401 && c <= 0x040C) || (c>= 0x040E && c <= 0x040F))
+	{
+	    c += 80;
+	}
+	else if (c >= 0x0410  && c <= 0x042F)
+	{
+	    c += 32;
+	}
+	else if (c >= 0x0460 && c <= 0x047F)
+	{
+	    if ((c & 1) == 0)
+		c += 1;
+	}
+	else if (c >= 0x0531 && c <= 0x0556)
+	{
+	    c += 48;
+	}
+	else if (c >= 0x10A0 && c <= 0x10C5)
+	{
+	    c += 48;
+	}
+	else if (c >= 0xFF21 && c <= 0xFF3A)
+	{
+	    c += 32;
+	}
+    }
+    return c;
+}
+
+/**
+ * If c is a Unicode lower case character, return the upper case
+ * equivalent, otherwise return c.
+ */
+dchar toUniUpper(dchar c)
+{
+    if (c >= 'a' && c <= 'z')
+    {
+	c -= 32;
+    }
+    else if (c >= 0x00E0)
+    {
+	if ((c >= 0x00E0 && c <= 0x00F6) || (c >= 0x00F8 && c <= 0x00FE))
+	{
+	    c -= 32;
+	}
+	else if (c == 0x00FF)
+	{
+	    c = 0x0178;
+	}
+	else if ((c >= 0x0100 && c < 0x0138) || (c > 0x0149 && c < 0x0178))
+	{
+	    if (c == 0x0131)
+		c = 0x0049;
+	    else if (c & 1)
+		c -= 1;
+	}
+	else if ((c >= 0x0139 && c < 0x0149) || (c > 0x0178 && c < 0x017F))
+	{
+	    if ((c & 1) == 0)
+		c = c-1;
+	}
+	else if (c == 0x017F)
+	{
+	    c = 0x0053;
+	}
+	else if (c >= 0x0200 && c <= 0x0217)
+	{
+	    if (c & 1)
+		c = c-1;
+	}
+	else if (c >= 0x0430 && c<= 0x044F)
+	{
+	    c -= 32;
+	}
+	else if ((c >= 0x0451 && c <= 0x045C) || (c >=0x045E && c<= 0x045F))
+	{
+	    c -= 80;
+	}
+	else if (c >= 0x0460 && c <= 0x047F)
+	{
+	    if (c & 1)
+		c -= 1;
+	}
+	else if (c >= 0x0561 && c < 0x0587)
+	{
+	    c -= 48;
+	}
+	else if (c >= 0xFF41 && c <= 0xFF5A)
+	{
+	    c -= 32;
+	}
+    }
+    return c;
+}
+
+
+/*******************************
+ * Return !=0 if u is a Unicode alpha character.
+ * (general Unicode category: Lu, Ll, Lt, Lm and Lo)
+ *
+ * Standards: Unicode 5.0.0
+ */
+
+int isUniAlpha(dchar u)
+{
+    static dchar table[][2] =
+    [
+	[ 'A', 'Z' ],
+	[ 'a', 'z' ],
+	[ 0x00AA, 0x00AA ],
+	[ 0x00B5, 0x00B5 ],
+	[ 0x00BA, 0x00BA ],
+	[ 0x00C0, 0x00D6 ],
+	[ 0x00D8, 0x00F6 ],
+	[ 0x00F8, 0x02C1 ],
+	[ 0x02C6, 0x02D1 ],
+	[ 0x02E0, 0x02E4 ],
+	[ 0x02EE, 0x02EE ],
+	[ 0x037A, 0x037D ],
+	[ 0x0386, 0x0386 ],
+	[ 0x0388, 0x038A ],
+	[ 0x038C, 0x038C ],
+	[ 0x038E, 0x03A1 ],
+	[ 0x03A3, 0x03CE ],
+	[ 0x03D0, 0x03F5 ],
+	[ 0x03F7, 0x0481 ],
+	[ 0x048A, 0x0513 ],
+	[ 0x0531, 0x0556 ],
+	[ 0x0559, 0x0559 ],
+	[ 0x0561, 0x0587 ],
+	[ 0x05D0, 0x05EA ],
+	[ 0x05F0, 0x05F2 ],
+	[ 0x0621, 0x063A ],
+	[ 0x0640, 0x064A ],
+	[ 0x066E, 0x066F ],
+	[ 0x0671, 0x06D3 ],
+	[ 0x06D5, 0x06D5 ],
+	[ 0x06E5, 0x06E6 ],
+	[ 0x06EE, 0x06EF ],
+	[ 0x06FA, 0x06FC ],
+	[ 0x06FF, 0x06FF ],
+	[ 0x0710, 0x0710 ],
+	[ 0x0712, 0x072F ],
+	[ 0x074D, 0x076D ],
+	[ 0x0780, 0x07A5 ],
+	[ 0x07B1, 0x07B1 ],
+	[ 0x07CA, 0x07EA ],
+	[ 0x07F4, 0x07F5 ],
+	[ 0x07FA, 0x07FA ],
+	[ 0x0904, 0x0939 ],
+	[ 0x093D, 0x093D ],
+	[ 0x0950, 0x0950 ],
+	[ 0x0958, 0x0961 ],
+	[ 0x097B, 0x097F ],
+	[ 0x0985, 0x098C ],
+	[ 0x098F, 0x0990 ],
+	[ 0x0993, 0x09A8 ],
+	[ 0x09AA, 0x09B0 ],
+	[ 0x09B2, 0x09B2 ],
+	[ 0x09B6, 0x09B9 ],
+	[ 0x09BD, 0x09BD ],
+	[ 0x09CE, 0x09CE ],
+	[ 0x09DC, 0x09DD ],
+	[ 0x09DF, 0x09E1 ],
+	[ 0x09F0, 0x09F1 ],
+	[ 0x0A05, 0x0A0A ],
+	[ 0x0A0F, 0x0A10 ],
+	[ 0x0A13, 0x0A28 ],
+	[ 0x0A2A, 0x0A30 ],
+	[ 0x0A32, 0x0A33 ],
+	[ 0x0A35, 0x0A36 ],
+	[ 0x0A38, 0x0A39 ],
+	[ 0x0A59, 0x0A5C ],
+	[ 0x0A5E, 0x0A5E ],
+	[ 0x0A72, 0x0A74 ],
+	[ 0x0A85, 0x0A8D ],
+	[ 0x0A8F, 0x0A91 ],
+	[ 0x0A93, 0x0AA8 ],
+	[ 0x0AAA, 0x0AB0 ],
+	[ 0x0AB2, 0x0AB3 ],
+	[ 0x0AB5, 0x0AB9 ],
+	[ 0x0ABD, 0x0ABD ],
+	[ 0x0AD0, 0x0AD0 ],
+	[ 0x0AE0, 0x0AE1 ],
+	[ 0x0B05, 0x0B0C ],
+	[ 0x0B0F, 0x0B10 ],
+	[ 0x0B13, 0x0B28 ],
+	[ 0x0B2A, 0x0B30 ],
+	[ 0x0B32, 0x0B33 ],
+	[ 0x0B35, 0x0B39 ],
+	[ 0x0B3D, 0x0B3D ],
+	[ 0x0B5C, 0x0B5D ],
+	[ 0x0B5F, 0x0B61 ],
+	[ 0x0B71, 0x0B71 ],
+	[ 0x0B83, 0x0B83 ],
+	[ 0x0B85, 0x0B8A ],
+	[ 0x0B8E, 0x0B90 ],
+	[ 0x0B92, 0x0B95 ],
+	[ 0x0B99, 0x0B9A ],
+	[ 0x0B9C, 0x0B9C ],
+	[ 0x0B9E, 0x0B9F ],
+	[ 0x0BA3, 0x0BA4 ],
+	[ 0x0BA8, 0x0BAA ],
+	[ 0x0BAE, 0x0BB9 ],
+	[ 0x0C05, 0x0C0C ],
+	[ 0x0C0E, 0x0C10 ],
+	[ 0x0C12, 0x0C28 ],
+	[ 0x0C2A, 0x0C33 ],
+	[ 0x0C35, 0x0C39 ],
+	[ 0x0C60, 0x0C61 ],
+	[ 0x0C85, 0x0C8C ],
+	[ 0x0C8E, 0x0C90 ],
+	[ 0x0C92, 0x0CA8 ],
+	[ 0x0CAA, 0x0CB3 ],
+	[ 0x0CB5, 0x0CB9 ],
+	[ 0x0CBD, 0x0CBD ],
+	[ 0x0CDE, 0x0CDE ],
+	[ 0x0CE0, 0x0CE1 ],
+	[ 0x0D05, 0x0D0C ],
+	[ 0x0D0E, 0x0D10 ],
+	[ 0x0D12, 0x0D28 ],
+	[ 0x0D2A, 0x0D39 ],
+	[ 0x0D60, 0x0D61 ],
+	[ 0x0D85, 0x0D96 ],
+	[ 0x0D9A, 0x0DB1 ],
+	[ 0x0DB3, 0x0DBB ],
+	[ 0x0DBD, 0x0DBD ],
+	[ 0x0DC0, 0x0DC6 ],
+	[ 0x0E01, 0x0E30 ],
+	[ 0x0E32, 0x0E33 ],
+	[ 0x0E40, 0x0E46 ],
+	[ 0x0E81, 0x0E82 ],
+	[ 0x0E84, 0x0E84 ],
+	[ 0x0E87, 0x0E88 ],
+	[ 0x0E8A, 0x0E8A ],
+	[ 0x0E8D, 0x0E8D ],
+	[ 0x0E94, 0x0E97 ],
+	[ 0x0E99, 0x0E9F ],
+	[ 0x0EA1, 0x0EA3 ],
+	[ 0x0EA5, 0x0EA5 ],
+	[ 0x0EA7, 0x0EA7 ],
+	[ 0x0EAA, 0x0EAB ],
+	[ 0x0EAD, 0x0EB0 ],
+	[ 0x0EB2, 0x0EB3 ],
+	[ 0x0EBD, 0x0EBD ],
+	[ 0x0EC0, 0x0EC4 ],
+	[ 0x0EC6, 0x0EC6 ],
+	[ 0x0EDC, 0x0EDD ],
+	[ 0x0F00, 0x0F00 ],
+	[ 0x0F40, 0x0F47 ],
+	[ 0x0F49, 0x0F6A ],
+	[ 0x0F88, 0x0F8B ],
+	[ 0x1000, 0x1021 ],
+	[ 0x1023, 0x1027 ],
+	[ 0x1029, 0x102A ],
+	[ 0x1050, 0x1055 ],
+	[ 0x10A0, 0x10C5 ],
+	[ 0x10D0, 0x10FA ],
+	[ 0x10FC, 0x10FC ],
+	[ 0x1100, 0x1159 ],
+	[ 0x115F, 0x11A2 ],
+	[ 0x11A8, 0x11F9 ],
+	[ 0x1200, 0x1248 ],
+	[ 0x124A, 0x124D ],
+	[ 0x1250, 0x1256 ],
+	[ 0x1258, 0x1258 ],
+	[ 0x125A, 0x125D ],
+	[ 0x1260, 0x1288 ],
+	[ 0x128A, 0x128D ],
+	[ 0x1290, 0x12B0 ],
+	[ 0x12B2, 0x12B5 ],
+	[ 0x12B8, 0x12BE ],
+	[ 0x12C0, 0x12C0 ],
+	[ 0x12C2, 0x12C5 ],
+	[ 0x12C8, 0x12D6 ],
+	[ 0x12D8, 0x1310 ],
+	[ 0x1312, 0x1315 ],
+	[ 0x1318, 0x135A ],
+	[ 0x1380, 0x138F ],
+	[ 0x13A0, 0x13F4 ],
+	[ 0x1401, 0x166C ],
+	[ 0x166F, 0x1676 ],
+	[ 0x1681, 0x169A ],
+	[ 0x16A0, 0x16EA ],
+	[ 0x1700, 0x170C ],
+	[ 0x170E, 0x1711 ],
+	[ 0x1720, 0x1731 ],
+	[ 0x1740, 0x1751 ],
+	[ 0x1760, 0x176C ],
+	[ 0x176E, 0x1770 ],
+	[ 0x1780, 0x17B3 ],
+	[ 0x17D7, 0x17D7 ],
+	[ 0x17DC, 0x17DC ],
+	[ 0x1820, 0x1877 ],
+	[ 0x1880, 0x18A8 ],
+	[ 0x1900, 0x191C ],
+	[ 0x1950, 0x196D ],
+	[ 0x1970, 0x1974 ],
+	[ 0x1980, 0x19A9 ],
+	[ 0x19C1, 0x19C7 ],
+	[ 0x1A00, 0x1A16 ],
+	[ 0x1B05, 0x1B33 ],
+	[ 0x1B45, 0x1B4B ],
+	[ 0x1D00, 0x1DBF ],
+	[ 0x1E00, 0x1E9B ],
+	[ 0x1EA0, 0x1EF9 ],
+	[ 0x1F00, 0x1F15 ],
+	[ 0x1F18, 0x1F1D ],
+	[ 0x1F20, 0x1F45 ],
+	[ 0x1F48, 0x1F4D ],
+	[ 0x1F50, 0x1F57 ],
+	[ 0x1F59, 0x1F59 ],
+	[ 0x1F5B, 0x1F5B ],
+	[ 0x1F5D, 0x1F5D ],
+	[ 0x1F5F, 0x1F7D ],
+	[ 0x1F80, 0x1FB4 ],
+	[ 0x1FB6, 0x1FBC ],
+	[ 0x1FBE, 0x1FBE ],
+	[ 0x1FC2, 0x1FC4 ],
+	[ 0x1FC6, 0x1FCC ],
+	[ 0x1FD0, 0x1FD3 ],
+	[ 0x1FD6, 0x1FDB ],
+	[ 0x1FE0, 0x1FEC ],
+	[ 0x1FF2, 0x1FF4 ],
+	[ 0x1FF6, 0x1FFC ],
+	[ 0x2071, 0x2071 ],
+	[ 0x207F, 0x207F ],
+	[ 0x2090, 0x2094 ],
+	[ 0x2102, 0x2102 ],
+	[ 0x2107, 0x2107 ],
+	[ 0x210A, 0x2113 ],
+	[ 0x2115, 0x2115 ],
+	[ 0x2119, 0x211D ],
+	[ 0x2124, 0x2124 ],
+	[ 0x2126, 0x2126 ],
+	[ 0x2128, 0x2128 ],
+	[ 0x212A, 0x212D ],
+	[ 0x212F, 0x2139 ],
+	[ 0x213C, 0x213F ],
+	[ 0x2145, 0x2149 ],
+	[ 0x214E, 0x214E ],
+	[ 0x2183, 0x2184 ],
+	[ 0x2C00, 0x2C2E ],
+	[ 0x2C30, 0x2C5E ],
+	[ 0x2C60, 0x2C6C ],
+	[ 0x2C74, 0x2C77 ],
+	[ 0x2C80, 0x2CE4 ],
+	[ 0x2D00, 0x2D25 ],
+	[ 0x2D30, 0x2D65 ],
+	[ 0x2D6F, 0x2D6F ],
+	[ 0x2D80, 0x2D96 ],
+	[ 0x2DA0, 0x2DA6 ],
+	[ 0x2DA8, 0x2DAE ],
+	[ 0x2DB0, 0x2DB6 ],
+	[ 0x2DB8, 0x2DBE ],
+	[ 0x2DC0, 0x2DC6 ],
+	[ 0x2DC8, 0x2DCE ],
+	[ 0x2DD0, 0x2DD6 ],
+	[ 0x2DD8, 0x2DDE ],
+	[ 0x3005, 0x3006 ],
+	[ 0x3031, 0x3035 ],
+	[ 0x303B, 0x303C ],
+	[ 0x3041, 0x3096 ],
+	[ 0x309D, 0x309F ],
+	[ 0x30A1, 0x30FA ],
+	[ 0x30FC, 0x30FF ],
+	[ 0x3105, 0x312C ],
+	[ 0x3131, 0x318E ],
+	[ 0x31A0, 0x31B7 ],
+	[ 0x31F0, 0x31FF ],
+	[ 0x3400, 0x4DB5 ],
+	[ 0x4E00, 0x9FBB ],
+	[ 0xA000, 0xA48C ],
+	[ 0xA717, 0xA71A ],
+	[ 0xA800, 0xA801 ],
+	[ 0xA803, 0xA805 ],
+	[ 0xA807, 0xA80A ],
+	[ 0xA80C, 0xA822 ],
+	[ 0xA840, 0xA873 ],
+	[ 0xAC00, 0xD7A3 ],
+	[ 0xF900, 0xFA2D ],
+	[ 0xFA30, 0xFA6A ],
+	[ 0xFA70, 0xFAD9 ],
+	[ 0xFB00, 0xFB06 ],
+	[ 0xFB13, 0xFB17 ],
+	[ 0xFB1D, 0xFB1D ],
+	[ 0xFB1F, 0xFB28 ],
+	[ 0xFB2A, 0xFB36 ],
+	[ 0xFB38, 0xFB3C ],
+	[ 0xFB3E, 0xFB3E ],
+	[ 0xFB40, 0xFB41 ],
+	[ 0xFB43, 0xFB44 ],
+	[ 0xFB46, 0xFBB1 ],
+	[ 0xFBD3, 0xFD3D ],
+	[ 0xFD50, 0xFD8F ],
+	[ 0xFD92, 0xFDC7 ],
+	[ 0xFDF0, 0xFDFB ],
+	[ 0xFE70, 0xFE74 ],
+	[ 0xFE76, 0xFEFC ],
+	[ 0xFF21, 0xFF3A ],
+	[ 0xFF41, 0xFF5A ],
+	[ 0xFF66, 0xFFBE ],
+	[ 0xFFC2, 0xFFC7 ],
+	[ 0xFFCA, 0xFFCF ],
+	[ 0xFFD2, 0xFFD7 ],
+	[ 0xFFDA, 0xFFDC ],
+	[ 0x10000, 0x1000B ],
+	[ 0x1000D, 0x10026 ],
+	[ 0x10028, 0x1003A ],
+	[ 0x1003C, 0x1003D ],
+	[ 0x1003F, 0x1004D ],
+	[ 0x10050, 0x1005D ],
+	[ 0x10080, 0x100FA ],
+	[ 0x10300, 0x1031E ],
+	[ 0x10330, 0x10340 ],
+	[ 0x10342, 0x10349 ],
+	[ 0x10380, 0x1039D ],
+	[ 0x103A0, 0x103C3 ],
+	[ 0x103C8, 0x103CF ],
+	[ 0x10400, 0x1049D ],
+	[ 0x10800, 0x10805 ],
+	[ 0x10808, 0x10808 ],
+	[ 0x1080A, 0x10835 ],
+	[ 0x10837, 0x10838 ],
+	[ 0x1083C, 0x1083C ],
+	[ 0x1083F, 0x1083F ],
+	[ 0x10900, 0x10915 ],
+	[ 0x10A00, 0x10A00 ],
+	[ 0x10A10, 0x10A13 ],
+	[ 0x10A15, 0x10A17 ],
+	[ 0x10A19, 0x10A33 ],
+	[ 0x12000, 0x1236E ],
+	[ 0x1D400, 0x1D454 ],
+	[ 0x1D456, 0x1D49C ],
+	[ 0x1D49E, 0x1D49F ],
+	[ 0x1D4A2, 0x1D4A2 ],
+	[ 0x1D4A5, 0x1D4A6 ],
+	[ 0x1D4A9, 0x1D4AC ],
+	[ 0x1D4AE, 0x1D4B9 ],
+	[ 0x1D4BB, 0x1D4BB ],
+	[ 0x1D4BD, 0x1D4C3 ],
+	[ 0x1D4C5, 0x1D505 ],
+	[ 0x1D507, 0x1D50A ],
+	[ 0x1D50D, 0x1D514 ],
+	[ 0x1D516, 0x1D51C ],
+	[ 0x1D51E, 0x1D539 ],
+	[ 0x1D53B, 0x1D53E ],
+	[ 0x1D540, 0x1D544 ],
+	[ 0x1D546, 0x1D546 ],
+	[ 0x1D54A, 0x1D550 ],
+	[ 0x1D552, 0x1D6A5 ],
+	[ 0x1D6A8, 0x1D6C0 ],
+	[ 0x1D6C2, 0x1D6DA ],
+	[ 0x1D6DC, 0x1D6FA ],
+	[ 0x1D6FC, 0x1D714 ],
+	[ 0x1D716, 0x1D734 ],
+	[ 0x1D736, 0x1D74E ],
+	[ 0x1D750, 0x1D76E ],
+	[ 0x1D770, 0x1D788 ],
+	[ 0x1D78A, 0x1D7A8 ],
+	[ 0x1D7AA, 0x1D7C2 ],
+	[ 0x1D7C4, 0x1D7CB ],
+	[ 0x20000, 0x2A6D6 ],
+	[ 0x2F800, 0x2FA1D ],
+    ];
+
+    debug
+    {
+	for (int i = 0; i < table.length; i++)
+	{
+	    assert(table[i][0] <= table[i][1]);
+	    if (i < table.length - 1)
+	    {
+//		if (table[i][1] >= table[i + 1][0])
+//		    printf("table[%d][1] = x%x, table[%d][0] = x%x\n", i, table[i][1], i + 1, table[i + 1][0]);
+		assert(table[i][1] < table[i + 1][0]);
+	    }
+	}
+    }
+
+    if (u < 0xAA)
+    {
+	if (u < 'A')
+	    goto Lisnot;
+	if (u <= 'Z')
+	    goto Lis;
+	if (u < 'a')
+	    goto Lisnot;
+	if (u <= 'z')
+	    goto Lis;
+	goto Lisnot;
+    }
+
+    // Binary search
+    uint mid;
+    uint low;
+    uint high;
+
+    low = 0;
+    high = table.length - 1;
+    while (cast(int)low <= cast(int)high)
+    {
+	mid = (low + high) >> 1;
+	if (u < table[mid][0])
+	    high = mid - 1;
+	else if (u > table[mid][1])
+	    low = mid + 1;
+	else
+	    goto Lis;
+    }
+
+Lisnot:
+    debug
+    {
+	for (int i = 0; i < table.length; i++)
+	{
+	    assert(u < table[i][0] || u > table[i][1]);
+	}
+    }
+    return 0;
+
+Lis:
+    debug
+    {
+	for (int i = 0; i < table.length; i++)
+	{
+	    if (u >= table[i][0] && u <= table[i][1])
+		return 1;
+	}
+	assert(0);		// should have been in table
+    }
+    return 1;
+}
+
+unittest
+{
+    for (uint i = 0; i < 0x80; i++)
+    {
+	if (i >= 'A' && i <= 'Z')
+	    assert(isUniAlpha(i));
+	else if (i >= 'a' && i <= 'z')
+	    assert(isUniAlpha(i));
+	else
+	    assert(!isUniAlpha(i));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/xml.css	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,71 @@
+@charset "utf-8";
+compilerinfo, sourcecode, linescolumn {
+  white-space: pre;
+  font-family: Monospace;
+  font-size: 0.8em;
+}
+compilerinfo, sourcecode {
+  display: block;
+}
+compilerinfo {
+  white-space: normal;
+  border: 1px solid #A22;
+  padding: 0.5em;
+  margin: 1em;
+}
+compilerinfo error { display: block; }
+linescolumn {
+  display: block;
+  float: left;
+  text-align: right;
+  margin-right: 0.2em;
+  border-right: 1px solid gray;
+}
+linescolumn a { display: block; color: #555; }
+/* Number */
+n { color: teal; }
+/* Keyword */
+k { color: darkblue; font-weight: bold; }
+/* Line, block and nested comments */
+lc, bc, nc { color: green; }
+/* Identifier */
+i { color: black; }
+/* String literal */
+sl { color: red; }
+/* Character literal */
+cl { color: purple; }
+/* All bracket types */
+br { color: orange; }
+/* Special tokens */
+st { color: green; font-weight: bold; }
+/* #line, hash line */
+hl { color: green; }
+/* filespec (e.g. #line number [filespec]) */
+fs { color: purple;}
+/* When the first line starts with #! it's a "shebang" */
+shebang { color: gray; }
+/* Deprecated styles. */
+/* Operator */
+/*op { color: royalblue; }*/
+/* Particular operators */
+/*op[t=aa] { content: "and"; }*/ /*&& ∧*/
+/*op[t=oo] { content: "or"; }*/ /*|| ∨*/
+/*op[t=n] { content: "¬"; }*/ /*!*/
+/*op[t=ne] { content: "≠"; }*/ /*!=*/
+/*op[t=le] { content: "≤"; }*/ /*<=*/
+/*op[t=ge] { content: "≥"; }*/ /*>=*/
+/*op[t=lg] { content: "≶"; }*/ /*<>*/
+/*
+d = Declaration
+s = Statement
+e = Expression
+t = Type
+o = Other
+*/
+/* d { background-color: #FFDDDD; } */
+/* e { background-color: #DDDDFF; } */
+d[t=Illegal], s[t=Illegal] { background-color: #DD4422; }
+d[t=Module] i, d[t=Import] i { color: blue; }
+t > i { color: #911; }
+t > br, t > op { color: #911; }
+t[t=Integral] k { color: #911; font-weight: normal; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/xml_map.d	Sun Mar 09 00:12:19 2008 +0100
@@ -0,0 +1,107 @@
+/// A map of document elements and D tokens to format strings.
+string[string] map = [
+  "DocHead" : `<?xml version="1.0"?>`\n
+              `<?xml-stylesheet href="xml.css" type="text/css"?>`\n
+              "<root>\n",
+  "DocEnd"  : "\n</root>",
+  "SourceBegin" : "<sourcecode>",
+  "SourceEnd"   : "\n</sourcecode>",
+  "CompBegin"   : "<compiler>\n",
+  "CompEnd"     : "</compiler>\n",
+  "LexerError"  : `<error t="L">{0}({1},{2})L: {3}</error>`\n,
+  "ParserError" : `<error t="P">{0}({1},{2})P: {3}</error>`\n,
+  "LineNumberBegin" : `<linescolumn>`,
+  "LineNumberEnd"   : `</linescolumn>`,
+  "LineNumber"      : `<a xml:id="L{0}">{0}</a>`,
+
+  // Node categories:
+  "Declaration" : "d",
+  "Statement"   : "s",
+  "Expression"  : "e",
+  "Type"        : "t",
+  "Other"       : "o",
+
+  // {0} = node category.
+  // {1} = node class name: "Call", "If", "Class" etc.
+  // E.g.: <d t="Struct">...</d>
+  "NodeBegin" : `<{0} t="{1}">`,
+  "NodeEnd"   : `</{0}>`,
+
+  "Identifier" : "<i>{0}</i>",
+  "String"     : "<sl>{0}</sl>",
+  "Char"       : "<cl>{0}</cl>",
+  "Number"     : "<n>{0}</n>",
+  "Keyword"    : "<k>{0}</k>",
+
+  "LineC"   : "<lc>{0}</lc>",
+  "BlockC"  : "<bc>{0}</bc>",
+  "NestedC" : "<nc>{0}</nc>",
+
+  "Shebang"  : "<shebang>{0}</shebang>",
+  "HLine"    : "<hl>{0}</hl>", // #line
+  "Filespec" : "<fs>{0}</fs>", // #line N "filespec"
+  "Newline"  : "{0}", // \n | \r | \r\n | LS | PS
+  "Illegal"  : "<ill>{0}</ill>", // A character not recognized by the lexer.
+
+  "SpecialToken" : "<st>{0}</st>", // __FILE__, __LINE__ etc.
+
+  "("    : "<br>(</br>",
+  ")"    : "<br>)</br>",
+  "["    : "<br>[</br>",
+  "]"    : "<br>]</br>",
+  "{"    : "<br>{</br>",
+  "}"    : "<br>}</br>",
+  "."    : ".",
+  ".."   : "..",
+  "..."  : "...",
+  "!<>=" : "!&lt;&gt;=", // Unordered
+  "!<>"  : "!&lt;&gt;",  // UorE
+  "!<="  : "!&lt;=",     // UorG
+  "!<"   : "!&lt;",      // UorGorE
+  "!>="  : "!&gt;=",     // UorL
+  "!>"   : "!&gt;",      // UorLorE
+  "<>="  : "&lt;&gt;=",  // LorEorG
+  "<>"   : "&lt;&gt;",   // LorG
+  "="    : "=",
+  "=="   : "==",
+  "!"    : "!",
+  "!="   : "!=",
+  "<="   : "&lt;=",
+  "<"    : "&lt;",
+  ">="   : "&gt;=",
+  ">"    : "&gt;",
+  "<<="  : "&lt;&lt;=",
+  "<<"   : "&lt;&lt;",
+  ">>="  : "&gt;&gt;=",
+  ">>"   : "&gt;&gt;",
+  ">>>=" : "&gt;&gt;&gt;=",
+  ">>>"  : "&gt;&gt;&gt;",
+  "|"    : "|",
+  "||"   : "||",
+  "|="   : "|=",
+  "&"    : "&amp;",
+  "&&"   : "&amp;&amp;",
+  "&="   : "&amp;=",
+  "+"    : "+",
+  "++"   : "++",
+  "+="   : "+=",
+  "-"    : "-",
+  "--"   : "--",
+  "-="   : "-=",
+  "/"    : "/",
+  "/="   : "/=",
+  "*"    : "*",
+  "*="   : "*=",
+  "%"    : "%",
+  "%="   : "%=",
+  "^"    : "^",
+  "^="   : "^=",
+  "~"    : "~",
+  "~="   : "~=",
+  ":"    : ":",
+  ";"    : ";",
+  "?"    : "?",
+  ","    : ",",
+  "$"    : "$",
+  "EOF"  : ""
+];
--- a/trunk/AUTHORS	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-Founder:
-  Aziz Köksal <aziz.koeksal@gmail.com>
-  "All rights to the code I've written will pass over to Jari-Matti Mäkelä,
-  in case I catch the bus or the bus catches me.
-  My death will probably not be made known anywhere on the internet,
-  therefore my testament will become effective if I don't
-  show any signs of life for 6 months on the internet.
-  Within this time limit I may always revoke or edit this testament,
-  by committing to the hg repository at http://hg.sharesource.org/dil/
-  Only the latest revision of this file is to be considered valid."
-    - Aziz Köksal
-Contributors:
-  Jari-Matti Mäkelä <jmjmak@utu.fi>
--- a/trunk/COPYING	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,674 +0,0 @@
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    <program>  Copyright (C) <year>  <name of author>
-    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
-  The GNU General Public License does not permit incorporating your program
-into proprietary programs.  If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.  But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
--- a/trunk/README	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-dil
-===
-Copyright (c) 2008 by Aziz Köksal <aziz.koeksal@gmail.com>
-This program is free software, licensed under the GPL3.
-Please, read the license file, COPYING, for further information.
-
-Description
-===========
-This software is a compiler written in D for the D programming language.
-
-How To Compile dil
-==================
-In order to compile dil you need to have:
- *) DMD 1.028 (http://www.digitalmars.com/d/1.0/changelog.html)
- *) Tango 0.99.5 (http://dsource.org/projects/tango/)
- *) DSSS 0.71 (http://dsource.org/projects/dsss/)
-
-If you can't compile dil because you have a newer version of these programs
-then please report the problem to me (see Bugs section.)
-
-Before you run dil, make sure that the executable can find config.d and
-lang_en.d (which are located in trunk/src/.)
-The language can be configured in config.d.
-
-Bugs And Patches
-================
-"errare humanum est, ignoscere divinum" - to err is human, to forgive divine.
- - Cicero
-
-Users can report problems with this software or submit patches by:
- *) contacting me: aziz.koeksal@gmail.com
- *) filing a bug report here: http://code.google.com/p/dil/issues/list
--- a/trunk/dsss.conf	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-name = dil
-version = 0.1
-[src/main.d]
-type = binary
-target = dil
-version(GNU) {
-  buildflags = -Isrc/ -Ldsss_objs/G/cmd.DDoc.o -Ldsss_objs/G/cmd.DDocXML.o
-} else {
-  buildflags = -Isrc/
-}
--- a/trunk/i18n/build.py	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-# -*- coding: utf-8 -*-
-# Author: Aziz Köksal
-# License: GPL2
--- a/trunk/i18n/de.cat	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-Authors:
-- {EMail: aziz.koeksal@gmail.com, Name: Aziz Köksal}
-LangCode: de
-License: GPL3
-Messages:
-- {Annot: '', ID: 0, LastEd: 0, Text: 'illegales Zeichen gefunden: ''{0}'''}
-- {Annot: '', ID: 1, LastEd: 0, Text: ungültiges Unicodezeichen.}
-- {Annot: '', ID: 2, LastEd: 0, Text: ungültige UTF-8-Sequenz.}
-- {Annot: '', ID: 3, LastEd: 0, Text: unterminiertes Zeichenliteral.}
-- {Annot: '', ID: 4, LastEd: 0, Text: leeres Zeichenliteral.}
-- {Annot: '', ID: 5, LastEd: 0, Text: erwartete 'line' nach '#'.}
-- {Annot: '', ID: 6, LastEd: 0, Text: 'Ganzzahl nach #line erwartet.'}
-- {Annot: '', ID: 7, LastEd: 0, Text: erwartete Dateispezifikation (z.B. "pfad\zur\datei".)}
-- {Annot: '', ID: 8, LastEd: 0, Text: unterminierte Dateispezifikation (filespec.)}
-- {Annot: '', ID: 9, LastEd: 0, Text: ein Special Token muss mit einem Zeilenumbruch
-    abgeschlossen werden.}
-- {Annot: '', ID: 10, LastEd: 0, Text: unterminiertes Zeichenkettenliteral.}
-- {Annot: '', ID: 11, LastEd: 0, Text: 'Nicht-Hexzeichen ''{0}'' in Hexzeichenkette
-    gefunden.'}
-- {Annot: '', ID: 12, LastEd: 0, Text: ungerade Anzahl von Hexziffern in Hexzeichenkette.}
-- {Annot: '', ID: 13, LastEd: 0, Text: unterminierte Hexzeichenkette.}
-- {Annot: '', ID: 14, LastEd: 0, Text: unterminierter Blockkommentar (/* */).}
-- {Annot: '', ID: 15, LastEd: 0, Text: unterminierter verschachtelter Kommentar (/+
-    +/).}
-- {Annot: '', ID: 16, LastEd: 0, Text: unterminierte rohe Zeichenkette.}
-- {Annot: '', ID: 17, LastEd: 0, Text: unterminierte Backquote-Zeichenkette.}
-- {Annot: '', ID: 18, LastEd: 0, Text: 'undefinierte Escapesequenz ''{0}'' gefunden.'}
-- {Annot: '', ID: 19, LastEd: 0, Text: 'ungültige Unicode-Escapesequenz ''{0}'' gefunden.'}
-- {Annot: '', ID: 20, LastEd: 0, Text: unzureichende Anzahl von Hexziffern in Escapesequenz.}
-- {Annot: '', ID: 21, LastEd: 0, Text: 'undefinierte HTML-Entität ''{0}'''}
-- {Annot: '', ID: 22, LastEd: 0, Text: 'unterminierte HTML-Entität ''{0}''.'}
-- {Annot: '', ID: 23, LastEd: 0, Text: HTML-Entitäten müssen mit einem Buchstaben
-    beginnen.}
-- {Annot: '', ID: 24, LastEd: 0, Text: Dezimalzahl überläuft im Vorzeichenbit.}
-- {Annot: '', ID: 25, LastEd: 0, Text: Überlauf in Dezimalzahl.}
-- {Annot: '', ID: 26, LastEd: 0, Text: Überlauf in Hexadezimalzahl.}
-- {Annot: '', ID: 27, LastEd: 0, Text: Überlauf in Binärzahl.}
-- {Annot: '', ID: 28, LastEd: 0, Text: Überlauf in Oktalzahl.}
-- {Annot: '', ID: 29, LastEd: 0, Text: Überlauf in Fließkommazahl.}
-- {Annot: '', ID: 30, LastEd: 0, Text: die Ziffern 8 und 9 sind in Oktalzahlen unzulässig.}
-- {Annot: '', ID: 31, LastEd: 0, Text: ungültige Hexzahl; mindestens eine Hexziffer
-    erforderlich.}
-- {Annot: '', ID: 32, LastEd: 0, Text: ungültige Binärzahl; mindestens eine Binärziffer
-    erforderlich.}
-- {Annot: '', ID: 33, LastEd: 0, Text: der Exponent einer hexadezimalen Fließkommazahl
-    ist erforderlich.}
-- {Annot: '', ID: 34, LastEd: 0, Text: Hexadezimal-Exponenten müssen mit einer Dezimalziffer
-    anfangen.}
-- {Annot: '', ID: 35, LastEd: 0, Text: Exponenten müssen mit einer Dezimalziffer anfangen.}
-- {Annot: '', ID: 36, LastEd: 0, Text: 'erwartete ''{0}'', fand aber ''{1}''.'}
-- {Annot: '', ID: 37, LastEd: 0, Text: '''{0}'' ist redundant.'}
-- {Annot: '', ID: 38, LastEd: 0, Text: Template-Tupel-Parameter dürfen nur am Ende
-    auftreten.}
-- {Annot: '', ID: 39, LastEd: 0, Text: der 'in'-Vertrag der Funktion wurde bereits
-    geparsed.}
-- {Annot: '', ID: 40, LastEd: 0, Text: der 'out'-Vertrag der Funktion wurde bereits
-    geparsed.}
-- {Annot: '', ID: 41, LastEd: 0, Text: es wurde kein Verbindungstyp angegeben.}
-- {Annot: '', ID: 42, LastEd: 0, Text: 'unbekannter Verbindungstyp ''{0}''; gültig
-    sind C, C++, D, Windows, Pascal und System.'}
-- {Annot: '', ID: 43, LastEd: 0, Text: 'erwartete eine oder mehrere Basisklassen,
-    nicht ''{0}''.'}
-- {Annot: '', ID: 44, LastEd: 0, Text: Basisklassen sind in Vorwärtsdeklarationen
-    nicht erlaubt.}
-- {Annot: '', ID: 45, LastEd: 0, Text: 'dil v{0}
-
-    Copyright (c) 2007, Aziz Köksal. Lizensiert unter der GPL3.
-
-
-    Befehle:
-
-    {1}
-
-    Geben Sie ''dil help <Befehl>'' ein, um mehr Hilfe zu einem bestimmten Befehl
-    zu
-
-    erhalten.
-
-
-    Kompiliert mit {2} v{3} am {4}.'}
-- {Annot: '', ID: 46, LastEd: 0, Text: "Generiere ein XML- oder HTML-Dokument aus\
-    \ einer D-Quelltextdatei.\nVerwendung:\n  dil gen datei.d [Optionen]\n\nOptionen:\n\
-    \  --syntax         : generiere Elemente für den Syntaxbaum\n  --xml         \
-    \   : verwende XML-Format (voreingestellt)\n  --html           : verwende HTML-Format\n\
-    \nBeispiel:\n  dil gen Parser.d --html --syntax > Parser.html"}
-- {Annot: '', ID: 47, LastEd: 0, Text: ''}
--- a/trunk/i18n/dil.tproj	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-BuildScript: build.py
-CreationDate: '2007-10-12 09:41:17.868084'
-LangFiles: [de.cat, tr.cat, fi.cat]
-MsgIDs:
-- {ID: 0, Name: IllegalCharacter, Order: 0}
-- {ID: 1, Name: InvalidUnicodeCharacter, Order: 1}
-- {ID: 2, Name: InvalidUTF8Sequence, Order: 2}
-- {ID: 3, Name: UnterminatedCharacterLiteral, Order: 3}
-- {ID: 4, Name: EmptyCharacterLiteral, Order: 4}
-- {ID: 5, Name: ExpectedIdentifierSTLine, Order: 5}
-- {ID: 6, Name: ExpectedIntegerAfterSTLine, Order: 6}
-- {ID: 7, Name: ExpectedFilespec, Order: 7}
-- {ID: 8, Name: UnterminatedFilespec, Order: 8}
-- {ID: 9, Name: UnterminatedSpecialToken, Order: 9}
-- {ID: 10, Name: UnterminatedString, Order: 10}
-- {ID: 11, Name: NonHexCharInHexString, Order: 11}
-- {ID: 12, Name: OddNumberOfDigitsInHexString, Order: 12}
-- {ID: 13, Name: UnterminatedHexString, Order: 13}
-- {ID: 14, Name: UnterminatedBlockComment, Order: 14}
-- {ID: 15, Name: UnterminatedNestedComment, Order: 15}
-- {ID: 16, Name: UnterminatedRawString, Order: 16}
-- {ID: 17, Name: UnterminatedBackQuoteString, Order: 17}
-- {ID: 18, Name: UndefinedEscapeSequence, Order: 18}
-- {ID: 19, Name: InvalidUnicodeEscapeSequence, Order: 19}
-- {ID: 20, Name: InsufficientHexDigits, Order: 20}
-- {ID: 21, Name: UndefinedHTMLEntity, Order: 21}
-- {ID: 22, Name: UnterminatedHTMLEntity, Order: 22}
-- {ID: 23, Name: InvalidBeginHTMLEntity, Order: 23}
-- {ID: 24, Name: OverflowDecimalSign, Order: 24}
-- {ID: 25, Name: OverflowDecimalNumber, Order: 25}
-- {ID: 26, Name: OverflowHexNumber, Order: 26}
-- {ID: 27, Name: OverflowBinaryNumber, Order: 27}
-- {ID: 28, Name: OverflowOctalNumber, Order: 28}
-- {ID: 29, Name: OverflowFloatNumber, Order: 29}
-- {ID: 30, Name: OctalNumberHasDecimals, Order: 30}
-- {ID: 31, Name: NoDigitsInHexNumber, Order: 31}
-- {ID: 32, Name: NoDigitsInBinNumber, Order: 32}
-- {ID: 33, Name: HexFloatExponentRequired, Order: 33}
-- {ID: 34, Name: HexFloatExpMustStartWithDigit, Order: 34}
-- {ID: 35, Name: FloatExpMustStartWithDigit, Order: 35}
-- {ID: 36, Name: ExpectedButFound, Order: 36}
-- {ID: 37, Name: RedundantStorageClass, Order: 37}
-- {ID: 38, Name: TemplateTupleParameter, Order: 38}
-- {ID: 39, Name: InContract, Order: 39}
-- {ID: 40, Name: OutContract, Order: 40}
-- {ID: 41, Name: MissingLinkageType, Order: 41}
-- {ID: 42, Name: UnrecognizedLinkageType, Order: 42}
-- {ID: 43, Name: ExpectedBaseClasses, Order: 43}
-- {ID: 44, Name: BaseClassInForwardDeclaration, Order: 44}
-- {ID: 45, Name: HelpMain, Order: 45}
-- {ID: 46, Name: HelpGenerate, Order: 46}
-- {ID: 47, Name: HelpImportGraph, Order: 47}
-Name: dil
-SourceLangFile: en.cat
--- a/trunk/i18n/en.cat	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-Authors:
-- {EMail: aziz.koeksal@gmail.com, Name: Aziz Köksal}
-LangCode: en
-License: GPL3
-Messages:
-- {Annot: '', ID: 0, LastEd: 0, Text: 'illegal character found: ''{0}'''}
-- {Annot: '', ID: 1, LastEd: 0, Text: invalid Unicode character.}
-- {Annot: '', ID: 2, LastEd: 0, Text: invalid UTF-8 sequence.}
-- {Annot: '', ID: 3, LastEd: 0, Text: unterminated character literal.}
-- {Annot: '', ID: 4, LastEd: 0, Text: empty character literal.}
-- {Annot: '', ID: 5, LastEd: 0, Text: expected 'line' after '#'.}
-- {Annot: '', ID: 6, LastEd: 0, Text: 'integer expected after #line'}
-- {Annot: '', ID: 7, LastEd: 0, Text: expected filespec string (e.g. "path\to\file".)}
-- {Annot: '', ID: 8, LastEd: 0, Text: unterminated filespec string.}
-- {Annot: '', ID: 9, LastEd: 0, Text: expected a terminating newline after special
-    token.}
-- {Annot: '', ID: 10, LastEd: 0, Text: unterminated string literal.}
-- {Annot: '', ID: 11, LastEd: 0, Text: 'non-hex character ''{0}'' found in hex string.'}
-- {Annot: '', ID: 12, LastEd: 0, Text: odd number of hex digits in hex string.}
-- {Annot: '', ID: 13, LastEd: 0, Text: unterminated hex string.}
-- {Annot: '', ID: 14, LastEd: 0, Text: unterminated block comment (/* */).}
-- {Annot: '', ID: 15, LastEd: 0, Text: unterminated nested comment (/+ +/).}
-- {Annot: '', ID: 16, LastEd: 0, Text: unterminated raw string.}
-- {Annot: '', ID: 17, LastEd: 0, Text: unterminated back quote string.}
-- {Annot: '', ID: 18, LastEd: 0, Text: 'found undefined escape sequence ''{0}''.'}
-- {Annot: '', ID: 19, LastEd: 0, Text: 'found invalid Unicode escape sequence ''{0}''.'}
-- {Annot: '', ID: 20, LastEd: 0, Text: insufficient number of hex digits in escape
-    sequence.}
-- {Annot: '', ID: 21, LastEd: 0, Text: 'undefined HTML entity ''{0}'''}
-- {Annot: '', ID: 22, LastEd: 0, Text: 'unterminated HTML entity ''{0}''.'}
-- {Annot: '', ID: 23, LastEd: 0, Text: HTML entities must begin with a letter.}
-- {Annot: '', ID: 24, LastEd: 0, Text: decimal number overflows sign bit.}
-- {Annot: '', ID: 25, LastEd: 0, Text: overflow in decimal number.}
-- {Annot: '', ID: 26, LastEd: 0, Text: overflow in hexadecimal number.}
-- {Annot: '', ID: 27, LastEd: 0, Text: overflow in binary number.}
-- {Annot: '', ID: 28, LastEd: 0, Text: overflow in octal number.}
-- {Annot: '', ID: 29, LastEd: 0, Text: overflow in float number.}
-- {Annot: '', ID: 30, LastEd: 0, Text: digits 8 and 9 are not allowed in octal numbers.}
-- {Annot: '', ID: 31, LastEd: 0, Text: invalid hex number; at least one hex digit
-    expected.}
-- {Annot: '', ID: 32, LastEd: 0, Text: invalid binary number; at least one binary
-    digit expected.}
-- {Annot: '', ID: 33, LastEd: 0, Text: the exponent of a hexadecimal float number
-    is required.}
-- {Annot: '', ID: 34, LastEd: 0, Text: hexadecimal float exponents must start with
-    a digit.}
-- {Annot: '', ID: 35, LastEd: 0, Text: exponents must start with a digit.}
-- {Annot: '', ID: 36, LastEd: 0, Text: 'expected ''{0}'', but found ''{1}''.'}
-- {Annot: '', ID: 37, LastEd: 0, Text: '''{0}'' is redundant.'}
-- {Annot: '', ID: 38, LastEd: 0, Text: template tuple parameters can only be last.}
-- {Annot: '', ID: 39, LastEd: 0, Text: the functions 'in' contract was already parsed.}
-- {Annot: '', ID: 40, LastEd: 0, Text: the functions 'out' contract was already parsed.}
-- {Annot: '', ID: 41, LastEd: 0, Text: no linkage type was specified.}
-- {Annot: '', ID: 42, LastEd: 0, Text: 'unrecognized linkage type ''{0}''; valid types
-    are C, C++, D, Windows, Pascal und System.'}
-- {Annot: '', ID: 43, LastEd: 0, Text: 'expected one or more base classes, not ''{0}''.'}
-- {Annot: '', ID: 44, LastEd: 0, Text: base classes are not allowed in forward declarations.}
-- {Annot: '', ID: 45, LastEd: 0, Text: 'dil v{0}
-
-    Copyright (c) 2007 by Aziz Köksal. Licensed under the GPL3.
-
-
-    Subcommands:
-
-    {1}
-
-    Type ''dil help <subcommand>'' for more help on a particular subcommand.
-
-
-    Compiled with {2} v{3} on {4}.'}
-- {Annot: '', ID: 46, LastEd: 0, Text: "Generate an XML or HTML document from a D\
-    \ source file.\nUsage:\n  dil gen file.d [Options]\n\nOptions:\n  --syntax   \
-    \      : generate tags for the syntax tree\n  --xml            : use XML format\
-    \ (default)\n  --html           : use HTML format\n\nExample:\n  dil gen Parser.d\
-    \ --html --syntax > Parser.html"}
-- {Annot: '', ID: 47, LastEd: 0, Text: "Parse a module and extract information from\
-    \ the resulting module dependency graph.\nUsage:\n  dil igraph file.d Format [Options]\n\
-    \n  The directory of file.d is implicitly added to the list of import paths.\n\
-    \nFormat:\n  --dot            : generate a dot document\n  Further options for\
-    \ --dot:\n  -gbp             : Group modules by package names\n  -gbf        \
-    \     : Group modules by full package name\n  -hle             : highlight cyclic\
-    \ edges in the graph\n  -hlv             : highlight modules in cyclic relationship\n\
-    \n  --paths          : print a list of paths to the modules imported by file.d\n\
-    \  --list           : print a list of the module names imported by file.d\n  Options\
-    \ common to --paths and --list:\n  -lN              : print N levels.\n  -m  \
-    \             : mark modules in cyclic relationships with a star.\n\nOptions:\n\
-    \  -Ipath           : add 'path' to the list of import paths where modules are\n\
-    \                     looked for\n  -rREGEXP         : exclude modules whose names\
-    \ match the regular expression\n                     REGEXP\n  -i            \
-    \   : include unlocatable modules\n\nExample:\n  dil igraph src/main.d"}
--- a/trunk/i18n/fi.cat	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-Authors:
-- {EMail: jmjm@iki.fi, Name: Jari-Matti Mäkelä}
-LangCode: fi
-License: GPL3
-Messages:
-- {Annot: '', ID: 0, LastEd: 0, Text: ''}
-- {Annot: '', ID: 1, LastEd: 0, Text: virheellinen Unicode-merkki.}
-- {Annot: '', ID: 2, LastEd: 0, Text: virheellinen UTF-8-merkkijono.}
-- {Annot: '', ID: 3, LastEd: 0, Text: päättämätön merkkiliteraali.}
-- {Annot: '', ID: 4, LastEd: 0, Text: tyhjä merkkiliteraali.}
-- {Annot: '', ID: 5, LastEd: 0, Text: 'odotettiin rivinumeroa ''#'':n jälkeen.'}
-- {Annot: '', ID: 6, LastEd: 0, Text: 'odotettiin kokonaislukua #line:n jälkeen'}
-- {Annot: '', ID: 7, LastEd: 0, Text: odotettiin tiedostomäärittelyn merkkijonoa (esim.
-    "polku\tiedostoon")}
-- {Annot: '', ID: 8, LastEd: 0, Text: päättämätön tiedostomäärittely.}
-- {Annot: '', ID: 9, LastEd: 0, Text: odotettiin päättävää rivinvaihtoa erikoismerkin
-    jälkeen.}
-- {Annot: '', ID: 10, LastEd: 0, Text: päättämätön merkkijonoliteraali.}
-- {Annot: '', ID: 11, LastEd: 0, Text: 'ei-heksamerkki ''{0}'' löytyi heksajonossa.'}
-- {Annot: '', ID: 12, LastEd: 0, Text: pariton määrä heksanumeroita heksajonossa.}
-- {Annot: '', ID: 13, LastEd: 0, Text: päättämätön heksajono.}
-- {Annot: '', ID: 14, LastEd: 0, Text: päättämätön lohkokommentti (/* */).}
-- {Annot: '', ID: 15, LastEd: 0, Text: päättämätön sisäkkäinen kommentti (/+ +/).}
-- {Annot: '', ID: 16, LastEd: 0, Text: päättämätön raakamerkkijono.}
-- {Annot: '', ID: 17, LastEd: 0, Text: päättämätön gravisaksenttimerkkijono.}
-- {Annot: '', ID: 18, LastEd: 0, Text: löydettiin määrittelemätön escape-sekvenssi.}
-- {Annot: '', ID: 19, LastEd: 0, Text: 'found invalid Unicode escape sequence ''{0}''.'}
-- {Annot: '', ID: 20, LastEd: 0, Text: riittämätön määrä heksanumeroita escape-sekvenssissä.}
-- {Annot: '', ID: 21, LastEd: 0, Text: 'määrittelemätön HTML-entiteetti ''{0}'''}
-- {Annot: '', ID: 22, LastEd: 0, Text: päättämätön HTML-entiteetti.}
-- {Annot: '', ID: 23, LastEd: 0, Text: HTML-entiteettien tulee alkaa kirjaimella.}
-- {Annot: '', ID: 24, LastEd: 0, Text: desimaaliluku ylivuotaa etumerkin.}
-- {Annot: '', ID: 25, LastEd: 0, Text: desimaaliluvun ylivuoto.}
-- {Annot: '', ID: 26, LastEd: 0, Text: heksadesimaaliluvun ylivuoto.}
-- {Annot: '', ID: 27, LastEd: 0, Text: binääriluvun ylivuoto.}
-- {Annot: '', ID: 28, LastEd: 0, Text: oktaaliluvun ylivuoto.}
-- {Annot: '', ID: 29, LastEd: 0, Text: liukuluvun ylivuoto.}
-- {Annot: '', ID: 30, LastEd: 0, Text: numerot 8 ja 9 eivät ole sallittuja oktaaliluvuissa.}
-- {Annot: '', ID: 31, LastEd: 0, Text: virheellinen heksaluku; odotettiin vähintään
-    yhtä heksanumeroa.}
-- {Annot: '', ID: 32, LastEd: 0, Text: virheellinen binääriluku; odotettiin vähintään
-    yhtä binäärinumeroa.}
-- {Annot: '', ID: 33, LastEd: 0, Text: heksadesimaalisen liukuluvun eksponentti vaaditaan.}
-- {Annot: '', ID: 34, LastEd: 0, Text: heksadesimaalisen liukuluvun eksponentista
-    puuttui numeroita.}
-- {Annot: '', ID: 35, LastEd: 0, Text: eksponenttien tulee alkaa numerolla.}
-- {Annot: '', ID: 36, LastEd: 0, Text: 'odotettiin ''{0}'':a, mutta löydettiin ''{1}''.'}
-- {Annot: '', ID: 37, LastEd: 0, Text: '''{0}'' on redundantti.'}
-- {Annot: '', ID: 38, LastEd: 0, Text: tupla voi esiintyä ainoastaan mallin viimeisenä
-    parametrina.}
-- {Annot: '', ID: 39, LastEd: 0, Text: funktion alkuehto jäsennettiin jo.}
-- {Annot: '', ID: 40, LastEd: 0, Text: funktion loppuehto jäsennettiin jo.}
-- {Annot: '', ID: 41, LastEd: 0, Text: linkitystyyppiä ei määritelty.}
-- {Annot: '', ID: 42, LastEd: 0, Text: 'tunnistamaton linkitystyyppi ''{0}''; sallittuja
-    tyyppejä ovat C, C++, D, Windows, Pascal ja System.'}
-- {Annot: '', ID: 43, LastEd: 0, Text: 'expected one or more base classes, not ''{0}''.'}
-- {Annot: '', ID: 44, LastEd: 0, Text: base classes are not allowed in forward declarations.}
-- {Annot: '', ID: 45, LastEd: 0, Text: 'dil v{0}
-
-    Copyright (c) 2007, Aziz Köksal. GPL3-lisensöity.
-
-
-    Alikomennot:
-
-    {1}
-
-    Lisäohjeita tietystä alitoiminnosta saa kirjoittamalla ''dil help <toiminto>''.
-
-
-    Käännetty {2}:n versiolla {3} {4}.'}
-- {Annot: '', ID: 46, LastEd: 0, Text: "Luo XML- tai HTML-dokumentti D-lähdekoodista.\n\
-    Käyttö:\n  dil gen tiedosto.d [Valinnat]\n\nValinnat:\n  --syntax         : luo\
-    \ elementtejä syntaksipuun mukaisesti\n  --xml            : käytä XML-muotoa (oletus)\n\
-    \  --html           : käytä HTML-muotoa\n\nEsimerkki:\n  dil gen Parser.d --html\
-    \ --syntax > Parser.html"}
-- {Annot: '', ID: 47, LastEd: 0, Text: ''}
--- a/trunk/i18n/tr.cat	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-Authors:
-- {EMail: aziz.koeksal@gmail.com, Name: Aziz Köksal}
-LangCode: tr
-License: GPL3
-Messages:
-- {Annot: '', ID: 0, LastEd: 0, Text: 'illegal karakter bulundu: ''{0}'''}
-- {Annot: '', ID: 1, LastEd: 0, Text: geçersiz Unikod karakteri.}
-- {Annot: '', ID: 2, LastEd: 0, Text: geçersiz UTF-8 serisi.}
-- {Annot: '', ID: 3, LastEd: 0, Text: kapanmamış karakter sabiti.}
-- {Annot: '', ID: 4, LastEd: 0, Text: boş karakter sabiti.}
-- {Annot: '', ID: 5, LastEd: 0, Text: '''#'' karakter''den sonra ''line'' beklendi.'}
-- {Annot: '', ID: 6, LastEd: 0, Text: '''#line''''den sonra rakam beklendi.'}
-- {Annot: '', ID: 7, LastEd: 0, Text: filespec dizgisi beklendi (e.g. "yol\dosya".)}
-- {Annot: '', ID: 8, LastEd: 0, Text: kapanmamış filespec dizgisi.}
-- {Annot: '', ID: 9, LastEd: 0, Text: özel belirtici'den (special token) sonra yeni
-    bir satır beklendi.}
-- {Annot: '', ID: 10, LastEd: 0, Text: kapanmamış çift tırnak dizgisi.}
-- {Annot: '', ID: 11, LastEd: 0, Text: 'heks sayı olmayan karakter ''{0}'' heks dizgisi
-    içinde bulundu.'}
-- {Annot: '', ID: 12, LastEd: 0, Text: heks dizginin içindeki sayılar çifter çifter
-    olmalıdır.}
-- {Annot: '', ID: 13, LastEd: 0, Text: kapanmamış heks dizgisi.}
-- {Annot: '', ID: 14, LastEd: 0, Text: kapanmamış blok açıklaması (/* */).}
-- {Annot: '', ID: 15, LastEd: 0, Text: kapanmamış iç içe koyulabilen açıklaması (/+
-    +/).}
-- {Annot: '', ID: 16, LastEd: 0, Text: kapanmamış çiğ dizgisi.}
-- {Annot: '', ID: 17, LastEd: 0, Text: kapanmamış ters tırnak dizgisi.}
-- {Annot: '', ID: 18, LastEd: 0, Text: 'tanımlanmamış çıkış serisi ''{0}'' bulundu.'}
-- {Annot: '', ID: 19, LastEd: 0, Text: 'geçersiz Unikod çıkış serisi ''{0}'' bulundu.'}
-- {Annot: '', ID: 20, LastEd: 0, Text: heksadesimal çıkış serisi sayıları yeterli
-    değil.}
-- {Annot: '', ID: 21, LastEd: 0, Text: 'tanımlanmamış HTML varlık ''{0}'''}
-- {Annot: '', ID: 22, LastEd: 0, Text: 'kapanmamış HTML varlık ''{0}''.'}
-- {Annot: '', ID: 23, LastEd: 0, Text: HTML varlık bir harf ile başlamalı.}
-- {Annot: '', ID: 24, LastEd: 0, Text: desimal rakamın bit işareti taşdı.}
-- {Annot: '', ID: 25, LastEd: 0, Text: desimal rakam taşması.}
-- {Annot: '', ID: 26, LastEd: 0, Text: heksadesimal rakam taşması.}
-- {Annot: '', ID: 27, LastEd: 0, Text: binari rakam taşması.}
-- {Annot: '', ID: 28, LastEd: 0, Text: oktal rakam taşması.}
-- {Annot: '', ID: 29, LastEd: 0, Text: float rakam taşması.}
-- {Annot: '', ID: 30, LastEd: 0, Text: 8 ve 9 sayılar oktal rakamlar'da geçersizdir.}
-- {Annot: '', ID: 31, LastEd: 0, Text: geçersiz heks rakam; minimum bir heks sayı
-    gereklidir.}
-- {Annot: '', ID: 32, LastEd: 0, Text: geçersiz binari rakam; minimum bir binari sayı
-    gereklidir.}
-- {Annot: '', ID: 33, LastEd: 0, Text: bir heksadesimal float rakamın üsü gereklidir.}
-- {Annot: '', ID: 34, LastEd: 0, Text: heksadesimal float üsler desimal sayı ile başlamalı.}
-- {Annot: '', ID: 35, LastEd: 0, Text: üsler desimal sayı ile başlamalı.}
-- {Annot: '', ID: 36, LastEd: 0, Text: '''{0}'' beklendi, ama ''{1}'' bulundu.'}
-- {Annot: '', ID: 37, LastEd: 0, Text: '''{0}'' lüzumsuz.'}
-- {Annot: '', ID: 38, LastEd: 0, Text: şablon tuple parametre son sırada olmalı.}
-- {Annot: '', ID: 39, LastEd: 0, Text: fonksiyonun 'in' kontratı daha önceden ayrıştırılmış.}
-- {Annot: '', ID: 40, LastEd: 0, Text: fonksiyonun 'out' kontratı daha önceden ayrıştırılmış.}
-- {Annot: '', ID: 41, LastEd: 0, Text: bağlantı tüp (linkage type) belirtilmedi.}
-- {Annot: '', ID: 42, LastEd: 0, Text: 'bilinmeyen bağlantı tüpü (linkage type) ''{0}'';
-    geçerli olanlar C, C++, D, Windows, Pascal ve System.'}
-- {Annot: '', ID: 43, LastEd: 0, Text: ''}
-- {Annot: '', ID: 44, LastEd: 0, Text: ''}
-- {Annot: '', ID: 45, LastEd: 0, Text: 'dil v{0}
-
-    Copyright (c) 2007, Aziz Köksal. Lisans GPL3.
-
-
-    Komutlar: {1} Belirli komut''a yardım edinmek için ''dil help <komut>'' yazınız.
-
-
-    Bu yazılım {2} v{3} ile {4} tarihinde derletilmiş.'}
-- {Annot: '', ID: 46, LastEd: 0, Text: "Bir D kaynak kodundan XML veya HTML dosyası\
-    \ oluştur.\nKullanım:\n  dil gen dosya.d [Seçenekler]\n\nSeçenekler:\n  --syntax\
-    \         : söz dizimi için etiketler yazdır\n  --xml            : XML biçimi\
-    \ kullan (varsayılır)\n  --html           : HTML biçimi kullan\n\nÖrnek:\n  dil\
-    \ gen Parser.d --html --syntax > Parser.html"}
-- {Annot: '', ID: 47, LastEd: 0, Text: ''}
--- a/trunk/release.py	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-# -*- coding: utf-8 -*-
-# Author: Aziz Köksal
-
-# TODO: port release.sh to Python
-
-# TODO: write subcommand that creates a Makefile
-def writeMakefile():
-  pass
--- a/trunk/release.sh	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-#!/bin/bash
-
-if [[ $1 != [0-9].[0-9][0-9][0-9] ]]; then
-  echo Wrong version format. Expected: d.ddd
-  exit;
-fi
-
-BUILD="./build"
-DIR="dil.$1"
-DEST="$BUILD/$DIR"
-FRESH_REPOS="$BUILD/fresh_repos"
-
-# Create build directory if it doesn't exist.
-[ ! -e $BUILD ] && mkdir $BUILD
-
-# Convert Unix newlines to Windows newlines
-# function unix2win
-# {
-#   sed {s/$/\\r/} $*
-# }
-
-# We need dil to get a list of all modules to be compiled.
-if [ ! -s ./dil ]; then
-  dsss build -full &> /dev/null
-fi
-
-if [ ! -s ./dil ]; then
-  echo "Couldn't build DIL. Can't get list of modules to be built."
-  exit;
-fi
-
-# Used by doc generation and winbuild function.
-SRC_FILES=`./dil igraph src/main.d --paths`
-
-# Recreate destination directory.
-rm -rf $DEST
-mkdir -p $DEST/{bin,doc/htmlsrc,src}
-
-# Create documentation.
-./dil ddoc $DEST/doc/ -v src/macros_dil.ddoc -version=DDoc src/config.d $SRC_FILES
-# Generate syntax highlighted HTML files.
-HTMLSRC="$DEST/doc/htmlsrc"
-for filepath in $SRC_FILES;
-do
-  htmlfile=`echo $filepath | sed -e 's@^src/@@' -e 's@/@.@g' -e 's@.d$@@'`.html
-  echo "FILE: $filepath > $HTMLSRC/$htmlfile";
-  ./dil gen --lines --syntax --html $filepath > "$HTMLSRC/$htmlfile";
-done
-
-# Linux Debug
-echo "***** Building Linux binaries *****"
-dsss build -clean -full -version=D2
-cp dil $DEST/bin/dil2_d
-dsss build -clean -full
-cp dil $DEST/bin/dil_d
-# Linux Release
-dsss build -clean -full -release -O -inline -version=D2
-cp dil $DEST/bin/dil2
-dsss build -clean -full -release -O -inline
-cp dil $DEST/bin/dil
-
-if [ -s ~/bin/dmd.exe ]; then
-  echo "***** Building Windows binaries *****"
-  function winbuild
-  { # obj dir is winobj. -op = don't strip paths from obj files.
-    wine ~/bin/dmd.exe -odwinobj -op -ofdil $* $SRC_FILES
-  }
-  # Windows Debug
-  winbuild -version=D2
-  cp dil.exe $DEST/bin/dil2_d.exe
-  winbuild
-  cp dil.exe $DEST/bin/dil_d.exe
-  # Windows Release
-  winbuild -release -O -inline -version=D2
-  cp dil.exe $DEST/bin/dil2.exe
-  winbuild -release -O -inline
-  cp dil.exe $DEST/bin/dil.exe
-fi
-
-# Copy source and other files.
-rm -rf $FRESH_REPOS
-hg archive -r tip -t files $FRESH_REPOS
-cp -r $FRESH_REPOS/trunk/* $DEST
-
-cp $FRESH_REPOS/trunk/src/config.d $DEST/bin/
-cp $FRESH_REPOS/trunk/src/lang_*.d $DEST/bin/
-cp $FRESH_REPOS/trunk/src/*_map.d $DEST/bin/
-cp $FRESH_REPOS/trunk/src/*.css $DEST/bin/
-cp $FRESH_REPOS/trunk/src/predefined.ddoc $DEST/bin/
-cp $FRESH_REPOS/trunk/src/html.css $HTMLSRC
-
-# Build archives
-# tar.gz doesn't compress well
-tar --owner root --group root -czf $DEST.tar.gz $DEST
-tar --owner root --group root --bzip2 -cf $DEST.tar.bz2 $DEST
-zip -q -9 -r $DEST.zip $DEST
--- a/trunk/src/Settings.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module Settings;
-import common;
-
-/// Global application settings.
-struct GlobalSettings
-{
-static:
-  /// Predefined version identifiers.
-  string[] versionIds;
-  /// Path to the language file.
-  string langFile = "lang_en.d";
-  /// Language code of loaded messages catalogue.
-  string langCode = "en";
-  /// Table of localized compiler messages.
-  string[] messages;
-  /// Array of import paths to look for modules.
-  string[] importPaths;
-  /// Array of DDoc macro file paths.
-  string[] ddocFilePaths;
-  string xmlMapFile = "xml_map.d"; /// XML map file.
-  string htmlMapFile = "html_map.d"; /// HTML map file.
-  string lexerErrorFormat = "{0}({1},{2})L: {3}"; /// Lexer error.
-  string parserErrorFormat = "{0}({1},{2})P: {3}"; /// Parser error.
-  string semanticErrorFormat = "{0}({1},{2})S: {3}"; /// Semantic error.
-}
--- a/trunk/src/SettingsLoader.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,252 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module SettingsLoader;
-
-import Settings;
-import dil.Messages;
-import dil.ast.Node, dil.ast.Declarations, dil.ast.Expressions;
-import dil.semantic.Module;
-import dil.semantic.Pass1;
-import dil.semantic.Symbol;
-import dil.semantic.Symbols;
-import dil.Information;
-import dil.Compilation;
-import common;
-
-import tango.io.FilePath;
-
-/// Loads settings from a D module file.
-class SettingsLoader
-{
-  InfoManager infoMan; /// Collects error messages.
-  Module mod; /// Current module.
-
-  this(InfoManager infoMan)
-  {
-    this.infoMan = infoMan;
-  }
-
-  static SettingsLoader opCall(InfoManager infoMan)
-  {
-    return new SettingsLoader(infoMan);
-  }
-
-  /// Creates an error report.
-  /// Params:
-  ///   token = where the error occurred.
-  ///   formatMsg = error message.
-  void error(Token* token, char[] formatMsg, ...)
-  {
-    auto location = token.getErrorLocation();
-    auto msg = Format(_arguments, _argptr, formatMsg);
-    infoMan ~= new SemanticError(location, msg);
-  }
-
-  T getValue(T)(char[] name)
-  {
-    auto var = mod.lookup(name);
-    if (!var) // Returning T.init instead of null, because dmd gives an error.
-      return error(mod.firstToken, "variable '{}' is not defined", name), T.init;
-    auto t = var.node.begin;
-    if (!var.isVariable)
-      return error(t, "'{}' is not a variable declaration", name), T.init;
-    auto value = var.to!(Variable).value;
-    if (!value)
-      return error(t, "'{}' variable has no value set", name), T.init;
-    T val = value.Is!(T); // Try casting to T.
-    if (!val)
-      error(value.begin, "the value of '{}' is not of type {}", name, typeof(T).stringof);
-    return val;
-  }
-
-  T castTo(T)(Node n)
-  {
-    char[] type;
-    is(T == StringExpression) && (type = "char[]");
-    if (!n.Is!(T))
-      error(n.begin, "expression is not of type {}", type);
-    return n.Is!(T);
-  }
-
-  void load()
-  {
-    scope execPath = new FilePath(GetExecutableFilePath());
-    execPath = new FilePath(execPath.folder());
-
-    // Load config.d
-    auto filePath = resolvePath(execPath, "config.d");
-    mod = new Module(filePath, infoMan);
-    mod.parse();
-
-    if (mod.hasErrors)
-      return;
-
-    auto context = new CompilationContext;
-    auto pass1 = new SemanticPass1(mod, context);
-    pass1.start();
-
-    if (auto array = getValue!(ArrayInitExpression)("version_ids"))
-      foreach (value; array.values)
-        if (auto str = castTo!(StringExpression)(value))
-          GlobalSettings.versionIds ~= str.getString();
-    if (auto val = getValue!(StringExpression)("langfile"))
-      GlobalSettings.langFile = val.getString();
-    if (auto array = getValue!(ArrayInitExpression)("import_paths"))
-      foreach (value; array.values)
-        if (auto str = castTo!(StringExpression)(value))
-          GlobalSettings.importPaths ~= str.getString();
-    if (auto array = getValue!(ArrayInitExpression)("ddoc_files"))
-      foreach (value; array.values)
-        if (auto str = castTo!(StringExpression)(value))
-          GlobalSettings.ddocFilePaths ~= resolvePath(execPath, str.getString());
-    if (auto val = getValue!(StringExpression)("xml_map"))
-      GlobalSettings.xmlMapFile = val.getString();
-    if (auto val = getValue!(StringExpression)("html_map"))
-      GlobalSettings.htmlMapFile = val.getString();
-    if (auto val = getValue!(StringExpression)("lexer_error"))
-      GlobalSettings.lexerErrorFormat = val.getString();
-    if (auto val = getValue!(StringExpression)("parser_error"))
-      GlobalSettings.parserErrorFormat = val.getString();
-    if (auto val = getValue!(StringExpression)("semantic_error"))
-      GlobalSettings.semanticErrorFormat = val.getString();
-
-    // Load language file.
-    filePath = resolvePath(execPath, GlobalSettings.langFile);
-    mod = new Module(filePath);
-    mod.parse();
-
-    if (mod.hasErrors)
-      return;
-
-    pass1 = new SemanticPass1(mod, context);
-    pass1.start();
-
-    if (auto array = getValue!(ArrayInitExpression)("messages"))
-    {
-      char[][] messages;
-      foreach (value; array.values)
-        if (auto str = castTo!(StringExpression)(value))
-          messages ~= str.getString();
-      if (messages.length != MID.max+1)
-        error(mod.firstToken,
-              "messages table in {} must exactly have {} entries, but not {}.",
-              filePath, MID.max+1, messages.length);
-      GlobalSettings.messages = messages;
-      dil.Messages.SetMessages(messages);
-    }
-    if (auto val = getValue!(StringExpression)("lang_code"))
-      GlobalSettings.langCode = val.getString();
-  }
-}
-
-/// Loads an associative array from a D module file.
-class TagMapLoader : SettingsLoader
-{
-  this(InfoManager infoMan)
-  {
-    super(infoMan);
-  }
-
-  static TagMapLoader opCall(InfoManager infoMan)
-  {
-    return new TagMapLoader(infoMan);
-  }
-
-  string[string] load(string filePath)
-  {
-    mod = new Module(filePath, infoMan);
-    mod.parse();
-    if (mod.hasErrors)
-      return null;
-
-    auto context = new CompilationContext;
-    auto pass1 = new SemanticPass1(mod, context);
-    pass1.start();
-
-    string[string] map;
-    if (auto array = getValue!(ArrayInitExpression)("map"))
-      foreach (i, value; array.values)
-      {
-        auto key = array.keys[i];
-        if (auto valExp = castTo!(StringExpression)(value))
-          if (!key)
-            error(value.begin, "expected key : value");
-          else if (auto keyExp = castTo!(StringExpression)(key))
-            map[keyExp.getString()] = valExp.getString();
-      }
-    return map;
-  }
-}
-
-/// Resolves the path to a file from the executable's dir path
-/// if it is relative.
-/// Returns: filePath if it is absolute or execPath + filePath.
-string resolvePath(FilePath execPath, string filePath)
-{
-  if ((new FilePath(filePath)).isAbsolute())
-    return filePath;
-  return execPath.dup.append(filePath).toString();
-}
-
-version(DDoc)
-{
-  /// Returns the fully qualified path to this executable.
-  char[] GetExecutableFilePath();
-}
-else version(Windows)
-{
-private extern(Windows) uint GetModuleFileNameA(void*, char*, uint);
-
-char[] GetExecutableFilePath()
-{
-  alias GetModuleFileNameA GetModuleFileName;
-  char[] buffer = new char[256];
-  uint count;
-
-  while (1)
-  {
-    if (buffer is null)
-      return null;
-
-    count = GetModuleFileName(null, buffer.ptr, buffer.length);
-    if (count == 0)
-      return null;
-    if (buffer.length != count && buffer[count] == 0)
-      break;
-    // Increase size of buffer
-    buffer.length = buffer.length * 2;
-  }
-  assert(buffer[count] == 0);
-  // Reduce buffer to the actual length of the string (excluding '\0'.)
-  if (count < buffer.length)
-    buffer.length = count;
-  return buffer;
-}
-}
-else version(linux)
-{
-private extern(C) size_t readlink(char* path, char* buf, size_t bufsize);
-
-char[] GetExecutableFilePath()
-{
-  char[] buffer = new char[256];
-  size_t count;
-
-  while (1)
-  {
-    // This won't work on very old Linux systems.
-    count = readlink("/proc/self/exe".ptr, buffer.ptr, buffer.length);
-    if (count == -1)
-      return null;
-    if (count < buffer.length)
-      break;
-    buffer.length = buffer.length * 2;
-  }
-  buffer.length = count;
-  return buffer;
-}
-}
-else
-  static assert(0, "GetExecutableFilePath() is not implemented on this platform.");
--- a/trunk/src/TypeRules.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module TypeRules;
-
-import cmd.Generate : xml_escape;
-
-import TypeRulesData;
-import common;
-
-static const string[] basicTypes = [
-  "char"[],   "wchar",   "dchar", "bool",
-  "byte",   "ubyte",   "short", "ushort",
-  "int",    "uint",    "long",  "ulong",
-  /+"cent",   "ucent",+/
-  "float",  "double",  "real",
-  "ifloat", "idouble", "ireal",
-  "cfloat", "cdouble", "creal"/+, "void"+/
-];
-
-static const string[] unaryExpressions = [
-  "!x",
-  "&x",
-  "~x",
-  "+x",
-  "-x",
-  "++x",
-  "--x",
-  "x++",
-  "x--",
-];
-
-static const string[] binaryExpressions = [
-  "x!<>=y",
-  "x!<>y",
-  "x!<=y",
-  "x!<y",
-  "x!>=y",
-  "x!>y",
-  "x<>=y",
-  "x<>y",
-
-  "x=y", "x==y", "x!=y",
-  "x<=y", "x<y",
-  "x>=y", "x>y",
-  "x<<=y", "x<<y",
-  "x>>=y","x>>y",
-  "x>>>=y", "x>>>y",
-  "x|=y", "x||y", "x|y",
-  "x&=y", "x&&y", "x&y",
-  "x+=y", "x+y",
-  "x-=y", "x-y",
-  "x/=y", "x/y",
-  "x*=y", "x*y",
-  "x%=y", "x%y",
-  "x^=y", "x^y",
-  "x~=y",
-  "x~y",
-  "x,y"
-];
-
-void genHTMLTypeRulesTables()
-{
-  Stdout(
-    `<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">`\n
-    `<html>`\n
-    `<head>`\n
-    `  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">`\n
-    `  <link href="" rel="stylesheet" type="text/css">`\n
-    `  <style type="text/css">`\n
-    `    .E { color: darkred; } /* Error */`\n
-    `    .R { font-size: 0.8em; } /* Result */`\n
-    `    .X { color: darkorange; }`\n
-    `    .Y { color: darkblue; }`\n
-    `  </style>`\n
-    `</head>`\n
-    `<body>`\n
-    `<p>These tables show what the type results of certain expressions are.</p>`\n
-  );
-
-  Stdout.format("<table>\n<tr><th colspan=\"{}\">Unary Expressions</th></tr>\n", unaryExpressions.length);
-  Stdout("<tr><td><!--typecol--></td>");
-  foreach (unaryExpression; unaryExpressions)
-    Stdout.format("<td>{}</td>", {
-      if (unaryExpression[0] == 'x')
-        return `<span class="X">x</span>` ~ xml_escape(unaryExpression[1..$]);
-      else
-        return xml_escape(unaryExpression[0..$-1]) ~ `<span class="X">x</span>`;
-    }());
-  Stdout("</tr>\n");
-  foreach (i, basicType; basicTypes)
-  {
-    Stdout.format("<tr>\n"`<td class="X">{}</td>`, basicType);
-    foreach (expResults; unaryExpsResults)
-    {
-      auto result =  expResults[i];
-      Stdout.format(`<td class="R">{}</td>`, result[0] == 'E' ? `<span class="E">Error</span>`[] : result);
-    }
-    Stdout("\n<tr>\n");
-  }
-  Stdout("</table>\n");
-
-  foreach (i, expResults; binaryExpsResults)
-  {
-    auto binaryExpression = binaryExpressions[i];
-    binaryExpression = `<span class="X">x</span> ` ~
-                       xml_escape(binaryExpression[1..$-1]) ~
-                       ` <span class="Y">y</span>`;
-    Stdout.format("<table>\n<tr><th colspan=\"{}\">{}</th></tr>\n", basicTypes.length, binaryExpression);
-    Stdout.format("<tr><td><!--typecol--></td>");
-    foreach (basicType; basicTypes)
-      Stdout.format(`<td class="Y">{}</td>`, basicType);
-    Stdout("\n<tr>\n");
-    foreach (j, results; expResults)
-    {
-      Stdout.format("<tr>\n"`<td class="X">{}</td>`, basicTypes[j]);
-      foreach (result; results)
-        Stdout.format(`<td class="R">{}</td>`, result[0] == 'E' ? `<span class="E">Error</span>`[] : result);
-      Stdout("\n<tr>\n");
-    }
-    Stdout("</table>\n");
-  }
-
-  Stdout(
-    "\n</body>"
-    "\n</html>"
-  );
-}
--- a/trunk/src/TypeRulesData.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-// Run TypeRulesGenerator.d
--- a/trunk/src/TypeRulesGenerator.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +0,0 @@
-#! /usr/bin/rdmd
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module TypeRulesGenerator;
-
-import tango.io.File;
-import tango.io.FilePath;
-
-alias char[] string;
-
-void main(char[][] args)
-{
-  char[] text = "// Generated by TypeRulesGenerator.d\n"
-                "module TypeRules.d;\n\n";
-  text ~= "char[][][] unaryExpsResults = [\n";
-  foreach (results; unaryExpsResults)
-  {
-    text ~= "  [";
-    foreach (result; results)
-      text ~= '"' ~ result ~ '"' ~ ", ";
-    text[$-2] = ']';
-    text[$-1] = ',';
-    text ~= \n;
-  }
-  text[$-2] = '\n';
-  text[$-1] = ']';
-  text ~= ";\n\n";
-
-  text ~= "char[][][][] binaryExpsResults = [\n";
-  foreach (expResults; binaryExpsResults)
-  {
-    text ~= "  [\n";
-    foreach (results; expResults)
-    {
-      text ~= "    [";
-      foreach (result; results)
-        text ~= '"' ~ result ~ '"' ~ ", ";
-      text[$-2] = ']';
-      text[$-1] = ',';
-      text ~= \n;
-    }
-    text[$-2] = '\n';
-    text[$-1] = ' ';
-    text ~= " ],\n";
-  }
-  text[$-2] = '\n';
-  text[$-1] = ']';
-  text ~= ";\n";
-
-  // Write the text to a D module.
-  auto file = new File("TypeRulesData.d");
-  file.write(text);
-}
-
-template ExpressionType(char[] T1, char[] T2, char[] expression)
-{
-  mixin("alias "~T1~" X;");
-  mixin("alias "~T2~" Y;");
-  X x;
-  Y y;
-  static if(is(typeof(mixin(expression)) ResultType))
-    const char[] result = ResultType.stringof;
-  else
-    const char[] result = "Error";
-}
-alias ExpressionType EType;
-
-// pragma(msg, EType!("char", "int", "&x").result);
-
-static const string[] basicTypes = [
-  "char"[],   "wchar",   "dchar", "bool",
-  "byte",   "ubyte",   "short", "ushort",
-  "int",    "uint",    "long",  "ulong",
-  /+"cent",   "ucent",+/
-  "float",  "double",  "real",
-  "ifloat", "idouble", "ireal",
-  "cfloat", "cdouble", "creal"/+, "void"+/
-];
-
-static const string[] unaryExpressions = [
-  "!x",
-  "&x",
-  "~x",
-  "+x",
-  "-x",
-  "++x",
-  "--x",
-  "x++",
-  "x--",
-];
-
-static const string[] binaryExpressions = [
-  "x!<>=y",
-  "x!<>y",
-  "x!<=y",
-  "x!<y",
-  "x!>=y",
-  "x!>y",
-  "x<>=y",
-  "x<>y",
-
-  "x=y", "x==y", "x!=y",
-  "x<=y", "x<y",
-  "x>=y", "x>y",
-  "x<<=y", "x<<y",
-  "x>>=y","x>>y",
-  "x>>>=y", "x>>>y",
-  "x|=y", "x||y", "x|y",
-  "x&=y", "x&&y", "x&y",
-  "x+=y", "x+y",
-  "x-=y", "x-y",
-  "x/=y", "x/y",
-  "x*=y", "x*y",
-  "x%=y", "x%y",
-  "x^=y", "x^y",
-  "x~=y",
-  "x~y",
-  "x,y"
-];
-
-char[] genBinaryExpArray(char[] expression)
-{
-  char[] result = "[\n";
-  foreach (t1; basicTypes)
-  {
-    result ~= "[\n";
-    foreach (t2; basicTypes)
-      result ~= `EType!("`~t1~`", "`~t2~`", "`~expression~`").result,`\n;
-    result[result.length-2] = ']'; // Overwrite last comma.
-    result[result.length-1] = ','; // Overwrite last \n.
-  }
-  result[result.length-1] = ']'; // Overwrite last comma.
-  return result;
-}
-// pragma(msg, mixin(genBinaryExpArray("x%y")).stringof);
-
-char[] genBinaryExpsArray()
-{
-  char[] result = "[\n";
-  foreach (expression; binaryExpressions)
-  {
-    result ~= genBinaryExpArray(expression);
-    result ~= ",\n";
-  }
-  result[result.length-2] = ']';
-  return result;
-}
-
-// pragma(msg, mixin(genBinaryExpsArray()).stringof);
-
-char[] genUnaryExpArray(char[] expression)
-{
-  char[] result = "[\n";
-  foreach (t1; basicTypes)
-    result ~= `EType!("`~t1~`", "int", "`~expression~`").result,`\n;
-  result[result.length-2] = ']'; // Overwrite last comma.
-  return result;
-}
-
-char[] genUnaryExpsArray()
-{
-  char[] result = "[\n";
-  foreach (expression; unaryExpressions)
-    result ~= genUnaryExpArray(expression) ~ ",\n";
-  result[result.length-2] = ']';
-  return result;
-}
-
-// pragma(msg, mixin(genUnaryExpsArray()).stringof);
-
-auto unaryExpsResults = mixin(genUnaryExpsArray());
-auto binaryExpsResults = mixin(genBinaryExpsArray());
--- a/trunk/src/cmd/ASTStats.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module cmd.ASTStats;
-
-import dil.ast.DefaultVisitor;
-import dil.ast.Node,
-       dil.ast.Declaration,
-       dil.ast.Statement,
-       dil.ast.Expression,
-       dil.ast.Types;
-
-/// Counts the nodes in a syntax tree.
-class ASTStats : DefaultVisitor
-{
-  uint[] table; /// Table for counting nodes.
-
-  /// Starts counting.
-  uint[] count(Node root)
-  {
-    table = new uint[g_classNames.length];
-    super.visitN(root);
-    return table;
-  }
-
-  // Override dispatch function.
-  override Node dispatch(Node n)
-  {
-    table[n.kind]++;
-    return super.dispatch(n);
-  }
-}
--- a/trunk/src/cmd/DDoc.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,849 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module cmd.DDoc;
-
-import cmd.DDocXML;
-import cmd.Generate;
-import dil.doc.Parser;
-import dil.doc.Macro;
-import dil.doc.Doc;
-import dil.ast.Node;
-import dil.ast.Declarations,
-       dil.ast.Statements,
-       dil.ast.Expression,
-       dil.ast.Parameters,
-       dil.ast.Types;
-import dil.ast.DefaultVisitor;
-import dil.lexer.Token;
-import dil.lexer.Funcs;
-import dil.semantic.Module;
-import dil.semantic.Pass1;
-import dil.semantic.Symbol;
-import dil.semantic.Symbols;
-import dil.Compilation;
-import dil.Information;
-import dil.Converter;
-import dil.SourceText;
-import dil.Enums;
-import dil.Time;
-import common;
-
-import tango.text.Ascii : toUpper;
-import tango.io.File;
-import tango.io.FilePath;
-
-/// Executes the doc generation command.
-void execute(string[] filePaths, string destDir, string[] macroPaths,
-             bool writeXML, bool incUndoc, bool verbose,
-             CompilationContext context, InfoManager infoMan)
-{
-  // Parse macro files.
-  MacroTable mtable;
-  MacroParser mparser;
-  foreach (macroPath; macroPaths)
-  {
-    auto macros = mparser.parse(loadMacroFile(macroPath, infoMan));
-    mtable = new MacroTable(mtable);
-    mtable.insert(macros);
-  }
-
-//   foreach (k, v; mtable.table)
-//     Stdout(k)("=")(v.text);
-
-  // For DDoc code sections.
-  auto tokenHL = new TokenHighlighter(infoMan, writeXML == false);
-
-  // Process D files.
-  foreach (filePath; filePaths)
-  {
-    auto mod = new Module(filePath, infoMan);
-    // Parse the file.
-    mod.parse();
-    if (mod.hasErrors)
-      continue;
-
-    // Start semantic analysis.
-    auto pass1 = new SemanticPass1(mod, context);
-    pass1.start();
-
-    // Generate documentation.
-    auto dest = new FilePath(destDir);
-    dest.append(mod.getFQN() ~ (writeXML ? ".xml" : ".html"));
-
-    InfoManager infoMan2; // Collects warnings from the macro expander.
-    if (verbose)
-    {
-      Stdout.formatln("{} > {}", mod.filePath, dest);
-      infoMan2 = new InfoManager();
-    }
-
-    writeDocFile(dest.toString(), mod, mtable, writeXML, incUndoc, tokenHL, infoMan2);
-
-    if (infoMan2)
-      infoMan ~= infoMan2.info;
-  }
-}
-
-void writeDocFile(string dest, Module mod, MacroTable mtable,
-                  bool writeXML, bool incUndoc,
-                  TokenHighlighter tokenHL, InfoManager infoMan)
-{
-  // Create a macro environment for this module.
-  mtable = new MacroTable(mtable);
-  // Define runtime macros.
-  // MODPATH is not in the specs.
-  mtable.insert("MODPATH", mod.getFQNPath() ~ "." ~ mod.fileExtension());
-  mtable.insert("TITLE", mod.getFQN());
-  mtable.insert("DOCFILENAME", mod.getFQN() ~ (writeXML ? ".xml" : ".html"));
-  auto timeStr = Time.toString();
-  mtable.insert("DATETIME", timeStr);
-  mtable.insert("YEAR", Time.year(timeStr));
-
-  DDocEmitter docEmitter;
-  if (writeXML)
-    docEmitter = new DDocXMLEmitter(mod, mtable, incUndoc, tokenHL);
-  else
-    docEmitter = new DDocEmitter(mod, mtable, incUndoc, tokenHL);
-  docEmitter.emit();
-  // Set BODY macro to the text produced by the DDocEmitter.
-  mtable.insert("BODY", docEmitter.text);
-  // Do the macro expansion pass.
-  auto fileText = MacroExpander.expand(mtable, "$(DDOC)", mod.filePath, infoMan);
-// fileText ~= "\n<pre>\n" ~ doc.text ~ "\n</pre>";
-  // Finally write the file out to the harddisk.
-  auto file = new File(dest);
-  file.write(fileText);
-}
-
-/// Loads a macro file. Converts any Unicode encoding to UTF-8.
-string loadMacroFile(string filePath, InfoManager infoMan)
-{
-  auto src = new SourceText(filePath);
-  src.load(infoMan);
-  auto text = src.data[0..$-1]; // Exclude '\0'.
-  return sanitizeText(text);
-}
-
-/// Traverses the syntax tree and writes DDoc macros to a string buffer.
-class DDocEmitter : DefaultVisitor
-{
-  char[] text; /// The buffer that is written to.
-  bool includeUndocumented;
-  MacroTable mtable;
-  Module modul;
-  TokenHighlighter tokenHL;
-
-  /// Constructs a DDocEmitter object.
-  /// Params:
-  ///   modul = the module to generate text for.
-  ///   mtable = the macro table.
-  ///   includeUndocumented = whether to include undocumented symbols.
-  ///   tokenHL = used to highlight code sections.
-  this(Module modul, MacroTable mtable, bool includeUndocumented,
-       TokenHighlighter tokenHL)
-  {
-    this.mtable = mtable;
-    this.includeUndocumented = includeUndocumented;
-    this.modul = modul;
-    this.tokenHL = tokenHL;
-  }
-
-  /// Entry method.
-  char[] emit()
-  {
-    if (auto d = modul.moduleDecl)
-    {
-      if (ddoc(d))
-      {
-        if (auto copyright = cmnt.takeCopyright())
-          mtable.insert(new Macro("COPYRIGHT", copyright.text));
-        writeComment();
-      }
-    }
-    MEMBERS("MODULE", { visitD(modul.root); });
-    return text;
-  }
-
-  char[] textSpan(Token* left, Token* right)
-  {
-    //assert(left && right && (left.end <= right.start || left is right));
-    //char[] result;
-    //TODO: filter out whitespace tokens.
-    return Token.textSpan(left, right);
-  }
-
-  TemplateParameters tparams; /// The template parameters of the current declaration.
-
-  DDocComment cmnt; /// Current comment.
-  DDocComment prevCmnt; /// Previous comment in scope.
-  /// An empty comment. Used for undocumented symbols.
-  static const DDocComment emptyCmnt;
-
-  /// Initializes the empty comment.
-  static this()
-  {
-    this.emptyCmnt = new DDocComment(null, null, null);
-  }
-
-  /// Keeps track of previous comments in each scope.
-  scope class Scope
-  {
-    DDocComment saved_prevCmnt;
-    bool saved_cmntIsDitto;
-    uint saved_prevDeclOffset;
-    this()
-    { // Save the previous comment of the parent scope.
-      saved_prevCmnt = this.outer.prevCmnt;
-      saved_cmntIsDitto = this.outer.cmntIsDitto;
-      saved_prevDeclOffset = this.outer.prevDeclOffset; 
-      // Entering a new scope. Clear variables.
-      this.outer.prevCmnt = null;
-      this.outer.cmntIsDitto = false;
-      this.outer.prevDeclOffset = 0;
-    }
-
-    ~this()
-    { // Restore the previous comment of the parent scope.
-      this.outer.prevCmnt = saved_prevCmnt;
-      this.outer.cmntIsDitto = saved_cmntIsDitto;
-      this.outer.prevDeclOffset = saved_prevDeclOffset;
-    }
-  }
-
-  bool cmntIsDitto; /// True if current comment is "ditto".
-
-  /// Returns the DDocComment for node.
-  DDocComment ddoc(Node node)
-  {
-    auto c = getDDocComment(node);
-    this.cmnt = null;
-    if (c)
-    {
-      if (c.isDitto)
-      {
-        this.cmnt = this.prevCmnt;
-        this.cmntIsDitto = true;
-      }
-      else
-      {
-        this.cmntIsDitto = false;
-        this.cmnt = c;
-        this.prevCmnt = c;
-      }
-    }
-    else if (includeUndocumented)
-      this.cmnt = this.emptyCmnt;
-    return this.cmnt;
-  }
-
-  /// List of predefined, special sections.
-  static char[][char[]] specialSections;
-  static this()
-  {
-    foreach (name; ["AUTHORS", "BUGS", "COPYRIGHT", "DATE", "DEPRECATED",
-                    "EXAMPLES", "HISTORY", "LICENSE", "RETURNS", "SEE_ALSO",
-                    "STANDARDS", "THROWS", "VERSION"])
-      specialSections[name] = name;
-  }
-
-  /// Writes the DDoc comment to the text buffer.
-  void writeComment()
-  {
-    auto c = this.cmnt;
-    assert(c !is null);
-    if (c.sections.length == 0)
-      return;
-    write("$(DDOC_SECTIONS ");
-      foreach (s; c.sections)
-      {
-        if (s is c.summary)
-          write("\n$(DDOC_SUMMARY ");
-        else if (s is c.description)
-          write("\n$(DDOC_DESCRIPTION ");
-        else if (auto name = toUpper(s.name.dup) in specialSections)
-          write("\n$(DDOC_" ~ *name ~ " ");
-        else if (s.Is("params"))
-        { // Process parameters section.
-          auto ps = new ParamsSection(s.name, s.text);
-          write("\n$(DDOC_PARAMS ");
-          foreach (i, paramName; ps.paramNames)
-            write("\n$(DDOC_PARAM_ROW ",
-                    "$(DDOC_PARAM_ID $(DDOC_PARAM ", paramName, "))",
-                    "$(DDOC_PARAM_DESC ", ps.paramDescs[i], ")",
-                  ")");
-          write(")");
-          continue;
-        }
-        else if (s.Is("macros"))
-        { // Declare the macros in this section.
-          auto ms = new MacrosSection(s.name, s.text);
-          mtable.insert(ms.macroNames, ms.macroTexts);
-          continue;
-        }
-        else
-          write("\n$(DDOC_SECTION $(DDOC_SECTION_H " ~ s.name ~ ":)");
-        write(scanCommentText(s.text), ")");
-      }
-    write(")");
-  }
-
-  /// Scans the comment text and:
-  /// $(UL
-  /// $(LI skips and leaves macro invocations unchanged)
-  /// $(LI skips HTML tags)
-  /// $(LI escapes '(', ')', '<', '>' and '&')
-  /// $(LI inserts $&#40;DDOC_BLANKLINE&#41; in place of \n\n)
-  /// $(LI highlights code in code sections)
-  /// )
-  char[] scanCommentText(char[] text)
-  {
-    char* p = text.ptr;
-    char* end = p + text.length;
-    char[] result = new char[text.length]; // Reserve space.
-    result.length = 0;
-
-    while (p < end)
-    {
-      switch (*p)
-      {
-      case '$':
-        if (auto macroEnd = MacroParser.scanMacro(p, end))
-        {
-          result ~= makeString(p, macroEnd); // Copy macro invocation as is.
-          p = macroEnd;
-          continue;
-        }
-        goto default;
-      case '<':
-        auto begin = p;
-        p++;
-        if (p+2 < end && *p == '!' && p[1] == '-' && p[2] == '-') // <!--
-        {
-          p += 2; // Point to 2nd '-'.
-          // Scan to closing "-->".
-          while (++p < end)
-            if (p+2 < end && *p == '-' && p[1] == '-' && p[2] == '>')
-            {
-              p += 3; // Point one past '>'.
-              break;
-            }
-          result ~= makeString(begin, p);
-        } // <tag ...> or </tag>
-        else if (p < end && (isalpha(*p) || *p == '/'))
-        {
-          while (++p < end && *p != '>') // Skip to closing '>'.
-          {}
-          if (p == end)
-          { // No closing '>' found.
-            p = begin + 1;
-            result ~= "&lt;";
-            continue;
-          }
-          p++; // Skip '>'.
-          result ~= makeString(begin, p);
-        }
-        else
-          result ~= "&lt;";
-        continue;
-      case '(': result ~= "&#40;"; break;
-      case ')': result ~= "&#41;"; break;
-      // case '\'': result ~= "&apos;"; break; // &#39;
-      // case '"': result ~= "&quot;"; break;
-      case '>': result ~= "&gt;"; break;
-      case '&':
-        if (p+1 < end && (isalpha(p[1]) || p[1] == '#'))
-          goto default;
-        result ~= "&amp;";
-        break;
-      case '\n':
-        if (!(p+1 < end && p[1] == '\n'))
-          goto default;
-        ++p;
-        result ~= "$(DDOC_BLANKLINE)";
-        break;
-      case '-':
-        if (p+2 < end && p[1] == '-' && p[2] == '-')
-        {
-          while (p < end && *p == '-')
-            p++;
-          auto codeBegin = p;
-          p--;
-          while (++p < end)
-            if (p+2 < end && *p == '-' && p[1] == '-' && p[2] == '-')
-              break;
-          auto codeText = makeString(codeBegin, p);
-          result ~= tokenHL.highlight(codeText, modul.filePath);
-          while (p < end && *p == '-')
-            p++;
-          continue;
-        }
-        //goto default;
-      default:
-        result ~= *p;
-      }
-      p++;
-    }
-    return result;
-  }
-
-  /// Escapes '<', '>' and '&' with named HTML entities.
-  char[] escape(char[] text)
-  {
-    char[] result = new char[text.length]; // Reserve space.
-    result.length = 0;
-    foreach(c; text)
-      switch(c)
-      {
-        case '<': result ~= "&lt;";  break;
-        case '>': result ~= "&gt;";  break;
-        case '&': result ~= "&amp;"; break;
-        default:  result ~= c;
-      }
-    if (result.length != text.length)
-      return result;
-    // Nothing escaped. Return original text.
-    delete result;
-    return text;
-  }
-
-  /// Writes an array of strings to the text buffer.
-  void write(char[][] strings...)
-  {
-    foreach (s; strings)
-      text ~= s;
-  }
-
-  /// Writes params to the text buffer.
-  void writeParams(Parameters params)
-  {
-    if (!params.items.length)
-      return write("()");
-    write("(");
-    auto lastParam = params.items[$-1];
-    foreach (param; params.items)
-    {
-      if (param.isCVariadic)
-        write("...");
-      else
-      {
-        assert(param.type);
-        // Write storage classes.
-        auto typeBegin = param.type.baseType.begin;
-        if (typeBegin !is param.begin) // Write storage classes.
-          write(textSpan(param.begin, typeBegin.prevNWS), " ");
-        write(escape(textSpan(typeBegin, param.type.end))); // Write type.
-        if (param.name)
-          write(" $(DDOC_PARAM ", param.name.str, ")");
-        if (param.isDVariadic)
-          write("...");
-        if (param.defValue)
-          write(" = ", escape(textSpan(param.defValue.begin, param.defValue.end)));
-      }
-      if (param !is lastParam)
-        write(", ");
-    }
-    write(")");
-  }
-
-  /// Writes the current template parameters to the text buffer.
-  void writeTemplateParams()
-  {
-    if (!tparams)
-      return;
-    write(escape(textSpan(tparams.begin, tparams.end)));
-    tparams = null;
-  }
-
-  /// Writes bases to the text buffer.
-  void writeInheritanceList(BaseClassType[] bases)
-  {
-    if (bases.length == 0)
-      return;
-    auto basesBegin = bases[0].begin.prevNWS;
-    if (basesBegin.kind == TOK.Colon)
-      basesBegin = bases[0].begin;
-    write(" : ", escape(textSpan(basesBegin, bases[$-1].end)));
-  }
-
-  /// Writes a symbol to the text buffer. E.g: $&#40;SYMBOL Buffer, 123&#41;
-  void SYMBOL(char[] name, Declaration d)
-  {
-    auto loc = d.begin.getRealLocation();
-    auto str = Format("$(SYMBOL {}, {})", name, loc.lineNum);
-    write(str);
-    // write("$(DDOC_PSYMBOL ", name, ")");
-  }
-
-  /// Offset at which to insert a declaration which have a "ditto" comment.
-  uint prevDeclOffset;
-
-  /// Writes a declaration to the text buffer.
-  void DECL(void delegate() dg, Declaration d, bool writeSemicolon = true)
-  {
-    if (cmntIsDitto)
-    { alias prevDeclOffset offs;
-      assert(offs != 0);
-      auto savedText = text;
-      text = "";
-      write("\n$(DDOC_DECL ");
-      dg();
-      writeSemicolon && write(";");
-      writeAttributes(d);
-      write(")");
-      // Insert text at offset.
-      auto len = text.length;
-      text = savedText[0..offs] ~ text ~ savedText[offs..$];
-      offs += len; // Add length of the inserted text to the offset.
-      return;
-    }
-    write("\n$(DDOC_DECL ");
-    dg();
-    writeSemicolon && write(";");
-    writeAttributes(d);
-    write(")");
-    prevDeclOffset = text.length;
-  }
-
-  /// Wraps the DDOC_DECL_DD macro around the text written by dg().
-  void DESC(void delegate() dg)
-  {
-    if (cmntIsDitto)
-      return;
-    write("\n$(DDOC_DECL_DD ");
-    dg();
-    write(")");
-  }
-
-  /// Wraps the DDOC_kind_MEMBERS macro around the text written by dg().
-  void MEMBERS(char[] kind, void delegate() dg)
-  {
-    write("\n$(DDOC_"~kind~"_MEMBERS ");
-    dg();
-    write(")");
-  }
-
-  /// Writes a class or interface declaration.
-  void writeClassOrInterface(T)(T d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({
-      write(d.begin.srcText, " ");
-      SYMBOL(d.name.str, d);
-      writeTemplateParams();
-      writeInheritanceList(d.bases);
-    }, d);
-    DESC({
-      writeComment();
-      MEMBERS(is(T == ClassDeclaration) ? "CLASS" : "INTERFACE", {
-        scope s = new Scope();
-        d.decls && super.visit(d.decls);
-      });
-    });
-  }
-
-  // templated decls are not virtual so we need these:
-
-  /// Writes a class declaration.
-  void writeClass(ClassDeclaration d) {
-    writeClassOrInterface(d);
-  }
-
-  /// Writes an interface declaration.
-  void writeInterface(InterfaceDeclaration d) {
-    writeClassOrInterface(d);
-  }
-
-  /// Writes a struct or union declaration.
-  void writeStructOrUnion(T)(T d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({
-      write(d.begin.srcText, d.name ? " " : "");
-      if (d.name)
-        SYMBOL(d.name.str, d);
-      writeTemplateParams();
-    }, d);
-    DESC({
-      writeComment();
-      MEMBERS(is(T == StructDeclaration) ? "STRUCT" : "UNION", {
-        scope s = new Scope();
-        d.decls && super.visit(d.decls);
-      });
-    });
-  }
-
-  // templated decls are not virtual so we need these:
-
-  /// Writes a struct declaration.
-  void writeStruct(StructDeclaration d) {
-    writeStructOrUnion(d);
-  }
-
-  /// Writes an union declaration.
-  void writeUnion(UnionDeclaration d) {
-    writeStructOrUnion(d);
-  }
-
-  /// Writes an alias or typedef declaration.
-  void writeAliasOrTypedef(T)(T d)
-  {
-    auto prefix = is(T == AliasDeclaration) ? "alias " : "typedef ";
-    if (auto vd = d.decl.Is!(VariablesDeclaration))
-    {
-      auto type = textSpan(vd.typeNode.baseType.begin, vd.typeNode.end);
-      foreach (name; vd.names)
-        DECL({ write(prefix); write(escape(type), " "); SYMBOL(name.str, d); }, d);
-    }
-    else if (auto fd = d.decl.Is!(FunctionDeclaration))
-    {}
-    // DECL({ write(textSpan(d.begin, d.end)); }, false);
-    DESC({ writeComment(); });
-  }
-
-  /// Writes the attributes of a declaration in brackets.
-  void writeAttributes(Declaration d)
-  {
-    char[][] attributes;
-
-    if (d.prot != Protection.None)
-      attributes ~= "$(PROT " ~ .toString(d.prot) ~ ")";
-
-    auto stc = d.stc;
-    stc &= ~StorageClass.Auto; // Ignore auto.
-    foreach (stcStr; .toStrings(stc))
-      attributes ~= "$(STC " ~ stcStr ~ ")";
-
-    LinkageType ltype;
-    if (auto vd = d.Is!(VariablesDeclaration))
-      ltype = vd.linkageType;
-    else if (auto fd = d.Is!(FunctionDeclaration))
-      ltype = fd.linkageType;
-
-    if (ltype != LinkageType.None)
-      attributes ~= "$(LINKAGE extern(" ~ .toString(ltype) ~ "))";
-
-    if (!attributes.length)
-      return;
-
-    write(" $(ATTRIBUTES ");
-    write(attributes[0]);
-    foreach (attribute; attributes[1..$])
-      write(", ", attribute);
-    write(")");
-  }
-
-  alias Declaration D;
-
-override:
-  D visit(AliasDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    writeAliasOrTypedef(d);
-    return d;
-  }
-
-  D visit(TypedefDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    writeAliasOrTypedef(d);
-    return d;
-  }
-
-  D visit(EnumDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({
-      write("enum", d.name ? " " : "");
-      d.name && SYMBOL(d.name.str, d);
-    }, d);
-    DESC({
-      writeComment();
-      MEMBERS("ENUM", { scope s = new Scope(); super.visit(d); });
-    });
-    return d;
-  }
-
-  D visit(EnumMemberDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({ SYMBOL(d.name.str, d); }, d, false);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(TemplateDeclaration d)
-  {
-    this.tparams = d.tparams;
-    if (d.begin.kind != TOK.Template)
-    { // This is a templatized class/interface/struct/union/function.
-      super.visit(d.decls);
-      this.tparams = null;
-      return d;
-    }
-    if (!ddoc(d))
-      return d;
-    DECL({
-      write("template ");
-      SYMBOL(d.name.str, d);
-      writeTemplateParams();
-    }, d);
-    DESC({
-      writeComment();
-      MEMBERS("TEMPLATE", {
-        scope s = new Scope();
-        super.visit(d.decls);
-      });
-    });
-    return d;
-  }
-
-  D visit(ClassDeclaration d)
-  {
-    writeClass(d);
-    return d;
-  }
-
-  D visit(InterfaceDeclaration d)
-  {
-    writeInterface(d);
-    return d;
-  }
-
-  D visit(StructDeclaration d)
-  {
-    writeStruct(d);
-    return d;
-  }
-
-  D visit(UnionDeclaration d)
-  {
-    writeUnion(d);
-    return d;
-  }
-
-  D visit(ConstructorDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({ SYMBOL("this", d); writeParams(d.params); }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(StaticConstructorDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({ write("static "); SYMBOL("this", d); write("()"); }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(DestructorDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({ write("~"); SYMBOL("this", d); write("()"); }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(StaticDestructorDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({ write("static ~"); SYMBOL("this", d); write("()"); }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(FunctionDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    auto type = textSpan(d.returnType.baseType.begin, d.returnType.end);
-    DECL({
-      write(escape(type), " ");
-      SYMBOL(d.name.str, d);
-      writeTemplateParams();
-      writeParams(d.params);
-    }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(NewDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({ SYMBOL("new", d); writeParams(d.params); }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(DeleteDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({ SYMBOL("delete", d); writeParams(d.params); }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(VariablesDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    char[] type = "auto";
-    if (d.typeNode)
-      type = textSpan(d.typeNode.baseType.begin, d.typeNode.end);
-    foreach (name; d.names)
-      DECL({ write(escape(type), " "); SYMBOL(name.str, d); }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(InvariantDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({ SYMBOL("invariant", d); }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(UnittestDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({ SYMBOL("unittest", d); }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(DebugDeclaration d)
-  {
-    d.compiledDecls && visitD(d.compiledDecls);
-    return d;
-  }
-
-  D visit(VersionDeclaration d)
-  {
-    d.compiledDecls && visitD(d.compiledDecls);
-    return d;
-  }
-
-  D visit(StaticIfDeclaration d)
-  {
-    d.ifDecls && visitD(d.ifDecls);
-    return d;
-  }
-}
--- a/trunk/src/cmd/DDocXML.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,406 +0,0 @@
-/++
-  Authors: Aziz Köksal & Jari-Matti Mäkelä
-  License: GPL3
-+/
-module cmd.DDocXML;
-
-import cmd.DDoc;
-import cmd.Generate;
-import dil.doc.Parser;
-import dil.doc.Macro;
-import dil.doc.Doc;
-import dil.ast.Node;
-import dil.ast.Declarations,
-       dil.ast.Statements,
-       dil.ast.Expression,
-       dil.ast.Parameters,
-       dil.ast.Types;
-import dil.ast.DefaultVisitor;
-import dil.lexer.Token;
-import dil.lexer.Funcs;
-import dil.semantic.Module;
-import dil.semantic.Pass1;
-import dil.semantic.Symbol;
-import dil.semantic.Symbols;
-import dil.Compilation;
-import dil.Information;
-import dil.Converter;
-import dil.SourceText;
-import dil.Enums;
-import dil.Time;
-import common;
-
-import tango.text.Ascii : toUpper;
-import tango.io.File;
-import tango.io.FilePath;
-
-/// Traverses the syntax tree and writes DDoc macros to a string buffer.
-class DDocXMLEmitter : DDocEmitter
-{
-  this(Module modul, MacroTable mtable, bool includeUndocumented,
-       TokenHighlighter tokenHL)
-  {
-    super(modul, mtable, includeUndocumented, tokenHL);
-  }
-
-  /// Writes params to the text buffer.
-  void writeParams(Parameters params)
-  {
-    if (!params.items.length)
-      return;
-
-    write("$(PARAMS ");
-    auto lastParam = params.items[$-1];
-    foreach (param; params.items)
-    {
-      if (param.isCVariadic)
-        write("...");
-      else
-      {
-        assert(param.type);
-        // Write storage classes.
-        auto typeBegin = param.type.baseType.begin;
-        if (typeBegin !is param.begin) // Write storage classes.
-          write(textSpan(param.begin, typeBegin.prevNWS), " ");
-        write(escape(textSpan(typeBegin, param.type.end))); // Write type.
-        if (param.name)
-          write(" $(DDOC_PARAM ", param.name.str, ")");
-        if (param.isDVariadic)
-          write("...");
-        if (param.defValue)
-          write(" = ", escape(textSpan(param.defValue.begin, param.defValue.end)));
-      }
-      if (param !is lastParam)
-        write(", ");
-    }
-    write(")");
-  }
-
-  /// Writes the current template parameters to the text buffer.
-  void writeTemplateParams()
-  {
-    if (!tparams)
-      return;
-    write("$(TEMPLATE_PARAMS ", escape(textSpan(tparams.begin, tparams.end))[1..$-1], ")");
-    tparams = null;
-  }
-
-  /// Writes bases to the text buffer.
-  void writeInheritanceList(BaseClassType[] bases)
-  {
-    if (bases.length == 0)
-      return;
-    auto basesBegin = bases[0].begin.prevNWS;
-    if (basesBegin.kind == TOK.Colon)
-      basesBegin = bases[0].begin;
-    write("$(PARENTS ", escape(textSpan(basesBegin, bases[$-1].end)), ")");
-  }
-
-  /// Writes a symbol to the text buffer. E.g: $&#40;SYMBOL Buffer, 123&#41;
-  void SYMBOL(char[] name, Declaration d)
-  {
-    auto loc = d.begin.getRealLocation();
-    auto str = Format("$(SYMBOL {}, {})", name, loc.lineNum);
-    write(str);
-    // write("$(DDOC_PSYMBOL ", name, ")");
-  }
-
-  /// Writes a declaration to the text buffer.
-  void DECL(void delegate() dg, Declaration d, bool writeSemicolon = true)
-  {
-    if (cmntIsDitto)
-    { alias prevDeclOffset offs;
-      assert(offs != 0);
-      auto savedText = text;
-      text = "";
-      write("\n$(DDOC_DECL ");
-      dg();
-      writeAttributes(d);
-      write(")");
-      // Insert text at offset.
-      auto len = text.length;
-      text = savedText[0..offs] ~ text ~ savedText[offs..$];
-      offs += len; // Add length of the inserted text to the offset.
-      return;
-    }
-    write("\n$(DDOC_DECL ");
-    dg();
-    writeAttributes(d);
-    write(")");
-    prevDeclOffset = text.length;
-  }
-
-
-  /// Writes a class or interface declaration.
-  void writeClassOrInterface(T)(T d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({
-      write(d.begin.srcText, ", ");
-      SYMBOL(d.name.str, d);
-      writeTemplateParams();
-      writeInheritanceList(d.bases);
-    }, d);
-    DESC({
-      writeComment();
-      MEMBERS(is(T == ClassDeclaration) ? "CLASS" : "INTERFACE", {
-        scope s = new Scope();
-        d.decls && DefaultVisitor.visit(d.decls);
-      });
-    });
-  }
-
-  // templated decls are not virtual so we need these:
-
-  /// Writes a class declaration.
-  void writeClass(ClassDeclaration d) {
-    writeClassOrInterface(d);
-  }
-
-  /// Writes an interface declaration.
-  void writeInterface(InterfaceDeclaration d) {
-    writeClassOrInterface(d);
-  }
-
-  /// Writes a struct or union declaration.
-  void writeStructOrUnion(T)(T d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({
-      write(d.begin.srcText, d.name ? ", " : "");
-      if (d.name)
-        SYMBOL(d.name.str, d);
-      writeTemplateParams();
-    }, d);
-    DESC({
-      writeComment();
-      MEMBERS(is(T == StructDeclaration) ? "STRUCT" : "UNION", {
-        scope s = new Scope();
-        d.decls && DefaultVisitor.visit(d.decls);
-      });
-    });
-  }
-
-  // templated decls are not virtual so we need these:
-
-  /// Writes a struct declaration.
-  void writeStruct(StructDeclaration d) {
-    writeStructOrUnion(d);
-  }
-
-  /// Writes an union declaration.
-  void writeUnion(UnionDeclaration d) {
-    writeStructOrUnion(d);
-  }
-
-  /// Writes an alias or typedef declaration.
-  void writeAliasOrTypedef(T)(T d)
-  {
-    auto prefix = is(T == AliasDeclaration) ? "alias " : "typedef ";
-    if (auto vd = d.decl.Is!(VariablesDeclaration))
-    {
-      auto type = textSpan(vd.typeNode.baseType.begin, vd.typeNode.end);
-      foreach (name; vd.names)
-        DECL({ write(prefix, ", "); write(escape(type), " "); SYMBOL(name.str, d); }, d);
-    }
-    else if (auto fd = d.decl.Is!(FunctionDeclaration))
-    {}
-    // DECL({ write(textSpan(d.begin, d.end)); }, false);
-    DESC({ writeComment(); });
-  }
-
-
-  /// Writes the attributes of a declaration in brackets.
-  void writeAttributes(Declaration d)
-  {
-    char[][] attributes;
-
-    if (d.prot != Protection.None)
-      attributes ~= "$(PROT " ~ .toString(d.prot) ~ ")";
-
-    auto stc = d.stc;
-    stc &= ~StorageClass.Auto; // Ignore auto.
-    foreach (stcStr; .toStrings(stc))
-      attributes ~= "$(STC " ~ stcStr ~ ")";
-
-    LinkageType ltype;
-    if (auto vd = d.Is!(VariablesDeclaration))
-      ltype = vd.linkageType;
-    else if (auto fd = d.Is!(FunctionDeclaration))
-      ltype = fd.linkageType;
-
-    if (ltype != LinkageType.None)
-      attributes ~= "$(LINKAGE extern(" ~ .toString(ltype) ~ "))";
-
-    if (!attributes.length)
-      return;
-
-    write("$(ATTRIBUTES ");
-    foreach (attribute; attributes)
-      write(attribute);
-    write(")");
-  }
-
-  alias Declaration D;
-
-  alias DDocEmitter.visit visit;
-
-  D visit(EnumDeclaration d)
-  {
-      /+ FIXME: broken, infinite recursion :/
-    if (!ddoc(d))
-      return d;
-    DECL({
-      write("enum, ", d.name ? " " : "");
-      d.name && SYMBOL(d.name.str, d);
-    }, d);
-    DESC({
-      writeComment();
-      Stdout("help\n");
-///*FIXME*/      MEMBERS("ENUM", { scope s = new Scope(); DDocEmitter.visit(d); });
-    });
-    +/
-    return d;
-  }
-
-  D visit(EnumMemberDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({ write("member, "); SYMBOL(d.name.str, d); }, d, false);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(TemplateDeclaration d)
-  {
-    this.tparams = d.tparams;
-    if (d.begin.kind != TOK.Template)
-    { // This is a templatized class/interface/struct/union/function.
-      DefaultVisitor.visit(d.decls);
-      this.tparams = null;
-      return d;
-    }
-    if (!ddoc(d))
-      return d;
-    DECL({
-      write("template, ");
-      SYMBOL(d.name.str, d);
-      writeTemplateParams();
-    }, d);
-    DESC({
-      writeComment();
-      MEMBERS("TEMPLATE", {
-        scope s = new Scope();
-        DefaultVisitor.visit(d.decls);
-      });
-    });
-    return d;
-  }
-
-  D visit(ConstructorDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({ write("constructor, "); SYMBOL("this", d); writeParams(d.params); }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(StaticConstructorDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({ write("static constructor, "); SYMBOL("this", d); write("()"); }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(DestructorDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({ write("destructor, ~"); SYMBOL("this", d); }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(StaticDestructorDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({ write("static destructor, ~"); SYMBOL("this", d); }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(FunctionDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    auto type = textSpan(d.returnType.baseType.begin, d.returnType.end);
-    DECL({
-      write("function, ");
-      write("$(TYPE ");
-      write("$(RETURNS ", escape(type), ")");
-      writeTemplateParams();
-      writeParams(d.params);
-      write(")");
-      SYMBOL(d.name.str, d);
-    }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(NewDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({ write("new, "); SYMBOL("new", d); writeParams(d.params); }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(DeleteDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({ write("delete, "); SYMBOL("delete", d); writeParams(d.params); }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(VariablesDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    char[] type = "auto";
-    if (d.typeNode)
-      type = textSpan(d.typeNode.baseType.begin, d.typeNode.end);
-    foreach (name; d.names)
-      DECL({ write("variable, "); write("$(TYPE ", escape(type), ")"); SYMBOL(name.str, d); }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(InvariantDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({ write("invariant, "); SYMBOL("invariant", d); }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-  D visit(UnittestDeclaration d)
-  {
-    if (!ddoc(d))
-      return d;
-    DECL({ write("unittest, "); SYMBOL("unittest", d); }, d);
-    DESC({ writeComment(); });
-    return d;
-  }
-
-}
--- a/trunk/src/cmd/Generate.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,489 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module cmd.Generate;
-
-import dil.ast.DefaultVisitor;
-import dil.ast.Node,
-       dil.ast.Declaration,
-       dil.ast.Statement,
-       dil.ast.Expression,
-       dil.ast.Types;
-import dil.lexer.Lexer;
-import dil.parser.Parser;
-import dil.semantic.Module;
-import dil.SourceText;
-import dil.Information;
-import SettingsLoader;
-import Settings;
-import common;
-
-import tango.io.GrowBuffer;
-import tango.io.Print;
-
-/// Options for the generate command.
-enum GenOption
-{
-  Empty,
-  Tokens = 1,
-  Syntax = 1<<1,
-  HTML   = 1<<2,
-  XML    = 1<<3,
-  PrintLines  = 1<<4
-}
-
-/// Executes the generate command.
-void execute(string filePath, GenOption options, InfoManager infoMan)
-{
-  assert(options != GenOption.Empty);
-  auto mapFilePath = options & GenOption.HTML ? GlobalSettings.htmlMapFile
-                                              : GlobalSettings.xmlMapFile;
-  auto map = TagMapLoader(infoMan).load(mapFilePath);
-  auto tags = new TagMap(map);
-
-  if (infoMan.hasInfo)
-    return;
-
-  if (options & GenOption.Syntax)
-    highlightSyntax(filePath, tags, Stdout, options);
-  else
-    highlightTokens(filePath, tags, Stdout, options);
-}
-
-/// Escapes the characters '<', '>' and '&' with named character entities.
-char[] xml_escape(char[] text)
-{
-  char[] result;
-  foreach(c; text)
-    switch(c)
-    {
-      case '<': result ~= "&lt;";  break;
-      case '>': result ~= "&gt;";  break;
-      case '&': result ~= "&amp;"; break;
-      default:  result ~= c;
-    }
-  if (result.length != text.length)
-    return result;
-  // Nothing escaped. Return original text.
-  delete result;
-  return text;
-}
-
-/// Maps tokens to (format) strings.
-class TagMap
-{
-  string[string] table;
-  string[TOK.MAX] tokenTable;
-
-  this(string[string] table)
-  {
-    this.table = table;
-    Identifier   = this["Identifier", "{0}"];
-    String       = this["String", "{0}"];
-    Char         = this["Char", "{0}"];
-    Number       = this["Number", "{0}"];
-    Keyword      = this["Keyword", "{0}"];
-    LineC        = this["LineC", "{0}"];
-    BlockC       = this["BlockC", "{0}"];
-    NestedC      = this["NestedC", "{0}"];
-    Shebang      = this["Shebang", "{0}"];
-    HLine        = this["HLine", "{0}"];
-    Filespec     = this["Filespec", "{0}"];
-    Illegal      = this["Illegal", "{0}"];
-    Newline      = this["Newline", "{0}"];
-    SpecialToken = this["SpecialToken", "{0}"];
-    Declaration  = this["Declaration", "d"];
-    Statement    = this["Statement", "s"];
-    Expression   = this["Expression", "e"];
-    Type         = this["Type", "t"];
-    Other        = this["Other", "o"];
-    EOF          = this["EOF", ""];
-
-    foreach (i, tokStr; tokToString)
-      if (auto pStr = tokStr in this.table)
-        tokenTable[i] = *pStr;
-  }
-
-  /// Returns the value for str, or 'fallback' if str is not in the table.
-  string opIndex(string str, string fallback = "")
-  {
-    auto p = str in table;
-    if (p)
-      return *p;
-    return fallback;
-  }
-
-  /// Returns the value for tok in O(1) time.
-  string opIndex(TOK tok)
-  {
-    return tokenTable[tok];
-  }
-
-  /// Shortcuts for quick access.
-  string Identifier, String, Char, Number, Keyword, LineC, BlockC,
-         NestedC, Shebang, HLine, Filespec, Illegal, Newline, SpecialToken,
-         Declaration, Statement, Expression, Type, Other, EOF;
-
-  /// Returns the tag for the category 'nc'.
-  string getTag(NodeCategory nc)
-  {
-    string tag;
-    switch (nc)
-    { alias NodeCategory NC;
-    case NC.Declaration: tag = Declaration; break;
-    case NC.Statement:   tag = Statement; break;
-    case NC.Expression:  tag = Expression; break;
-    case NC.Type:        tag = Type; break;
-    case NC.Other:       tag = Other; break;
-    default: assert(0);
-    }
-    return tag;
-  }
-}
-
-/// Find the last occurrence of object in subject.
-/// Returns: the index if found, or -1 if not.
-int rfind(char[] subject, char object)
-{
-  foreach_reverse(i, c; subject)
-    if (c == object)
-      return i;
-  return -1;
-}
-
-/// Returns the short class name of a class descending from Node.$(BR)
-/// E.g.: dil.ast.Declarations.ClassDeclaration -> Class
-char[] getShortClassName(Node node)
-{
-  static char[][] name_table;
-  if (name_table is null)
-    name_table = new char[][NodeKind.max+1]; // Create a new table.
-  // Look up in table.
-  char[] name = name_table[node.kind];
-  if (name !is null)
-    return name; // Return cached name.
-
-  name = node.classinfo.name; // Get the fully qualified name of the class.
-  name = name[rfind(name, '.')+1 .. $]; // Remove package and module name.
-
-  uint suffixLength;
-  switch (node.category)
-  {
-  alias NodeCategory NC;
-  case NC.Declaration:
-    suffixLength = "Declaration".length;
-    break;
-  case NC.Statement:
-    suffixLength = "Statement".length;
-    break;
-  case NC.Expression:
-    suffixLength = "Expression".length;
-    break;
-  case NC.Type:
-    suffixLength = "Type".length;
-    break;
-  case NC.Other:
-    break;
-  default:
-    assert(0);
-  }
-  // Remove common suffix.
-  name = name[0 .. $ - suffixLength];
-  // Store the name in the table.
-  name_table[node.kind] = name;
-  return name;
-}
-
-/// Extended token structure.
-struct TokenEx
-{
-  Token* token; /// The lexer token.
-  Node[] beginNodes; /// beginNodes[n].begin == token
-  Node[] endNodes; /// endNodes[n].end == token
-}
-
-/// Builds an array of TokenEx items.
-class TokenExBuilder : DefaultVisitor
-{
-  private TokenEx*[Token*] tokenTable;
-
-  TokenEx[] build(Node root, Token* first)
-  {
-    auto token = first;
-
-    uint count; // Count tokens.
-    for (; token; token = token.next)
-      count++;
-    // Creat the exact number of TokenEx instances.
-    auto toks = new TokenEx[count];
-    token = first;
-    foreach (ref tokEx; toks)
-    {
-      tokEx.token = token;
-      if (!token.isWhitespace)
-        tokenTable[token] = &tokEx;
-      token = token.next;
-    }
-
-    super.visitN(root);
-    tokenTable = null;
-    return toks;
-  }
-
-  TokenEx* getTokenEx()(Token* t)
-  {
-    auto p = t in tokenTable;
-    assert(p, t.srcText~" is not in tokenTable");
-    return *p;
-  }
-
-  // Override dispatch function.
-  override Node dispatch(Node n)
-  {
-    auto begin = n.begin;
-    if (begin)
-    { assert(n.end);
-      auto txbegin = getTokenEx(begin);
-      auto txend = getTokenEx(n.end);
-      txbegin.beginNodes ~= n;
-      txend.endNodes ~= n;
-    }
-    return super.dispatch(n);
-  }
-}
-
-void printErrors(Lexer lx, TagMap tags, Print!(char) print)
-{
-  foreach (e; lx.errors)
-    print.format(tags["LexerError"], e.filePath, e.loc, e.col, xml_escape(e.getMsg));
-}
-
-void printErrors(Parser parser, TagMap tags, Print!(char) print)
-{
-  foreach (e; parser.errors)
-    print.format(tags["ParserError"], e.filePath, e.loc, e.col, xml_escape(e.getMsg));
-}
-
-void printLines(uint lines, TagMap tags, Print!(char) print)
-{
-  auto lineNumberFormat = tags["LineNumber"];
-  for (auto lineNum = 1; lineNum <= lines; lineNum++)
-    print.format(lineNumberFormat, lineNum);
-}
-
-// void printMultiline(Token* token, TagMap tags, Print!(char) print)
-// {
-// }
-
-/// Highlights the syntax in a source file.
-void highlightSyntax(string filePath, TagMap tags, Print!(char) print, GenOption options)
-{
-  auto parser = new Parser(new SourceText(filePath, true));
-  auto root = parser.start();
-  auto lx = parser.lexer;
-
-  auto builder = new TokenExBuilder();
-  auto tokenExList = builder.build(root, lx.firstToken());
-
-  print(tags["DocHead"]);
-  if (lx.errors.length || parser.errors.length)
-  { // Output error messages.
-    print(tags["CompBegin"]);
-    printErrors(lx, tags, print);
-    printErrors(parser, tags, print);
-    print(tags["CompEnd"]);
-  }
-
-  if (options & GenOption.PrintLines)
-  {
-    print(tags["LineNumberBegin"]);
-    printLines(lx.lineNum, tags, print);
-    print(tags["LineNumberEnd"]);
-  }
-
-  print(tags["SourceBegin"]);
-
-  auto tagNodeBegin = tags["NodeBegin"];
-  auto tagNodeEnd = tags["NodeEnd"];
-
-  // Iterate over list of tokens.
-  foreach (ref tokenEx; tokenExList)
-  {
-    auto token = tokenEx.token;
-
-    token.ws && print(token.wsChars); // Print preceding whitespace.
-    if (token.isWhitespace) {
-      printToken(token, tags, print);
-      continue;
-    }
-    // <node>
-    foreach (node; tokenEx.beginNodes)
-      print.format(tagNodeBegin, tags.getTag(node.category), getShortClassName(node));
-    // Token text.
-    printToken(token, tags, print);
-    // </node>
-    if (options & GenOption.HTML)
-      foreach_reverse (node; tokenEx.endNodes)
-        print(tagNodeEnd);
-    else
-      foreach_reverse (node; tokenEx.endNodes)
-        print.format(tagNodeEnd, tags.getTag(node.category));
-  }
-  print(tags["SourceEnd"]);
-  print(tags["DocEnd"]);
-}
-
-/// Highlights all tokens of a source file.
-void highlightTokens(string filePath, TagMap tags, Print!(char) print, GenOption options)
-{
-  auto lx = new Lexer(new SourceText(filePath, true));
-  lx.scanAll();
-
-  print(tags["DocHead"]);
-  if (lx.errors.length)
-  {
-    print(tags["CompBegin"]);
-    printErrors(lx, tags, print);
-    print(tags["CompEnd"]);
-  }
-
-  if (options & GenOption.PrintLines)
-  {
-    print(tags["LineNumberBegin"]);
-    printLines(lx.lineNum, tags, print);
-    print(tags["LineNumberEnd"]);
-  }
-
-  print(tags["SourceBegin"]);
-  // Traverse linked list and print tokens.
-  for (auto token = lx.firstToken(); token; token = token.next) {
-    token.ws && print(token.wsChars); // Print preceding whitespace.
-    printToken(token, tags, print);
-  }
-  print(tags["SourceEnd"]);
-  print(tags["DocEnd"]);
-}
-
-/// A token highlighter designed for DDoc.
-class TokenHighlighter
-{
-  TagMap tags;
-  this(InfoManager infoMan, bool useHTML = true)
-  {
-    string filePath = GlobalSettings.htmlMapFile;
-    if (!useHTML)
-      filePath = GlobalSettings.xmlMapFile;
-    auto map = TagMapLoader(infoMan).load(filePath);
-    tags = new TagMap(map);
-  }
-
-  /// Highlights tokens in a DDoc code section.
-  /// Returns: a string with the highlighted tokens (in HTML tags.)
-  string highlight(string text, string filePath)
-  {
-    auto buffer = new GrowBuffer(text.length);
-    auto print = new Print!(char)(Format, buffer);
-
-    auto lx = new Lexer(new SourceText(filePath, text));
-    lx.scanAll();
-
-    // Traverse linked list and print tokens.
-    print("$(D_CODE\n");
-    if (lx.errors.length)
-    { // Output error messages.
-      print(tags["CompBegin"]);
-      printErrors(lx, tags, print);
-      print(tags["CompEnd"]);
-    }
-    // Traverse linked list and print tokens.
-    for (auto token = lx.firstToken(); token; token = token.next) {
-      token.ws && print(token.wsChars); // Print preceding whitespace.
-      printToken(token, tags, print);
-    }
-    print("\n)");
-    return cast(char[])buffer.slice();
-  }
-}
-
-/// Prints a token to the stream print.
-void printToken(Token* token, TagMap tags, Print!(char) print)
-{
-  switch(token.kind)
-  {
-  case TOK.Identifier:
-    print.format(tags.Identifier, token.srcText);
-    break;
-  case TOK.Comment:
-    string formatStr;
-    switch (token.start[1])
-    {
-    case '/': formatStr = tags.LineC; break;
-    case '*': formatStr = tags.BlockC; break;
-    case '+': formatStr = tags.NestedC; break;
-    default: assert(0);
-    }
-    print.format(formatStr, xml_escape(token.srcText));
-    break;
-  case TOK.String:
-    print.format(tags.String, xml_escape(token.srcText));
-    break;
-  case TOK.CharLiteral:
-    print.format(tags.Char, xml_escape(token.srcText));
-    break;
-  case TOK.Int32, TOK.Int64, TOK.Uint32, TOK.Uint64,
-       TOK.Float32, TOK.Float64, TOK.Float80,
-       TOK.Imaginary32, TOK.Imaginary64, TOK.Imaginary80:
-    print.format(tags.Number, token.srcText);
-    break;
-  case TOK.Shebang:
-    print.format(tags.Shebang, xml_escape(token.srcText));
-    break;
-  case TOK.HashLine:
-    auto formatStr = tags.HLine;
-    // The text to be inserted into formatStr.
-    auto buffer = new GrowBuffer;
-    auto print2 = new Print!(char)(Format, buffer);
-
-    void printWS(char* start, char* end)
-    {
-      start != end && print2(start[0 .. end - start]);
-    }
-
-    auto num = token.tokLineNum;
-    if (num is null)
-    { // Malformed #line
-      print.format(formatStr, token.srcText);
-      break;
-    }
-
-    // Print whitespace between #line and number.
-    printWS(token.start, num.start); // Prints "#line" as well.
-    printToken(num, tags, print2); // Print the number.
-
-    if (auto filespec = token.tokLineFilespec)
-    { // Print whitespace between number and filespec.
-      printWS(num.end, filespec.start);
-      print2.format(tags.Filespec, xml_escape(filespec.srcText));
-    }
-    // Finally print the whole token.
-    print.format(formatStr, cast(char[])buffer.slice());
-    break;
-  case TOK.Illegal:
-    print.format(tags.Illegal, token.srcText());
-    break;
-  case TOK.Newline:
-    print.format(tags.Newline, token.srcText());
-    break;
-  case TOK.EOF:
-    print(tags.EOF);
-    break;
-  default:
-    if (token.isKeyword())
-      print.format(tags.Keyword, token.srcText);
-    else if (token.isSpecialToken)
-      print.format(tags.SpecialToken, token.srcText);
-    else
-      print(tags[token.kind]);
-  }
-}
--- a/trunk/src/cmd/ImportGraph.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,424 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module cmd.ImportGraph;
-
-import dil.ast.Node;
-import dil.ast.Declarations;
-import dil.semantic.Module;
-import dil.parser.ImportParser;
-import dil.SourceText;
-import dil.Compilation;
-import Settings;
-import common;
-
-import tango.text.Regex : RegExp = Regex;
-import tango.io.FilePath;
-import tango.io.FileConst;
-import tango.text.Util;
-
-alias FileConst.PathSeparatorChar dirSep;
-
-/// Options for the importgraph command.
-enum IGraphOption
-{
-  None,
-  IncludeUnlocatableModules = 1,
-  PrintDot                  = 1<<1,
-  HighlightCyclicEdges      = 1<<2,
-  HighlightCyclicVertices   = 1<<3,
-  GroupByPackageNames       = 1<<4,
-  GroupByFullPackageName    = 1<<5,
-  PrintPaths                = 1<<6,
-  PrintList                 = 1<<7,
-  MarkCyclicModules         = 1<<8,
-}
-
-/// Represents a module dependency graph.
-class Graph
-{
-  Vertex[] vertices; /// The vertices or modules.
-  Edge[] edges; /// The edges or import statements.
-
-  void addVertex(Vertex vertex)
-  {
-    vertex.id = vertices.length;
-    vertices ~= vertex;
-  }
-
-  Edge addEdge(Vertex from, Vertex to)
-  {
-    auto edge = new Edge(from, to);
-    edges ~= edge;
-    from.outgoing ~= to;
-    to.incoming ~= from;
-    return edge;
-  }
-
-  /// Walks the graph and marks cyclic vertices and edges.
-  void detectCycles()
-  { // Cycles could also be detected in the GraphBuilder,
-    // but having the code here makes things much clearer.
-
-    // Commented out because this algorithm doesn't work.
-    // Returns true if the vertex is in status Visiting.
-    /+bool visit(Vertex vertex)
-    {
-      switch (vertex.status)
-      {
-      case Vertex.Status.Visiting:
-        vertex.isCyclic = true;
-        return true;
-      case Vertex.Status.None:
-        vertex.status = Vertex.Status.Visiting; // Flag as visiting.
-        foreach (outVertex; vertex.outgoing)    // Visit successors.
-          vertex.isCyclic |= visit(outVertex);
-        vertex.status = Vertex.Status.Visited;  // Flag as visited.
-        break;
-      case Vertex.Status.Visited:
-        break;
-      default:
-        assert(0, "unknown vertex status");
-      }
-      return false; // return (vertex.status == Vertex.Status.Visiting);
-    }
-    // Start visiting vertices.
-    visit(vertices[0]);+/
-
-    //foreach (edge; edges)
-    //  if (edge.from.isCyclic && edge.to.isCyclic)
-    //    edge.isCyclic = true;
-
-    // Use functioning algorithm.
-    analyzeGraph(vertices, edges);
-  }
-}
-
-/// Represents a directed connection between two vertices.
-class Edge
-{
-  Vertex from;   /// Coming from vertex.
-  Vertex to;     /// Going to vertex.
-  bool isCyclic; /// Edge connects cyclic vertices.
-  bool isPublic; /// Public import.
-  bool isStatic; /// Static import.
-
-  this(Vertex from, Vertex to)
-  {
-    this.from = from;
-    this.to = to;
-  }
-}
-
-/// Represents a module in the graph.
-class Vertex
-{
-  Module modul;      /// The module represented by this vertex.
-  uint id;           /// The nth vertex in the graph.
-  Vertex[] incoming; /// Also called predecessors.
-  Vertex[] outgoing; /// Also called successors.
-  bool isCyclic;     /// Whether this vertex is in a cyclic relationship with other vertices.
-
-  enum Status : ubyte
-  { None, Visiting, Visited }
-  Status status; /// Used by the cycle detection algorithm.
-}
-
-/// Searches for a module in the file system looking in importPaths.
-/// Returns: the file path to the module, or null if it wasn't found.
-string findModuleFilePath(string moduleFQNPath, string[] importPaths)
-{
-  auto filePath = new FilePath();
-  foreach (importPath; importPaths)
-  {
-    filePath.set(importPath);
-    filePath.append(moduleFQNPath);
-    foreach (moduleSuffix; [".d", ".di"/*interface file*/])
-    {
-      filePath.suffix(moduleSuffix);
-      if (filePath.exists())
-        return filePath.toString();
-    }
-  }
-  return null;
-}
-
-/// Builds a module dependency graph.
-class GraphBuilder
-{
-  Graph graph;
-  IGraphOption options;
-  string[] importPaths; /// Where to look for modules.
-  Vertex[string] loadedModulesTable; /// Maps FQN paths to modules.
-  bool delegate(string) filterPredicate;
-
-  this()
-  {
-    this.graph = new Graph;
-  }
-
-  /// Start building the graph and return that.
-  /// Params:
-  ///   fileName = the file name of the root module.
-  Graph start(string fileName)
-  {
-    loadModule(fileName);
-    return graph;
-  }
-
-  /// Loads all modules recursively and builds the graph at the same time.
-  /// Params:
-  ///   moduleFQNPath = the path version of the module FQN.$(BR)
-  ///                   E.g.: FQN = dil.ast.Node -> FQNPath = dil/ast/Node
-  Vertex loadModule(string moduleFQNPath)
-  {
-    // Look up in table if the module is already loaded.
-    auto pVertex = moduleFQNPath in loadedModulesTable;
-    if (pVertex !is null)
-      return *pVertex; // Returns null for filtered or unlocatable modules.
-
-    // Filter out modules.
-    if (filterPredicate && filterPredicate(moduleFQNPath))
-    { // Store null for filtered modules.
-      loadedModulesTable[moduleFQNPath] = null;
-      return null;
-    }
-
-    // Locate the module in the file system.
-    auto moduleFilePath = findModuleFilePath(moduleFQNPath, importPaths);
-
-    Vertex vertex;
-
-    if (moduleFilePath is null)
-    { // Module not found.
-      if (options & IGraphOption.IncludeUnlocatableModules)
-      { // Include module nevertheless.
-        vertex = new Vertex;
-        vertex.modul = new Module("");
-        vertex.modul.setFQN(replace(moduleFQNPath, dirSep, '.'));
-        graph.addVertex(vertex);
-      }
-      // Store vertex in the table (vertex may be null.)
-      loadedModulesTable[moduleFQNPath] = vertex;
-    }
-    else
-    {
-      auto modul = new Module(moduleFilePath);
-      // Use lightweight ImportParser.
-      modul.setParser(new ImportParser(modul.sourceText));
-      modul.parse();
-
-      vertex = new Vertex;
-      vertex.modul = modul;
-
-      graph.addVertex(vertex);
-      loadedModulesTable[modul.getFQNPath()] = vertex;
-
-      // Load the modules which this module depends on.
-      foreach (importDecl; modul.imports)
-      {
-        foreach (moduleFQNPath2; importDecl.getModuleFQNs(dirSep))
-        {
-          auto loaded = loadModule(moduleFQNPath2);
-          if (loaded !is null)
-          {
-            auto edge = graph.addEdge(vertex, loaded);
-            edge.isPublic = importDecl.isPublic();
-            edge.isStatic = importDecl.isStatic();
-          }
-        }
-      }
-    }
-    return vertex;
-  }
-}
-
-/// Executes the importgraph command.
-void execute(string filePathString, CompilationContext context, string[] strRegexps,
-             uint levels, string siStyle, string piStyle, IGraphOption options)
-{
-  // Init regular expressions.
-  RegExp[] regexps;
-  foreach (strRegexp; strRegexps)
-    regexps ~= new RegExp(strRegexp);
-
-  // Add the directory of the file to the import paths.
-  auto filePath = new FilePath(filePathString);
-  auto fileDir = filePath.folder();
-  context.importPaths ~= fileDir;
-
-  auto gbuilder = new GraphBuilder;
-
-  gbuilder.importPaths = context.importPaths;
-  gbuilder.options = options;
-  gbuilder.filterPredicate = (string moduleFQNPath) {
-    foreach (rx; regexps)
-      // Replace slashes: dil/ast/Node -> dil.ast.Node
-      if (rx.test(replace(moduleFQNPath.dup, dirSep, '.')))
-        return true;
-    return false;
-  };
-
-  auto graph = gbuilder.start(filePath.name());
-
-  if (options & (IGraphOption.PrintList | IGraphOption.PrintPaths))
-  {
-    if (options & IGraphOption.MarkCyclicModules)
-      graph.detectCycles();
-
-    if (options & IGraphOption.PrintPaths)
-      printModulePaths(graph.vertices, levels+1, "");
-    else
-      printModuleList(graph.vertices, levels+1, "");
-  }
-  else
-    printDotDocument(graph, siStyle, piStyle, options);
-}
-
-/// Prints the file paths to the modules.
-void printModulePaths(Vertex[] vertices, uint level, char[] indent)
-{
-  if (level == 0)
-    return;
-  foreach (vertex; vertices)
-  {
-    Stdout(indent)((vertex.isCyclic?"*":"")~vertex.modul.filePath).newline;
-    if (vertex.outgoing.length)
-      printModulePaths(vertex.outgoing, level-1, indent~"  ");
-  }
-}
-
-/// Prints a list of module FQNs.
-void printModuleList(Vertex[] vertices, uint level, char[] indent)
-{
-  if (level == 0)
-    return;
-  foreach (vertex; vertices)
-  {
-    Stdout(indent)((vertex.isCyclic?"*":"")~vertex.modul.getFQN()).newline;
-    if (vertex.outgoing.length)
-      printModuleList(vertex.outgoing, level-1, indent~"  ");
-  }
-}
-
-/// Prints the graph as a graphviz dot document.
-void printDotDocument(Graph graph, string siStyle, string piStyle,
-                      IGraphOption options)
-{
-  Vertex[][string] verticesByPckgName;
-  if (options & IGraphOption.GroupByFullPackageName)
-    foreach (vertex; graph.vertices)
-      verticesByPckgName[vertex.modul.packageName] ~= vertex;
-
-  if (options & (IGraphOption.HighlightCyclicVertices |
-                 IGraphOption.HighlightCyclicEdges))
-    graph.detectCycles();
-
-  // Output header of the dot document.
-  Stdout("Digraph ImportGraph\n{\n");
-  // Output nodes.
-  // 'i' and vertex.id should be the same.
-  foreach (i, vertex; graph.vertices)
-    Stdout.formatln(`  n{} [label="{}"{}];`, i, vertex.modul.getFQN(), (vertex.isCyclic ? ",style=filled,fillcolor=tomato" : ""));
-
-  // Output edges.
-  foreach (edge; graph.edges)
-  {
-    string edgeStyles = "";
-    if (edge.isStatic || edge.isPublic)
-    {
-      edgeStyles = `[style="`;
-      edge.isStatic && (edgeStyles ~= siStyle ~ ",");
-      edge.isPublic && (edgeStyles ~= piStyle);
-      edgeStyles[$-1] == ',' && (edgeStyles = edgeStyles[0..$-1]); // Remove last comma.
-      edgeStyles ~= `"]`;
-    }
-    edge.isCyclic && (edgeStyles ~= "[color=red]");
-    Stdout.formatln(`  n{} -> n{} {};`, edge.from.id, edge.to.id, edgeStyles);
-  }
-
-  if (options & IGraphOption.GroupByFullPackageName)
-    foreach (packageName, vertices; verticesByPckgName)
-    { // Output nodes in a cluster.
-      Stdout.format(`  subgraph "cluster_{}" {`\n`    label="{}";color=blue;`"\n    ", packageName, packageName);
-      foreach (vertex; vertices)
-        Stdout.format(`n{};`, vertex.id);
-      Stdout("\n  }\n");
-    }
-
-  Stdout("}\n");
-}
-
-// This is the old algorithm that was used to detect cycles in a directed graph.
-void analyzeGraph(Vertex[] vertices_init, Edge[] edges)
-{
-  edges = edges.dup;
-  void recursive(Vertex[] vertices)
-  {
-    foreach (idx, vertex; vertices)
-    {
-      uint outgoing, incoming;
-      foreach (j, edge; edges)
-      {
-        if (edge.from is vertex)
-          outgoing++;
-        if (edge.to is vertex)
-          incoming++;
-      }
-
-      if (outgoing == 0)
-      {
-        if (incoming != 0)
-        {
-          // Vertex is a sink.
-          alias outgoing i; // Reuse
-          alias incoming j; // Reuse
-          // Remove edges.
-          for (i=j=0; i < edges.length; i++)
-            if (edges[i].to !is vertex)
-              edges[j++] = edges[i];
-          edges.length = j;
-          vertices = vertices[0..idx] ~ vertices[idx+1..$];
-          recursive(vertices);
-          return;
-        }
-        else
-        {
-          // Edges to this vertex were removed previously.
-          // Only remove vertex now.
-          vertices = vertices[0..idx] ~ vertices[idx+1..$];
-          recursive(vertices);
-          return;
-        }
-      }
-      else if (incoming == 0)
-      {
-        // Vertex is a source
-        alias outgoing i; // Reuse
-        alias incoming j; // Reuse
-        // Remove edges.
-        for (i=j=0; i < edges.length; i++)
-          if (edges[i].from !is vertex)
-            edges[j++] = edges[i];
-        edges.length = j;
-        vertices = vertices[0..idx] ~ vertices[idx+1..$];
-        recursive(vertices);
-        return;
-      }
-//       else
-//       {
-//         // source && sink
-//         // continue loop.
-//       }
-    }
-
-    // When reaching this point it means only cylic edges and vertices are left.
-    foreach (vertex; vertices)
-      vertex.isCyclic = true;
-    foreach (edge; edges)
-      if (edge)
-        edge.isCyclic = true;
-  }
-  recursive(vertices_init);
-}
--- a/trunk/src/cmd/Statistics.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,212 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module cmd.Statistics;
-
-import cmd.ASTStats;
-import dil.lexer.Lexer;
-import dil.lexer.Token;
-import dil.parser.Parser;
-import dil.ast.NodesEnum;
-import dil.SourceText;
-import common;
-
-/// A group of statistics variables.
-struct Statistics
-{
-  uint whitespaceCount; /// Counter for whitespace characters.
-  uint wsTokenCount;    /// Counter for all whitespace tokens.
-  uint keywordCount;    /// Counter for keywords.
-  uint identCount;      /// Counter for identifiers.
-  uint numberCount;     /// Counter for number literals.
-  uint commentCount;    /// Counter for comments.
-  uint tokenCount;      /// Counter for all tokens produced by the Lexer.
-  uint linesOfCode;     /// Number of lines.
-  uint[] tokensTable;   /// Table of counters for all token kinds.
-  uint[] nodesTable;    /// Table of counters for all node kinds.
-
-  static Statistics opCall(bool allocateTokensTable, bool allocateNodesTable = false)
-  {
-    Statistics s;
-    if (allocateTokensTable)
-      s.tokensTable = new uint[TOK.MAX];
-    if (allocateNodesTable)
-      s.nodesTable = new uint[g_classNames.length];
-    return s;
-  }
-
-  void opAddAssign(Statistics s)
-  {
-    this.whitespaceCount += s.whitespaceCount;
-    this.wsTokenCount    += s.wsTokenCount;
-    this.keywordCount    += s.keywordCount;
-    this.identCount      += s.identCount;
-    this.numberCount     += s.numberCount;
-    this.commentCount    += s.commentCount;
-    this.tokenCount      += s.tokenCount;
-    this.linesOfCode     += s.linesOfCode;
-    foreach (i, count; s.tokensTable)
-      this.tokensTable[i] += count;
-    foreach (i, count; s.nodesTable)
-      this.nodesTable[i] += count;
-  }
-}
-
-/// Executes the statistics command.
-void execute(string[] filePaths, bool printTokensTable, bool printNodesTable)
-{
-  Statistics[] stats;
-  foreach (filePath; filePaths)
-    stats ~= getStatistics(filePath, printTokensTable, printNodesTable);
-
-  auto total = Statistics(printTokensTable, printNodesTable);
-
-  foreach (i, ref stat; stats)
-  {
-    total += stat;
-    Stdout.formatln(
-      "----\n"
-      "File: {}\n"
-      "Whitespace character count: {}\n"
-      "Whitespace token count: {}\n"
-      "Keyword count: {}\n"
-      "Identifier count: {}\n"
-      "Number count: {}\n"
-      "Comment count: {}\n"
-      "All tokens count: {}\n"
-      "Lines of code: {}",
-      filePaths[i],
-      stat.whitespaceCount,
-      stat.wsTokenCount,
-      stat.keywordCount,
-      stat.identCount,
-      stat.numberCount,
-      stat.commentCount,
-      stat.tokenCount,
-      stat.linesOfCode
-    );
-  }
-
-  if (filePaths.length > 1)
-  {
-    Stdout.formatln(
-      "--------------------------------------------------------------------------------\n"
-      "Total of {} files:\n"
-      "Whitespace character count: {}\n"
-      "Whitespace token count: {}\n"
-      "Keyword count: {}\n"
-      "Identifier count: {}\n"
-      "Number count: {}\n"
-      "Comment count: {}\n"
-      "All tokens count: {}\n"
-      "Lines of code: {}",
-      filePaths.length,
-      total.whitespaceCount,
-      total.wsTokenCount,
-      total.keywordCount,
-      total.identCount,
-      total.numberCount,
-      total.commentCount,
-      total.tokenCount,
-      total.linesOfCode
-    );
-  }
-
-  if (printTokensTable)
-  {
-    Stdout("Table of tokens:").newline;
-    Stdout.formatln(" {,10} | {}", "Count", "Token kind");
-    Stdout("-----------------------------").newline;
-    foreach (i, count; total.tokensTable)
-      Stdout.formatln(" {,10} | {}", count, Token.toString(cast(TOK)i));
-    Stdout("// End of tokens table.").newline;
-  }
-
-  if(printNodesTable)
-  {
-    Stdout("Table of nodes:").newline;
-    Stdout.formatln(" {,10} | {}", "Count", "Node kind");
-    Stdout("-----------------------------").newline;
-    foreach (i, count; total.nodesTable)
-      Stdout.formatln(" {,10} | {}", count, g_classNames[i]);
-    Stdout("// End of nodes table.").newline;
-  }
-}
-
-/// Returns the statistics for a D source file.
-Statistics getStatistics(string filePath, bool printTokensTable, bool printNodesTable)
-{
-  // Create a new record.
-  auto stats = Statistics(printTokensTable);
-
-  auto sourceText = new SourceText(filePath, true);
-  Parser parser;
-  Lexer lx;
-  if (printNodesTable)
-  {
-    parser = new Parser(sourceText);
-    auto rootNode = parser.start();
-    // Count nodes.
-    stats.nodesTable = (new ASTStats).count(rootNode);
-    lx = parser.lexer;
-  }
-  else
-  {
-    lx = new Lexer(sourceText);
-    lx.scanAll();
-  }
-
-  auto token = lx.firstToken();
-
-  // Count tokens.
-  // Lexer creates HEAD + Newline, which are not in the source text.
-  // No token left behind!
-  stats.tokenCount = 2;
-  stats.linesOfCode = lx.lineNum;
-  if (printTokensTable)
-  {
-    stats.tokensTable[TOK.HEAD] = 1;
-    stats.tokensTable[TOK.Newline] = 1;
-  }
-  // Traverse linked list.
-  while (1)
-  {
-    stats.tokenCount += 1;
-
-    if (printTokensTable)
-      stats.tokensTable[token.kind] += 1;
-
-    // Count whitespace characters
-    if (token.ws !is null)
-      stats.whitespaceCount += token.start - token.ws;
-
-    switch (token.kind)
-    {
-    case TOK.Identifier:
-      stats.identCount++;
-      break;
-    case TOK.Comment:
-      stats.commentCount++;
-      break;
-    case TOK.Int32, TOK.Int64, TOK.Uint32, TOK.Uint64,
-         TOK.Float32, TOK.Float64, TOK.Float80,
-         TOK.Imaginary32, TOK.Imaginary64, TOK.Imaginary80:
-      stats.numberCount++;
-      break;
-    case TOK.Newline:
-      break;
-    default:
-      if (token.isKeyword)
-        stats.keywordCount++;
-      else if (token.isWhitespace)
-        stats.wsTokenCount++;
-    }
-
-    if (token.next is null)
-      break;
-    token = token.next;
-  }
-  assert(token.kind == TOK.EOF);
-  return stats;
-}
--- a/trunk/src/common.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module common;
-
-public import tango.io.Stdout;
-public import tango.text.convert.Layout;
-
-/// String aliases.
-alias char[] string;
-alias wchar[] wstring; /// ditto
-alias dchar[] dstring; /// ditto
-
-/// Global formatter instance.
-static Layout!(char) Format;
-static this()
-{
-  Format = new typeof(Format);
-}
--- a/trunk/src/config.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/// The configuration file of dil.
-///
-/// Relative paths are resolved from the directory of the executable.
-module config;
-
-/// Predefined version identifiers.
-var version_ids = ["X86", "linux", "LittleEndian"];
-// "X86_64", "Windows", "Win32", "Win64", "BigEndian"
-
-/// Path to the language file.
-var langfile = "lang_en.d";
-
-/// An array of import paths to look for modules.
-var import_paths = []; /// E.g.: ["src/", "import/"]
-
-/// DDoc macro file paths.
-///
-/// Macro definitions in ddoc_files[n] override the ones in ddoc_files[n-1].
-var ddoc_files = ["predefined.ddoc"]; /// E.g.: ["src/mymacros.ddoc", "othermacros.ddoc"]
-
-var xml_map = "xml_map.d";
-var html_map = "html_map.d";
-
-/// Customizable formats for error messages.
-///
-/// <ul>
-///   <li>0: file path to the source text.</li>
-///   <li>1: line number.</li>
-///   <li>2: column number.</li>
-///   <li>3: error message.</li>
-/// </ul>
-var lexer_error = "{0}({1},{2})L: {3}";
-var parser_error = "{0}({1},{2})P: {3}"; /// ditto
-var semantic_error = "{0}({1},{2})S: {3}"; /// ditto
--- a/trunk/src/dil/Compilation.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.Compilation;
-
-import common;
-
-/// A group of settings relevant to the compilation process.
-class CompilationContext
-{
-  alias typeof(this) CC;
-  CC parent;
-  string[] importPaths;
-  uint debugLevel;
-  uint versionLevel;
-  bool[string] debugIds;
-  bool[string] versionIds;
-  bool releaseBuild;
-  uint structAlign = 4;
-
-  this(CC parent = null)
-  {
-    this.parent = parent;
-    if (parent)
-    {
-      this.importPaths = parent.importPaths.dup;
-      this.debugLevel = parent.debugLevel;
-      this.versionLevel = parent.versionLevel;
-      this.releaseBuild = parent.releaseBuild;
-      this.structAlign = parent.structAlign;
-    }
-  }
-
-  void addDebugId(string id)
-  {
-    debugIds[id] = true;
-  }
-
-  void addVersionId(string id)
-  {
-    versionIds[id] = true;
-  }
-
-  bool findDebugId(string id)
-  {
-    auto pId = id in debugIds;
-    if (pId)
-      return true;
-    if (!isRoot())
-      return parent.findDebugId(id);
-    return false;
-  }
-
-  bool findVersionId(string id)
-  {
-    auto pId = id in versionIds;
-    if (pId)
-      return true;
-    if (!isRoot())
-      return parent.findVersionId(id);
-    return false;
-  }
-
-  bool isRoot()
-  {
-    return parent is null;
-  }
-}
--- a/trunk/src/dil/CompilerInfo.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.CompilerInfo;
-
-version(D2)
-  /// The major version number of this compiler.
-  const uint VERSION_MAJOR = 2;
-else
-  /// The major version number of this compiler.
-  const uint VERSION_MAJOR = 1;
-
-/// The minor version number of this compiler.
-const uint VERSION_MINOR = 0;
-
-private char[] toString(uint x)
-{
-  char[] str;
-  do
-    str = cast(char)('0' + (x % 10)) ~ str;
-  while (x /= 10)
-  return str;
-}
-
-private char[] toString(uint x, uint pad)
-{
-  char[] str = toString(x);
-  if (pad < str.length)
-    return str;
-  for (uint i = pad-str.length; i; i--)
-    str = "0" ~ str;
-  return str;
-}
-
-/// The compiler version formatted as a string.
-const char[] VERSION = toString(VERSION_MAJOR)~"."~toString(VERSION_MINOR, 3);
-/// The name of the compiler.
-const char[] VENDOR = "dil";
-
-/// The global, default alignment size for struct fields.
-const uint DEFAULT_ALIGN_SIZE = 4;
-
-version(DDoc)
-  const uint PTR_SIZE = 0; /// The pointer size depending on the platform.
-else
-version(X86_64)
-  const uint PTR_SIZE = 8; // Pointer size on 64-bit platforms.
-else
-  const uint PTR_SIZE = 4; // Pointer size on 32-bit platforms.
--- a/trunk/src/dil/Converter.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,334 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.Converter;
-
-import dil.Information;
-import dil.Location;
-import dil.Unicode;
-import dil.FileBOM;
-import dil.lexer.Funcs;
-import dil.Messages;
-import common;
-
-/// Converts various Unicode encoding formats to UTF-8.
-struct Converter
-{
-  char[] filePath; /// For error messages.
-  InfoManager infoMan;
-
-  static Converter opCall(char[] filePath, InfoManager infoMan)
-  {
-    Converter conv;
-    conv.filePath = filePath;
-    conv.infoMan = infoMan;
-    return conv;
-  }
-
-  /// Byte-swaps c.
-  dchar swapBytes(dchar c)
-  {
-    return c = (c << 24) |
-              ((c >> 8) & 0xFF00) |
-              ((c << 8) & 0xFF0000) |
-              (c >> 24);
-  }
-
-  /// Byte-swaps c.
-  wchar swapBytes(wchar c)
-  {
-    return (c << 8) | (c >> 8);
-  }
-
-  /// Swaps the bytes of c on a little-endian machine.
-  dchar BEtoMachineDword(dchar c)
-  {
-    version(LittleEndian)
-      return swapBytes(c);
-    else
-      return c;
-  }
-
-  /// Swaps the bytes of c on a big-endian machine.
-  dchar LEtoMachineDword(dchar c)
-  {
-    version(LittleEndian)
-      return c;
-    else
-      return swapBytes(c);
-  }
-
-  /// Swaps the bytes of c on a little-endian machine.
-  wchar BEtoMachineWord(wchar c)
-  {
-    version(LittleEndian)
-      return swapBytes(c);
-    else
-      return c;
-  }
-
-  /// Swaps the bytes of c on a big-endian machine.
-  wchar LEtoMachineWord(wchar c)
-  {
-    version(LittleEndian)
-      return c;
-    else
-      return swapBytes(c);
-  }
-
-  /// Converts a UTF-32 text to UTF-8.
-  char[] UTF32toUTF8(bool isBigEndian)(ubyte[] data)
-  {
-    if (data.length == 0)
-      return null;
-
-    char[] result;
-    uint lineNum = 1;
-    dchar[] text = cast(dchar[]) data[0 .. $-($%4)]; // Trim to multiple of 4.
-    foreach (dchar c; text)
-    {
-      static if (isBigEndian)
-        c = BEtoMachineDword(c);
-      else
-        c = LEtoMachineDword(c);
-
-      if (!isValidChar(c))
-      {
-        infoMan ~= new LexerError(
-          new Location(filePath, lineNum),
-          Format(MSG.InvalidUTF32Character, c)
-        );
-        c = REPLACEMENT_CHAR;
-      }
-
-      if (isNewline(c))
-        ++lineNum;
-      dil.Unicode.encode(result, c);
-    }
-
-    if (data.length % 4)
-      infoMan ~= new LexerError(
-        new Location(filePath, lineNum),
-        MSG.UTF32FileMustBeDivisibleBy4
-      );
-
-    return result;
-  }
-
-  alias UTF32toUTF8!(true) UTF32BEtoUTF8; /// Instantiation for UTF-32 BE.
-  alias UTF32toUTF8!(false) UTF32LEtoUTF8; /// Instantiation for UTF-32 LE.
-
-  /// Converts a UTF-16 text to UTF-8.
-  char[] UTF16toUTF8(bool isBigEndian)(ubyte[] data)
-  {
-    if (data.length == 0)
-      return null;
-
-    wchar[] text = cast(wchar[]) data[0 .. $-($%2)]; // Trim to multiple of two.
-    wchar* p = text.ptr,
-         end = text.ptr + text.length;
-    char[] result;
-    uint lineNum = 1;
-
-    for (; p < end; p++)
-    {
-      dchar c = *p;
-      static if (isBigEndian)
-        c = BEtoMachineWord(c);
-      else
-        c = LEtoMachineWord(c);
-
-      if (0xD800 > c || c > 0xDFFF)
-      {}
-      else if (c <= 0xDBFF && p+1 < end)
-      { // Decode surrogate pairs.
-        wchar c2 = p[1];
-        static if (isBigEndian)
-          c2 = BEtoMachineWord(c2);
-        else
-          c2 = LEtoMachineWord(c2);
-
-        if (0xDC00 <= c2 && c2 <= 0xDFFF)
-        {
-          c = (c - 0xD7C0) << 10;
-          c |= (c2 & 0x3FF);
-          ++p;
-        }
-      }
-      else
-      {
-        infoMan ~= new LexerError(
-          new Location(filePath, lineNum),
-          Format(MSG.InvalidUTF16Character, c)
-        );
-        c = REPLACEMENT_CHAR;
-      }
-
-      if (isNewline(c))
-        ++lineNum;
-      dil.Unicode.encode(result, c);
-    }
-
-    if (data.length % 2)
-      infoMan ~= new LexerError(
-        new Location(filePath, lineNum),
-        MSG.UTF16FileMustBeDivisibleBy2
-      );
-    return result;
-  }
-
-  alias UTF16toUTF8!(true) UTF16BEtoUTF8; /// Instantiation for UTF-16 BE.
-  alias UTF16toUTF8!(false) UTF16LEtoUTF8; /// Instantiation for UTF-16 LE.
-
-  /// Converts the text in data to UTF-8.
-  /// Leaves data unchanged if it is in UTF-8 already.
-  char[] data2UTF8(ubyte[] data)
-  {
-    if (data.length == 0)
-      return "";
-
-    char[] text;
-    BOM bom = tellBOM(data);
-
-    switch (bom)
-    {
-    case BOM.None:
-      // No BOM found. According to the specs the first character
-      // must be an ASCII character.
-      if (data.length >= 4)
-      {
-        if (data[0..3] == cast(ubyte[3])x"00 00 00")
-        {
-          text = UTF32BEtoUTF8(data); // UTF-32BE: 00 00 00 XX
-          break;
-        }
-        else if (data[1..4] == cast(ubyte[3])x"00 00 00")
-        {
-          text = UTF32LEtoUTF8(data); // UTF-32LE: XX 00 00 00
-          break;
-        }
-      }
-      if (data.length >= 2)
-      {
-        if (data[0] == 0) // UTF-16BE: 00 XX
-        {
-          text = UTF16BEtoUTF8(data);
-          break;
-        }
-        else if (data[1] == 0) // UTF-16LE: XX 00
-        {
-          text = UTF16LEtoUTF8(data);
-          break;
-        }
-      }
-      text = cast(char[])data; // UTF-8
-      break;
-    case BOM.UTF8:
-      text = cast(char[])data[3..$];
-      break;
-    case BOM.UTF16BE:
-      text = UTF16BEtoUTF8(data[2..$]);
-      break;
-    case BOM.UTF16LE:
-      text = UTF16LEtoUTF8(data[2..$]);
-      break;
-    case BOM.UTF32BE:
-      text = UTF32BEtoUTF8(data[4..$]);
-      break;
-    case BOM.UTF32LE:
-      text = UTF32LEtoUTF8(data[4..$]);
-      break;
-    default:
-      assert(0);
-    }
-    return text;
-  }
-}
-
-/// Replaces invalid UTF-8 sequences with U+FFFD (if there's enough space,)
-/// and Newlines with '\n'.
-string sanitizeText(string text)
-{
-  if (!text.length)
-    return null;
-
-  char* p = text.ptr;
-  char* end = p + text.length;
-  char* q = p;
-
-  for (; p < end; p++, q++)
-  {
-    assert(q <= p);
-    switch (*p)
-    {
-    case '\r':
-      if (p+1 < end && p[1] == '\n')
-        p++;
-    case '\n':
-      *q = '\n';
-      continue;
-    default:
-      if (isascii(*p))
-        break;
-      if (p+2 < end && isUnicodeNewline(p))
-      {
-        p += 2;
-        goto case '\n';
-      }
-      auto p2 = p; // Beginning of the UTF-8 sequence.
-      dchar c = decode(p, end);
-      if (c == ERROR_CHAR)
-      { // Skip to next ASCII character or valid UTF-8 sequence.
-        while (++p < end && isTrailByte(*p))
-        {}
-        alias REPLACEMENT_STR R;
-        if (q+2 < p) // Copy replacement char if there is enough space.
-          (*q = R[0]), (*++q = R[1]), (*++q = R[2]);
-        p--;
-      }
-      else
-      { // Copy the valid UTF-8 sequence.
-        while (p2 <= p) // p points to the last trail byte.
-          *q++ = *p2++; // Copy code units.
-        q--;
-      }
-      continue;
-    }
-    assert(isascii(*p));
-    *q = *p;
-  }
-  assert(p == end);
-  text.length = text.length - (p - q);
-  //text = text.ptr[0 .. q - text.ptr]; // Another way.
-  return text;
-}
-
-unittest
-{
-  Stdout("Testing function Converter.\n");
-  struct Data2Text
-  {
-    char[] text;
-    char[] expected = "source";
-    ubyte[] data()
-    { return cast(ubyte[])text; }
-  }
-  const Data2Text[] map = [
-    // Without BOM
-    {"source"},
-    {"s\0o\0u\0r\0c\0e\0"},
-    {"\0s\0o\0u\0r\0c\0e"},
-    {"s\0\0\0o\0\0\0u\0\0\0r\0\0\0c\0\0\0e\0\0\0"},
-    {"\0\0\0s\0\0\0o\0\0\0u\0\0\0r\0\0\0c\0\0\0e"},
-    // With BOM
-    {"\xEF\xBB\xBFsource"},
-    {"\xFE\xFF\0s\0o\0u\0r\0c\0e"},
-    {"\xFF\xFEs\0o\0u\0r\0c\0e\0"},
-    {"\x00\x00\xFE\xFF\0\0\0s\0\0\0o\0\0\0u\0\0\0r\0\0\0c\0\0\0e"},
-    {"\xFF\xFE\x00\x00s\0\0\0o\0\0\0u\0\0\0r\0\0\0c\0\0\0e\0\0\0"},
-  ];
-  auto converter = Converter("", new InfoManager);
-  foreach (i, pair; map)
-    assert(converter.data2UTF8(pair.data) == pair.expected, Format("failed at item {}", i));
-}
--- a/trunk/src/dil/Enums.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.Enums;
-
-import common;
-
-/// Enumeration of storage classes.
-enum StorageClass
-{
-  None         = 0,
-  Abstract     = 1,
-  Auto         = 1<<2,
-  Const        = 1<<3,
-  Deprecated   = 1<<4,
-  Extern       = 1<<5,
-  Final        = 1<<6,
-  Invariant    = 1<<7,
-  Override     = 1<<8,
-  Scope        = 1<<9,
-  Static       = 1<<10,
-  Synchronized = 1<<11,
-  In           = 1<<12,
-  Out          = 1<<13,
-  Ref          = 1<<14,
-  Lazy         = 1<<15,
-  Variadic     = 1<<16,
-}
-
-/// Enumeration of protection attributes.
-enum Protection
-{
-  None,
-  Private/+   = 1+/,
-  Protected/+ = 1<<1+/,
-  Package/+   = 1<<2+/,
-  Public/+    = 1<<3+/,
-  Export/+    = 1<<4+/
-}
-
-/// Enumeration of linkage types.
-enum LinkageType
-{
-  None,
-  C,
-  Cpp,
-  D,
-  Windows,
-  Pascal,
-  System
-}
-
-/// Returns the string for prot.
-string toString(Protection prot)
-{
-  switch (prot)
-  { alias Protection P;
-  case P.None:      return "";
-  case P.Private:   return "private";
-  case P.Protected: return "protected";
-  case P.Package:   return "package";
-  case P.Public:    return "public";
-  case P.Export:    return "export";
-  default:
-    assert(0);
-  }
-}
-
-/// Returns the string of a storage class. Only one bit may be set.
-string toString(StorageClass stc)
-{
-  switch (stc)
-  { alias StorageClass SC;
-  case SC.Abstract:     return "abstract";
-  case SC.Auto:         return "auto";
-  case SC.Const:        return "const";
-  case SC.Deprecated:   return "deprecated";
-  case SC.Extern:       return "extern";
-  case SC.Final:        return "final";
-  case SC.Invariant:    return "invariant";
-  case SC.Override:     return "override";
-  case SC.Scope:        return "scope";
-  case SC.Static:       return "static";
-  case SC.Synchronized: return "synchronized";
-  case SC.In:           return "in";
-  case SC.Out:          return "out";
-  case SC.Ref:          return "ref";
-  case SC.Lazy:         return "lazy";
-  case SC.Variadic:     return "variadic";
-  default:
-    assert(0);
-  }
-}
-
-/// Returns the strings for stc. Any number of bits may be set.
-string[] toStrings(StorageClass stc)
-{
-  string[] result;
-  for (auto i = StorageClass.max; i; i >>= 1)
-    if (stc & i)
-      result ~= toString(i);
-  return result;
-}
-
-/// Returns the string for ltype.
-string toString(LinkageType ltype)
-{
-  switch (ltype)
-  { alias LinkageType LT;
-  case LT.None:    return "";
-  case LT.C:       return "C";
-  case LT.Cpp:     return "Cpp";
-  case LT.D:       return "D";
-  case LT.Windows: return "Windows";
-  case LT.Pascal:  return "Pascal";
-  case LT.System:  return "System";
-  default:
-    assert(0);
-  }
-}
--- a/trunk/src/dil/FileBOM.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.FileBOM;
-import common;
-
-/// Enumeration of byte order marks.
-enum BOM
-{
-  None,    /// No BOM
-  UTF8,    /// UTF-8: EF BB BF
-  UTF16BE, /// UTF-16 Big Endian: FE FF
-  UTF16LE, /// UTF-16 Little Endian: FF FE
-  UTF32BE, /// UTF-32 Big Endian: 00 00 FE FF
-  UTF32LE  /// UTF-32 Little Endian: FF FE 00 00
-}
-
-/// Looks at the first bytes of data and returns the corresponding BOM.
-BOM tellBOM(ubyte[] data)
-{
-  BOM bom = BOM.None;
-  if (data.length < 2)
-    return bom;
-
-  if (data[0..2] == cast(ubyte[2])x"FE FF")
-  {
-    bom = BOM.UTF16BE; // FE FF
-  }
-  else if (data[0..2] == cast(ubyte[2])x"FF FE")
-  {
-    if (data.length >= 4 && data[2..4] == cast(ubyte[2])x"00 00")
-      bom = BOM.UTF32LE; // FF FE 00 00
-    else
-      bom = BOM.UTF16LE; // FF FE XX XX
-  }
-  else if (data[0..2] == cast(ubyte[2])x"00 00")
-  {
-    if (data.length >= 4 && data[2..4] == cast(ubyte[2])x"FE FF")
-      bom = BOM.UTF32BE; // 00 00 FE FF
-  }
-  else if (data[0..2] ==  cast(ubyte[2])x"EF BB")
-  {
-    if (data.length >= 3 && data[2] == '\xBF')
-      bom =  BOM.UTF8; // EF BB BF
-  }
-  return bom;
-}
-
-unittest
-{
-  Stdout("Testing function tellBOM().\n");
-
-  struct Data2BOM
-  {
-    ubyte[] data;
-    BOM bom;
-  }
-  alias ubyte[] ub;
-  const Data2BOM[] map = [
-    {cast(ub)x"12",          BOM.None},
-    {cast(ub)x"12 34",       BOM.None},
-    {cast(ub)x"00 00 FF FE", BOM.None},
-    {cast(ub)x"EF BB FF",    BOM.None},
-
-    {cast(ub)x"EF",          BOM.None},
-    {cast(ub)x"EF BB",       BOM.None},
-    {cast(ub)x"FE",          BOM.None},
-    {cast(ub)x"FF",          BOM.None},
-    {cast(ub)x"00",          BOM.None},
-    {cast(ub)x"00 00",       BOM.None},
-    {cast(ub)x"00 00 FE",    BOM.None},
-
-    {cast(ub)x"FE FF 00",    BOM.UTF16BE},
-    {cast(ub)x"FE FF 00 FF", BOM.UTF16BE},
-
-    {cast(ub)x"EF BB BF",    BOM.UTF8},
-    {cast(ub)x"FE FF",       BOM.UTF16BE},
-    {cast(ub)x"FF FE",       BOM.UTF16LE},
-    {cast(ub)x"00 00 FE FF", BOM.UTF32BE},
-    {cast(ub)x"FF FE 00 00", BOM.UTF32LE}
-  ];
-
-  foreach (pair; map)
-    assert(tellBOM(pair.data) == pair.bom, Format("Failed at {0}", pair.data));
-}
--- a/trunk/src/dil/HtmlEntities.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,376 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.HtmlEntities;
-
-import common;
-
-/// A named HTML entity.
-struct Entity
-{
-  char[] name;
-  dchar value;
-}
-
-/// The table of named HTML entities.
-static const Entity[] namedEntities = [
-  {"Aacute", '\u00C1'},
-  {"aacute", '\u00E1'},
-  {"Acirc", '\u00C2'},
-  {"acirc", '\u00E2'},
-  {"acute", '\u00B4'},
-  {"AElig", '\u00C6'},
-  {"aelig", '\u00E6'},
-  {"Agrave", '\u00C0'},
-  {"agrave", '\u00E0'},
-  {"alefsym", '\u2135'},
-  {"Alpha", '\u0391'},
-  {"alpha", '\u03B1'},
-  {"amp", '\u0026'},
-  {"and", '\u2227'},
-  {"ang", '\u2220'},
-  {"Aring", '\u00C5'},
-  {"aring", '\u00E5'},
-  {"asymp", '\u2248'},
-  {"Atilde", '\u00C3'},
-  {"atilde", '\u00E3'},
-  {"Auml", '\u00C4'},
-  {"auml", '\u00E4'},
-  {"bdquo", '\u201E'},
-  {"Beta", '\u0392'},
-  {"beta", '\u03B2'},
-  {"brvbar", '\u00A6'},
-  {"bull", '\u2022'},
-  {"cap", '\u2229'},
-  {"Ccedil", '\u00C7'},
-  {"ccedil", '\u00E7'},
-  {"cedil", '\u00B8'},
-  {"cent", '\u00A2'},
-  {"Chi", '\u03A7'},
-  {"chi", '\u03C7'},
-  {"circ", '\u02C6'},
-  {"clubs", '\u2663'},
-  {"cong", '\u2245'},
-  {"copy", '\u00A9'},
-  {"crarr", '\u21B5'},
-  {"cup", '\u222A'},
-  {"curren", '\u00A4'},
-  {"Dagger", '\u2021'},
-  {"dagger", '\u2020'},
-  {"dArr", '\u21D3'},
-  {"darr", '\u2193'},
-  {"deg", '\u00B0'},
-  {"Delta", '\u0394'},
-  {"delta", '\u03B4'},
-  {"diams", '\u2666'},
-  {"divide", '\u00F7'},
-  {"Eacute", '\u00C9'},
-  {"eacute", '\u00E9'},
-  {"Ecirc", '\u00CA'},
-  {"ecirc", '\u00EA'},
-  {"Egrave", '\u00C8'},
-  {"egrave", '\u00E8'},
-  {"empty", '\u2205'},
-  {"emsp", '\u2003'},
-  {"ensp", '\u2002'},
-  {"Epsilon", '\u0395'},
-  {"epsilon", '\u03B5'},
-  {"equiv", '\u2261'},
-  {"Eta", '\u0397'},
-  {"eta", '\u03B7'},
-  {"ETH", '\u00D0'},
-  {"eth", '\u00F0'},
-  {"Euml", '\u00CB'},
-  {"euml", '\u00EB'},
-  {"euro", '\u20AC'},
-  {"exist", '\u2203'},
-  {"fnof", '\u0192'},
-  {"forall", '\u2200'},
-  {"frac12", '\u00BD'},
-  {"frac14", '\u00BC'},
-  {"frac34", '\u00BE'},
-  {"frasl", '\u2044'},
-  {"Gamma", '\u0393'},
-  {"gamma", '\u03B3'},
-  {"ge", '\u2265'},
-  {"gt", '\u003E'},
-  {"hArr", '\u21D4'},
-  {"harr", '\u2194'},
-  {"hearts", '\u2665'},
-  {"hellip", '\u2026'},
-  {"Iacute", '\u00CD'},
-  {"iacute", '\u00ED'},
-  {"Icirc", '\u00CE'},
-  {"icirc", '\u00EE'},
-  {"iexcl", '\u00A1'},
-  {"Igrave", '\u00CC'},
-  {"igrave", '\u00EC'},
-  {"image", '\u2111'},
-  {"infin", '\u221E'},
-  {"int", '\u222B'},
-  {"Iota", '\u0399'},
-  {"iota", '\u03B9'},
-  {"iquest", '\u00BF'},
-  {"isin", '\u2208'},
-  {"Iuml", '\u00CF'},
-  {"iuml", '\u00EF'},
-  {"Kappa", '\u039A'},
-  {"kappa", '\u03BA'},
-  {"Lambda", '\u039B'},
-  {"lambda", '\u03BB'},
-  {"lang", '\u2329'},
-  {"laquo", '\u00AB'},
-  {"lArr", '\u21D0'},
-  {"larr", '\u2190'},
-  {"lceil", '\u2308'},
-  {"ldquo", '\u201C'},
-  {"le", '\u2264'},
-  {"lfloor", '\u230A'},
-  {"lowast", '\u2217'},
-  {"loz", '\u25CA'},
-  {"lrm", '\u200E'},
-  {"lsaquo", '\u2039'},
-  {"lsquo", '\u2018'},
-  {"lt", '\u003C'},
-  {"macr", '\u00AF'},
-  {"mdash", '\u2014'},
-  {"micro", '\u00B5'},
-  {"middot", '\u00B7'},
-  {"minus", '\u2212'},
-  {"Mu", '\u039C'},
-  {"mu", '\u03BC'},
-  {"nabla", '\u2207'},
-  {"nbsp", '\u00A0'},
-  {"ndash", '\u2013'},
-  {"ne", '\u2260'},
-  {"ni", '\u220B'},
-  {"not", '\u00AC'},
-  {"notin", '\u2209'},
-  {"nsub", '\u2284'},
-  {"Ntilde", '\u00D1'},
-  {"ntilde", '\u00F1'},
-  {"Nu", '\u039D'},
-  {"nu", '\u03BD'},
-  {"Oacute", '\u00D3'},
-  {"oacute", '\u00F3'},
-  {"Ocirc", '\u00D4'},
-  {"ocirc", '\u00F4'},
-  {"OElig", '\u0152'},
-  {"oelig", '\u0153'},
-  {"Ograve", '\u00D2'},
-  {"ograve", '\u00F2'},
-  {"oline", '\u203E'},
-  {"Omega", '\u03A9'},
-  {"omega", '\u03C9'},
-  {"Omicron", '\u039F'},
-  {"omicron", '\u03BF'},
-  {"oplus", '\u2295'},
-  {"or", '\u2228'},
-  {"ordf", '\u00AA'},
-  {"ordm", '\u00BA'},
-  {"Oslash", '\u00D8'},
-  {"oslash", '\u00F8'},
-  {"Otilde", '\u00D5'},
-  {"otilde", '\u00F5'},
-  {"otimes", '\u2297'},
-  {"Ouml", '\u00D6'},
-  {"ouml", '\u00F6'},
-  {"para", '\u00B6'},
-  {"part", '\u2202'},
-  {"permil", '\u2030'},
-  {"perp", '\u22A5'},
-  {"Phi", '\u03A6'},
-  {"phi", '\u03C6'},
-  {"Pi", '\u03A0'},
-  {"pi", '\u03C0'},
-  {"piv", '\u03D6'},
-  {"plusmn", '\u00B1'},
-  {"pound", '\u00A3'},
-  {"Prime", '\u2033'},
-  {"prime", '\u2032'},
-  {"prod", '\u220F'},
-  {"prop", '\u221D'},
-  {"Psi", '\u03A8'},
-  {"psi", '\u03C8'},
-  {"quot", '\u0022'},
-  {"radic", '\u221A'},
-  {"rang", '\u232A'},
-  {"raquo", '\u00BB'},
-  {"rArr", '\u21D2'},
-  {"rarr", '\u2192'},
-  {"rceil", '\u2309'},
-  {"rdquo", '\u201D'},
-  {"real", '\u211C'},
-  {"reg", '\u00AE'},
-  {"rfloor", '\u230B'},
-  {"Rho", '\u03A1'},
-  {"rho", '\u03C1'},
-  {"rlm", '\u200F'},
-  {"rsaquo", '\u203A'},
-  {"rsquo", '\u2019'},
-  {"sbquo", '\u201A'},
-  {"Scaron", '\u0160'},
-  {"scaron", '\u0161'},
-  {"sdot", '\u22C5'},
-  {"sect", '\u00A7'},
-  {"shy", '\u00AD'},
-  {"Sigma", '\u03A3'},
-  {"sigma", '\u03C3'},
-  {"sigmaf", '\u03C2'},
-  {"sim", '\u223C'},
-  {"spades", '\u2660'},
-  {"sub", '\u2282'},
-  {"sube", '\u2286'},
-  {"sum", '\u2211'},
-  {"sup", '\u2283'},
-  {"sup1", '\u00B9'},
-  {"sup2", '\u00B2'},
-  {"sup3", '\u00B3'},
-  {"supe", '\u2287'},
-  {"szlig", '\u00DF'},
-  {"Tau", '\u03A4'},
-  {"tau", '\u03C4'},
-  {"there4", '\u2234'},
-  {"Theta", '\u0398'},
-  {"theta", '\u03B8'},
-  {"thetasym", '\u03D1'},
-  {"thinsp", '\u2009'},
-  {"THORN", '\u00DE'},
-  {"thorn", '\u00FE'},
-  {"tilde", '\u02DC'},
-  {"times", '\u00D7'},
-  {"trade", '\u2122'},
-  {"Uacute", '\u00DA'},
-  {"uacute", '\u00FA'},
-  {"uArr", '\u21D1'},
-  {"uarr", '\u2191'},
-  {"Ucirc", '\u00DB'},
-  {"ucirc", '\u00FB'},
-  {"Ugrave", '\u00D9'},
-  {"ugrave", '\u00F9'},
-  {"uml", '\u00A8'},
-  {"upsih", '\u03D2'},
-  {"Upsilon", '\u03A5'},
-  {"upsilon", '\u03C5'},
-  {"Uuml", '\u00DC'},
-  {"uuml", '\u00FC'},
-  {"weierp", '\u2118'},
-  {"Xi", '\u039E'},
-  {"xi", '\u03BE'},
-  {"Yacute", '\u00DD'},
-  {"yacute", '\u00FD'},
-  {"yen", '\u00A5'},
-  {"Yuml", '\u0178'},
-  {"yuml", '\u00FF'},
-  {"Zeta", '\u0396'},
-  {"zeta", '\u03B6'},
-  {"zwj", '\u200D'},
-  {"zwnj", '\u200C'}
-];
-
-uint stringToHash(char[] str)
-{
-  uint hash;
-  foreach(c; str) {
-    hash *= 11;
-    hash += c;
-  }
-  return hash;
-}
-
-char[] toString(uint x)
-{
-  char[] str;
-  do
-    str = cast(char)('0' + (x % 10)) ~ str;
-  while (x /= 10)
-  return str;
-}
-
-char[] generateHashAndValueArrays()
-{
-  uint[] hashes; // String hashes.
-  dchar[] values; // Unicode codepoints.
-  // Build arrays:
-  foreach (entity; namedEntities)
-  {
-    auto hash = stringToHash(entity.name);
-    auto value = entity.value;
-    assert(hash != 0);
-    // Find insertion place.
-    uint i;
-    for (; i < hashes.length; ++i)
-    {
-      assert(hash != hashes[i], "bad hash function: conflicting hashes");
-      if (hash < hashes[i])
-        break;
-    }
-    // Insert hash and value into tables.
-    if (i == hashes.length)
-    {
-      hashes ~= hash;
-      values ~= value;
-    }
-    else
-    {
-      hashes = hashes[0..i] ~ hash ~ hashes[i..$]; // Insert before index.
-      values = values[0..i] ~ value ~ values[i..$]; // Insert before index.
-    }
-    assert(hashes[i] == hash && values[i] == value);
-  }
-  // Build source text:
-  char[] hashesText = "private static const uint[] hashes = [",
-         valuesText = "private static const dchar[] values = [";
-  foreach (i, hash; hashes)
-  {
-    hashesText ~= toString(hash) ~ ",";
-    valuesText ~= toString(values[i]) ~ ",";
-  }
-  hashesText ~= "];";
-  valuesText ~= "];";
-  return hashesText ~"\n"~ valuesText;
-}
-
-version(DDoc)
-{
-  /// Table of hash values of the entities' names.
-  private static const uint[] hashes;
-  /// Table of Unicode codepoints.
-  private static const dchar[] values;
-}
-else
-  mixin(generateHashAndValueArrays);
-// pragma(msg, generateHashAndValueArrays());
-
-/// Converts a named HTML entity into its equivalent Unicode codepoint.
-/// Returns: the entity's value or 0xFFFF if it doesn't exist.
-dchar entity2Unicode(char[] entity)
-{
-  auto hash = stringToHash(entity);
-  // Binary search:
-  size_t lower = void, index = void, upper = void;
-  lower = 0;
-  upper = hashes.length -1;
-  while (lower <= upper)
-  {
-    index = (lower + upper) / 2;
-    if (hash < hashes[index])
-      upper = index - 1;
-    else if (hash > hashes[index])
-      lower = index + 1;
-    else
-      return values[index]; // Return the Unicode codepoint.
-  }
-  return 0xFFFF; // Return error value.
-}
-
-unittest
-{
-  Stdout("Testing entity2Unicode().").newline;
-  alias entity2Unicode f;
-  foreach (entity; namedEntities)
-    assert(f(entity.name) == entity.value,
-      Format("'&{};' == \\u{:X4}, not \\u{:X4}", entity.name, entity.value, cast(uint)f(entity.name))
-    );
-}
--- a/trunk/src/dil/Information.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.Information;
-
-import dil.Messages;
-import common;
-
-public import dil.Location;
-
-/// Information that can be displayed to the user.
-class Information
-{
-
-}
-
-/// Collects information.
-class InfoManager
-{
-  Information[] info;
-
-  bool hasInfo()
-  {
-    return info.length != 0;
-  }
-
-  void opCatAssign(Information info)
-  {
-    this.info ~= info;
-  }
-
-  void opCatAssign(Information[] info)
-  {
-    this.info ~= info;
-  }
-}
-
-/// For reporting a problem in the compilation process.
-class Problem : Information
-{
-  Location location;
-  uint column; /// Cache variable for column.
-  string message;
-
-  this(Location location, string message)
-  {
-    assert(location !is null);
-    this.location = location;
-    this.message = message;
-  }
-
-  /// Returns the message.
-  string getMsg()
-  {
-    return this.message;
-  }
-
-  /// Returns the line of code.
-  size_t loc()
-  {
-    return location.lineNum;
-  }
-
-  /// Returns the column.
-  size_t col()
-  {
-    if (column == 0)
-      column = location.calculateColumn();
-    return column;
-  }
-
-  /// Returns the file path.
-  string filePath()
-  {
-    return location.filePath;
-  }
-}
-
-/// For reporting warnings.
-class Warning : Problem
-{
-  this(Location location, string message)
-  {
-    super(location, message);
-  }
-}
-
-/// For reporting a compiler error.
-class Error : Problem
-{
-  this(Location location, string message)
-  {
-    super(location, message);
-  }
-}
-
-/// An error reported by the Lexer.
-class LexerError : Error
-{
-  this(Location location, string message)
-  {
-    super(location, message);
-  }
-}
-
-/// An error reported by the Parser.
-class ParserError : Error
-{
-  this(Location location, string message)
-  {
-    super(location, message);
-  }
-}
-
-/// An error reported by a semantic analyzer.
-class SemanticError : Error
-{
-  this(Location location, string message)
-  {
-    super(location, message);
-  }
-}
--- a/trunk/src/dil/Location.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.Location;
-
-import dil.lexer.Funcs;
-import dil.Unicode;
-
-/// Represents a location in a source text.
-final class Location
-{
-  char[] filePath; /// The file path.
-  size_t lineNum; /// The line number.
-  char* lineBegin, to; /// Used to calculate the column.
-
-  /// Forwards the parameters to the second constructor.
-  this(char[] filePath, size_t lineNum)
-  {
-    set(filePath, lineNum);
-  }
-
-  /// Constructs a Location object.
-  this(char[] filePath, size_t lineNum, char* lineBegin, char* to)
-  {
-    set(filePath, lineNum, lineBegin, to);
-  }
-
-  void set(char[] filePath, size_t lineNum)
-  {
-    set(filePath, lineNum, null, null);
-  }
-
-  void set(char[] filePath, size_t lineNum, char* lineBegin, char* to)
-  {
-    this.filePath  = filePath;
-    set(lineNum, lineBegin, to);
-  }
-
-  void set(size_t lineNum, char* lineBegin, char* to)
-  {
-    assert(lineBegin <= to);
-    this.lineNum   = lineNum;
-    this.lineBegin = lineBegin;
-    this.to        = to;
-  }
-
-  void setFilePath(char[] filePath)
-  {
-    this.filePath = filePath;
-  }
-
-  /// This is a primitive method to count the number of characters in a string.
-  /// Note: Unicode compound characters and other special characters are not
-  /// taken into account. The tabulator character is counted as one.
-  uint calculateColumn()
-  {
-    uint col;
-    auto p = lineBegin;
-    if (!p)
-      return 0;
-    for (; p <= to; ++p)
-    {
-      assert(delegate ()
-        {
-          // Check that there is no newline between p and to.
-          // But 'to' may point to a newline.
-          if (p != to && isNewline(*p))
-            return false;
-          if (to-p >= 2 && isUnicodeNewline(p))
-            return false;
-          return true;
-        }() == true
-      );
-
-      // Skip this byte if it is a trail byte of a UTF-8 sequence.
-      if (isTrailByte(*p))
-        continue; // *p == 0b10xx_xxxx
-      // Only count ASCII characters and the first byte of a UTF-8 sequence.
-      ++col;
-    }
-    return col;
-  }
-  alias calculateColumn colNum;
-}
--- a/trunk/src/dil/Messages.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.Messages;
-
-import common;
-
-/// Enumeration of indices into the table of compiler messages.
-enum MID
-{
-  // Lexer messages:
-  IllegalCharacter,
-//   InvalidUnicodeCharacter,
-  InvalidUTF8Sequence,
-  // ''
-  UnterminatedCharacterLiteral,
-  EmptyCharacterLiteral,
-  // #line
-  ExpectedIdentifierSTLine,
-  ExpectedIntegerAfterSTLine,
-//   ExpectedFilespec,
-  UnterminatedFilespec,
-  UnterminatedSpecialToken,
-  // ""
-  UnterminatedString,
-  // x""
-  NonHexCharInHexString,
-  OddNumberOfDigitsInHexString,
-  UnterminatedHexString,
-  // /* */ /+ +/
-  UnterminatedBlockComment,
-  UnterminatedNestedComment,
-  // `` r""
-  UnterminatedRawString,
-  UnterminatedBackQuoteString,
-  // \x \u \U
-  UndefinedEscapeSequence,
-  InvalidUnicodeEscapeSequence,
-  InsufficientHexDigits,
-  // \&[a-zA-Z][a-zA-Z0-9]+;
-  UndefinedHTMLEntity,
-  UnterminatedHTMLEntity,
-  InvalidBeginHTMLEntity,
-  // integer overflows
-  OverflowDecimalSign,
-  OverflowDecimalNumber,
-  OverflowHexNumber,
-  OverflowBinaryNumber,
-  OverflowOctalNumber,
-  OverflowFloatNumber,
-  OctalNumberHasDecimals,
-  NoDigitsInHexNumber,
-  NoDigitsInBinNumber,
-  HexFloatExponentRequired,
-  HexFloatExpMustStartWithDigit,
-  FloatExpMustStartWithDigit,
-
-  // Parser messages:
-  ExpectedButFound,
-  RedundantStorageClass,
-  TemplateTupleParameter,
-  InContract,
-  OutContract,
-  MissingLinkageType,
-  UnrecognizedLinkageType,
-  ExpectedBaseClasses,
-  BaseClassInForwardDeclaration,
-
-  // Help messages:
-  HelpMain,
-  HelpGenerate,
-  HelpImportGraph,
-}
-
-/// The table of compiler messages.
-private string[] g_compilerMessages;
-
-static this()
-{
-  g_compilerMessages = new string[MID.max+1];
-}
-
-/// Sets the compiler messages.
-void SetMessages(string[] msgs)
-{
-  assert(MID.max+1 == msgs.length);
-  g_compilerMessages = msgs;
-}
-
-/// Returns the compiler message for mid.
-string GetMsg(MID mid)
-{
-  assert(mid < g_compilerMessages.length);
-  return g_compilerMessages[mid];
-}
-
-/// Returns a formatted string.
-char[] FormatMsg(MID mid, ...)
-{
-  return Format(_arguments, _argptr, GetMsg(mid));
-}
-
-/// Collection of error messages with no MID yet.
-struct MSG
-{
-static:
-  // Converter:
-  auto InvalidUTF16Character = "invalid UTF-16 character '\\u{:X4}'.";
-  auto InvalidUTF32Character = "invalid UTF-32 character '\\U{:X8}'.";
-  auto UTF16FileMustBeDivisibleBy2 = "the byte length of a UTF-16 source file must be divisible by 2.";
-  auto UTF32FileMustBeDivisibleBy4 = "the byte length of a UTF-32 source file must be divisible by 4.";
-  // DDoc macros:
-  auto UndefinedDDocMacro = "DDoc macro '{}' is undefined";
-  auto UnterminatedDDocMacro = "DDoc macro '{}' has no closing ')'";
-  // Lexer messages:
-  auto InvalidOctalEscapeSequence = "value of octal escape sequence is greater than 0xFF: '{}'";
-  // Parser messages:
-  auto InvalidUTF8SequenceInString = "invalid UTF-8 sequence in string literal: '{0}'";
-  auto ModuleDeclarationNotFirst = "a module declaration is only allowed as the first declaration in a file";
-  auto StringPostfixMismatch = "string literal has mistmatching postfix character";
-  auto ExpectedIdAfterTypeDot = "expected identifier after '(Type).', not '{}'";
-  auto ExpectedModuleIdentifier = "expected module identifier, not '{}'";
-  auto IllegalDeclaration = "illegal declaration found: {}";
-  auto ExpectedFunctionName = "expected function name, not '{}'";
-  auto ExpectedVariableName = "expected variable name, not '{}'";
-  auto ExpectedFunctionBody = "expected function body, not '{}'";
-  auto RedundantLinkageType = "redundant linkage type: {}";
-  auto ExpectedPragmaIdentifier = "expected pragma identifier, not '{}'";
-  auto ExpectedAliasModuleName = "expected alias module name, not '{}'";
-  auto ExpectedAliasImportName = "expected alias name, not '{}'";
-  auto ExpectedImportName = "expected an identifier, not '{}'";
-  auto ExpectedEnumMember = "expected enum member, not '{}'";
-  auto ExpectedEnumBody = "expected enum body, not '{}'";
-  auto ExpectedClassName = "expected class name, not '{}'";
-  auto ExpectedClassBody = "expected class body, not '{}'";
-  auto ExpectedInterfaceName = "expected interface name, not '{}'";
-  auto ExpectedInterfaceBody = "expected interface body, not '{}'";
-  auto ExpectedStructBody = "expected struct body, not '{}'";
-  auto ExpectedUnionBody = "expected union body, not '{}'";
-  auto ExpectedTemplateName = "expected template name, not '{}'";
-  auto ExpectedAnIdentifier = "expected an identifier, not '{}'";
-  auto IllegalStatement = "illegal statement found: {}";
-  auto ExpectedNonEmptyStatement = "didn't expect ';', use {{ } instead";
-  auto ExpectedScopeIdentifier = "expected 'exit', 'success' or 'failure', not '{}'";
-  auto InvalidScopeIdentifier = "'exit', 'success', 'failure' are valid scope identifiers, but not '{}'";
-  auto ExpectedIntegerAfterAlign = "expected an integer after align, not '{}'";
-  auto IllegalAsmStatement = "illegal asm statement found: {}";
-  auto ExpectedDeclaratorIdentifier = "expected declarator identifier, not '{}'";
-  auto ExpectedTemplateParameters = "expected one or more template parameters, not ')'";
-  auto ExpectedTypeOrExpression = "expected a type or and expression, not ')'";
-  auto ExpectedAliasTemplateParam = "expected name for alias template parameter, not '{}'";
-  auto ExpectedNameForThisTempParam = "expected name for 'this' template parameter, not '{}'";
-  auto ExpectedIdentOrInt = "expected an identifier or an integer, not '{}'";
-  auto MissingCatchOrFinally = "try statement is missing a catch or finally body.";
-  // Semantic analysis:
-  auto UndefinedIdentifier = "undefined identifier '{}'";
-  auto DeclConflictsWithDecl = "declaration '{}' conflicts with declaration @{}";
-  auto VariableConflictsWithDecl = "variable '{}' conflicts with declaration @{}";
-  auto InterfaceCantHaveVariables = "an interface can't have member variables";
-  auto MixinArgumentMustBeString = "the mixin argument must evaluate to a string";
-  auto DebugSpecModuleLevel = "debug={} must be a module level";
-  auto VersionSpecModuleLevel = "version={} must be a module level";
-}
--- a/trunk/src/dil/SourceText.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.SourceText;
-
-import dil.Converter;
-import dil.Information;
-import common;
-
-import tango.io.File;
-
-/// Represents D source code.
-///
-/// The source text may come from a file or from a memory buffer.
-final class SourceText
-{
-  string filePath; /// The file path to the source text. Mainly used for error messages.
-  char[] data; /// The UTF-8, zero-terminated source text.
-
-  /// Constructs a SourceText object.
-  /// Params:
-  ///   filePath = file path to the source file.
-  ///   loadFile = whether to load the file in the constructor.
-  this(string filePath, bool loadFile = false)
-  {
-    this.filePath = filePath;
-    loadFile && load();
-  }
-
-  /// Constructs a SourceText object.
-  /// Params:
-  ///   filePath = file path for error messages.
-  ///   data = memory buffer.
-  this(string filePath, char[] data)
-  {
-    this(filePath);
-    this.data = data;
-    addSentinelCharacter();
-  }
-
-  /// Loads the source text from a file.
-  void load(InfoManager infoMan = null)
-  {
-    if (!infoMan)
-      infoMan = new InfoManager;
-    assert(filePath.length);
-    // Read the file.
-    auto rawdata = cast(ubyte[]) (new File(filePath)).read();
-    // Convert the data.
-    auto converter = Converter(filePath, infoMan);
-    data = converter.data2UTF8(rawdata);
-    addSentinelCharacter();
-  }
-
-  /// Adds '\0' to the text (if not already there.)
-  private void addSentinelCharacter()
-  {
-    if (data.length == 0 || data[$-1] != 0)
-      data ~= 0;
-  }
-}
--- a/trunk/src/dil/Time.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.Time;
-
-import tango.stdc.time : time_t, time, ctime;
-import tango.stdc.string : strlen;
-
-/// Some convenience functions for dealing with C's time functions.
-struct Time
-{
-static:
-  /// Returns the current date as a string.
-  char[] toString()
-  {
-    time_t time_val;
-    .time(&time_val);
-    char* str = ctime(&time_val); // ctime returns a pointer to a static array.
-    char[] timeStr = str[0 .. strlen(str)-1]; // -1 removes trailing '\n'.
-    return timeStr.dup;
-  }
-
-  /// Returns the time of timeStr: hh:mm:ss
-  char[] time(char[] timeStr)
-  {
-    return timeStr[11..19];
-  }
-
-  /// Returns the month and day of timeStr: Mmm dd
-  char[] month_day(char[] timeStr)
-  {
-    return timeStr[4..10];
-  }
-
-  /// Returns the year of timeStr: yyyy
-  char[] year(char[] timeStr)
-  {
-    return timeStr[20..24];
-  }
-}
--- a/trunk/src/dil/Unicode.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,345 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.Unicode;
-public import util.uni : isUniAlpha;
-
-/// U+FFFD = �. Used to replace invalid Unicode characters.
-const dchar REPLACEMENT_CHAR = '\uFFFD';
-const char[3] REPLACEMENT_STR = \uFFFD; /// Ditto
-/// Invalid character, returned on errors.
-const dchar ERROR_CHAR = 0xD800;
-
-/// Returns: true if this character is not a surrogate
-/// code point and not higher than 0x10FFFF.
-bool isValidChar(dchar d)
-{
-  return d < 0xD800 || d > 0xDFFF && d <= 0x10FFFF;
-}
-
-/// There are a total of 66 noncharacters.
-/// Returns: true if this is one of them.
-/// See_also: Chapter 16.7 Noncharacters in Unicode 5.0
-bool isNoncharacter(dchar d)
-{
-  return 0xFDD0 <= d && d <= 0xFDEF || // 32
-         d <= 0x10FFFF && (d & 0xFFFF) >= 0xFFFE; // 34
-}
-
-/// Returns: true if this is a trail byte of a UTF-8 sequence.
-bool isTrailByte(ubyte b)
-{
-  return (b & 0xC0) == 0x80; // 10xx_xxxx
-}
-
-/// Returns: true if this is a lead byte of a UTF-8 sequence.
-bool isLeadByte(ubyte b)
-{
-  return (b & 0xC0) == 0xC0; // 11xx_xxxx
-}
-
-/// Advances ref_p only if this is a valid Unicode alpha character.
-bool isUnicodeAlpha(ref char* ref_p, char* end)
-in { assert(ref_p && ref_p < end); }
-body
-{
-  if (*ref_p < 0x80)
-    return false;
-  auto p = ref_p;
-  auto c = decode(p, end);
-  if (!isUniAlpha(c))
-    return false;
-  ref_p = p;
-  return true;
-}
-
-/// Decodes a character from str at index.
-/// Params:
-///   index = set to one past the ASCII char or one past the last trail byte
-///           of the valid UTF-8 sequence.
-dchar decode(char[] str, ref size_t index)
-in { assert(str.length && index < str.length); }
-out { assert(index <= str.length); }
-body
-{
-  char* p = str.ptr + index;
-  char* end = str.ptr + str.length;
-  dchar c = decode(p, end);
-  if (c != ERROR_CHAR)
-    index = p - str.ptr;
-  return c;
-}
-
-/// Decodes a character starting at ref_p.
-/// Params:
-///   ref_p = set to one past the ASCII char or one past the last trail byte
-///           of the valid UTF-8 sequence.
-dchar decode(ref char* ref_p, char* end)
-in { assert(ref_p && ref_p < end); }
-out(c) { assert(ref_p <= end && (isValidChar(c) || c == ERROR_CHAR)); }
-body
-{
-  char* p = ref_p;
-  dchar c = *p;
-
-  if (c < 0x80)
-    return ref_p++, c;
-
-  p++; // Move to second byte.
-  if (!(p < end))
-    return ERROR_CHAR;
-
-  // Error if second byte is not a trail byte.
-  if (!isTrailByte(*p))
-    return ERROR_CHAR;
-
-  // Check for overlong sequences.
-  switch (c)
-  {
-  case 0xE0, // 11100000 100xxxxx
-       0xF0, // 11110000 1000xxxx
-       0xF8, // 11111000 10000xxx
-       0xFC: // 11111100 100000xx
-    if ((*p & c) == 0x80)
-      return ERROR_CHAR;
-  default:
-    if ((c & 0xFE) == 0xC0) // 1100000x
-      return ERROR_CHAR;
-  }
-
-  const char[] checkNextByte = "if (!(++p < end && isTrailByte(*p)))"
-                                "  return ERROR_CHAR;";
-  const char[] appendSixBits = "c = (c << 6) | *p & 0b0011_1111;";
-
-  // Decode
-  if ((c & 0b1110_0000) == 0b1100_0000)
-  {
-    // 110xxxxx 10xxxxxx
-    c &= 0b0001_1111;
-    mixin(appendSixBits);
-  }
-  else if ((c & 0b1111_0000) == 0b1110_0000)
-  {
-    // 1110xxxx 10xxxxxx 10xxxxxx
-    c &= 0b0000_1111;
-    mixin(appendSixBits ~
-          checkNextByte ~ appendSixBits);
-  }
-  else if ((c & 0b1111_1000) == 0b1111_0000)
-  {
-    // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
-    c &= 0b0000_0111;
-    mixin(appendSixBits ~
-          checkNextByte ~ appendSixBits ~
-          checkNextByte ~ appendSixBits);
-  }
-  else
-    // 5 and 6 byte UTF-8 sequences are not allowed yet.
-    // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
-    // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
-    return ERROR_CHAR;
-
-  assert(isTrailByte(*p));
-
-  if (!isValidChar(c))
-    return ERROR_CHAR;
-  ref_p = p+1;
-  return c;
-}
-
-/// Encodes c and appends it to str.
-void encode(ref char[] str, dchar c)
-{
-  assert(isValidChar(c), "check if character is valid before calling encode().");
-
-  char[6] b = void;
-  if (c < 0x80)
-    str ~= c;
-  else if (c < 0x800)
-  {
-    b[0] = 0xC0 | (c >> 6);
-    b[1] = 0x80 | (c & 0x3F);
-    str ~= b[0..2];
-  }
-  else if (c < 0x10000)
-  {
-    b[0] = 0xE0 | (c >> 12);
-    b[1] = 0x80 | ((c >> 6) & 0x3F);
-    b[2] = 0x80 | (c & 0x3F);
-    str ~= b[0..3];
-  }
-  else if (c < 0x200000)
-  {
-    b[0] = 0xF0 | (c >> 18);
-    b[1] = 0x80 | ((c >> 12) & 0x3F);
-    b[2] = 0x80 | ((c >> 6) & 0x3F);
-    b[3] = 0x80 | (c & 0x3F);
-    str ~= b[0..4];
-  }
-  /+ // There are no 5 and 6 byte UTF-8 sequences yet.
-  else if (c < 0x4000000)
-  {
-    b[0] = 0xF8 | (c >> 24);
-    b[1] = 0x80 | ((c >> 18) & 0x3F);
-    b[2] = 0x80 | ((c >> 12) & 0x3F);
-    b[3] = 0x80 | ((c >> 6) & 0x3F);
-    b[4] = 0x80 | (c & 0x3F);
-    str ~= b[0..5];
-  }
-  else if (c < 0x80000000)
-  {
-    b[0] = 0xFC | (c >> 30);
-    b[1] = 0x80 | ((c >> 24) & 0x3F);
-    b[2] = 0x80 | ((c >> 18) & 0x3F);
-    b[3] = 0x80 | ((c >> 12) & 0x3F);
-    b[4] = 0x80 | ((c >> 6) & 0x3F);
-    b[5] = 0x80 | (c & 0x3F);
-    str ~= b[0..6];
-  }
-  +/
-  else
-    assert(0);
-}
-
-/// Encodes c and appends it to str.
-void encode(ref wchar[] str, dchar c)
-in { assert(isValidChar(c)); }
-body
-{
-  if (c < 0x10000)
-    str ~= cast(wchar)c;
-  else
-  { // Encode with surrogate pair.
-    wchar[2] pair = void;
-    c -= 0x10000; // c'
-    // higher10bits(c') | 0b1101_10xx_xxxx_xxxx
-    pair[0] = (c >> 10) | 0xD800;
-    // lower10bits(c') | 0b1101_11yy_yyyy_yyyy
-    pair[1] = (c & 0x3FF) | 0xDC00;
-    str ~= pair;
-  }
-}
-
-/// Decodes a character from a UTF-16 sequence.
-/// Params:
-///   str = the UTF-16 sequence.
-///   index = where to start from.
-/// Returns: ERROR_CHAR in case of an error in the sequence.
-dchar decode(wchar[] str, ref size_t index)
-{
-  assert(str.length && index < str.length);
-  dchar c = str[index];
-  if (0xD800 > c || c > 0xDFFF)
-  {
-    ++index;
-    return c;
-  }
-  if (c <= 0xDBFF && index+1 != str.length)
-  {
-    wchar c2 = str[index+1];
-    if (0xDC00 <= c2 && c2 <= 0xDFFF)
-    { // Decode surrogate pair.
-      // (c - 0xD800) << 10 + 0x10000 ->
-      // (c - 0xD800 + 0x40) << 10 ->
-      c = (c - 0xD7C0) << 10;
-      c |= (c2 & 0x3FF);
-      index += 2;
-      return c;
-    }
-  }
-  return ERROR_CHAR;
-}
-
-/// Decodes a character from a UTF-16 sequence.
-/// Params:
-///   p = start of the UTF-16 sequence.
-///   end = one past the end of the sequence.
-/// Returns: ERROR_CHAR in case of an error in the sequence.
-dchar decode(ref wchar* p, wchar* end)
-{
-  assert(p && p < end);
-  dchar c = *p;
-  if (0xD800 > c || c > 0xDFFF)
-  {
-    ++p;
-    return c;
-  }
-  if (c <= 0xDBFF && p+1 != end)
-  {
-    wchar c2 = p[1];
-    if (0xDC00 <= c2 && c2 <= 0xDFFF)
-    {
-      c = (c - 0xD7C0) << 10;
-      c |= (c2 & 0x3FF);
-      p += 2;
-      return c;
-    }
-  }
-  return ERROR_CHAR;
-}
-
-/// Decodes a character from a zero-terminated UTF-16 string.
-/// Params:
-///   p = start of the UTF-16 sequence.
-/// Returns: ERROR_CHAR in case of an error in the sequence.
-dchar decode(ref wchar* p)
-{
-  assert(p);
-  dchar c = *p;
-  if (0xD800 > c || c > 0xDFFF)
-  {
-    ++p;
-    return c;
-  }
-  if (c <= 0xDBFF)
-  {
-    wchar c2 = p[1];
-    if (0xDC00 <= c2 && c2 <= 0xDFFF)
-    {
-      c = (c - 0xD7C0) << 10;
-      c |= (c2 & 0x3FF);
-      p += 2;
-      return c;
-    }
-  }
-  return ERROR_CHAR;
-}
-
-/// Converts a UTF-8 string to a UTF-16 string.
-wchar[] toUTF16(char[] str)
-{
-  wchar[] result;
-  size_t idx;
-  while (idx < str.length)
-  {
-    auto c = decode(str, idx);
-    if (c == ERROR_CHAR)
-    { // Skip trail bytes.
-      while (++idx < str.length && isTrailByte(str[idx]))
-      {}
-      c = REPLACEMENT_CHAR;
-    }
-    encode(result, c);
-  }
-  return result;
-}
-
-/// Converts a UTF-8 string to a UTF-32 string.
-dchar[] toUTF32(char[] str)
-{
-  dchar[] result;
-  size_t idx;
-  while (idx < str.length)
-  {
-    auto c = decode(str, idx);
-    if (c == ERROR_CHAR)
-    { // Skip trail bytes.
-      while (++idx < str.length && isTrailByte(str[idx]))
-      {}
-      c = REPLACEMENT_CHAR;
-    }
-    result ~= c;
-  }
-  return result;
-}
--- a/trunk/src/dil/ast/Declaration.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.ast.Declaration;
-
-import dil.ast.Node;
-import dil.Enums;
-
-/// The root class of all declarations.
-abstract class Declaration : Node
-{
-  bool hasBody;
-  this()
-  {
-    super(NodeCategory.Declaration);
-  }
-
-  // Members relevant to semantic phase.
-  StorageClass stc; /// The storage classes of this declaration.
-  Protection prot;  /// The protection attribute of this declaration.
-
-  final bool isStatic()
-  {
-    return !!(stc & StorageClass.Static);
-  }
-
-  final bool isPublic()
-  {
-    return !!(prot & Protection.Public);
-  }
-
-  final void setStorageClass(StorageClass stc)
-  {
-    this.stc = stc;
-  }
-
-  final void setProtection(Protection prot)
-  {
-    this.prot = prot;
-  }
-
-  override abstract Declaration copy();
-}
--- a/trunk/src/dil/ast/Declarations.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,720 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.ast.Declarations;
-
-public import dil.ast.Declaration;
-import dil.ast.Node;
-import dil.ast.Expression;
-import dil.ast.Types;
-import dil.ast.Statements;
-import dil.ast.Parameters;
-import dil.ast.NodeCopier;
-import dil.lexer.IdTable;
-import dil.semantic.Symbols;
-import dil.Enums;
-import common;
-
-class CompoundDeclaration : Declaration
-{
-  this()
-  {
-    hasBody = true;
-    mixin(set_kind);
-  }
-
-  void opCatAssign(Declaration d)
-  {
-    addChild(d);
-  }
-
-  void opCatAssign(CompoundDeclaration ds)
-  {
-    addChildren(ds.children);
-  }
-
-  Declaration[] decls()
-  {
-    return cast(Declaration[])this.children;
-  }
-
-  void decls(Declaration[] decls)
-  {
-    this.children = decls;
-  }
-
-  mixin(copyMethod);
-}
-
-/// Single semicolon.
-class EmptyDeclaration : Declaration
-{
-  this()
-  {
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-
-/// Illegal declarations encompass all tokens that don't
-/// start a DeclarationDefinition.
-/// See_Also: dil.lexer.Token.isDeclDefStartToken()
-class IllegalDeclaration : Declaration
-{
-  this()
-  {
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-
-/// FQN = fully qualified name
-alias Identifier*[] ModuleFQN; // Identifier(.Identifier)*
-
-class ModuleDeclaration : Declaration
-{
-  Identifier* moduleName;
-  Identifier*[] packages;
-  this(ModuleFQN moduleFQN)
-  {
-    mixin(set_kind);
-    assert(moduleFQN.length != 0);
-    this.moduleName = moduleFQN[$-1];
-    this.packages = moduleFQN[0..$-1];
-  }
-
-  char[] getFQN()
-  {
-    auto pname = getPackageName('.');
-    if (pname.length)
-      return pname ~ "." ~ getName();
-    else
-      return getName();
-  }
-
-  char[] getName()
-  {
-    if (moduleName)
-      return moduleName.str;
-    return null;
-  }
-
-  char[] getPackageName(char separator)
-  {
-    char[] pname;
-    foreach (pckg; packages)
-      if (pckg)
-        pname ~= pckg.str ~ separator;
-    if (pname.length)
-      pname = pname[0..$-1]; // Remove last separator
-    return pname;
-  }
-
-  mixin(copyMethod);
-}
-
-class ImportDeclaration : Declaration
-{
-  private alias Identifier*[] Ids;
-  ModuleFQN[] moduleFQNs;
-  Ids moduleAliases;
-  Ids bindNames;
-  Ids bindAliases;
-
-  this(ModuleFQN[] moduleFQNs, Ids moduleAliases, Ids bindNames, Ids bindAliases, bool isStatic)
-  {
-    mixin(set_kind);
-    this.moduleFQNs = moduleFQNs;
-    this.moduleAliases = moduleAliases;
-    this.bindNames = bindNames;
-    this.bindAliases = bindAliases;
-    if (isStatic)
-      this.stc |= StorageClass.Static;
-  }
-
-  char[][] getModuleFQNs(char separator)
-  {
-    char[][] FQNs;
-    foreach (moduleFQN; moduleFQNs)
-    {
-      char[] FQN;
-      foreach (ident; moduleFQN)
-        if (ident)
-          FQN ~= ident.str ~ separator;
-      FQNs ~= FQN[0..$-1]; // Remove last separator
-    }
-    return FQNs;
-  }
-
-  mixin(copyMethod);
-}
-
-class AliasDeclaration : Declaration
-{
-  Declaration decl;
-  this(Declaration decl)
-  {
-    mixin(set_kind);
-    addChild(decl);
-    this.decl = decl;
-  }
-  mixin(copyMethod);
-}
-
-class TypedefDeclaration : Declaration
-{
-  Declaration decl;
-  this(Declaration decl)
-  {
-    mixin(set_kind);
-    addChild(decl);
-    this.decl = decl;
-  }
-  mixin(copyMethod);
-}
-
-class EnumDeclaration : Declaration
-{
-  Identifier* name;
-  TypeNode baseType;
-  EnumMemberDeclaration[] members;
-  this(Identifier* name, TypeNode baseType, EnumMemberDeclaration[] members, bool hasBody)
-  {
-    super.hasBody = hasBody;
-    mixin(set_kind);
-    addOptChild(baseType);
-    addOptChildren(members);
-
-    this.name = name;
-    this.baseType = baseType;
-    this.members = members;
-  }
-
-  Enum symbol;
-
-  mixin(copyMethod);
-}
-
-class EnumMemberDeclaration : Declaration
-{
-  Identifier* name;
-  Expression value;
-  this(Identifier* name, Expression value)
-  {
-    mixin(set_kind);
-    addOptChild(value);
-
-    this.name = name;
-    this.value = value;
-  }
-
-  EnumMember symbol;
-
-  mixin(copyMethod);
-}
-
-class TemplateDeclaration : Declaration
-{
-  Identifier* name;
-  TemplateParameters tparams;
-  CompoundDeclaration decls;
-  this(Identifier* name, TemplateParameters tparams, CompoundDeclaration decls)
-  {
-    super.hasBody = true;
-    mixin(set_kind);
-    addChild(tparams);
-    addChild(decls);
-
-    this.name = name;
-    this.tparams = tparams;
-    this.decls = decls;
-  }
-
-  Template symbol; /// The template symbol for this declaration.
-
-  mixin(copyMethod);
-}
-
-abstract class AggregateDeclaration : Declaration
-{
-  Identifier* name;
-//   TemplateParameters tparams;
-  CompoundDeclaration decls;
-  this(Identifier* name, /+TemplateParameters tparams, +/CompoundDeclaration decls)
-  {
-    super.hasBody = decls !is null;
-    this.name = name;
-//     this.tparams = tparams;
-    this.decls = decls;
-  }
-  mixin(copyMethod);
-}
-
-class ClassDeclaration : AggregateDeclaration
-{
-  BaseClassType[] bases;
-  this(Identifier* name, /+TemplateParameters tparams, +/BaseClassType[] bases, CompoundDeclaration decls)
-  {
-    super(name, /+tparams, +/decls);
-    mixin(set_kind);
-//     addChild(tparams);
-    addOptChildren(bases);
-    addOptChild(decls);
-
-    this.bases = bases;
-  }
-
-  Class symbol; /// The class symbol for this declaration.
-
-  mixin(copyMethod);
-}
-
-class InterfaceDeclaration : AggregateDeclaration
-{
-  BaseClassType[] bases;
-  this(Identifier* name, /+TemplateParameters tparams, +/BaseClassType[] bases, CompoundDeclaration decls)
-  {
-    super(name, /+tparams, +/decls);
-    mixin(set_kind);
-//     addChild(tparams);
-    addOptChildren(bases);
-    addOptChild(decls);
-
-    this.bases = bases;
-  }
-
-  alias dil.semantic.Symbols.Interface Interface;
-
-  Interface symbol; /// The interface symbol for this declaration.
-
-  mixin(copyMethod);
-}
-
-class StructDeclaration : AggregateDeclaration
-{
-  uint alignSize;
-  this(Identifier* name, /+TemplateParameters tparams, +/CompoundDeclaration decls)
-  {
-    super(name, /+tparams, +/decls);
-    mixin(set_kind);
-//     addChild(tparams);
-    addOptChild(decls);
-  }
-
-  void setAlignSize(uint alignSize)
-  {
-    this.alignSize = alignSize;
-  }
-
-  Struct symbol; /// The struct symbol for this declaration.
-
-  mixin(copyMethod);
-}
-
-class UnionDeclaration : AggregateDeclaration
-{
-  this(Identifier* name, /+TemplateParameters tparams, +/CompoundDeclaration decls)
-  {
-    super(name, /+tparams, +/decls);
-    mixin(set_kind);
-//     addChild(tparams);
-    addOptChild(decls);
-  }
-
-  Union symbol; /// The union symbol for this declaration.
-
-  mixin(copyMethod);
-}
-
-class ConstructorDeclaration : Declaration
-{
-  Parameters params;
-  FuncBodyStatement funcBody;
-  this(Parameters params, FuncBodyStatement funcBody)
-  {
-    super.hasBody = true;
-    mixin(set_kind);
-    addChild(params);
-    addChild(funcBody);
-
-    this.params = params;
-    this.funcBody = funcBody;
-  }
-  mixin(copyMethod);
-}
-
-class StaticConstructorDeclaration : Declaration
-{
-  FuncBodyStatement funcBody;
-  this(FuncBodyStatement funcBody)
-  {
-    super.hasBody = true;
-    mixin(set_kind);
-    addChild(funcBody);
-
-    this.funcBody = funcBody;
-  }
-  mixin(copyMethod);
-}
-
-class DestructorDeclaration : Declaration
-{
-  FuncBodyStatement funcBody;
-  this(FuncBodyStatement funcBody)
-  {
-    super.hasBody = true;
-    mixin(set_kind);
-    addChild(funcBody);
-
-    this.funcBody = funcBody;
-  }
-  mixin(copyMethod);
-}
-
-class StaticDestructorDeclaration : Declaration
-{
-  FuncBodyStatement funcBody;
-  this(FuncBodyStatement funcBody)
-  {
-    super.hasBody = true;
-    mixin(set_kind);
-    addChild(funcBody);
-
-    this.funcBody = funcBody;
-  }
-  mixin(copyMethod);
-}
-
-class FunctionDeclaration : Declaration
-{
-  TypeNode returnType;
-  Identifier* name;
-//   TemplateParameters tparams;
-  Parameters params;
-  FuncBodyStatement funcBody;
-  LinkageType linkageType;
-  this(TypeNode returnType, Identifier* name,/+ TemplateParameters tparams,+/
-       Parameters params, FuncBodyStatement funcBody)
-  {
-    super.hasBody = funcBody.funcBody !is null;
-    mixin(set_kind);
-    addChild(returnType);
-//     addChild(tparams);
-    addChild(params);
-    addChild(funcBody);
-
-    this.returnType = returnType;
-    this.name = name;
-//     this.tparams = tparams;
-    this.params = params;
-    this.funcBody = funcBody;
-  }
-
-  void setLinkageType(LinkageType linkageType)
-  {
-    this.linkageType = linkageType;
-  }
-
-  bool isTemplatized()
-  { // E.g.: void func(T)(T t)
-    //                  ^ params.begin.prevNWS
-    return params.begin.prevNWS.kind == TOK.RParen;
-  }
-
-  mixin(copyMethod);
-}
-
-/// VariablesDeclaration := Type? Identifier ("=" Init)? ("," Identifier ("=" Init)?)* ";"
-class VariablesDeclaration : Declaration
-{
-  TypeNode typeNode;
-  Identifier*[] names;
-  Expression[] inits;
-  this(TypeNode typeNode, Identifier*[] names, Expression[] inits)
-  {
-    // No empty arrays allowed. Both arrays must be of same size.
-    assert(names.length != 0 && names.length == inits.length);
-    // If no type (in case of AutoDeclaration), first value mustn't be null.
-    assert(typeNode ? 1 : inits[0] !is null);
-    mixin(set_kind);
-    addOptChild(typeNode);
-    foreach(init; inits)
-      addOptChild(init);
-
-    this.typeNode = typeNode;
-    this.names = names;
-    this.inits = inits;
-  }
-
-  LinkageType linkageType;
-
-  void setLinkageType(LinkageType linkageType)
-  {
-    this.linkageType = linkageType;
-  }
-
-  Variable[] variables;
-
-  mixin(copyMethod);
-}
-
-class InvariantDeclaration : Declaration
-{
-  FuncBodyStatement funcBody;
-  this(FuncBodyStatement funcBody)
-  {
-    super.hasBody = true;
-    mixin(set_kind);
-    addChild(funcBody);
-
-    this.funcBody = funcBody;
-  }
-  mixin(copyMethod);
-}
-
-class UnittestDeclaration : Declaration
-{
-  FuncBodyStatement funcBody;
-  this(FuncBodyStatement funcBody)
-  {
-    super.hasBody = true;
-    mixin(set_kind);
-    addChild(funcBody);
-
-    this.funcBody = funcBody;
-  }
-  mixin(copyMethod);
-}
-
-abstract class ConditionalCompilationDeclaration : Declaration
-{
-  Token* spec;
-  Token* cond;
-  Declaration decls, elseDecls;
-
-  this(Token* spec, Token* cond, Declaration decls, Declaration elseDecls)
-  {
-    super.hasBody = decls !is null;
-    addOptChild(decls);
-    addOptChild(elseDecls);
-
-    this.spec = spec;
-    this.cond = cond;
-    this.decls = decls;
-    this.elseDecls = elseDecls;
-  }
-
-  bool isSpecification()
-  {
-    return decls is null;
-  }
-
-  bool isCondition()
-  {
-    return decls !is null;
-  }
-
-  /// The branch to be compiled in.
-  Declaration compiledDecls;
-}
-
-class DebugDeclaration : ConditionalCompilationDeclaration
-{
-  this(Token* spec, Token* cond, Declaration decls, Declaration elseDecls)
-  {
-    super(spec, cond, decls, elseDecls);
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-
-class VersionDeclaration : ConditionalCompilationDeclaration
-{
-  this(Token* spec, Token* cond, Declaration decls, Declaration elseDecls)
-  {
-    super(spec, cond, decls, elseDecls);
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-
-class StaticIfDeclaration : Declaration
-{
-  Expression condition;
-  Declaration ifDecls, elseDecls;
-  this(Expression condition, Declaration ifDecls, Declaration elseDecls)
-  {
-    super.hasBody = true;
-    mixin(set_kind);
-    addChild(condition);
-    addChild(ifDecls);
-    addOptChild(elseDecls);
-
-    this.condition = condition;
-    this.ifDecls = ifDecls;
-    this.elseDecls = elseDecls;
-  }
-  mixin(copyMethod);
-}
-
-class StaticAssertDeclaration : Declaration
-{
-  Expression condition, message;
-  this(Expression condition, Expression message)
-  {
-    super.hasBody = true;
-    mixin(set_kind);
-    addChild(condition);
-    addOptChild(message);
-
-    this.condition = condition;
-    this.message = message;
-  }
-  mixin(copyMethod);
-}
-
-class NewDeclaration : Declaration
-{
-  Parameters params;
-  FuncBodyStatement funcBody;
-  this(Parameters params, FuncBodyStatement funcBody)
-  {
-    super.hasBody = true;
-    mixin(set_kind);
-    addChild(params);
-    addChild(funcBody);
-
-    this.params = params;
-    this.funcBody = funcBody;
-  }
-  mixin(copyMethod);
-}
-
-class DeleteDeclaration : Declaration
-{
-  Parameters params;
-  FuncBodyStatement funcBody;
-  this(Parameters params, FuncBodyStatement funcBody)
-  {
-    super.hasBody = true;
-    mixin(set_kind);
-    addChild(params);
-    addChild(funcBody);
-
-    this.params = params;
-    this.funcBody = funcBody;
-  }
-  mixin(copyMethod);
-}
-
-abstract class AttributeDeclaration : Declaration
-{
-  Declaration decls;
-  this(Declaration decls)
-  {
-    super.hasBody = true;
-    addChild(decls);
-    this.decls = decls;
-  }
-}
-
-class ProtectionDeclaration : AttributeDeclaration
-{
-  Protection prot;
-  this(Protection prot, Declaration decls)
-  {
-    super(decls);
-    mixin(set_kind);
-    this.prot = prot;
-  }
-  mixin(copyMethod);
-}
-
-class StorageClassDeclaration : AttributeDeclaration
-{
-  StorageClass storageClass;
-  this(StorageClass storageClass, Declaration decl)
-  {
-    super(decl);
-    mixin(set_kind);
-
-    this.storageClass = storageClass;
-  }
-  mixin(copyMethod);
-}
-
-class LinkageDeclaration : AttributeDeclaration
-{
-  LinkageType linkageType;
-  this(LinkageType linkageType, Declaration decls)
-  {
-    super(decls);
-    mixin(set_kind);
-
-    this.linkageType = linkageType;
-  }
-  mixin(copyMethod);
-}
-
-class AlignDeclaration : AttributeDeclaration
-{
-  int size;
-  this(int size, Declaration decls)
-  {
-    super(decls);
-    mixin(set_kind);
-    this.size = size;
-  }
-  mixin(copyMethod);
-}
-
-class PragmaDeclaration : AttributeDeclaration
-{
-  Identifier* ident;
-  Expression[] args;
-  this(Identifier* ident, Expression[] args, Declaration decls)
-  {
-    addOptChildren(args); // Add args before calling super().
-    super(decls);
-    mixin(set_kind);
-
-    this.ident = ident;
-    this.args = args;
-  }
-  mixin(copyMethod);
-}
-
-class MixinDeclaration : Declaration
-{
-  /// IdExpression := IdentifierExpression | TemplateInstanceExpression
-  /// MixinTemplate := IdExpression ("." IdExpression)*
-  Expression templateExpr;
-  Identifier* mixinIdent; /// Optional mixin identifier.
-  Expression argument; /// "mixin" "(" AssignExpression ")"
-  Declaration decls; /// Initialized in the semantic phase.
-
-  this(Expression templateExpr, Identifier* mixinIdent)
-  {
-    mixin(set_kind);
-    addChild(templateExpr);
-
-    this.templateExpr = templateExpr;
-    this.mixinIdent = mixinIdent;
-  }
-
-  this(Expression argument)
-  {
-    mixin(set_kind);
-    addChild(argument);
-
-    this.argument = argument;
-  }
-
-  bool isMixinExpression()
-  {
-    return argument !is null;
-  }
-
-  mixin(copyMethod);
-}
--- a/trunk/src/dil/ast/DefaultVisitor.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,375 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.ast.DefaultVisitor;
-
-import dil.ast.Visitor;
-
-import dil.ast.Node;
-import dil.ast.Declarations,
-       dil.ast.Expressions,
-       dil.ast.Statements,
-       dil.ast.Types,
-       dil.ast.Parameters;
-import common;
-
-/// This huge template function, when instantiated for a certain node class,
-/// generates a body of calls to visit() on the subnodes.
-returnType!(T.stringof) visitDefault(T)(T t)
-{
-  assert(t !is null, "node passed to visitDefault() is null");
-  //Stdout(t).newline;
-
-  alias t d, s, e, n; // Variable aliases of t.
-
-  static if (is(T : Declaration))
-  {
-    alias T D;
-    static if (is(D == CompoundDeclaration))
-      foreach (decl; d.decls)
-        visitD(decl);
-    //EmptyDeclaration,
-    //IllegalDeclaration,
-    //ModuleDeclaration have no subnodes.
-    static if (is(D == AliasDeclaration) ||
-               is(D == TypedefDeclaration))
-      visitD(d.decl);
-    static if (is(D == EnumDeclaration))
-    {
-      d.baseType && visitT(d.baseType);
-      foreach (member; d.members)
-        visitD(member);
-    }
-    static if (is(D == EnumMemberDeclaration))
-      d.value && visitE(d.value);
-    static if (is(D == ClassDeclaration) || is( D == InterfaceDeclaration))
-    {
-//       visitN(d.tparams);
-      foreach (base; d.bases)
-        visitT(base);
-      d.decls && visitD(d.decls);
-    }
-    static if (is(D == StructDeclaration) || is(D == UnionDeclaration))
-//       visitN(d.tparams),
-      d.decls && visitD(d.decls);
-    static if (is(D == ConstructorDeclaration))
-      visitN(d.params), visitS(d.funcBody);
-    static if (is(D == StaticConstructorDeclaration) ||
-               is(D == DestructorDeclaration) ||
-               is(D == StaticDestructorDeclaration) ||
-               is(D == InvariantDeclaration) ||
-               is(D == UnittestDeclaration))
-      visitS(d.funcBody);
-    static if (is(D == FunctionDeclaration))
-      visitT(d.returnType),
-//       visitN(d.tparams),
-      visitN(d.params),
-      visitS(d.funcBody);
-    static if (is(D == VariablesDeclaration))
-    {
-      d.typeNode && visitT(d.typeNode);
-      foreach(init; d.inits)
-        init && visitE(init);
-    }
-    static if (is(D == DebugDeclaration) || is(D == VersionDeclaration))
-      d.decls && visitD(d.decls),
-      d.elseDecls && visitD(d.elseDecls);
-    static if (is(D == StaticIfDeclaration))
-      visitE(d.condition),
-      visitD(d.ifDecls),
-      d.elseDecls && visitD(d.elseDecls);
-    static if (is(D == StaticAssertDeclaration))
-      visitE(d.condition),
-      d.message && visitE(d.message);
-    static if (is(D == TemplateDeclaration))
-      visitN(d.tparams),
-      visitD(d.decls);
-    static if (is(D == NewDeclaration) || is(D == DeleteDeclaration))
-      visitN(d.params),
-      visitS(d.funcBody);
-    static if (is(D == ProtectionDeclaration) ||
-               is(D == StorageClassDeclaration) ||
-               is(D == LinkageDeclaration) ||
-               is(D == AlignDeclaration))
-      visitD(d.decls);
-    static if (is(D == PragmaDeclaration))
-    {
-      foreach (arg; d.args)
-        visitE(arg);
-      visitD(d.decls);
-    }
-    static if (is(D == MixinDeclaration))
-      d.templateExpr ? visitE(d.templateExpr) : visitE(d.argument);
-  }
-  else
-  static if (is(T : Expression))
-  {
-    alias T E;
-    static if (is(E == IllegalExpression))
-    {}
-    else
-    static if (is(E == CondExpression))
-      visitE(e.condition), visitE(e.lhs), visitE(e.rhs);
-    else
-    static if (is(E : BinaryExpression))
-      visitE(e.lhs), visitE(e.rhs);
-    else
-    static if (is(E : UnaryExpression))
-    {
-      static if (is(E == CastExpression))
-        visitT(e.type);
-      visitE(e.e); // Visit member in base class UnaryExpression.
-      static if (is(E == IndexExpression))
-        foreach (arg; e.args)
-          visitE(arg);
-      static if (is(E == SliceExpression))
-        e.left && (visitE(e.left), visitE(e.right));
-      static if (is(E == AsmPostBracketExpression))
-        visitE(e.e2);
-    }
-    else
-    {
-      static if (is(E == NewExpression))
-      {
-        foreach (arg; e.newArgs)
-          visitE(arg);
-        visitT(e.type);
-        foreach (arg; e.ctorArgs)
-          visitE(arg);
-      }
-      static if (is(E == NewAnonClassExpression))
-      {
-        foreach (arg; e.newArgs)
-          visitE(arg);
-        foreach (base; e.bases)
-          visitT(base);
-        foreach (arg; e.ctorArgs)
-          visitE(arg);
-        visitD(e.decls);
-      }
-      static if (is(E == AsmBracketExpression))
-        visitE(e.e);
-      static if (is(E == TemplateInstanceExpression))
-        e.targs && visitN(e.targs);
-      static if (is(E == ArrayLiteralExpression))
-        foreach (value; e.values)
-          visitE(value);
-      static if (is(E == AArrayLiteralExpression))
-        foreach (i, key; e.keys)
-          visitE(key), visitE(e.values[i]);
-      static if (is(E == AssertExpression))
-        visitE(e.expr), e.msg && visitE(e.msg);
-      static if (is(E == MixinExpression) ||
-                 is(E == ImportExpression))
-        visitE(e.expr);
-      static if (is(E == TypeofExpression) ||
-                 is(E == TypeDotIdExpression) ||
-                 is(E == TypeidExpression))
-        visitT(e.type);
-      static if (is(E == IsExpression))
-        visitT(e.type), e.specType && visitT(e.specType),
-        e.tparams && visitN(e.tparams);
-      static if (is(E == FunctionLiteralExpression))
-        e.returnType && visitT(e.returnType),
-        e.params && visitN(e.params),
-        visitS(e.funcBody);
-      static if (is(E == ParenExpression))
-        visitE(e.next);
-      static if (is(E == TraitsExpression))
-        visitN(e.targs);
-      // VoidInitializer has no subnodes.
-      static if (is(E == ArrayInitExpression))
-        foreach (i, key; e.keys)
-          key && visitE(key), visitE(e.values[i]);
-      static if (is(E == StructInitExpression))
-        foreach (value; e.values)
-          visitE(value);
-    }
-  }
-  else
-  static if (is(T : Statement))
-  {
-    alias T S;
-    static if (is(S == CompoundStatement))
-      foreach (stmnt; s.stmnts)
-        visitS(stmnt);
-    //IllegalStatement has no subnodes.
-    static if (is(S == FuncBodyStatement))
-      s.funcBody && visitS(s.funcBody),
-      s.inBody && visitS(s.inBody),
-      s.outBody && visitS(s.outBody);
-    static if (is(S == ScopeStatement) || is(S == LabeledStatement))
-      visitS(s.s);
-    static if (is(S == ExpressionStatement))
-      visitE(s.e);
-    static if (is(S == DeclarationStatement))
-      visitD(s.decl);
-    static if (is(S == IfStatement))
-    {
-      s.variable ? cast(Node)visitS(s.variable) : visitE(s.condition);
-      visitS(s.ifBody), s.elseBody && visitS(s.elseBody);
-    }
-    static if (is(S == WhileStatement))
-      visitE(s.condition), visitS(s.whileBody);
-    static if (is(S == DoWhileStatement))
-      visitS(s.doBody), visitE(s.condition);
-    static if (is(S == ForStatement))
-      s.init && visitS(s.init),
-      s.condition && visitE(s.condition),
-      s.increment && visitE(s.increment),
-      visitS(s.forBody);
-    static if (is(S == ForeachStatement))
-      visitN(s.params), visitE(s.aggregate), visitS(s.forBody);
-    static if (is(S == ForeachRangeStatement))
-      visitN(s.params), visitE(s.lower), visitE(s.upper), visitS(s.forBody);
-    static if (is(S == SwitchStatement))
-      visitE(s.condition), visitS(s.switchBody);
-    static if (is(S == CaseStatement))
-    {
-      foreach (value; s.values)
-        visitE(value);
-      visitS(s.caseBody);
-    }
-    static if (is(S == DefaultStatement))
-      visitS(s.defaultBody);
-    //ContinueStatement,
-    //BreakStatement have no subnodes.
-    static if (is(S == ReturnStatement))
-      s.e && visitE(s.e);
-    static if (is(S == GotoStatement))
-      s.caseExpr && visitE(s.caseExpr);
-    static if (is(S == WithStatement))
-      visitE(s.e), visitS(s.withBody);
-    static if (is(S == SynchronizedStatement))
-      s.e && visitE(s.e), visitS(s.syncBody);
-    static if (is(S == TryStatement))
-    {
-      visitS(s.tryBody);
-      foreach (catchBody; s.catchBodies)
-        visitS(catchBody);
-      s.finallyBody && visitS(s.finallyBody);
-    }
-    static if (is(S == CatchStatement))
-      s.param && visitN(s.param), visitS(s.catchBody);
-    static if (is(S == FinallyStatement))
-      visitS(s.finallyBody);
-    static if (is(S == ScopeGuardStatement))
-      visitS(s.scopeBody);
-    static if (is(S == ThrowStatement))
-      visitE(s.e);
-    static if (is(S == VolatileStatement))
-      s.volatileBody && visitS(s.volatileBody);
-    static if (is(S == AsmBlockStatement))
-      visitS(s.statements);
-    static if (is(S == AsmStatement))
-      foreach (op; s.operands)
-        visitE(op);
-    //AsmAlignStatement,
-    //IllegalAsmStatement have no subnodes.
-    static if (is(S == PragmaStatement))
-    {
-      foreach (arg; s.args)
-        visitE(arg);
-      visitS(s.pragmaBody);
-    }
-    static if (is(S == MixinStatement))
-      visitE(s.templateExpr);
-    static if (is(S == StaticIfStatement))
-      visitE(s.condition), visitS(s.ifBody), s.elseBody && visitS(s.elseBody);
-    static if (is(S == StaticAssertStatement))
-      visitE(s.condition), s.message && visitE(s.message);
-    static if (is(S == DebugStatement) || is(S == VersionStatement))
-      visitS(s.mainBody), s.elseBody && visitS(s.elseBody);
-  }
-  else
-  static if (is(T : TypeNode))
-  {
-    //IllegalType,
-    //IntegralType,
-    //ModuleScopeType,
-    //IdentifierType have no subnodes.
-    static if (is(T == QualifiedType))
-      visitT(t.lhs), visitT(t.rhs);
-    static if (is(T == TypeofType))
-      visitE(t.e);
-    static if (is(T == TemplateInstanceType))
-      t.targs && visitN(t.targs);
-    static if (is(T == PointerType))
-      visitT(t.next);
-    static if (is(T == ArrayType))
-    {
-      visitT(t.next);
-      if (t.assocType)
-        visitT(t.assocType);
-      else if (t.e1)
-        visitE(t.e1), t.e2 && visitE(t.e2);
-    }
-    static if (is(T == FunctionType) || is(T == DelegateType))
-      visitT(t.returnType), visitN(t.params);
-    static if (is(T == CFuncPointerType))
-      visitT(t.next), t.params && visitN(t.params);
-    static if (is(T == BaseClassType) ||
-               is(T == ConstType) ||
-               is(T == InvariantType))
-      visitT(t.next);
-  }
-  else
-  static if (is(T == Parameter))
-  {
-    n.type && visitT(n.type);
-    n.defValue && visitE(n.defValue);
-  }
-  else
-  static if (is(T == Parameters) ||
-             is(T == TemplateParameters) ||
-             is(T == TemplateArguments))
-  {
-    foreach (node; n.children)
-      visitN(node);
-  }
-  else
-  static if (is(T : TemplateParameter))
-  {
-    static if (is(N == TemplateAliasParameter) ||
-               is(N == TemplateTypeParameter) ||
-               is(N == TemplateThisParameter))
-      n.specType && visitN(n.specType),
-      n.defType && visitN(n.defType);
-    static if (is(N == TemplateValueParameter))
-      visitT(n.valueType),
-      n.specValue && visitN(n.specValue),
-      n.defValue && visitN(n.defValue);
-    //TemplateTupleParameter has no subnodes.
-  }
-  else
-    static assert(0, "Missing default visit method for: "~typeof(t).stringof);
-  return t;
-}
-
-/// Generates the default visit methods.
-///
-/// E.g:
-/// ---
-/// private mixin .visitDefault!(ClassDeclaration) _ClassDeclaration;
-/// override returnType!("ClassDeclaration") visit(ClassDeclaration node)
-/// { return _ClassDeclaration.visitDefault(node); }
-/// ---
-char[] generateDefaultVisitMethods()
-{
-  char[] text;
-  foreach (className; g_classNames)
-    text ~= "private mixin .visitDefault!("~className~") _"~className~";\n"
-            "override returnType!(\""~className~"\") visit("~className~" node)"
-            "{return _"~className~".visitDefault(node);}\n";
-  return text;
-}
-// pragma(msg, generateDefaultVisitMethods());
-
-/// This class provides default methods for
-/// traversing nodes and their sub-nodes.
-class DefaultVisitor : Visitor
-{
-  // Comment out if too many errors are shown.
-  mixin(generateDefaultVisitMethods());
-}
--- a/trunk/src/dil/ast/Expression.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.ast.Expression;
-
-import dil.ast.Node;
-import dil.semantic.Types;
-import common;
-
-/// The root class of all expressions.
-abstract class Expression : Node
-{
-  Type type; /// The semantic type of this expression.
-
-  this()
-  {
-    super(NodeCategory.Expression);
-  }
-
-  override abstract Expression copy();
-}
--- a/trunk/src/dil/ast/Expressions.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1118 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.ast.Expressions;
-
-public import dil.ast.Expression;
-import dil.ast.Node;
-import dil.ast.Types;
-import dil.ast.Declarations;
-import dil.ast.Statements;
-import dil.ast.Parameters;
-import dil.ast.NodeCopier;
-import dil.lexer.Identifier;
-import dil.semantic.Types;
-import common;
-
-class IllegalExpression : Expression
-{
-  this()
-  {
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-
-abstract class BinaryExpression : Expression
-{
-  Expression lhs; /// Left-hand side expression.
-  Expression rhs; /// Right-hand side expression.
-  Token* tok;
-  this(Expression lhs, Expression rhs, Token* tok)
-  {
-    addChildren([lhs, rhs]);
-    this.lhs = lhs;
-    this.rhs = rhs;
-    this.tok = tok;
-  }
-  mixin(copyMethod);
-}
-
-class CondExpression : BinaryExpression
-{
-  Expression condition;
-  this(Expression condition, Expression left, Expression right, Token* tok)
-  {
-    addChild(condition);
-    super(left, right, tok);
-    mixin(set_kind);
-    this.condition = condition;
-  }
-  mixin(copyMethod);
-}
-
-class CommaExpression : BinaryExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-class OrOrExpression : BinaryExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-class AndAndExpression : BinaryExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-class OrExpression : BinaryExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-class XorExpression : BinaryExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-class AndExpression : BinaryExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-abstract class CmpExpression : BinaryExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-  }
-}
-
-class EqualExpression : CmpExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-/// Expression "!"? "is" Expression
-class IdentityExpression : CmpExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-class RelExpression : CmpExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-class InExpression : BinaryExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-class LShiftExpression : BinaryExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-class RShiftExpression : BinaryExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-class URShiftExpression : BinaryExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-class PlusExpression : BinaryExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-class MinusExpression : BinaryExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-class CatExpression : BinaryExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-class MulExpression : BinaryExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-class DivExpression : BinaryExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-class ModExpression : BinaryExpression
-{
-  this(Expression left, Expression right, Token* tok)
-  {
-    super(left, right, tok);
-    mixin(set_kind);
-  }
-}
-
-class AssignExpression : BinaryExpression
-{
-  this(Expression left, Expression right)
-  {
-    super(left, right, null);
-    mixin(set_kind);
-  }
-}
-class LShiftAssignExpression : BinaryExpression
-{
-  this(Expression left, Expression right)
-  {
-    super(left, right, null);
-    mixin(set_kind);
-  }
-}
-class RShiftAssignExpression : BinaryExpression
-{
-  this(Expression left, Expression right)
-  {
-    super(left, right, null);
-    mixin(set_kind);
-  }
-}
-class URShiftAssignExpression : BinaryExpression
-{
-  this(Expression left, Expression right)
-  {
-    super(left, right, null);
-    mixin(set_kind);
-  }
-}
-class OrAssignExpression : BinaryExpression
-{
-  this(Expression left, Expression right)
-  {
-    super(left, right, null);
-    mixin(set_kind);
-  }
-}
-class AndAssignExpression : BinaryExpression
-{
-  this(Expression left, Expression right)
-  {
-    super(left, right, null);
-    mixin(set_kind);
-  }
-}
-class PlusAssignExpression : BinaryExpression
-{
-  this(Expression left, Expression right)
-  {
-    super(left, right, null);
-    mixin(set_kind);
-  }
-}
-class MinusAssignExpression : BinaryExpression
-{
-  this(Expression left, Expression right)
-  {
-    super(left, right, null);
-    mixin(set_kind);
-  }
-}
-class DivAssignExpression : BinaryExpression
-{
-  this(Expression left, Expression right)
-  {
-    super(left, right, null);
-    mixin(set_kind);
-  }
-}
-class MulAssignExpression : BinaryExpression
-{
-  this(Expression left, Expression right)
-  {
-    super(left, right, null);
-    mixin(set_kind);
-  }
-}
-class ModAssignExpression : BinaryExpression
-{
-  this(Expression left, Expression right)
-  {
-    super(left, right, null);
-    mixin(set_kind);
-  }
-}
-class XorAssignExpression : BinaryExpression
-{
-  this(Expression left, Expression right)
-  {
-    super(left, right, null);
-    mixin(set_kind);
-  }
-}
-class CatAssignExpression : BinaryExpression
-{
-  this(Expression left, Expression right)
-  {
-    super(left, right, null);
-    mixin(set_kind);
-  }
-}
-
-/// DotExpression := Expression '.' Expression
-class DotExpression : BinaryExpression
-{
-  this(Expression left, Expression right)
-  {
-    super(left, right, null);
-    mixin(set_kind);
-  }
-}
-
-/*++++++++++++++++++++
-+ Unary Expressions: +
-++++++++++++++++++++*/
-
-abstract class UnaryExpression : Expression
-{
-  Expression e;
-  this(Expression e)
-  {
-    addChild(e);
-    this.e = e;
-  }
-  mixin(copyMethod);
-}
-
-class AddressExpression : UnaryExpression
-{
-  this(Expression e)
-  {
-    super(e);
-    mixin(set_kind);
-  }
-}
-
-class PreIncrExpression : UnaryExpression
-{
-  this(Expression e)
-  {
-    super(e);
-    mixin(set_kind);
-  }
-}
-
-class PreDecrExpression : UnaryExpression
-{
-  this(Expression e)
-  {
-    super(e);
-    mixin(set_kind);
-  }
-}
-
-class PostIncrExpression : UnaryExpression
-{
-  this(Expression e)
-  {
-    super(e);
-    mixin(set_kind);
-  }
-}
-
-class PostDecrExpression : UnaryExpression
-{
-  this(Expression e)
-  {
-    super(e);
-    mixin(set_kind);
-  }
-}
-
-class DerefExpression : UnaryExpression
-{
-  this(Expression e)
-  {
-    super(e);
-    mixin(set_kind);
-  }
-}
-
-class SignExpression : UnaryExpression
-{
-  this(Expression e)
-  {
-    super(e);
-    mixin(set_kind);
-  }
-
-  bool isPos()
-  {
-    assert(begin !is null);
-    return begin.kind == TOK.Plus;
-  }
-
-  bool isNeg()
-  {
-    assert(begin !is null);
-    return begin.kind == TOK.Minus;
-  }
-}
-
-class NotExpression : UnaryExpression
-{
-  this(Expression e)
-  {
-    super(e);
-    mixin(set_kind);
-  }
-}
-
-class CompExpression : UnaryExpression
-{
-  this(Expression e)
-  {
-    super(e);
-    mixin(set_kind);
-  }
-}
-
-class CallExpression : UnaryExpression
-{
-  Expression[] args;
-  this(Expression e, Expression[] args)
-  {
-    super(e);
-    mixin(set_kind);
-    addOptChildren(args);
-    this.args = args;
-  }
-}
-
-class NewExpression : /*Unary*/Expression
-{
-  Expression[] newArgs;
-  TypeNode type;
-  Expression[] ctorArgs;
-  this(/*Expression e, */Expression[] newArgs, TypeNode type, Expression[] ctorArgs)
-  {
-    /*super(e);*/
-    mixin(set_kind);
-    addOptChildren(newArgs);
-    addChild(type);
-    addOptChildren(ctorArgs);
-    this.newArgs = newArgs;
-    this.type = type;
-    this.ctorArgs = ctorArgs;
-  }
-  mixin(copyMethod);
-}
-
-class NewAnonClassExpression : /*Unary*/Expression
-{
-  Expression[] newArgs;
-  BaseClassType[] bases;
-  Expression[] ctorArgs;
-  CompoundDeclaration decls;
-  this(/*Expression e, */Expression[] newArgs, BaseClassType[] bases, Expression[] ctorArgs, CompoundDeclaration decls)
-  {
-    /*super(e);*/
-    mixin(set_kind);
-    addOptChildren(newArgs);
-    addOptChildren(bases);
-    addOptChildren(ctorArgs);
-    addChild(decls);
-
-    this.newArgs = newArgs;
-    this.bases = bases;
-    this.ctorArgs = ctorArgs;
-    this.decls = decls;
-  }
-  mixin(copyMethod);
-}
-
-class DeleteExpression : UnaryExpression
-{
-  this(Expression e)
-  {
-    super(e);
-    mixin(set_kind);
-  }
-}
-
-class CastExpression : UnaryExpression
-{
-  TypeNode type;
-  this(Expression e, TypeNode type)
-  {
-    addChild(type); // Add type before super().
-    super(e);
-    mixin(set_kind);
-    this.type = type;
-  }
-  mixin(copyMethod);
-}
-
-class IndexExpression : UnaryExpression
-{
-  Expression[] args;
-  this(Expression e, Expression[] args)
-  {
-    super(e);
-    mixin(set_kind);
-    addChildren(args);
-    this.args = args;
-  }
-  mixin(copyMethod);
-}
-
-class SliceExpression : UnaryExpression
-{
-  Expression left, right;
-  this(Expression e, Expression left, Expression right)
-  {
-    super(e);
-    mixin(set_kind);
-    assert(left ? (right !is null) : right is null);
-    if (left)
-      addChildren([left, right]);
-
-    this.left = left;
-    this.right = right;
-  }
-  mixin(copyMethod);
-}
-
-/// Module scope operator: '.' (IdentifierExpression|TemplateInstanceExpression)
-class ModuleScopeExpression : UnaryExpression
-{
-  this(Expression e)
-  {
-    super(e);
-    assert(e.kind == NodeKind.IdentifierExpression ||
-           e.kind == NodeKind.TemplateInstanceExpression
-    );
-    mixin(set_kind);
-  }
-}
-
-/*++++++++++++++++++++++
-+ Primary Expressions: +
-++++++++++++++++++++++*/
-
-class IdentifierExpression : Expression
-{
-  Identifier* identifier;
-  this(Identifier* identifier)
-  {
-    mixin(set_kind);
-    this.identifier = identifier;
-  }
-  mixin(copyMethod);
-}
-
-class SpecialTokenExpression : Expression
-{
-  Token* specialToken;
-  this(Token* specialToken)
-  {
-    mixin(set_kind);
-    this.specialToken = specialToken;
-  }
-
-  Expression value; /// The expression created in the semantic phase.
-
-  mixin(copyMethod);
-}
-
-class TemplateInstanceExpression : Expression
-{
-  Identifier* ident;
-  TemplateArguments targs;
-  this(Identifier* ident, TemplateArguments targs)
-  {
-    mixin(set_kind);
-    addOptChild(targs);
-    this.ident = ident;
-    this.targs = targs;
-  }
-  mixin(copyMethod);
-}
-
-class ThisExpression : Expression
-{
-  this()
-  {
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-
-class SuperExpression : Expression
-{
-  this()
-  {
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-
-class NullExpression : Expression
-{
-  this()
-  {
-    mixin(set_kind);
-  }
-
-  this(Type type)
-  {
-    this();
-    this.type = type;
-  }
-
-  mixin(copyMethod);
-}
-
-class DollarExpression : Expression
-{
-  this()
-  {
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-
-class BoolExpression : Expression
-{
-  this()
-  {
-    mixin(set_kind);
-  }
-
-  bool toBool()
-  {
-    assert(begin !is null);
-    return begin.kind == TOK.True ? true : false;
-  }
-
-  Expression value; /// IntExpression of type int.
-
-  mixin(copyMethod);
-}
-
-class IntExpression : Expression
-{
-  ulong number;
-
-  this(ulong number, Type type)
-  {
-    mixin(set_kind);
-    this.number = number;
-    this.type = type;
-  }
-
-  this(Token* token)
-  {
-    auto type = Types.Int; // Should be most common case.
-    switch (token.kind)
-    {
-    // case TOK.Int32:
-    //   type = Types.Int; break;
-    case TOK.Uint32:
-      type = Types.Uint; break;
-    case TOK.Int64:
-      type = Types.Long; break;
-    case TOK.Uint64:
-      type = Types.Ulong; break;
-    default:
-      assert(token.kind == TOK.Int32);
-    }
-    this(token.ulong_, type);
-  }
-
-  mixin(copyMethod);
-}
-
-class RealExpression : Expression
-{
-  real number;
-
-  this(real number, Type type)
-  {
-    mixin(set_kind);
-    this.number = number;
-    this.type = type;
-  }
-
-  this(Token* token)
-  {
-    auto type = Types.Double; // Most common case?
-    switch (token.kind)
-    {
-    case TOK.Float32:
-      type = Types.Float; break;
-    // case TOK.Float64:
-    //   type = Types.Double; break;
-    case TOK.Float80:
-      type = Types.Real; break;
-    case TOK.Imaginary32:
-      type = Types.Ifloat; break;
-    case TOK.Imaginary64:
-      type = Types.Idouble; break;
-    case TOK.Imaginary80:
-      type = Types.Ireal; break;
-    default:
-      assert(token.kind == TOK.Float64);
-    }
-    this(token.real_, type);
-  }
-
-  mixin(copyMethod);
-}
-
-
-/// This expression holds a complex number.
-/// It is only created in the semantic phase.
-class ComplexExpression : Expression
-{
-  creal number;
-  this(creal number, Type type)
-  {
-    mixin(set_kind);
-    this.number = number;
-    this.type = type;
-  }
-  mixin(copyMethod);
-}
-
-class CharExpression : Expression
-{
-  dchar character;
-  this(dchar character)
-  {
-    mixin(set_kind);
-    this.character = character;
-  }
-  mixin(copyMethod);
-}
-
-class StringExpression : Expression
-{
-  ubyte[] str;   /// The string data.
-  Type charType; /// The character type of the string.
-
-  this(ubyte[] str, Type charType)
-  {
-    mixin(set_kind);
-    this.str = str;
-    this.charType = charType;
-    type = new TypeSArray(charType, str.length);
-  }
-
-  this(char[] str)
-  {
-    this(cast(ubyte[])str, Types.Char);
-  }
-
-  this(wchar[] str)
-  {
-    this(cast(ubyte[])str, Types.Wchar);
-  }
-
-  this(dchar[] str)
-  {
-    this(cast(ubyte[])str, Types.Dchar);
-  }
-
-  /// Returns the string excluding the terminating 0.
-  char[] getString()
-  {
-    // TODO: convert to char[] if charType !is Types.Char.
-    return cast(char[])str[0..$-1];
-  }
-
-  mixin(copyMethod);
-}
-
-class ArrayLiteralExpression : Expression
-{
-  Expression[] values;
-  this(Expression[] values)
-  {
-    mixin(set_kind);
-    addOptChildren(values);
-    this.values = values;
-  }
-  mixin(copyMethod);
-}
-
-class AArrayLiteralExpression : Expression
-{
-  Expression[] keys, values;
-  this(Expression[] keys, Expression[] values)
-  {
-    assert(keys.length == values.length);
-    mixin(set_kind);
-    foreach (i, key; keys)
-      addChildren([key, values[i]]);
-    this.keys = keys;
-    this.values = values;
-  }
-  mixin(copyMethod);
-}
-
-class AssertExpression : Expression
-{
-  Expression expr, msg;
-  this(Expression expr, Expression msg)
-  {
-    mixin(set_kind);
-    addChild(expr);
-    addOptChild(msg);
-    this.expr = expr;
-    this.msg = msg;
-  }
-  mixin(copyMethod);
-}
-
-class MixinExpression : Expression
-{
-  Expression expr;
-  this(Expression expr)
-  {
-    mixin(set_kind);
-    addChild(expr);
-    this.expr = expr;
-  }
-  mixin(copyMethod);
-}
-
-class ImportExpression : Expression
-{
-  Expression expr;
-  this(Expression expr)
-  {
-    mixin(set_kind);
-    addChild(expr);
-    this.expr = expr;
-  }
-  mixin(copyMethod);
-}
-
-class TypeofExpression : Expression
-{
-  TypeNode type;
-  this(TypeNode type)
-  {
-    mixin(set_kind);
-    addChild(type);
-    this.type = type;
-  }
-  mixin(copyMethod);
-}
-
-class TypeDotIdExpression : Expression
-{
-  TypeNode type;
-  Identifier* ident;
-  this(TypeNode type, Identifier* ident)
-  {
-    mixin(set_kind);
-    addChild(type);
-    this.type = type;
-    this.ident = ident;
-  }
-  mixin(copyMethod);
-}
-
-class TypeidExpression : Expression
-{
-  TypeNode type;
-  this(TypeNode type)
-  {
-    mixin(set_kind);
-    addChild(type);
-    this.type = type;
-  }
-  mixin(copyMethod);
-}
-
-class IsExpression : Expression
-{
-  TypeNode type;
-  Identifier* ident;
-  Token* opTok, specTok;
-  TypeNode specType;
-  TemplateParameters tparams; // D 2.0
-  this(TypeNode type, Identifier* ident, Token* opTok, Token* specTok,
-       TypeNode specType, typeof(tparams) tparams)
-  {
-    mixin(set_kind);
-    addChild(type);
-    addOptChild(specType);
-  version(D2)
-    addOptChild(tparams);
-    this.type = type;
-    this.ident = ident;
-    this.opTok = opTok;
-    this.specTok = specTok;
-    this.specType = specType;
-    this.tparams = tparams;
-  }
-  mixin(copyMethod);
-}
-
-class FunctionLiteralExpression : Expression
-{
-  TypeNode returnType;
-  Parameters params;
-  FuncBodyStatement funcBody;
-
-  this()
-  {
-    mixin(set_kind);
-    addOptChild(returnType);
-    addOptChild(params);
-    addChild(funcBody);
-  }
-
-  this(TypeNode returnType, Parameters params, FuncBodyStatement funcBody)
-  {
-    this.returnType = returnType;
-    this.params = params;
-    this.funcBody = funcBody;
-    this();
-  }
-
-  this(FuncBodyStatement funcBody)
-  {
-    this.funcBody = funcBody;
-    this();
-  }
-
-  mixin(copyMethod);
-}
-
-/// ParenthesisExpression := "(" Expression ")"
-class ParenExpression : Expression
-{
-  Expression next;
-  this(Expression next)
-  {
-    mixin(set_kind);
-    addChild(next);
-    this.next = next;
-  }
-  mixin(copyMethod);
-}
-
-// version(D2)
-// {
-class TraitsExpression : Expression
-{
-  Identifier* ident;
-  TemplateArguments targs;
-  this(typeof(ident) ident, typeof(targs) targs)
-  {
-    mixin(set_kind);
-    addOptChild(targs);
-    this.ident = ident;
-    this.targs = targs;
-  }
-  mixin(copyMethod);
-}
-// }
-
-class VoidInitExpression : Expression
-{
-  this()
-  {
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-
-class ArrayInitExpression : Expression
-{
-  Expression[] keys;
-  Expression[] values;
-  this(Expression[] keys, Expression[] values)
-  {
-    assert(keys.length == values.length);
-    mixin(set_kind);
-    foreach (i, key; keys)
-    {
-      addOptChild(key); // The key is optional in ArrayInitializers.
-      addChild(values[i]);
-    }
-    this.keys = keys;
-    this.values = values;
-  }
-  mixin(copyMethod);
-}
-
-class StructInitExpression : Expression
-{
-  Identifier*[] idents;
-  Expression[] values;
-  this(Identifier*[] idents, Expression[] values)
-  {
-    mixin(set_kind);
-    addOptChildren(values);
-    this.idents = idents;
-    this.values = values;
-  }
-  mixin(copyMethod);
-}
-
-class AsmTypeExpression : UnaryExpression
-{
-  this(Expression e)
-  {
-    super(e);
-    mixin(set_kind);
-  }
-}
-
-class AsmOffsetExpression : UnaryExpression
-{
-  this(Expression e)
-  {
-    super(e);
-    mixin(set_kind);
-  }
-}
-
-class AsmSegExpression : UnaryExpression
-{
-  this(Expression e)
-  {
-    super(e);
-    mixin(set_kind);
-  }
-}
-
-class AsmPostBracketExpression : UnaryExpression
-{
-  Expression e2; /// Expression in brackets: e [ e2 ]
-  this(Expression e, Expression e2)
-  {
-    super(e);
-    mixin(set_kind);
-    addChild(e2);
-    this.e2 = e2;
-  }
-  mixin(copyMethod);
-}
-
-class AsmBracketExpression : Expression
-{
-  Expression e;
-  this(Expression e)
-  {
-    mixin(set_kind);
-    addChild(e);
-    this.e = e;
-  }
-  mixin(copyMethod);
-}
-
-class AsmLocalSizeExpression : Expression
-{
-  this()
-  {
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-
-class AsmRegisterExpression : Expression
-{
-  Identifier* register;
-  int number; // ST(0) - ST(7) or FS:0, FS:4, FS:8
-  this(Identifier* register, int number = -1)
-  {
-    mixin(set_kind);
-    this.register = register;
-    this.number = number;
-  }
-  mixin(copyMethod);
-}
--- a/trunk/src/dil/ast/Node.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.ast.Node;
-
-import common;
-
-public import dil.lexer.Token;
-public import dil.ast.NodesEnum;
-
-/// The root class of all D syntax tree elements.
-abstract class Node
-{
-  NodeCategory category; /// The category of this node.
-  NodeKind kind; /// The kind of this node.
-  Node[] children; // Will be probably removed sometime.
-  Token* begin, end; /// The begin and end tokens of this node.
-
-  /// Constructs a node object.
-  this(NodeCategory category)
-  {
-    assert(category != NodeCategory.Undefined);
-    this.category = category;
-  }
-
-  void setTokens(Token* begin, Token* end)
-  {
-    this.begin = begin;
-    this.end = end;
-  }
-
-  Class setToks(Class)(Class node)
-  {
-    node.setTokens(this.begin, this.end);
-    return node;
-  }
-
-  void addChild(Node child)
-  {
-    assert(child !is null, "failed in " ~ this.classinfo.name);
-    this.children ~= child;
-  }
-
-  void addOptChild(Node child)
-  {
-    child is null || addChild(child);
-  }
-
-  void addChildren(Node[] children)
-  {
-    assert(children !is null && delegate{
-      foreach (child; children)
-        if (child is null)
-          return false;
-      return true; }(),
-      "failed in " ~ this.classinfo.name
-    );
-    this.children ~= children;
-  }
-
-  void addOptChildren(Node[] children)
-  {
-    children is null || addChildren(children);
-  }
-
-  /// Returns a reference to Class if this node can be cast to it.
-  Class Is(Class)()
-  {
-    if (kind == mixin("NodeKind." ~ typeof(Class).stringof))
-      return cast(Class)cast(void*)this;
-    return null;
-  }
-
-  /// Casts this node to Class.
-  Class to(Class)()
-  {
-    return cast(Class)cast(void*)this;
-  }
-
-  /// Returns a deep copy of this node.
-  abstract Node copy();
-
-  /// Returns a shallow copy of this object.
-  final Node dup()
-  {
-    // Find out the size of this object.
-    alias typeof(this.classinfo.init[0]) byte_t;
-    size_t size = this.classinfo.init.length;
-    // Copy this object's data.
-    byte_t[] data = (cast(byte_t*)this)[0..size].dup;
-    return cast(Node)data.ptr;
-  }
-
-  /// This string is mixed into the constructor of a class that inherits
-  /// from Node. It sets the member kind.
-  const string set_kind = `this.kind = mixin("NodeKind." ~ typeof(this).stringof);`;
-}
--- a/trunk/src/dil/ast/NodeCopier.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,324 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.ast.NodeCopier;
-
-import common;
-
-/// Mixed into the body of a class that inherits from Node.
-const string copyMethod = `
-  override typeof(this) copy()
-  {
-    mixin copyNode!(typeof(this));
-    return copyNode(this);
-  }`;
-
-/// A helper function that generates code for copying subnodes.
-string doCopy_(string obj, string[] members)
-{
-  char[] result;
-  foreach (member; members)
-  {
-    if (member.length > 2 && member[$-2..$] == "[]") // Array copy.
-    {
-      member = member[0..$-2];
-      // obj.member = obj.member.dup;
-      // foreach (ref m_; obj.member)
-      //   m_ = m_.copy();
-      result ~= obj~"."~member~" = "~obj~"."~member~".dup;"
-      "foreach (ref m_; "~obj~"."~member~")"
-        "m_ = m_.copy();";
-    }
-    else if (member[$-1] == '?') // Optional member copy.
-    {
-      member = member[0..$-1];
-      // obj.member && (obj.member = obj.member.copy());
-      result ~= obj~"."~member~" && ("~obj~"."~member~" = "~obj~"."~member~".copy());";
-    }
-    else // Non-optional member copy.
-      // obj.member = obj.member.copy();
-      result ~= obj~"."~member~" = "~obj~"."~member~".copy();";
-  }
-  return result;
-}
-
-string doCopy(string[] members)
-{
-  return doCopy_("x", members);
-}
-
-string doCopy(string member)
-{
-  return doCopy_("x", [member]);
-}
-
-// pragma(msg, doCopy("decls?"));
-
-/// Returns a deep copy of node.
-T copyNode(T)(T node)
-{
-  assert(node !is null);
-
-  // Firstly do a shallow copy.
-  T x = cast(T)cast(void*)node.dup;
-
-  // Now copy the subnodes.
-  static if (is(Declaration) && is(T : Declaration))
-  {
-    alias T D;
-    static if (is(D == CompoundDeclaration))
-      mixin(doCopy("decls[]"));
-    //EmptyDeclaration,
-    //IllegalDeclaration,
-    //ModuleDeclaration have no subnodes.
-    static if (is(D == AliasDeclaration) ||
-               is(D == TypedefDeclaration))
-      mixin(doCopy("decl"));
-    static if (is(D == EnumDeclaration))
-      mixin(doCopy(["baseType?", "members[]"]));
-    static if (is(D == EnumMemberDeclaration))
-      mixin(doCopy("value"));
-    static if (is(D == ClassDeclaration) || is( D == InterfaceDeclaration))
-      mixin(doCopy(["bases[]", "decls"]));
-    static if (is(D == StructDeclaration) || is(D == UnionDeclaration))
-      mixin(doCopy("decls"));
-    static if (is(D == ConstructorDeclaration))
-      mixin(doCopy(["params", "funcBody"]));
-    static if (is(D == StaticConstructorDeclaration) ||
-               is(D == DestructorDeclaration) ||
-               is(D == StaticDestructorDeclaration) ||
-               is(D == InvariantDeclaration) ||
-               is(D == UnittestDeclaration))
-      mixin(doCopy("funcBody"));
-    static if (is(D == FunctionDeclaration))
-      mixin(doCopy(["returnType", "params", "funcBody"]));
-    static if (is(D == VariablesDeclaration))
-    {
-      mixin(doCopy("typeNode?"));
-      x.inits = x.inits.dup;
-      foreach(ref init; x.inits)
-        init && (init = init.copy());
-    }
-    static if (is(D == DebugDeclaration) || is(D == VersionDeclaration))
-      mixin(doCopy(["decls?","elseDecls?"]));
-    static if (is(D == StaticIfDeclaration))
-      mixin(doCopy(["condition","ifDecls", "elseDecls?"]));
-    static if (is(D == StaticAssertDeclaration))
-      mixin(doCopy(["condition","message?"]));
-    static if (is(D == TemplateDeclaration))
-      mixin(doCopy(["tparams","decls"]));
-    static if (is(D == NewDeclaration) || is(D == DeleteDeclaration))
-      mixin(doCopy(["params","funcBody"]));
-    static if (is(D == ProtectionDeclaration) ||
-               is(D == StorageClassDeclaration) ||
-               is(D == LinkageDeclaration) ||
-               is(D == AlignDeclaration))
-      mixin(doCopy("decls"));
-    static if (is(D == PragmaDeclaration))
-      mixin(doCopy(["args[]","decls"]));
-    static if (is(D == MixinDeclaration))
-      mixin(doCopy(["templateExpr?","argument?"]));
-  }
-  else
-  static if (is(Expression) && is(T : Expression))
-  {
-    alias T E;
-    static if (is(E == IllegalExpression))
-    {}
-    else
-    static if (is(E == CondExpression))
-      mixin(doCopy(["condition", "lhs", "rhs"]));
-    else
-    static if (is(E : BinaryExpression))
-      mixin(doCopy(["lhs", "rhs"]));
-    else
-    static if (is(E : UnaryExpression))
-    {
-      static if (is(E == CastExpression))
-        mixin(doCopy("type"));
-      mixin(doCopy("e")); // Copy member in base class UnaryExpression.
-      static if (is(E == IndexExpression))
-        mixin(doCopy("args[]"));
-      static if (is(E == SliceExpression))
-        mixin(doCopy(["left?", "right?"]));
-      static if (is(E == AsmPostBracketExpression))
-        mixin(doCopy("e2"));
-    }
-    else
-    {
-      static if (is(E == NewExpression))
-        mixin(doCopy(["newArgs[]", "type", "ctorArgs[]"]));
-      static if (is(E == NewAnonClassExpression))
-        mixin(doCopy(["newArgs[]", "bases[]", "ctorArgs[]", "decls"]));
-      static if (is(E == AsmBracketExpression))
-        mixin(doCopy("e"));
-      static if (is(E == TemplateInstanceExpression))
-        mixin(doCopy("targs?"));
-      static if (is(E == ArrayLiteralExpression))
-        mixin(doCopy("values[]"));
-      static if (is(E == AArrayLiteralExpression))
-        mixin(doCopy(["keys[]", "values[]"]));
-      static if (is(E == AssertExpression))
-        mixin(doCopy(["expr", "msg?"]));
-      static if (is(E == MixinExpression) ||
-                 is(E == ImportExpression))
-        mixin(doCopy("expr"));
-      static if (is(E == TypeofExpression) ||
-                 is(E == TypeDotIdExpression) ||
-                 is(E == TypeidExpression))
-        mixin(doCopy("type"));
-      static if (is(E == IsExpression))
-        mixin(doCopy(["type", "specType?", "tparams?"]));
-      static if (is(E == FunctionLiteralExpression))
-        mixin(doCopy(["returnType?", "params?", "funcBody"]));
-      static if (is(E == ParenExpression))
-        mixin(doCopy("next"));
-      static if (is(E == TraitsExpression))
-        mixin(doCopy("targs"));
-      // VoidInitializer has no subnodes.
-      static if (is(E == ArrayInitExpression))
-      {
-        mixin(doCopy("values[]"));
-        x.keys = x.keys.dup;
-        foreach(ref key; x.keys)
-          key && (key = key.copy());
-      }
-      static if (is(E == StructInitExpression))
-        mixin(doCopy("values[]"));
-      static if (is(E == StringExpression))
-        x.str = x.str.dup;
-    }
-  }
-  else
-  static if (is(Statement) && is(T : Statement))
-  {
-    alias T S;
-    static if (is(S == CompoundStatement))
-      mixin(doCopy("stmnts[]"));
-    //IllegalStatement,
-    //EmptyStatement have no subnodes.
-    static if (is(S == FuncBodyStatement))
-      mixin(doCopy(["funcBody?", "inBody?", "outBody?"]));
-    static if (is(S == ScopeStatement) || is(S == LabeledStatement))
-      mixin(doCopy("s"));
-    static if (is(S == ExpressionStatement))
-      mixin(doCopy("e"));
-    static if (is(S == DeclarationStatement))
-      mixin(doCopy("decl"));
-    static if (is(S == IfStatement))
-    {
-      if (x.variable)
-        mixin(doCopy("variable"));
-      else
-        mixin(doCopy("condition"));
-      mixin(doCopy(["ifBody", "elseBody?"]));
-    }
-    static if (is(S == WhileStatement))
-      mixin(doCopy(["condition", "whileBody"]));
-    static if (is(S == DoWhileStatement))
-      mixin(doCopy(["doBody", "condition"]));
-    static if (is(S == ForStatement))
-      mixin(doCopy(["init?", "condition?", "increment?", "forBody"]));
-    static if (is(S == ForeachStatement))
-      mixin(doCopy(["params", "aggregate", "forBody"]));
-    static if (is(S == ForeachRangeStatement))
-      mixin(doCopy(["params", "lower", "upper", "forBody"]));
-    static if (is(S == SwitchStatement))
-      mixin(doCopy(["condition", "switchBody"]));
-    static if (is(S == CaseStatement))
-      mixin(doCopy(["values[]", "caseBody"]));
-    static if (is(S == DefaultStatement))
-      mixin(doCopy("defaultBody"));
-    //ContinueStatement,
-    //BreakStatement have no subnodes.
-    static if (is(S == ReturnStatement))
-      mixin(doCopy("e?"));
-    static if (is(S == GotoStatement))
-      mixin(doCopy("caseExpr?"));
-    static if (is(S == WithStatement))
-      mixin(doCopy(["e", "withBody"]));
-    static if (is(S == SynchronizedStatement))
-      mixin(doCopy(["e?", "syncBody"]));
-    static if (is(S == TryStatement))
-      mixin(doCopy(["tryBody", "catchBodies[]", "finallyBody?"]));
-    static if (is(S == CatchStatement))
-      mixin(doCopy(["param?", "catchBody"]));
-    static if (is(S == FinallyStatement))
-      mixin(doCopy("finallyBody"));
-    static if (is(S == ScopeGuardStatement))
-      mixin(doCopy("scopeBody"));
-    static if (is(S == ThrowStatement))
-      mixin(doCopy("e"));
-    static if (is(S == VolatileStatement))
-      mixin(doCopy("volatileBody?"));
-    static if (is(S == AsmBlockStatement))
-      mixin(doCopy("statements"));
-    static if (is(S == AsmStatement))
-      mixin(doCopy("operands[]"));
-    //AsmAlignStatement,
-    //IllegalAsmStatement have no subnodes.
-    static if (is(S == PragmaStatement))
-      mixin(doCopy(["args[]", "pragmaBody"]));
-    static if (is(S == MixinStatement))
-      mixin(doCopy("templateExpr"));
-    static if (is(S == StaticIfStatement))
-      mixin(doCopy(["condition", "ifBody", "elseBody?"]));
-    static if (is(S == StaticAssertStatement))
-      mixin(doCopy(["condition", "message?"]));
-    static if (is(S == DebugStatement) || is(S == VersionStatement))
-      mixin(doCopy(["mainBody", "elseBody?"]));
-  }
-  else
-  static if (is(TypeNode) && is(T : TypeNode))
-  {
-    //IllegalType,
-    //IntegralType,
-    //ModuleScopeType,
-    //IdentifierType have no subnodes.
-    static if (is(T == QualifiedType))
-      mixin(doCopy(["lhs", "rhs"]));
-    static if (is(T == TypeofType))
-      mixin(doCopy("e"));
-    static if (is(T == TemplateInstanceType))
-      mixin(doCopy("targs?"));
-    static if (is(T == PointerType))
-      mixin(doCopy("next"));
-    static if (is(T == ArrayType))
-      mixin(doCopy(["next", "assocType?", "e1?", "e2?"]));
-    static if (is(T == FunctionType) || is(T == DelegateType))
-      mixin(doCopy(["returnType", "params"]));
-    static if (is(T == CFuncPointerType))
-      mixin(doCopy(["next", "params?"]));
-    static if (is(T == BaseClassType) ||
-               is(T == ConstType) ||
-               is(T == InvariantType))
-      mixin(doCopy("next"));
-  }
-  else
-  static if (is(Parameter) && is(T == Parameter))
-  {
-    mixin(doCopy(["type?", "defValue?"]));
-  }
-  else
-  static if (is(Parameter) && is(T == Parameters) ||
-             is(TemplateParameter) && is(T == TemplateParameters) ||
-             is(TemplateArguments) && is(T == TemplateArguments))
-  {
-    mixin(doCopy("children[]"));
-  }
-  else
-  static if (is(TemplateParameter) && is(T : TemplateParameter))
-  {
-    static if (is(N == TemplateAliasParameter) ||
-               is(N == TemplateTypeParameter) ||
-               is(N == TemplateThisParameter))
-      mixin(doCopy(["specType", "defType"]));
-    static if (is(N == TemplateValueParameter))
-      mixin(doCopy(["valueType", "specValue?", "defValue?"]));
-    //TemplateTupleParameter has no subnodes.
-  }
-  else
-    static assert(0, "copying of "~typeof(x).stringof~" is not handled");
-  return x;
-}
--- a/trunk/src/dil/ast/NodesEnum.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,234 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.ast.NodesEnum;
-
-/// Enumerates the categories of a node.
-enum NodeCategory : ushort
-{
-  Undefined,
-  Declaration,
-  Statement,
-  Expression,
-  Type,
-  Other
-}
-
-/// A list of all class names that inherit from Node.
-static const char[][] g_classNames = [
-  // Declarations:
-  "CompoundDeclaration",
-  "EmptyDeclaration",
-  "IllegalDeclaration",
-  "ModuleDeclaration",
-  "ImportDeclaration",
-  "AliasDeclaration",
-  "TypedefDeclaration",
-  "EnumDeclaration",
-  "EnumMemberDeclaration",
-  "ClassDeclaration",
-  "InterfaceDeclaration",
-  "StructDeclaration",
-  "UnionDeclaration",
-  "ConstructorDeclaration",
-  "StaticConstructorDeclaration",
-  "DestructorDeclaration",
-  "StaticDestructorDeclaration",
-  "FunctionDeclaration",
-  "VariablesDeclaration",
-  "InvariantDeclaration",
-  "UnittestDeclaration",
-  "DebugDeclaration",
-  "VersionDeclaration",
-  "StaticIfDeclaration",
-  "StaticAssertDeclaration",
-  "TemplateDeclaration",
-  "NewDeclaration",
-  "DeleteDeclaration",
-  "ProtectionDeclaration",
-  "StorageClassDeclaration",
-  "LinkageDeclaration",
-  "AlignDeclaration",
-  "PragmaDeclaration",
-  "MixinDeclaration",
-
-  // Statements:
-  "CompoundStatement",
-  "IllegalStatement",
-  "EmptyStatement",
-  "FuncBodyStatement",
-  "ScopeStatement",
-  "LabeledStatement",
-  "ExpressionStatement",
-  "DeclarationStatement",
-  "IfStatement",
-  "WhileStatement",
-  "DoWhileStatement",
-  "ForStatement",
-  "ForeachStatement",
-  "ForeachRangeStatement", // D2.0
-  "SwitchStatement",
-  "CaseStatement",
-  "DefaultStatement",
-  "ContinueStatement",
-  "BreakStatement",
-  "ReturnStatement",
-  "GotoStatement",
-  "WithStatement",
-  "SynchronizedStatement",
-  "TryStatement",
-  "CatchStatement",
-  "FinallyStatement",
-  "ScopeGuardStatement",
-  "ThrowStatement",
-  "VolatileStatement",
-  "AsmBlockStatement",
-  "AsmStatement",
-  "AsmAlignStatement",
-  "IllegalAsmStatement",
-  "PragmaStatement",
-  "MixinStatement",
-  "StaticIfStatement",
-  "StaticAssertStatement",
-  "DebugStatement",
-  "VersionStatement",
-
-  // Expressions:
-  "IllegalExpression",
-  "CondExpression",
-  "CommaExpression",
-  "OrOrExpression",
-  "AndAndExpression",
-  "OrExpression",
-  "XorExpression",
-  "AndExpression",
-  "EqualExpression",
-  "IdentityExpression",
-  "RelExpression",
-  "InExpression",
-  "LShiftExpression",
-  "RShiftExpression",
-  "URShiftExpression",
-  "PlusExpression",
-  "MinusExpression",
-  "CatExpression",
-  "MulExpression",
-  "DivExpression",
-  "ModExpression",
-  "AssignExpression",
-  "LShiftAssignExpression",
-  "RShiftAssignExpression",
-  "URShiftAssignExpression",
-  "OrAssignExpression",
-  "AndAssignExpression",
-  "PlusAssignExpression",
-  "MinusAssignExpression",
-  "DivAssignExpression",
-  "MulAssignExpression",
-  "ModAssignExpression",
-  "XorAssignExpression",
-  "CatAssignExpression",
-  "AddressExpression",
-  "PreIncrExpression",
-  "PreDecrExpression",
-  "PostIncrExpression",
-  "PostDecrExpression",
-  "DerefExpression",
-  "SignExpression",
-  "NotExpression",
-  "CompExpression",
-  "CallExpression",
-  "NewExpression",
-  "NewAnonClassExpression",
-  "DeleteExpression",
-  "CastExpression",
-  "IndexExpression",
-  "SliceExpression",
-  "ModuleScopeExpression",
-  "IdentifierExpression",
-  "SpecialTokenExpression",
-  "DotExpression",
-  "TemplateInstanceExpression",
-  "ThisExpression",
-  "SuperExpression",
-  "NullExpression",
-  "DollarExpression",
-  "BoolExpression",
-  "IntExpression",
-  "RealExpression",
-  "ComplexExpression",
-  "CharExpression",
-  "StringExpression",
-  "ArrayLiteralExpression",
-  "AArrayLiteralExpression",
-  "AssertExpression",
-  "MixinExpression",
-  "ImportExpression",
-  "TypeofExpression",
-  "TypeDotIdExpression",
-  "TypeidExpression",
-  "IsExpression",
-  "ParenExpression",
-  "FunctionLiteralExpression",
-  "TraitsExpression", // D2.0
-  "VoidInitExpression",
-  "ArrayInitExpression",
-  "StructInitExpression",
-  "AsmTypeExpression",
-  "AsmOffsetExpression",
-  "AsmSegExpression",
-  "AsmPostBracketExpression",
-  "AsmBracketExpression",
-  "AsmLocalSizeExpression",
-  "AsmRegisterExpression",
-
-  // Types:
-  "IllegalType",
-  "IntegralType",
-  "QualifiedType",
-  "ModuleScopeType",
-  "IdentifierType",
-  "TypeofType",
-  "TemplateInstanceType",
-  "PointerType",
-  "ArrayType",
-  "FunctionType",
-  "DelegateType",
-  "CFuncPointerType",
-  "BaseClassType",
-  "ConstType", // D2.0
-  "InvariantType", // D2.0
-
-  // Other:
-  "Parameter",
-  "Parameters",
-  "TemplateAliasParameter",
-  "TemplateTypeParameter",
-  "TemplateThisParameter", // D2.0
-  "TemplateValueParameter",
-  "TemplateTupleParameter",
-  "TemplateParameters",
-  "TemplateArguments",
-];
-
-/// Generates the members of enum NodeKind.
-char[] generateNodeKindMembers()
-{
-  char[] text;
-  foreach (className; g_classNames)
-    text ~= className ~ ",";
-  return text;
-}
-// pragma(msg, generateNodeKindMembers());
-
-version(DDoc)
-  /// The node kind identifies every class that inherits from Node.
-  enum NodeKind : ushort;
-else
-mixin(
-  "enum NodeKind : ushort"
-  "{"
-    ~ generateNodeKindMembers ~
-  "}"
-);
--- a/trunk/src/dil/ast/Parameters.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,227 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.ast.Parameters;
-
-import dil.ast.Node;
-import dil.ast.Type;
-import dil.ast.Expression;
-import dil.ast.NodeCopier;
-import dil.lexer.Identifier;
-import dil.Enums;
-
-/// A function or foreach parameter.
-class Parameter : Node
-{
-  StorageClass stc; /// The storage classes of the parameter.
-  TypeNode type; /// The parameter's type.
-  Identifier* name; /// The name of the parameter.
-  Expression defValue; /// The default initialization value.
-
-  this(StorageClass stc, TypeNode type, Identifier* name, Expression defValue)
-  {
-    super(NodeCategory.Other);
-    mixin(set_kind);
-    // type can be null when param in foreach statement
-    addOptChild(type);
-    addOptChild(defValue);
-
-    this.stc = stc;
-    this.type = type;
-    this.name = name;
-    this.defValue = defValue;
-  }
-
-  /// Returns true if this is a D-style variadic parameter.
-  /// E.g.: func(int[] values ...)
-  bool isDVariadic()
-  {
-    return isVariadic && !isCVariadic;
-  }
-
-  /// Returns true if this is a C-style variadic parameter.
-  /// E.g.: func(...)
-  bool isCVariadic()
-  {
-    return stc == StorageClass.Variadic &&
-           type is null && name is null;
-  }
-
-  /// Returns true if this is a D- or C-style variadic parameter.
-  bool isVariadic()
-  {
-    return !!(stc & StorageClass.Variadic);
-  }
-
-  mixin(copyMethod);
-}
-
-/// Array of parameters.
-class Parameters : Node
-{
-  this()
-  {
-    super(NodeCategory.Other);
-    mixin(set_kind);
-  }
-
-  bool hasVariadic()
-  {
-    if (children.length != 0)
-      return items[$-1].isVariadic();
-    return false;
-  }
-
-  void opCatAssign(Parameter param)
-  { addChild(param); }
-
-  Parameter[] items()
-  { return cast(Parameter[])children; }
-
-  size_t length()
-  { return children.length; }
-
-  mixin(copyMethod);
-}
-
-/*~~~~~~~~~~~~~~~~~~~~~~
-~ Template parameters: ~
-~~~~~~~~~~~~~~~~~~~~~~*/
-
-/// Abstract base class for all template parameters.
-abstract class TemplateParameter : Node
-{
-  Identifier* ident;
-  this(Identifier* ident)
-  {
-    super(NodeCategory.Other);
-    this.ident = ident;
-  }
-  override abstract TemplateParameter copy();
-}
-
-/// E.g.: (alias T)
-class TemplateAliasParameter : TemplateParameter
-{
-  TypeNode specType, defType;
-  this(Identifier* ident, TypeNode specType, TypeNode defType)
-  {
-    super(ident);
-    mixin(set_kind);
-    addOptChild(specType);
-    addOptChild(defType);
-    this.ident = ident;
-    this.specType = specType;
-    this.defType = defType;
-  }
-  mixin(copyMethod);
-}
-
-/// E.g.: (T t)
-class TemplateTypeParameter : TemplateParameter
-{
-  TypeNode specType, defType;
-  this(Identifier* ident, TypeNode specType, TypeNode defType)
-  {
-    super(ident);
-    mixin(set_kind);
-    addOptChild(specType);
-    addOptChild(defType);
-    this.ident = ident;
-    this.specType = specType;
-    this.defType = defType;
-  }
-  mixin(copyMethod);
-}
-
-// version(D2)
-// {
-/// E.g.: (this T)
-class TemplateThisParameter : TemplateParameter
-{
-  TypeNode specType, defType;
-  this(Identifier* ident, TypeNode specType, TypeNode defType)
-  {
-    super(ident);
-    mixin(set_kind);
-    addOptChild(specType);
-    addOptChild(defType);
-    this.ident = ident;
-    this.specType = specType;
-    this.defType = defType;
-  }
-  mixin(copyMethod);
-}
-// }
-
-/// E.g.: (T)
-class TemplateValueParameter : TemplateParameter
-{
-  TypeNode valueType;
-  Expression specValue, defValue;
-  this(TypeNode valueType, Identifier* ident, Expression specValue, Expression defValue)
-  {
-    super(ident);
-    mixin(set_kind);
-    addChild(valueType);
-    addOptChild(specValue);
-    addOptChild(defValue);
-    this.valueType = valueType;
-    this.ident = ident;
-    this.specValue = specValue;
-    this.defValue = defValue;
-  }
-  mixin(copyMethod);
-}
-
-/// E.g.: (T...)
-class TemplateTupleParameter : TemplateParameter
-{
-  this(Identifier* ident)
-  {
-    super(ident);
-    mixin(set_kind);
-    this.ident = ident;
-  }
-  mixin(copyMethod);
-}
-
-/// Array of template parameters.
-class TemplateParameters : Node
-{
-  this()
-  {
-    super(NodeCategory.Other);
-    mixin(set_kind);
-  }
-
-  void opCatAssign(TemplateParameter parameter)
-  {
-    addChild(parameter);
-  }
-
-  TemplateParameter[] items()
-  {
-    return cast(TemplateParameter[])children;
-  }
-
-  mixin(copyMethod);
-}
-
-/// Array of template arguments.
-class TemplateArguments : Node
-{
-  this()
-  {
-    super(NodeCategory.Other);
-    mixin(set_kind);
-  }
-
-  void opCatAssign(Node argument)
-  {
-    addChild(argument);
-  }
-
-  mixin(copyMethod);
-}
--- a/trunk/src/dil/ast/Statement.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.ast.Statement;
-
-import dil.ast.Node;
-
-/// The root class of all statements.
-abstract class Statement : Node
-{
-  this()
-  {
-    super(NodeCategory.Statement);
-  }
-
-  override abstract Statement copy();
-}
--- a/trunk/src/dil/ast/Statements.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,607 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.ast.Statements;
-
-public import dil.ast.Statement;
-import dil.ast.Node;
-import dil.ast.Expression;
-import dil.ast.Declaration;
-import dil.ast.Type;
-import dil.ast.Parameters;
-import dil.ast.NodeCopier;
-import dil.lexer.IdTable;
-
-class CompoundStatement : Statement
-{
-  this()
-  {
-    mixin(set_kind);
-  }
-
-  void opCatAssign(Statement s)
-  {
-    addChild(s);
-  }
-
-  Statement[] stmnts()
-  {
-    return cast(Statement[])this.children;
-  }
-
-  void stmnts(Statement[] stmnts)
-  {
-    this.children = stmnts;
-  }
-
-  mixin(copyMethod);
-}
-
-class IllegalStatement : Statement
-{
-  this()
-  {
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-
-class EmptyStatement : Statement
-{
-  this()
-  {
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-
-class FuncBodyStatement : Statement
-{
-  Statement funcBody, inBody, outBody;
-  Identifier* outIdent;
-  this()
-  {
-    mixin(set_kind);
-  }
-
-  void finishConstruction()
-  {
-    addOptChild(funcBody);
-    addOptChild(inBody);
-    addOptChild(outBody);
-  }
-
-  bool isEmpty()
-  {
-    return funcBody is null;
-  }
-
-  mixin(copyMethod);
-}
-
-class ScopeStatement : Statement
-{
-  Statement s;
-  this(Statement s)
-  {
-    mixin(set_kind);
-    addChild(s);
-    this.s = s;
-  }
-  mixin(copyMethod);
-}
-
-class LabeledStatement : Statement
-{
-  Identifier* label;
-  Statement s;
-  this(Identifier* label, Statement s)
-  {
-    mixin(set_kind);
-    addChild(s);
-    this.label = label;
-    this.s = s;
-  }
-  mixin(copyMethod);
-}
-
-class ExpressionStatement : Statement
-{
-  Expression e;
-  this(Expression e)
-  {
-    mixin(set_kind);
-    addChild(e);
-    this.e = e;
-  }
-  mixin(copyMethod);
-}
-
-class DeclarationStatement : Statement
-{
-  Declaration decl;
-  this(Declaration decl)
-  {
-    mixin(set_kind);
-    addChild(decl);
-    this.decl = decl;
-  }
-  mixin(copyMethod);
-}
-
-class IfStatement : Statement
-{
-  Statement variable; // AutoDeclaration or VariableDeclaration
-  Expression condition;
-  Statement ifBody;
-  Statement elseBody;
-  this(Statement variable, Expression condition, Statement ifBody, Statement elseBody)
-  {
-    mixin(set_kind);
-    if (variable)
-      addChild(variable);
-    else
-      addChild(condition);
-    addChild(ifBody);
-    addOptChild(elseBody);
-
-    this.variable = variable;
-    this.condition = condition;
-    this.ifBody = ifBody;
-    this.elseBody = elseBody;
-  }
-  mixin(copyMethod);
-}
-
-class WhileStatement : Statement
-{
-  Expression condition;
-  Statement whileBody;
-  this(Expression condition, Statement whileBody)
-  {
-    mixin(set_kind);
-    addChild(condition);
-    addChild(whileBody);
-
-    this.condition = condition;
-    this.whileBody = whileBody;
-  }
-  mixin(copyMethod);
-}
-
-class DoWhileStatement : Statement
-{
-  Statement doBody;
-  Expression condition;
-  this(Expression condition, Statement doBody)
-  {
-    mixin(set_kind);
-    addChild(doBody);
-    addChild(condition);
-
-    this.condition = condition;
-    this.doBody = doBody;
-  }
-  mixin(copyMethod);
-}
-
-class ForStatement : Statement
-{
-  Statement init;
-  Expression condition, increment;
-  Statement forBody;
-
-  this(Statement init, Expression condition, Expression increment, Statement forBody)
-  {
-    mixin(set_kind);
-    addOptChild(init);
-    addOptChild(condition);
-    addOptChild(increment);
-    addChild(forBody);
-
-    this.init = init;
-    this.condition = condition;
-    this.increment = increment;
-    this.forBody = forBody;
-  }
-  mixin(copyMethod);
-}
-
-class ForeachStatement : Statement
-{
-  TOK tok;
-  Parameters params;
-  Expression aggregate;
-  Statement forBody;
-
-  this(TOK tok, Parameters params, Expression aggregate, Statement forBody)
-  {
-    mixin(set_kind);
-    addChildren([cast(Node)params, aggregate, forBody]);
-
-    this.tok = tok;
-    this.params = params;
-    this.aggregate = aggregate;
-    this.forBody = forBody;
-  }
-  mixin(copyMethod);
-}
-
-// version(D2)
-// {
-class ForeachRangeStatement : Statement
-{
-  TOK tok;
-  Parameters params;
-  Expression lower, upper;
-  Statement forBody;
-
-  this(TOK tok, Parameters params, Expression lower, Expression upper, Statement forBody)
-  {
-    mixin(set_kind);
-    addChildren([cast(Node)params, lower, upper, forBody]);
-
-    this.tok = tok;
-    this.params = params;
-    this.lower = lower;
-    this.upper = upper;
-    this.forBody = forBody;
-  }
-  mixin(copyMethod);
-}
-// }
-
-class SwitchStatement : Statement
-{
-  Expression condition;
-  Statement switchBody;
-
-  this(Expression condition, Statement switchBody)
-  {
-    mixin(set_kind);
-    addChild(condition);
-    addChild(switchBody);
-
-    this.condition = condition;
-    this.switchBody = switchBody;
-  }
-  mixin(copyMethod);
-}
-
-class CaseStatement : Statement
-{
-  Expression[] values;
-  Statement caseBody;
-
-  this(Expression[] values, Statement caseBody)
-  {
-    mixin(set_kind);
-    addChildren(values);
-    addChild(caseBody);
-
-    this.values = values;
-    this.caseBody = caseBody;
-  }
-  mixin(copyMethod);
-}
-
-class DefaultStatement : Statement
-{
-  Statement defaultBody;
-  this(Statement defaultBody)
-  {
-    mixin(set_kind);
-    addChild(defaultBody);
-
-    this.defaultBody = defaultBody;
-  }
-  mixin(copyMethod);
-}
-
-class ContinueStatement : Statement
-{
-  Identifier* ident;
-  this(Identifier* ident)
-  {
-    mixin(set_kind);
-    this.ident = ident;
-  }
-  mixin(copyMethod);
-}
-
-class BreakStatement : Statement
-{
-  Identifier* ident;
-  this(Identifier* ident)
-  {
-    mixin(set_kind);
-    this.ident = ident;
-  }
-  mixin(copyMethod);
-}
-
-class ReturnStatement : Statement
-{
-  Expression e;
-  this(Expression e)
-  {
-    mixin(set_kind);
-    addOptChild(e);
-    this.e = e;
-  }
-  mixin(copyMethod);
-}
-
-class GotoStatement : Statement
-{
-  Identifier* ident;
-  Expression caseExpr;
-  this(Identifier* ident, Expression caseExpr)
-  {
-    mixin(set_kind);
-    addOptChild(caseExpr);
-    this.ident = ident;
-    this.caseExpr = caseExpr;
-  }
-  mixin(copyMethod);
-}
-
-class WithStatement : Statement
-{
-  Expression e;
-  Statement withBody;
-  this(Expression e, Statement withBody)
-  {
-    mixin(set_kind);
-    addChild(e);
-    addChild(withBody);
-
-    this.e = e;
-    this.withBody = withBody;
-  }
-  mixin(copyMethod);
-}
-
-class SynchronizedStatement : Statement
-{
-  Expression e;
-  Statement syncBody;
-  this(Expression e, Statement syncBody)
-  {
-    mixin(set_kind);
-    addOptChild(e);
-    addChild(syncBody);
-
-    this.e = e;
-    this.syncBody = syncBody;
-  }
-  mixin(copyMethod);
-}
-
-class TryStatement : Statement
-{
-  Statement tryBody;
-  CatchStatement[] catchBodies;
-  FinallyStatement finallyBody;
-  this(Statement tryBody, CatchStatement[] catchBodies, FinallyStatement finallyBody)
-  {
-    mixin(set_kind);
-    addChild(tryBody);
-    addOptChildren(catchBodies);
-    addOptChild(finallyBody);
-
-    this.tryBody = tryBody;
-    this.catchBodies = catchBodies;
-    this.finallyBody = finallyBody;
-  }
-  mixin(copyMethod);
-}
-
-class CatchStatement : Statement
-{
-  Parameter param;
-  Statement catchBody;
-  this(Parameter param, Statement catchBody)
-  {
-    mixin(set_kind);
-    addOptChild(param);
-    addChild(catchBody);
-    this.param = param;
-    this.catchBody = catchBody;
-  }
-  mixin(copyMethod);
-}
-
-class FinallyStatement : Statement
-{
-  Statement finallyBody;
-  this(Statement finallyBody)
-  {
-    mixin(set_kind);
-    addChild(finallyBody);
-    this.finallyBody = finallyBody;
-  }
-  mixin(copyMethod);
-}
-
-class ScopeGuardStatement : Statement
-{
-  Identifier* condition;
-  Statement scopeBody;
-  this(Identifier* condition, Statement scopeBody)
-  {
-    mixin(set_kind);
-    addChild(scopeBody);
-    this.condition = condition;
-    this.scopeBody = scopeBody;
-  }
-  mixin(copyMethod);
-}
-
-class ThrowStatement : Statement
-{
-  Expression e;
-  this(Expression e)
-  {
-    mixin(set_kind);
-    addChild(e);
-    this.e = e;
-  }
-  mixin(copyMethod);
-}
-
-class VolatileStatement : Statement
-{
-  Statement volatileBody;
-  this(Statement volatileBody)
-  {
-    mixin(set_kind);
-    addOptChild(volatileBody);
-    this.volatileBody = volatileBody;
-  }
-  mixin(copyMethod);
-}
-
-class AsmBlockStatement : Statement
-{
-  CompoundStatement statements;
-  this(CompoundStatement statements)
-  {
-    mixin(set_kind);
-    addChild(statements);
-    this.statements = statements;
-  }
-  mixin(copyMethod);
-}
-
-class AsmStatement : Statement
-{
-  Identifier* ident;
-  Expression[] operands;
-  this(Identifier* ident, Expression[] operands)
-  {
-    mixin(set_kind);
-    addOptChildren(operands);
-    this.ident = ident;
-    this.operands = operands;
-  }
-  mixin(copyMethod);
-}
-
-class AsmAlignStatement : Statement
-{
-  int number;
-  this(int number)
-  {
-    mixin(set_kind);
-    this.number = number;
-  }
-  mixin(copyMethod);
-}
-
-class IllegalAsmStatement : IllegalStatement
-{
-  this()
-  {
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-
-class PragmaStatement : Statement
-{
-  Identifier* ident;
-  Expression[] args;
-  Statement pragmaBody;
-  this(Identifier* ident, Expression[] args, Statement pragmaBody)
-  {
-    mixin(set_kind);
-    addOptChildren(args);
-    addChild(pragmaBody);
-
-    this.ident = ident;
-    this.args = args;
-    this.pragmaBody = pragmaBody;
-  }
-  mixin(copyMethod);
-}
-
-class MixinStatement : Statement
-{
-  Expression templateExpr;
-  Identifier* mixinIdent;
-  this(Expression templateExpr, Identifier* mixinIdent)
-  {
-    mixin(set_kind);
-    addChild(templateExpr);
-    this.templateExpr = templateExpr;
-    this.mixinIdent = mixinIdent;
-  }
-  mixin(copyMethod);
-}
-
-class StaticIfStatement : Statement
-{
-  Expression condition;
-  Statement ifBody, elseBody;
-  this(Expression condition, Statement ifBody, Statement elseBody)
-  {
-    mixin(set_kind);
-    addChild(condition);
-    addChild(ifBody);
-    addOptChild(elseBody);
-    this.condition = condition;
-    this.ifBody = ifBody;
-    this.elseBody = elseBody;
-  }
-  mixin(copyMethod);
-}
-
-class StaticAssertStatement : Statement
-{
-  Expression condition, message;
-  this(Expression condition, Expression message)
-  {
-    mixin(set_kind);
-    addChild(condition);
-    addOptChild(message);
-    this.condition = condition;
-    this.message = message;
-  }
-  mixin(copyMethod);
-}
-
-abstract class ConditionalCompilationStatement : Statement
-{
-  Token* cond;
-  Statement mainBody, elseBody;
-  this(Token* cond, Statement mainBody, Statement elseBody)
-  {
-    addChild(mainBody);
-    addOptChild(elseBody);
-    this.cond = cond;
-    this.mainBody = mainBody;
-    this.elseBody = elseBody;
-  }
-}
-
-class DebugStatement : ConditionalCompilationStatement
-{
-  this(Token* cond, Statement debugBody, Statement elseBody)
-  {
-    super(cond, debugBody, elseBody);
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-
-class VersionStatement : ConditionalCompilationStatement
-{
-  this(Token* cond, Statement versionBody, Statement elseBody)
-  {
-    super(cond, versionBody, elseBody);
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
--- a/trunk/src/dil/ast/Type.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.ast.Type;
-
-import dil.ast.Node;
-import dil.semantic.Types;
-
-/// The root class of all type nodes.
-abstract class TypeNode : Node
-{
-  TypeNode next; /// The next type in the type chain.
-  Type type; /// The semantic type of this type node.
-
-  this()
-  {
-    this(null);
-  }
-
-  this(TypeNode next)
-  {
-    super(NodeCategory.Type);
-    addOptChild(next);
-    this.next = next;
-  }
-
-  /// Returns the root type of the type chain.
-  TypeNode baseType()
-  {
-    auto type = this;
-    while (type.next)
-      type = type.next;
-    return type;
-  }
-
-  override abstract TypeNode copy();
-}
--- a/trunk/src/dil/ast/Types.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,262 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.ast.Types;
-
-public import dil.ast.Type;
-import dil.ast.Node;
-import dil.ast.Expression;
-import dil.ast.Parameters;
-import dil.ast.NodeCopier;
-import dil.lexer.Identifier;
-import dil.semantic.Types;
-import dil.Enums;
-
-/// Syntax error.
-class IllegalType : TypeNode
-{
-  this()
-  {
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-
-/// char, int, float etc.
-class IntegralType : TypeNode
-{
-  TOK tok;
-  this(TOK tok)
-  {
-    mixin(set_kind);
-    this.tok = tok;
-  }
-  mixin(copyMethod);
-}
-
-/// Identifier
-class IdentifierType : TypeNode
-{
-  Identifier* ident;
-  this(Identifier* ident)
-  {
-    mixin(set_kind);
-    this.ident = ident;
-  }
-  mixin(copyMethod);
-}
-
-/// Type "." Type
-class QualifiedType : TypeNode
-{
-  alias next lhs; /// Left-hand side type.
-  TypeNode rhs; /// Right-hand side type.
-  this(TypeNode lhs, TypeNode rhs)
-  {
-    super(lhs);
-    mixin(set_kind);
-    addChild(rhs);
-    this.rhs = rhs;
-  }
-  mixin(copyMethod);
-}
-
-/// "." Type
-class ModuleScopeType : TypeNode
-{
-  this()
-  {
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-
-/// "typeof" "(" Expression ")" or$(BR)
-/// "typeof" "(" "return" ")" (D2.0)
-class TypeofType : TypeNode
-{
-  Expression e;
-  this(Expression e)
-  {
-    this();
-    addChild(e);
-    this.e = e;
-  }
-
-  // For D2.0: "typeof" "(" "return" ")"
-  this()
-  {
-    mixin(set_kind);
-  }
-
-  bool isTypeofReturn()
-  {
-    return e is null;
-  }
-
-  mixin(copyMethod);
-}
-
-/// Identifier "!" "(" TemplateParameters? ")"
-class TemplateInstanceType : TypeNode
-{
-  Identifier* ident;
-  TemplateArguments targs;
-  this(Identifier* ident, TemplateArguments targs)
-  {
-    mixin(set_kind);
-    addOptChild(targs);
-    this.ident = ident;
-    this.targs = targs;
-  }
-  mixin(copyMethod);
-}
-
-/// Type *
-class PointerType : TypeNode
-{
-  this(TypeNode next)
-  {
-    super(next);
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-
-/// Dynamic array: T[] or$(BR)
-/// Static array: T[E] or$(BR)
-/// Slice array (for tuples): T[E..E] or$(BR)
-/// Associative array: T[T]
-class ArrayType : TypeNode
-{
-  Expression e1, e2;
-  TypeNode assocType;
-
-  this(TypeNode t)
-  {
-    super(t);
-    mixin(set_kind);
-  }
-
-  this(TypeNode t, Expression e1, Expression e2)
-  {
-    this(t);
-    addChild(e1);
-    addOptChild(e2);
-    this.e1 = e1;
-    this.e2 = e2;
-  }
-
-  this(TypeNode t, TypeNode assocType)
-  {
-    this(t);
-    addChild(assocType);
-    this.assocType = assocType;
-  }
-
-  bool isDynamic()
-  {
-    return !assocType && !e1;
-  }
-
-  bool isStatic()
-  {
-    return e1 && !e2;
-  }
-
-  bool isSlice()
-  {
-    return e1 && e2;
-  }
-
-  bool isAssociative()
-  {
-    return assocType !is null;
-  }
-
-  mixin(copyMethod);
-}
-
-/// ReturnType "function" "(" Parameters? ")"
-class FunctionType : TypeNode
-{
-  alias next returnType;
-  Parameters params;
-  this(TypeNode returnType, Parameters params)
-  {
-    super(returnType);
-    mixin(set_kind);
-    addChild(params);
-    this.params = params;
-  }
-  mixin(copyMethod);
-}
-
-/// ReturnType "delegate" "(" Parameters? ")"
-class DelegateType : TypeNode
-{
-  alias next returnType;
-  Parameters params;
-  this(TypeNode returnType, Parameters params)
-  {
-    super(returnType);
-    mixin(set_kind);
-    addChild(params);
-    this.params = params;
-  }
-  mixin(copyMethod);
-}
-
-/// Type "(" BasicType2 Identifier ")" "(" Parameters? ")"
-class CFuncPointerType : TypeNode
-{
-  Parameters params;
-  this(TypeNode type, Parameters params)
-  {
-    super(type);
-    mixin(set_kind);
-    addOptChild(params);
-  }
-  mixin(copyMethod);
-}
-
-/// "class" Identifier : BaseClasses
-class BaseClassType : TypeNode
-{
-  Protection prot;
-  this(Protection prot, TypeNode type)
-  {
-    super(type);
-    mixin(set_kind);
-    this.prot = prot;
-  }
-  mixin(copyMethod);
-}
-
-// version(D2)
-// {
-/// "const" "(" Type ")"
-class ConstType : TypeNode
-{
-  this(TypeNode next)
-  {
-    // If t is null: cast(const)
-    super(next);
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-
-/// "invariant" "(" Type ")"
-class InvariantType : TypeNode
-{
-  this(TypeNode next)
-  {
-    // If t is null: cast(invariant)
-    super(next);
-    mixin(set_kind);
-  }
-  mixin(copyMethod);
-}
-// } // version(D2)
--- a/trunk/src/dil/ast/Visitor.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.ast.Visitor;
-
-import dil.ast.Node;
-import dil.ast.Declarations,
-       dil.ast.Expressions,
-       dil.ast.Statements,
-       dil.ast.Types,
-       dil.ast.Parameters;
-
-/// Generate visit methods.
-///
-/// E.g.:
-/// ---
-/// Declaration visit(ClassDeclaration){return null;};
-/// Expression visit(CommaExpression){return null;};
-/// ---
-char[] generateVisitMethods()
-{
-  char[] text;
-  foreach (className; g_classNames)
-    text ~= "returnType!(\""~className~"\") visit("~className~" node){return node;}\n";
-  return text;
-}
-// pragma(msg, generateAbstractVisitMethods());
-
-/// Gets the appropriate return type for the provided class.
-template returnType(char[] className)
-{
-  static if (is(typeof(mixin(className)) : Declaration))
-    alias Declaration returnType;
-  else
-  static if (is(typeof(mixin(className)) : Statement))
-    alias Statement returnType;
-  else
-  static if (is(typeof(mixin(className)) : Expression))
-    alias Expression returnType;
-  else
-  static if (is(typeof(mixin(className)) : TypeNode))
-    alias TypeNode returnType;
-  else
-    alias Node returnType;
-}
-
-/// Generate functions which do the second dispatch.
-///
-/// E.g.:
-/// ---
-/// Expression visitCommaExpression(Visitor visitor, CommaExpression c)
-/// { visitor.visit(c); /* Second dispatch. */ }
-/// ---
-/// The equivalent in the traditional visitor pattern would be:
-/// ---
-/// class CommaExpression : Expression
-/// {
-///   void accept(Visitor visitor)
-///   { visitor.visit(this); }
-/// }
-/// ---
-char[] generateDispatchFunctions()
-{
-  char[] text;
-  foreach (className; g_classNames)
-    text ~= "returnType!(\""~className~"\") visit"~className~"(Visitor visitor, "~className~" c)\n"
-            "{ return visitor.visit(c); }\n";
-  return text;
-}
-// pragma(msg, generateDispatchFunctions());
-
-/++
- Generates an array of function pointers.
-
- ---
- [
-   cast(void*)&visitCommaExpression,
-   // etc.
- ]
- ---
-+/
-char[] generateVTable()
-{
-  char[] text = "[";
-  foreach (className; g_classNames)
-    text ~= "cast(void*)&visit"~className~",\n";
-  return text[0..$-2]~"]"; // slice away last ",\n"
-}
-// pragma(msg, generateVTable());
-
-/// Implements a variation of the visitor pattern.
-///
-/// Inherited by classes that need to traverse a D syntax tree
-/// and do computations, transformations and other things on it.
-abstract class Visitor
-{
-  mixin(generateVisitMethods());
-
-  static
-    mixin(generateDispatchFunctions());
-
-  /// The table holding function pointers to the second dispatch functions.
-  static const void*[] dispatch_vtable = mixin(generateVTable());
-  static assert(dispatch_vtable.length == g_classNames.length, "vtable length doesn't match number of classes");
-
-  /// Looks up the second dispatch function for n and returns that.
-  Node function(Visitor, Node) getDispatchFunction()(Node n)
-  {
-    return cast(Node function(Visitor, Node))dispatch_vtable[n.kind];
-  }
-
-  /// The main and first dispatch function.
-  Node dispatch(Node n)
-  { // Second dispatch is done in the called function.
-    return getDispatchFunction(n)(this, n);
-  }
-
-final:
-  Declaration visit(Declaration n)
-  { return visitD(n); }
-  Statement visit(Statement n)
-  { return visitS(n); }
-  Expression visit(Expression n)
-  { return visitE(n); }
-  TypeNode visit(TypeNode n)
-  { return visitT(n); }
-  Node visit(Node n)
-  { return visitN(n); }
-
-  Declaration visitD(Declaration n)
-  {
-    return cast(Declaration)cast(void*)dispatch(n);
-  }
-
-  Statement visitS(Statement n)
-  {
-    return cast(Statement)cast(void*)dispatch(n);
-  }
-
-  Expression visitE(Expression n)
-  {
-    return cast(Expression)cast(void*)dispatch(n);
-  }
-
-  TypeNode visitT(TypeNode n)
-  {
-    return cast(TypeNode)cast(void*)dispatch(n);
-  }
-
-  Node visitN(Node n)
-  {
-    return dispatch(n);
-  }
-}
--- a/trunk/src/dil/doc/Doc.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,463 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.doc.Doc;
-
-import dil.doc.Parser;
-import dil.ast.Node;
-import dil.lexer.Funcs;
-import dil.Unicode;
-import common;
-
-import tango.text.Ascii : icompare;
-
-/// Represents a sanitized and parsed DDoc comment.
-class DDocComment
-{
-  Section[] sections; /// The sections of this comment.
-  Section summary; /// Optional summary section.
-  Section description; /// Optional description section.
-
-  this(Section[] sections, Section summary, Section description)
-  {
-    this.sections = sections;
-    this.summary = summary;
-    this.description = description;
-  }
-
-  /// Removes the first copyright section and returns it.
-  Section takeCopyright()
-  {
-    foreach (i, section; sections)
-      if (section.Is("copyright"))
-      {
-        sections = sections[0..i] ~ sections[i+1..$];
-        return section;
-      }
-    return null;
-  }
-
-  /// Returns true if "ditto" is the only text in this comment.
-  bool isDitto()
-  {
-    if (summary && sections.length == 1 &&
-        icompare(strip(summary.text), "ditto") == 0)
-      return true;
-    return false;
-  }
-}
-
-/// Returns a node's DDocComment.
-DDocComment getDDocComment(Node node)
-{
-  DDocParser p;
-  auto docTokens = getDocTokens(node);
-  if (!docTokens.length)
-    return null;
-  p.parse(getDDocText(docTokens));
-  return new DDocComment(p.sections, p.summary, p.description);
-}
-
-/// Strips leading and trailing whitespace characters.
-/// Whitespace: ' ', '\t', '\v', '\f' and '\n'
-/// Returns: a slice into str.
-char[] strip(char[] str)
-{
-  if (str.length == 0)
-    return null;
-  uint i;
-  for (; i < str.length; i++)
-    if (!isspace(str[i]) && str[i] != '\n')
-      break;
-  if (str.length == i)
-    return null;
-  str = str[i..$];
-  assert(str.length);
-  for (i = str.length; i; i--)
-    if (!isspace(str[i-1]) && str[i-1] != '\n')
-      break;
-  return str[0..i];
-}
-
-/// Parses a DDoc comment string.
-struct DDocParser
-{
-  char* p; /// Current character pointer.
-  char* textEnd; /// Points one character past the end of the text.
-  Section[] sections; /// Parsed sections.
-  Section summary; /// Optional summary section.
-  Section description; /// Optional description section.
-
-  /// Parses the DDoc text into sections.
-  Section[] parse(string text)
-  {
-    if (!text.length)
-      return null;
-    p = text.ptr;
-    textEnd = p + text.length;
-
-    char* summaryBegin;
-    string ident, nextIdent;
-    char* bodyBegin, nextBodyBegin;
-
-    skipWhitespace(p);
-    summaryBegin = p;
-
-    if (findNextIdColon(ident, bodyBegin))
-    { // Check that this is not an explicit section.
-      if (summaryBegin != ident.ptr)
-        scanSummaryAndDescription(summaryBegin, ident.ptr);
-    }
-    else // There are no explicit sections.
-    {
-      scanSummaryAndDescription(summaryBegin, textEnd);
-      return sections;
-    }
-
-    assert(ident.length);
-    // Continue parsing.
-    while (findNextIdColon(nextIdent, nextBodyBegin))
-    {
-      sections ~= new Section(ident, textBody(bodyBegin, nextIdent.ptr));
-      ident = nextIdent;
-      bodyBegin = nextBodyBegin;
-    }
-    // Add last section.
-    sections ~= new Section(ident, textBody(bodyBegin, textEnd));
-    return sections;
-  }
-
-  /// Returns the text body. Trailing whitespace characters are not included.
-  char[] textBody(char* begin, char* end)
-  {
-    // The body of A is empty, e.g.:
-    // A:
-    // B: some text
-    // ^- begin and end point to B (or to this.textEnd in the 2nd case.)
-    if (begin is end)
-      return "";
-    // Remove trailing whitespace.
-    while (isspace(*--end) || *end == '\n')
-    {}
-    end++;
-    return makeString(begin, end);
-  }
-
-  /// Separates the text between p and end
-  /// into a summary and description section.
-  void scanSummaryAndDescription(char* p, char* end)
-  {
-    assert(p <= end);
-    char* sectionBegin = p;
-    // Search for the end of the first paragraph.
-    end--; // Decrement end, so we can look ahead one character.
-    while (p < end && !(*p == '\n' && p[1] == '\n'))
-    {
-      if (isCodeSection(p, end))
-        skipCodeSection(p, end);
-      p++;
-    }
-    end++;
-    if (p+1 >= end)
-      p = end;
-    assert(p == end || (*p == '\n' && p[1] == '\n'));
-    // The first paragraph is the summary.
-    summary = new Section("", makeString(sectionBegin, p));
-    sections ~= summary;
-    // The rest is the description section.
-    if (p < end)
-    {
-      skipWhitespace(p);
-      sectionBegin = p;
-      if (p < end)
-      {
-        description = new Section("", makeString(sectionBegin, end));
-        sections ~= description;
-      }
-    }
-  }
-
-  /// Returns true if p points to "$(DDD)".
-  bool isCodeSection(char* p, char* end)
-  {
-    return p+2 < end && *p == '-' && p[1] == '-' && p[2] == '-';
-  }
-
-  /// Skips over a code section.
-  ///
-  /// Note that dmd apparently doesn't skip over code sections when
-  /// parsing DDoc sections. However, from experience it seems
-  /// to be a good idea to do that.
-  void skipCodeSection(ref char* p, char* end)
-  out { assert(p+1 == end || *p == '-'); }
-  body
-  {
-    assert(isCodeSection(p, end));
-
-    while (p < end && *p == '-')
-      p++;
-    p--;
-    while (++p < end)
-      if (p+2 < end && *p == '-' && p[1] == '-' && p[2] == '-')
-        break;
-    while (p < end && *p == '-')
-      p++;
-    p--;
-  }
-
-  void skipWhitespace(ref char* p)
-  {
-    while (p < textEnd && (isspace(*p) || *p == '\n'))
-      p++;
-  }
-
-  /// Find next "Identifier:".
-  /// Params:
-  ///   ident = set to the Identifier.
-  ///   bodyBegin = set to the beginning of the text body (whitespace skipped.)
-  /// Returns: true if found.
-  bool findNextIdColon(ref char[] ident, ref char* bodyBegin)
-  {
-    while (p < textEnd)
-    {
-      skipWhitespace(p);
-      if (p >= textEnd)
-        break;
-      if (isCodeSection(p, textEnd))
-      {
-        skipCodeSection(p, textEnd);
-        p++;
-        continue;
-      }
-      assert(isascii(*p) || isLeadByte(*p));
-      auto idBegin = p;
-      if (isidbeg(*p) || isUnicodeAlpha(p, textEnd)) // IdStart
-      {
-        do // IdChar*
-          p++;
-        while (p < textEnd && (isident(*p) || isUnicodeAlpha(p, textEnd)))
-        auto idEnd = p;
-        if (p < textEnd && *p == ':') // :
-        {
-          p++;
-          skipWhitespace(p);
-          bodyBegin = p;
-          ident = makeString(idBegin, idEnd);
-          return true;
-        }
-      }
-      // Skip this line.
-      while (p < textEnd && *p != '\n')
-        p++;
-    }
-    return false;
-  }
-}
-
-/// Represents a DDoc section.
-class Section
-{
-  string name;
-  string text;
-  this(string name, string text)
-  {
-    this.name = name;
-    this.text = text;
-  }
-
-  /// Case-insensitively compares the section's name with name2.
-  bool Is(char[] name2)
-  {
-    return icompare(name, name2) == 0;
-  }
-}
-
-class ParamsSection : Section
-{
-  string[] paramNames; /// Parameter names.
-  string[] paramDescs; /// Parameter descriptions.
-  this(string name, string text)
-  {
-    super(name, text);
-    IdentValueParser parser;
-    auto idvalues = parser.parse(text);
-    this.paramNames = new string[idvalues.length];
-    this.paramDescs = new string[idvalues.length];
-    foreach (i, idvalue; idvalues)
-    {
-      this.paramNames[i] = idvalue.ident;
-      this.paramDescs[i] = idvalue.value;
-    }
-  }
-}
-
-class MacrosSection : Section
-{
-  string[] macroNames; /// Macro names.
-  string[] macroTexts; /// Macro texts.
-  this(string name, string text)
-  {
-    super(name, text);
-    IdentValueParser parser;
-    auto idvalues = parser.parse(text);
-    this.macroNames = new string[idvalues.length];
-    this.macroTexts = new string[idvalues.length];
-    foreach (i, idvalue; idvalues)
-    {
-      this.macroNames[i] = idvalue.ident;
-      this.macroTexts[i] = idvalue.value;
-    }
-  }
-}
-
-/// Returns true if token is a Doxygen comment.
-bool isDoxygenComment(Token* token)
-{ // Doxygen: '/+!' '/*!' '//!'
-  return token.kind == TOK.Comment && token.start[2] == '!';
-}
-
-/// Returns true if token is a DDoc comment.
-bool isDDocComment(Token* token)
-{ // DDOC: '/++' '/**' '///'
-  return token.kind == TOK.Comment && token.start[1] == token.start[2];
-}
-
-/// Returns the surrounding documentation comment tokens.
-/// Params:
-///   node = the node to find doc comments for.
-///   isDocComment = a function predicate that checks for doc comment tokens.
-/// Note: this function works correctly only if
-///       the source text is syntactically correct.
-Token*[] getDocTokens(Node node, bool function(Token*) isDocComment = &isDDocComment)
-{
-  Token*[] comments;
-  auto isEnumMember = node.kind == NodeKind.EnumMemberDeclaration;
-  // Get preceding comments.
-  auto token = node.begin;
-  // Scan backwards until we hit another declaration.
-Loop:
-  for (; token; token = token.prev)
-  {
-    if (token.kind == TOK.LBrace ||
-        token.kind == TOK.RBrace ||
-        token.kind == TOK.Semicolon ||
-        /+token.kind == TOK.HEAD ||+/
-        (isEnumMember && token.kind == TOK.Comma))
-      break;
-
-    if (token.kind == TOK.Comment)
-    { // Check that this comment doesn't belong to the previous declaration.
-      switch (token.prev.kind)
-      {
-      case TOK.Semicolon, TOK.RBrace, TOK.Comma:
-        break Loop;
-      default:
-        if (isDocComment(token))
-          comments = [token] ~ comments;
-      }
-    }
-  }
-  // Get single comment to the right.
-  token = node.end.next;
-  if (token.kind == TOK.Comment && isDocComment(token))
-    comments ~= token;
-  else if (isEnumMember)
-  {
-    token = node.end.nextNWS;
-    if (token.kind == TOK.Comma)
-    {
-      token = token.next;
-      if (token.kind == TOK.Comment && isDocComment(token))
-        comments ~= token;
-    }
-  }
-  return comments;
-}
-
-bool isLineComment(Token* t)
-{
-  assert(t.kind == TOK.Comment);
-  return t.start[1] == '/';
-}
-
-/// Extracts the text body of the comment tokens.
-string getDDocText(Token*[] tokens)
-{
-  if (tokens.length == 0)
-    return null;
-  string result;
-  foreach (token; tokens)
-  {
-    auto n = isLineComment(token) ? 0 : 2; // 0 for "//", 2 for "+/" and "*/".
-    result ~= sanitize(token.srcText[3 .. $-n], token.start[1]);
-    assert(token.next);
-    if (token.next.kind == TOK.Newline)
-      result ~= \n;
-    else
-      result ~= ' ';
-  }
-//   Stdout.formatln("→{}←", result);
-  return result[0..$-1]; // Remove \n or ' '
-}
-
-/// Sanitizes a DDoc comment string.
-///
-/// Leading "commentChar"s are removed from the lines.
-/// The various newline types are converted to '\n'.
-/// Params:
-///   comment = the string to be sanitized.
-///   commentChar = '/', '+', or '*'
-string sanitize(string comment, char commentChar)
-{
-  alias comment result;
-
-  bool newline = true; // True when at the beginning of a new line.
-  uint i, j;
-  auto len = result.length;
-  for (; i < len; i++, j++)
-  {
-    if (newline)
-    { // Ignore commentChars at the beginning of each new line.
-      newline = false;
-      auto begin = i;
-      while (i < len && isspace(result[i]))
-        i++;
-      if (i < len && result[i] == commentChar)
-        while (++i < len && result[i] == commentChar)
-        {}
-      else
-        i = begin; // Reset. No commentChar found.
-      if (i >= len)
-        break;
-    }
-    // Check for Newline.
-    switch (result[i])
-    {
-    case '\r':
-      if (i+1 < len && result[i+1] == '\n')
-        i++;
-    case '\n':
-      result[j] = '\n'; // Copy Newline as '\n'.
-      newline = true;
-      continue;
-    default:
-      if (!isascii(result[i]) && i+2 < len && isUnicodeNewline(result.ptr + i))
-      {
-        i += 2;
-        goto case '\n';
-      }
-    }
-    // Copy character.
-    result[j] = result[i];
-  }
-  result.length = j; // Adjust length.
-  // Lastly, strip trailing commentChars.
-  if (!result.length)
-    return null;
-  i = result.length;
-  for (; i && result[i-1] == commentChar; i--)
-  {}
-  result.length = i;
-  return result;
-}
--- a/trunk/src/dil/doc/Macro.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,348 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.doc.Macro;
-
-import dil.doc.Parser;
-import dil.lexer.Funcs;
-import dil.Unicode;
-import dil.Information;
-import dil.Messages;
-import common;
-
-/// The DDoc macro class.
-class Macro
-{
-  string name; /// The name of the macro.
-  string text; /// The substitution text.
-  uint callLevel;  /// Recursive call level.
-  this (string name, string text)
-  {
-    this.name = name;
-    this.text = text;
-  }
-}
-
-/// Maps macro names to Macro objects.
-///
-/// MacroTables can be chained so that they build a linear hierarchy.
-/// Macro definitions in the current table override the ones in the parent tables.
-class MacroTable
-{
-  /// The parent in the hierarchy. Or null if this is the root.
-  MacroTable parent;
-  Macro[string] table; /// The associative array that holds the macro definitions.
-
-  /// Constructs a MacroTable instance.
-  this(MacroTable parent = null)
-  {
-    this.parent = parent;
-  }
-
-  /// Inserts the macro m into the table.
-  /// Overwrites the current macro if one exists.
-  void insert(Macro m)
-  {
-    table[m.name] = m;
-  }
-
-  /// Inserts an array of macros into the table.
-  void insert(Macro[] macros)
-  {
-    foreach (m; macros)
-      insert(m);
-  }
-
-  /// Creates a macro using name and text and inserts that into the table.
-  void insert(string name, string text)
-  {
-    insert(new Macro(name, text));
-  }
-
-  /// Creates a macro using name[n] and text[n] and inserts that into the table.
-  void insert(string[] names, string[] texts)
-  {
-    assert(names.length == texts.length);
-    foreach (i, name; names)
-      insert(name, texts[i]);
-  }
-
-  /// Searches for a macro.
-  ///
-  /// If the macro isn't found in this table the search
-  /// continues upwards in the table hierarchy.
-  /// Returns: the macro if found, or null if not.
-  Macro search(string name)
-  {
-    auto pmacro = name in table;
-    if (pmacro)
-      return *pmacro;
-    if (!isRoot())
-      return parent.search(name);
-    return null;
-  }
-
-  /// Returns: true if this is the root of the hierarchy.
-  bool isRoot()
-  { return parent is null; }
-}
-
-/// Parses a text with macro definitions.
-struct MacroParser
-{
-  Macro[] parse(string text)
-  {
-    IdentValueParser parser;
-    auto idvalues = parser.parse(text);
-    auto macros = new Macro[idvalues.length];
-    foreach (i, idvalue; idvalues)
-      macros[i] = new Macro(idvalue.ident, idvalue.value);
-    return macros;
-  }
-
-  /// Scans for a macro invocation. E.g.: &#36;(DDOC)
-  /// Returns: a pointer set to one char past the closing parenthesis,
-  /// or null if this isn't a macro invocation.
-  static char* scanMacro(char* p, char* textEnd)
-  {
-    assert(*p == '$');
-    if (p+2 < textEnd && p[1] == '(')
-    {
-      p += 2;
-      if (isidbeg(*p) || isUnicodeAlpha(p, textEnd)) // IdStart
-      {
-        do // IdChar*
-          p++;
-        while (p < textEnd && (isident(*p) || isUnicodeAlpha(p, textEnd)))
-        MacroExpander.scanArguments(p, textEnd);
-        p != textEnd && p++; // Skip ')'.
-        return p;
-      }
-    }
-    return null;
-  }
-}
-
-/// Expands DDoc macros in a text.
-struct MacroExpander
-{
-  MacroTable mtable; /// Used to look up macros.
-  InfoManager infoMan; /// Collects warning messages.
-  char[] filePath; /// Used in warning messages.
-
-  /// Starts expanding the macros.
-  static char[] expand(MacroTable mtable, char[] text, char[] filePath,
-                       InfoManager infoMan = null)
-  {
-    MacroExpander me;
-    me.mtable = mtable;
-    me.infoMan = infoMan;
-    me.filePath = filePath;
-    return me.expandMacros(text);
-  }
-
-  /// Reports a warning message.
-  void warning(char[] msg, char[] macroName)
-  {
-    msg = Format(msg, macroName);
-    if (infoMan)
-      infoMan ~= new Warning(new Location(filePath, 0), msg);
-  }
-
-  /// Expands the macros from the table in the text.
-  char[] expandMacros(char[] text, char[] prevArg0 = null/+, uint depth = 1000+/)
-  {
-    // if (depth == 0)
-    //   return  text;
-    // depth--;
-    char[] result;
-    char* p = text.ptr;
-    char* textEnd = p + text.length;
-    char* macroEnd = p;
-    while (p+3 < textEnd) // minimum 4 chars: $(x)
-    {
-      if (*p == '$' && p[1] == '(')
-      {
-        // Copy string between macros.
-        if (macroEnd != p)
-          result ~= makeString(macroEnd, p);
-        p += 2;
-        auto idBegin = p;
-        if (isidbeg(*p) || isUnicodeAlpha(p, textEnd)) // IdStart
-        {
-          do // IdChar*
-            p++;
-          while (p < textEnd && (isident(*p) || isUnicodeAlpha(p, textEnd)))
-          // Create macro name.
-          auto macroName = makeString(idBegin, p);
-          // Get arguments.
-          auto macroArgs = scanArguments(p, textEnd);
-          if (p == textEnd)
-          {
-            warning(MSG.UnterminatedDDocMacro, macroName);
-            result ~= "$(" ~ macroName ~ " ";
-          }
-          else
-            p++;
-          macroEnd = p; // Point past ')'.
-
-          auto macro_ = mtable.search(macroName);
-          if (macro_)
-          { // Ignore recursive macro if:
-            auto macroArg0 = macroArgs.length ? macroArgs[0] : null;
-            if (macro_.callLevel != 0 &&
-                (macroArgs.length == 0/+ || // Macro has no arguments.
-                 prevArg0 == macroArg0+/)) // macroArg0 equals previous arg0.
-            { continue; }
-            macro_.callLevel++;
-            // Expand the arguments in the macro text.
-            auto expandedText = expandArguments(macro_.text, macroArgs);
-            result ~= expandMacros(expandedText, macroArg0/+, depth+/);
-            macro_.callLevel--;
-          }
-          else
-          {
-            warning(MSG.UndefinedDDocMacro, macroName);
-            //result ~= makeString(macroName.ptr-2, macroEnd);
-          }
-          continue;
-        }
-      }
-      p++;
-    }
-    if (macroEnd == text.ptr)
-      return text; // No macros found. Return original text.
-    if (macroEnd < textEnd)
-      result ~= makeString(macroEnd, textEnd);
-    return result;
-  }
-
-  /// Scans until the closing parenthesis is found. Sets p to one char past it.
-  /// Returns: [arg0, arg1, arg2 ...].
-  static char[][] scanArguments(ref char* p, char* textEnd)
-  out(args) { assert(args.length != 1); }
-  body
-  {
-    // D specs: "The argument text can contain nested parentheses,
-    //           "" or '' strings, comments, or tags."
-    uint level = 1; // Nesting level of the parentheses.
-    char[][] args;
-
-    // Skip leading spaces.
-    while (p < textEnd && isspace(*p))
-      p++;
-
-    char* arg0Begin = p; // Whole argument list.
-    char* argBegin = p;
-  MainLoop:
-    while (p < textEnd)
-    {
-      switch (*p)
-      {
-      case ',':
-        if (level != 1) // Ignore comma if inside ().
-          break;
-        // Add a new argument.
-        args ~= makeString(argBegin, p);
-        while (++p < textEnd && isspace(*p)) // Skip spaces.
-        {}
-        argBegin = p;
-        continue;
-      case '(':
-        level++;
-        break;
-      case ')':
-        if (--level == 0)
-          break MainLoop;
-        break;
-      // Commented out: causes too many problems in the expansion pass.
-      // case '"', '\'':
-      //   auto c = *p;
-      //   while (++p < textEnd && *p != c) // Scan to next " or '.
-      //   {}
-      //   assert(*p == c || p == textEnd);
-      //   if (p == textEnd)
-      //     break MainLoop;
-      //   break;
-      case '<':
-        p++;
-        if (p+2 < textEnd && *p == '!' && p[1] == '-' && p[2] == '-') // <!--
-        {
-          p += 2; // Point to 2nd '-'.
-          // Scan to closing "-->".
-          while (++p < textEnd)
-            if (p+2 < textEnd && *p == '-' && p[1] == '-' && p[2] == '>')
-              p += 2; // Point to '>'.
-        } // <tag ...> or </tag>
-        else if (p < textEnd && (isalpha(*p) || *p == '/'))
-          while (++p < textEnd && *p != '>') // Skip to closing '>'.
-          {}
-        else
-          continue MainLoop;
-        if (p == textEnd)
-          break MainLoop;
-        assert(*p == '>');
-        break;
-      default:
-      }
-      p++;
-    }
-    assert(*p == ')' && level == 0 || p == textEnd);
-    if (arg0Begin == p)
-      return null;
-    // arg0 spans the whole argument list.
-    auto arg0 = makeString(arg0Begin, p);
-    // Add last argument.
-    args ~= makeString(argBegin, p);
-    return arg0 ~ args;
-  }
-
-  /// Expands "&#36;+", "&#36;0" - "&#36;9" with args[n] in text.
-  /// Params:
-  ///   text = the text to scan for argument placeholders.
-  ///   args = the first element, args[0], is the whole argument string and
-  ///          the following elements are slices into it.$(BR)
-  ///          The array is empty if there are no arguments.
-  char[] expandArguments(char[] text, char[][] args)
-  in { assert(args.length != 1, "zero or more than 1 args expected"); }
-  body
-  {
-    char[] result;
-    char* p = text.ptr;
-    char* textEnd = p + text.length;
-    char* placeholderEnd = p;
-
-    while (p+1 < textEnd)
-    {
-      if (*p == '$' && (*++p == '+' || isdigit(*p)))
-      {
-        // Copy string between argument placeholders.
-        if (placeholderEnd != p-1)
-          result ~= makeString(placeholderEnd, p-1);
-        placeholderEnd = p+1; // Set new placeholder end.
-
-        if (args.length == 0)
-          continue;
-
-        if (*p == '+')
-        { // $+ = $2 to $n
-          if (args.length > 2)
-            result ~= makeString(args[2].ptr, args[0].ptr + args[0].length);
-        }
-        else
-        { // 0 - 9
-          uint nthArg = *p - '0';
-          if (nthArg < args.length)
-            result ~= args[nthArg];
-        }
-      }
-      p++;
-    }
-    if (placeholderEnd == text.ptr)
-      return text; // No placeholders found. Return original text.
-    if (placeholderEnd < textEnd)
-      result ~= makeString(placeholderEnd, textEnd);
-    return result;
-  }
-}
--- a/trunk/src/dil/doc/Parser.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.doc.Parser;
-
-import dil.lexer.Funcs;
-import dil.Unicode;
-import common;
-
-/// A pair of strings.
-class IdentValue
-{
-  string ident;
-  string value;
-  this (string ident, string value)
-  {
-    this.ident = ident;
-    this.value = value;
-  }
-}
-
-/// Parses text of the form:
-/// <pre>
-/// ident = value
-/// ident2 = value2
-///          more text
-/// </pre>
-struct IdentValueParser
-{
-  char* p; /// Current pointer.
-  char* textEnd;
-
-  IdentValue[] parse(string text)
-  {
-    if (!text.length)
-      return null;
-
-    p = text.ptr;
-    textEnd = p + text.length;
-
-    IdentValue[] idvalues;
-
-    string ident, nextIdent;
-    char* bodyBegin = p, nextBodyBegin;
-
-    // Init.
-    findNextIdent(ident, bodyBegin);
-    // Continue.
-    while (findNextIdent(nextIdent, nextBodyBegin))
-    {
-      idvalues ~= new IdentValue(ident, textBody(bodyBegin, nextIdent.ptr));
-      ident = nextIdent;
-      bodyBegin = nextBodyBegin;
-    }
-    // Add last ident value.
-    idvalues ~= new IdentValue(ident, textBody(bodyBegin, textEnd));
-    return idvalues;
-  }
-
-  /// Returns the text body. Trailing whitespace characters are not included.
-  char[] textBody(char* begin, char* end)
-  {
-    // The body of A is empty, e.g.:
-    // A =
-    // B = some text
-    // ^- begin and end point to B (or to this.textEnd in the 2nd case.)
-    if (begin is end)
-      return "";
-    // Remove trailing whitespace.
-    while (isspace(*--end) || *end == '\n')
-    {}
-    end++;
-    return makeString(begin, end);
-  }
-
-  /// Finds the next "Identifier =".
-  /// Params:
-  ///   ident = set to Identifier.
-  ///   bodyBegin = set to the beginning of the text body (whitespace skipped.)
-  /// Returns: true if found.
-  bool findNextIdent(ref string ident, ref char* bodyBegin)
-  {
-    while (p < textEnd)
-    {
-      skipWhitespace();
-      if (p >= textEnd)
-        break;
-      auto idBegin = p;
-      if (isidbeg(*p) || isUnicodeAlpha(p, textEnd)) // IdStart
-      {
-        do // IdChar*
-          p++;
-        while (p < textEnd && (isident(*p) || isUnicodeAlpha(p, textEnd)))
-        auto idEnd = p;
-
-        skipWhitespace();
-        if (p < textEnd && *p == '=')
-        {
-          p++;
-          skipWhitespace();
-          bodyBegin = p;
-          ident = makeString(idBegin, idEnd);
-          return true;
-        }
-      }
-      skipLine();
-    }
-    return false;
-  }
-
-  void skipWhitespace()
-  {
-    while (p < textEnd && (isspace(*p) || *p == '\n'))
-      p++;
-  }
-
-  void skipLine()
-  {
-    while (p < textEnd && *p != '\n')
-      p++;
-    p++;
-  }
-}
-
-/// Returns a string slice ranging from begin to end.
-char[] makeString(char* begin, char* end)
-{
-  assert(begin && end && begin <= end);
-  return begin[0 .. end - begin];
-}
--- a/trunk/src/dil/lexer/Funcs.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.lexer.Funcs;
-
-const char[3] LS = \u2028; /// Unicode line separator.
-const dchar LSd = 0x2028;  /// ditto
-const char[3] PS = \u2029; /// Unicode paragraph separator.
-const dchar PSd = 0x2029;  /// ditto
-static assert(LS[0] == PS[0] && LS[1] == PS[1]);
-
-const dchar _Z_ = 26; /// Control+Z.
-
-/// Returns: true if d is a Unicode line or paragraph separator.
-bool isUnicodeNewlineChar(dchar d)
-{
-  return d == LSd || d == PSd;
-}
-
-/// Returns: true if p points to a line or paragraph separator.
-bool isUnicodeNewline(char* p)
-{
-  return *p == LS[0] && p[1] == LS[1] && (p[2] == LS[2] || p[2] == PS[2]);
-}
-
-/// Returns: true if p points to the start of a Newline.
-/// Newline: \n | \r | \r\n | LS | PS
-bool isNewline(char* p)
-{
-  return *p == '\n' || *p == '\r' || isUnicodeNewline(p);
-}
-
-/// Returns: true if c is a Newline character.
-bool isNewline(dchar c)
-{
-  return c == '\n' || c == '\r' || isUnicodeNewlineChar(c);
-}
-
-/// Returns: true if p points to an EOF character.
-/// EOF: 0 | _Z_
-bool isEOF(dchar c)
-{
-  return c == 0 || c == _Z_;
-}
-
-/// Returns: true if p points to the first character of an EndOfLine.
-/// EndOfLine: Newline | EOF
-bool isEndOfLine(char* p)
-{
-  return isNewline(p) || isEOF(*p);
-}
-
-/// Scans a Newline and sets p one character past it.
-/// Returns: '\n' if found or 0 otherwise.
-dchar scanNewline(ref char* p)
-{
-  switch (*p)
-  {
-  case '\r':
-    if (p[1] == '\n')
-      ++p;
-  case '\n':
-    ++p;
-    return '\n';
-  default:
-    if (isUnicodeNewline(p))
-    {
-      p += 3;
-      return '\n';
-    }
-  }
-  return 0;
-}
-
-/// ASCII character properties table.
-static const int ptable[256] = [
- 0, 0, 0, 0, 0, 0, 0, 0, 0,32, 0,32,32, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-32, 0, 0x2200, 0, 0, 0, 0, 0x2700, 0, 0, 0, 0, 0, 0, 0, 0,
- 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 0, 0, 0, 0, 0, 0x3f00,
- 0,12,12,12,12,12,12, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0x5c00, 0, 0,16,
- 0, 0x70c, 0x80c,12,12,12, 0xc0c, 8, 8, 8, 8, 8, 8, 8, 0xa08, 8,
- 8, 8, 0xd08, 8, 0x908, 8, 0xb08, 8, 8, 8, 8, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-];
-
-/// Enumeration of character property flags.
-enum CProperty
-{
-       Octal = 1,    /// 0-7
-       Digit = 1<<1, /// 0-9
-         Hex = 1<<2, /// 0-9a-fA-F
-       Alpha = 1<<3, /// a-zA-Z
-  Underscore = 1<<4, /// _
-  Whitespace = 1<<5  /// ' ' \t \v \f
-}
-
-const uint EVMask = 0xFF00; // Bit mask for escape value.
-
-private alias CProperty CP;
-/// Returns: true if c is an octal digit.
-int isoctal(char c) { return ptable[c] & CP.Octal; }
-/// Returns: true if c is a decimal digit.
-int isdigit(char c) { return ptable[c] & CP.Digit; }
-/// Returns: true if c is a hexadecimal digit.
-int ishexad(char c) { return ptable[c] & CP.Hex; }
-/// Returns: true if c is a letter.
-int isalpha(char c) { return ptable[c] & CP.Alpha; }
-/// Returns: true if c is an alphanumeric.
-int isalnum(char c) { return ptable[c] & (CP.Alpha | CP.Digit); }
-/// Returns: true if c is the beginning of a D identifier (only ASCII.)
-int isidbeg(char c) { return ptable[c] & (CP.Alpha | CP.Underscore); }
-/// Returns: true if c is a D identifier character (only ASCII.)
-int isident(char c) { return ptable[c] & (CP.Alpha | CP.Underscore | CP.Digit); }
-/// Returns: true if c is a whitespace character.
-int isspace(char c) { return ptable[c] & CP.Whitespace; }
-/// Returns: the escape value for c.
-int char2ev(char c) { return ptable[c] >> 8; /*(ptable[c] & EVMask) >> 8;*/ }
-/// Returns: true if c is an ASCII character.
-int isascii(uint c) { return c < 128; }
-
-version(gen_ptable)
-static this()
-{
-  alias ptable p;
-  assert(p.length == 256);
-  // Initialize character properties table.
-  for (int i; i < p.length; ++i)
-  {
-    p[i] = 0; // Reset
-    if ('0' <= i && i <= '7')
-      p[i] |= CP.Octal;
-    if ('0' <= i && i <= '9')
-      p[i] |= CP.Digit | CP.Hex;
-    if ('a' <= i && i <= 'f' || 'A' <= i && i <= 'F')
-      p[i] |= CP.Hex;
-    if ('a' <= i && i <= 'z' || 'A' <= i && i <= 'Z')
-      p[i] |= CP.Alpha;
-    if (i == '_')
-      p[i] |= CP.Underscore;
-    if (i == ' ' || i == '\t' || i == '\v' || i == '\f')
-      p[i] |= CP.Whitespace;
-  }
-  // Store escape sequence values in second byte.
-  assert(CProperty.max <= ubyte.max, "character property flags and escape value byte overlap.");
-  p['\''] |= 39 << 8;
-  p['"'] |= 34 << 8;
-  p['?'] |= 63 << 8;
-  p['\\'] |= 92 << 8;
-  p['a'] |= 7 << 8;
-  p['b'] |= 8 << 8;
-  p['f'] |= 12 << 8;
-  p['n'] |= 10 << 8;
-  p['r'] |= 13 << 8;
-  p['t'] |= 9 << 8;
-  p['v'] |= 11 << 8;
-  // Print a formatted array literal.
-  char[] array = "[\n";
-  foreach (i, c; ptable)
-  {
-    array ~= Format((c>255?" 0x{0:x},":"{0,2},"), c) ~ (((i+1) % 16) ? "":"\n");
-  }
-  array[$-2..$] = "\n]";
-  Stdout(array).newline;
-}
--- a/trunk/src/dil/lexer/IdTable.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.lexer.IdTable;
-
-import dil.lexer.TokensEnum;
-import dil.lexer.IdentsGenerator;
-import dil.lexer.Keywords;
-import common;
-
-public import dil.lexer.Identifier;
-public import dil.lexer.IdentsEnum;
-
-/// A namespace for the predefined identifiers.
-struct Ident
-{
-  const static
-  {
-    mixin(generateIdentMembers());
-  }
-
-  static Identifier*[] allIds()
-  {
-    return __allIds;
-  }
-}
-
-/// Global table for hoarding and retrieving identifiers.
-struct IdTable
-{
-static:
-  /// A set of common, predefined identifiers for fast lookups.
-  private Identifier*[string] staticTable;
-  /// A table that grows with every newly found, unique identifier.
-  private Identifier*[string] growingTable;
-
-  /// Loads keywords and predefined identifiers into the static table.
-  static this()
-  {
-    foreach (ref k; g_reservedIds)
-      staticTable[k.str] = &k;
-    foreach (id; Ident.allIds())
-      staticTable[id.str] = id;
-    staticTable.rehash;
-  }
-
-  /// Looks up idString in both tables.
-  Identifier* lookup(string idString)
-  {
-    auto id = inStatic(idString);
-    if (id)
-      return id;
-    return inGrowing(idString);
-  }
-
-  /// Looks up idString in the static table.
-  Identifier* inStatic(string idString)
-  {
-    auto id = idString in staticTable;
-    return id ? *id : null;
-  }
-
-  alias Identifier* function(string idString) LookupFunction;
-  /// Looks up idString in the growing table.
-  LookupFunction inGrowing = &_inGrowing_unsafe; // Default to unsafe function.
-
-  /// Sets the thread safety mode of the growing table.
-  void setThreadsafe(bool b)
-  {
-    if (b)
-      inGrowing = &_inGrowing_safe;
-    else
-      inGrowing = &_inGrowing_unsafe;
-  }
-
-  /// Returns true if access to the growing table is thread-safe.
-  bool isThreadsafe()
-  {
-    return inGrowing is &_inGrowing_safe;
-  }
-
-  /// Looks up idString in the table.
-  ///
-  /// Adds idString to the table if not found.
-  private Identifier* _inGrowing_unsafe(string idString)
-  out(id)
-  { assert(id !is null); }
-  body
-  {
-    auto id = idString in growingTable;
-    if (id)
-      return *id;
-    auto newID = Identifier(idString, TOK.Identifier);
-    growingTable[idString] = newID;
-    return newID;
-  }
-
-  /// Looks up idString in the table.
-  ///
-  /// Adds idString to the table if not found.
-  /// Access to the data structure is synchronized.
-  private Identifier* _inGrowing_safe(string idString)
-  {
-    synchronized
-      return _inGrowing_unsafe(idString);
-  }
-
-  /+
-  Identifier* addIdentifiers(char[][] idStrings)
-  {
-    auto ids = new Identifier*[idStrings.length];
-    foreach (i, idString; idStrings)
-    {
-      Identifier** id = idString in tabulatedIds;
-      if (!id)
-      {
-        auto newID = Identifier(TOK.Identifier, idString);
-        tabulatedIds[idString] = newID;
-        id = &newID;
-      }
-      ids[i] = *id;
-    }
-  }
-  +/
-
-  static uint anonCount; /// Counter for anonymous identifiers.
-
-  /// Generates an anonymous identifier.
-  ///
-  /// Concatenates prefix with anonCount.
-  /// The identifier is not inserted into the table.
-  Identifier* genAnonymousID(string prefix)
-  {
-    ++anonCount;
-    auto x = anonCount;
-    // Convert count to a string and append it to str.
-    char[] num;
-    do
-      num = cast(char)('0' + (x % 10)) ~ num;
-    while (x /= 10)
-    return Identifier(prefix ~ num, TOK.Identifier);
-  }
-
-  /// Generates an identifier for an anonymous enum.
-  Identifier* genAnonEnumID()
-  {
-    return genAnonymousID("__anonenum");
-  }
-}
-
-unittest
-{
-  // TODO: write benchmark.
-  // Single table
-
-  // Single table. synchronized
-
-  // Two tables.
-
-  // Two tables. synchronized
-}
--- a/trunk/src/dil/lexer/Identifier.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.lexer.Identifier;
-
-import dil.lexer.TokensEnum;
-import dil.lexer.IdentsEnum;
-import common;
-
-/// Represents an identifier as defined in the D specs.
-///
-///<pre>
-///  Identifier := IdStart IdChar*
-///  IdStart := "_" | Letter
-///  IdChar := IdStart | "0"-"9"
-///  Letter := UniAlpha
-///</pre>
-///  Unicode alphas are defined in Unicode 5.0.0.
-align(1)
-struct Identifier
-{
-  string str; /// The UTF-8 string of the identifier.
-  TOK kind;   /// The token kind.
-  IDK idKind; /// Only for predefined identifiers.
-
-  static Identifier* opCall(string str, TOK kind)
-  {
-    auto id = new Identifier;
-    id.str = str;
-    id.kind = kind;
-    return id;
-  }
-
-  static Identifier* opCall(string str, TOK kind, IDK idKind)
-  {
-    auto id = new Identifier;
-    id.str = str;
-    id.kind = kind;
-    id.idKind = idKind;
-    return id;
-  }
-
-  uint toHash()
-  {
-    uint hash;
-    foreach(c; str) {
-      hash *= 11;
-      hash += c;
-    }
-    return hash;
-  }
-}
-// pragma(msg, Identifier.sizeof.stringof);
--- a/trunk/src/dil/lexer/IdentsEnum.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.lexer.IdentsEnum;
-
-import dil.lexer.IdentsGenerator;
-
-version(DDoc)
-  enum IDK : ushort; /// Enumeration of predefined identifier kinds.
-else
-mixin(
-  // Enumerates predefined identifiers.
-  "enum IDK : ushort {"
-    "Null,"
-    ~ generateIDMembers ~
-  "}"
-);
--- a/trunk/src/dil/lexer/IdentsGenerator.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.lexer.IdentsGenerator;
-
-struct StrPair
-{
-const:
-  char[] str;   /// Identifier string in code.
-  char[] idStr; /// In table.
-}
-
-/// Table of predefined identifiers.
-static const StrPair[] identPairs = [
-  // Predefined version identifiers:
-  {"DigitalMars"}, {"X86"}, {"X86_64"},
-  /*{"Windows"}, */{"Win32"}, {"Win64"},
-  {"linux"}, {"LittleEndian"}, {"BigEndian"},
-  {"D_Coverage"}, {"D_InlineAsm_X86"}, {"D_Version2"},
-  {"none"}, {"all"},
-  // Variadic parameters:
-  {"_arguments"}, {"_argptr"},
-  // scope:
-  {"exit"}, {"success"}, {"failure"},
-  // pragma:
-  {"msg"}, {"lib"}, {"startaddress"},
-  // Linkage:
-  {"C"}, {"D"}, {"Windows"}, {"Pascal"}, {"System"},
-  // Con-/Destructor:
-  {"__ctor"}, {"__dtor"},
-  // new() and delete() methods.
-  {"__new"}, {"__delete"},
-  // Unittest and invariant.
-  {"__unittest"}, {"__invariant"},
-  // Operator methods:
-  {"opNeg"},
-  {"opPos"},
-  {"opComp"},
-  {"opAddAssign"},
-  {"opSubAssign"},
-  {"opPostInc"},
-  {"opPostDec"},
-  {"opCall"},
-  {"opCast"},
-  {"opIndex"},
-  {"opSlice"},
-  // ASM identifiers:
-  {"near"}, {"far"}, {"word"}, {"dword"}, {"qword"},
-  {"ptr"}, {"offset"}, {"seg"}, {"__LOCAL_SIZE"},
-  {"FS"}, {"ST"},
-  {"AL"}, {"AH"}, {"AX"}, {"EAX"},
-  {"BL"}, {"BH"}, {"BX"}, {"EBX"},
-  {"CL"}, {"CH"}, {"CX"}, {"ECX"},
-  {"DL"}, {"DH"}, {"DX"}, {"EDX"},
-  {"BP"}, {"EBP"}, {"SP"}, {"ESP"},
-  {"DI"}, {"EDI"}, {"SI"}, {"ESI"},
-  {"ES"}, {"CS"}, {"SS"}, {"DS"}, {"GS"},
-  {"CR0"}, {"CR2"}, {"CR3"}, {"CR4"},
-  {"DR0"}, {"DR1"}, {"DR2"}, {"DR3"}, {"DR6"}, {"DR7"},
-  {"TR3"}, {"TR4"}, {"TR5"}, {"TR6"}, {"TR7"},
-  {"MM0"}, {"MM1"}, {"MM2"}, {"MM3"},
-  {"MM4"}, {"MM5"}, {"MM6"}, {"MM7"},
-  {"XMM0"}, {"XMM1"}, {"XMM2"}, {"XMM3"},
-  {"XMM4"}, {"XMM5"}, {"XMM6"}, {"XMM7"},
-];
-
-/++
- CTF for generating the members of the struct Ident.
-
- The resulting string looks like this:
- ---
-  private struct Ids {static const:
-    Identifier _str = {"str", TOK.Identifier, IDK.str};
-    // more ...
-  }
-  Identifier* str = &Ids._str;
-  // more ...
-  private Identifier*[] __allIds = [
-    str,
-    // more ...
-  ]
- ---
-+/
-char[] generateIdentMembers()
-{
-  char[] private_members = "private struct Ids {static const:";
-
-  char[] public_members = "";
-  char[] array = "private Identifier*[] __allIds = [";
-  foreach (pair; identPairs)
-  {
-    // N.B.: Compiler cries for some reason when trying to access pair.idStr.
-    // Identifier _str = {"str", TOK.Identifier, ID.str};
-    private_members ~= "Identifier _"~pair.str~` = {"`~pair.str~`", TOK.Identifier, IDK.`~pair.str~"};\n";
-    // Identifier* str = &_str;
-    public_members ~= "Identifier* "~pair.str~" = &Ids._"~pair.str~";\n";
-    array ~= pair.str~",";
-  }
-
-  private_members ~= "}"; // Close private {
-  array ~= "];";
-
-  return private_members ~ public_members ~ array;
-}
-
-/// CTF for generating the members of the enum IDK.
-char[] generateIDMembers()
-{
-  char[] members;
-  foreach (pair; identPairs)
-    members ~= pair.str ~ ",\n";
-  return members;
-}
-
-// pragma(msg, generateIdentMembers());
-// pragma(msg, generateIDMembers());
--- a/trunk/src/dil/lexer/Keywords.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.lexer.Keywords;
-
-import dil.lexer.Token;
-import dil.lexer.Identifier;
-
-/// Table of reserved identifiers.
-static const Identifier[] g_reservedIds = [
-  {"abstract", TOK.Abstract},
-  {"alias", TOK.Alias},
-  {"align", TOK.Align},
-  {"asm", TOK.Asm},
-  {"assert", TOK.Assert},
-  {"auto", TOK.Auto},
-  {"body", TOK.Body},
-  {"bool", TOK.Bool},
-  {"break", TOK.Break},
-  {"byte", TOK.Byte},
-  {"case", TOK.Case},
-  {"cast", TOK.Cast},
-  {"catch", TOK.Catch},
-  {"cdouble", TOK.Cdouble},
-  {"cent", TOK.Cent},
-  {"cfloat", TOK.Cfloat},
-  {"char", TOK.Char},
-  {"class", TOK.Class},
-  {"const", TOK.Const},
-  {"continue", TOK.Continue},
-  {"creal", TOK.Creal},
-  {"dchar", TOK.Dchar},
-  {"debug", TOK.Debug},
-  {"default", TOK.Default},
-  {"delegate", TOK.Delegate},
-  {"delete", TOK.Delete},
-  {"deprecated", TOK.Deprecated},
-  {"do", TOK.Do},
-  {"double", TOK.Double},
-  {"else", TOK.Else},
-  {"enum", TOK.Enum},
-  {"export", TOK.Export},
-  {"extern", TOK.Extern},
-  {"false", TOK.False},
-  {"final", TOK.Final},
-  {"finally", TOK.Finally},
-  {"float", TOK.Float},
-  {"for", TOK.For},
-  {"foreach", TOK.Foreach},
-  {"foreach_reverse", TOK.Foreach_reverse},
-  {"function", TOK.Function},
-  {"goto", TOK.Goto},
-  {"idouble", TOK.Idouble},
-  {"if", TOK.If},
-  {"ifloat", TOK.Ifloat},
-  {"import", TOK.Import},
-  {"in", TOK.In},
-  {"inout", TOK.Inout},
-  {"int", TOK.Int},
-  {"interface", TOK.Interface},
-  {"invariant", TOK.Invariant},
-  {"ireal", TOK.Ireal},
-  {"is", TOK.Is},
-  {"lazy", TOK.Lazy},
-  {"long", TOK.Long},
-  {"macro", TOK.Macro}, // D2.0
-  {"mixin", TOK.Mixin},
-  {"module", TOK.Module},
-  {"new", TOK.New},
-  {"nothrow", TOK.Nothrow}, // D2.0
-  {"null", TOK.Null},
-  {"out", TOK.Out},
-  {"override", TOK.Override},
-  {"package", TOK.Package},
-  {"pragma", TOK.Pragma},
-  {"private", TOK.Private},
-  {"protected", TOK.Protected},
-  {"public", TOK.Public},
-  {"pure", TOK.Pure}, // D2.0
-  {"real", TOK.Real},
-  {"ref", TOK.Ref},
-  {"return", TOK.Return},
-  {"scope", TOK.Scope},
-  {"short", TOK.Short},
-  {"static", TOK.Static},
-  {"struct", TOK.Struct},
-  {"super", TOK.Super},
-  {"switch", TOK.Switch},
-  {"synchronized", TOK.Synchronized},
-  {"template", TOK.Template},
-  {"this", TOK.This},
-  {"throw", TOK.Throw},
-  {"__traits", TOK.Traits}, // D2.0
-  {"true", TOK.True},
-  {"try", TOK.Try},
-  {"typedef", TOK.Typedef},
-  {"typeid", TOK.Typeid},
-  {"typeof", TOK.Typeof},
-  {"ubyte", TOK.Ubyte},
-  {"ucent", TOK.Ucent},
-  {"uint", TOK.Uint},
-  {"ulong", TOK.Ulong},
-  {"union", TOK.Union},
-  {"unittest", TOK.Unittest},
-  {"ushort", TOK.Ushort},
-  {"version", TOK.Version},
-  {"void", TOK.Void},
-  {"volatile", TOK.Volatile},
-  {"wchar", TOK.Wchar},
-  {"while", TOK.While},
-  {"with", TOK.With},
-  // Special tokens:
-  {"__FILE__", TOK.FILE},
-  {"__LINE__", TOK.LINE},
-  {"__DATE__", TOK.DATE},
-  {"__TIME__", TOK.TIME},
-  {"__TIMESTAMP__", TOK.TIMESTAMP},
-  {"__VENDOR__", TOK.VENDOR},
-  {"__VERSION__", TOK.VERSION},
-  {"__EOF__", TOK.EOF}, // D2.0
-];
--- a/trunk/src/dil/lexer/Lexer.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2900 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.lexer.Lexer;
-
-import dil.lexer.Token;
-import dil.lexer.Keywords;
-import dil.lexer.Identifier;
-import dil.lexer.IdTable;
-import dil.Information;
-import dil.Messages;
-import dil.HtmlEntities;
-import dil.CompilerInfo;
-import dil.Unicode;
-import dil.SourceText;
-import dil.Time;
-import common;
-
-import tango.stdc.stdlib : strtof, strtod, strtold;
-import tango.stdc.errno : errno, ERANGE;
-
-public import dil.lexer.Funcs;
-
-/// The Lexer analyzes the characters of a source text and
-/// produces a doubly-linked list of tokens.
-class Lexer
-{
-  SourceText srcText; /// The source text.
-  char* p;            /// Points to the current character in the source text.
-  char* end;          /// Points one character past the end of the source text.
-
-  Token* head;  /// The head of the doubly linked token list.
-  Token* tail;  /// The tail of the linked list. Set in scan().
-  Token* token; /// Points to the current token in the token list.
-
-  // Members used for error messages:
-  InfoManager infoMan;
-  LexerError[] errors;
-  /// Always points to the first character of the current line.
-  char* lineBegin;
-//   Token* newline;     /// Current newline token.
-  uint lineNum = 1;   /// Current, actual source text line number.
-  uint lineNum_hline; /// Line number set by #line.
-  uint inTokenString; /// > 0 if inside q{ }
-  /// Holds the original file path and the modified one (by #line.)
-  NewlineData.FilePaths* filePaths;
-
-  /// Construct a Lexer object.
-  /// Params:
-  ///   srcText = the UTF-8 source code.
-  ///   infoMan = used for collecting error messages.
-  this(SourceText srcText, InfoManager infoMan = null)
-  {
-    this.srcText = srcText;
-    this.infoMan = infoMan;
-
-    assert(text.length && text[$-1] == 0, "source text has no sentinel character");
-    this.p = text.ptr;
-    this.end = this.p + text.length;
-    this.lineBegin = this.p;
-
-    this.head = new Token;
-    this.head.kind = TOK.HEAD;
-    this.head.start = this.head.end = this.p;
-    this.token = this.head;
-    // Initialize this.filePaths.
-    newFilePath(this.srcText.filePath);
-    // Add a newline as the first token after the head.
-    auto newline = new Token;
-    newline.kind = TOK.Newline;
-    newline.setWhitespaceFlag();
-    newline.start = newline.end = this.p;
-    newline.newline.filePaths = this.filePaths;
-    newline.newline.oriLineNum = 1;
-    newline.newline.setLineNum = 0;
-    // Link in.
-    this.token.next = newline;
-    newline.prev = this.token;
-    this.token = newline;
-//     this.newline = newline;
-    scanShebang();
-  }
-
-  /// The destructor deletes the doubly-linked token list.
-  ~this()
-  {
-    auto token = head.next;
-    while (token !is null)
-    {
-      assert(token.kind == TOK.EOF ? token == tail && token.next is null : 1);
-      delete token.prev;
-      token = token.next;
-    }
-    delete tail;
-  }
-
-  char[] text()
-  {
-    return srcText.data;
-  }
-
-  /// The "shebang" may optionally appear once at the beginning of a file.
-  /// Regexp: #![^\EndOfLine]*
-  void scanShebang()
-  {
-    if (*p == '#' && p[1] == '!')
-    {
-      auto t = new Token;
-      t.kind = TOK.Shebang;
-      t.setWhitespaceFlag();
-      t.start = p;
-      ++p;
-      while (!isEndOfLine(++p))
-        isascii(*p) || decodeUTF8();
-      t.end = p;
-      this.token.next = t;
-      t.prev = this.token;
-    }
-  }
-
-  /// Sets the value of the special token.
-  void finalizeSpecialToken(ref Token t)
-  {
-    assert(t.srcText[0..2] == "__");
-    switch (t.kind)
-    {
-    case TOK.FILE:
-      t.str = this.filePaths.setPath;
-      break;
-    case TOK.LINE:
-      t.uint_ = this.errorLineNumber(this.lineNum);
-      break;
-    case TOK.DATE,
-         TOK.TIME,
-         TOK.TIMESTAMP:
-      auto time_str = Time.toString();
-      switch (t.kind)
-      {
-      case TOK.DATE:
-        time_str = Time.month_day(time_str) ~ ' ' ~ Time.year(time_str); break;
-      case TOK.TIME:
-        time_str = Time.time(time_str); break;
-      case TOK.TIMESTAMP:
-        break; // time_str is the timestamp.
-      default: assert(0);
-      }
-      time_str ~= '\0'; // Terminate with a zero.
-      t.str = time_str;
-      break;
-    case TOK.VENDOR:
-      t.str = VENDOR;
-      break;
-    case TOK.VERSION:
-      t.uint_ = VERSION_MAJOR*1000 + VERSION_MINOR;
-      break;
-    default:
-      assert(0);
-    }
-  }
-
-  /// Sets a new file path.
-  void newFilePath(char[] newPath)
-  {
-    auto paths = new NewlineData.FilePaths;
-    paths.oriPath = this.srcText.filePath;
-    paths.setPath = newPath;
-    this.filePaths = paths;
-  }
-
-  private void setLineBegin(char* p)
-  {
-    // Check that we can look behind one character.
-    assert((p-1) >= text.ptr && p < end);
-    // Check that previous character is a newline.
-    assert(isNewlineEnd(p - 1));
-    this.lineBegin = p;
-  }
-
-  /// Scans the next token in the source text.
-  ///
-  /// Creates a new token if t.next is null and appends it to the list.
-  private void scanNext(ref Token* t)
-  {
-    assert(t !is null);
-    if (t.next)
-    {
-      t = t.next;
-//       if (t.kind == TOK.Newline)
-//         this.newline = t;
-    }
-    else if (t != this.tail)
-    {
-      Token* new_t = new Token;
-      scan(*new_t);
-      new_t.prev = t;
-      t.next = new_t;
-      t = new_t;
-    }
-  }
-
-  /// Advance t one token forward.
-  void peek(ref Token* t)
-  {
-    scanNext(t);
-  }
-
-  /// Advance to the next token in the source text.
-  TOK nextToken()
-  {
-    scanNext(this.token);
-    return this.token.kind;
-  }
-
-  /// Returns true if p points to the last character of a Newline.
-  bool isNewlineEnd(char* p)
-  {
-    if (*p == '\n' || *p == '\r')
-      return true;
-    if (*p == LS[2] || *p == PS[2])
-      if ((p-2) >= text.ptr)
-        if (p[-1] == LS[1] && p[-2] == LS[0])
-          return true;
-    return false;
-  }
-
-  /// The main method which recognizes the characters that make up a token.
-  ///
-  /// Complicated tokens are scanned in separate methods.
-  public void scan(ref Token t)
-  in
-  {
-    assert(text.ptr <= p && p < end);
-  }
-  out
-  {
-    assert(text.ptr <= t.start && t.start < end, Token.toString(t.kind));
-    assert(text.ptr <= t.end && t.end <= end, Token.toString(t.kind));
-  }
-  body
-  {
-    // Scan whitespace.
-    if (isspace(*p))
-    {
-      t.ws = p;
-      while (isspace(*++p))
-      {}
-    }
-
-    // Scan a token.
-    uint c = *p;
-    {
-      t.start = p;
-      // Newline.
-      switch (*p)
-      {
-      case '\r':
-        if (p[1] == '\n')
-          ++p;
-      case '\n':
-        assert(isNewlineEnd(p));
-        ++p;
-        ++lineNum;
-        setLineBegin(p);
-//         this.newline = &t;
-        t.kind = TOK.Newline;
-        t.setWhitespaceFlag();
-        t.newline.filePaths = this.filePaths;
-        t.newline.oriLineNum = lineNum;
-        t.newline.setLineNum = lineNum_hline;
-        t.end = p;
-        return;
-      default:
-        if (isUnicodeNewline(p))
-        {
-          ++p; ++p;
-          goto case '\n';
-        }
-      }
-      // Identifier or string literal.
-      if (isidbeg(c))
-      {
-        if (c == 'r' && p[1] == '"' && ++p)
-          return scanRawStringLiteral(t);
-        if (c == 'x' && p[1] == '"')
-          return scanHexStringLiteral(t);
-      version(D2)
-      {
-        if (c == 'q' && p[1] == '"')
-          return scanDelimitedStringLiteral(t);
-        if (c == 'q' && p[1] == '{')
-          return scanTokenStringLiteral(t);
-      }
-        // Scan identifier.
-      Lidentifier:
-        do
-        { c = *++p; }
-        while (isident(c) || !isascii(c) && isUnicodeAlpha())
-
-        t.end = p;
-
-        auto id = IdTable.lookup(t.srcText);
-        t.kind = id.kind;
-        t.ident = id;
-
-        if (t.kind == TOK.Identifier || t.isKeyword)
-          return;
-        else if (t.isSpecialToken)
-          finalizeSpecialToken(t);
-        else if (t.kind == TOK.EOF)
-        {
-          tail = &t;
-          assert(t.srcText == "__EOF__");
-        }
-        else
-          assert(0, "unexpected token type: " ~ Token.toString(t.kind));
-        return;
-      }
-
-      if (isdigit(c))
-        return scanNumber(t);
-
-      if (c == '/')
-      {
-        c = *++p;
-        switch(c)
-        {
-        case '=':
-          ++p;
-          t.kind = TOK.DivAssign;
-          t.end = p;
-          return;
-        case '+':
-          return scanNestedComment(t);
-        case '*':
-          return scanBlockComment(t);
-        case '/':
-          while (!isEndOfLine(++p))
-            isascii(*p) || decodeUTF8();
-          t.kind = TOK.Comment;
-          t.setWhitespaceFlag();
-          t.end = p;
-          return;
-        default:
-          t.kind = TOK.Div;
-          t.end = p;
-          return;
-        }
-      }
-
-      switch (c)
-      {
-      case '\'':
-        return scanCharacterLiteral(t);
-      case '`':
-        return scanRawStringLiteral(t);
-      case '"':
-        return scanNormalStringLiteral(t);
-      case '\\':
-        char[] buffer;
-        do
-        {
-          bool isBinary;
-          c = scanEscapeSequence(isBinary);
-          if (isascii(c) || isBinary)
-            buffer ~= c;
-          else
-            encodeUTF8(buffer, c);
-        } while (*p == '\\')
-        buffer ~= 0;
-        t.kind = TOK.String;
-        t.str = buffer;
-        t.end = p;
-        return;
-      case '>': /* >  >=  >>  >>=  >>>  >>>= */
-        c = *++p;
-        switch (c)
-        {
-        case '=':
-          t.kind = TOK.GreaterEqual;
-          goto Lcommon;
-        case '>':
-          if (p[1] == '>')
-          {
-            ++p;
-            if (p[1] == '=')
-            { ++p;
-              t.kind = TOK.URShiftAssign;
-            }
-            else
-              t.kind = TOK.URShift;
-          }
-          else if (p[1] == '=')
-          {
-            ++p;
-            t.kind = TOK.RShiftAssign;
-          }
-          else
-            t.kind = TOK.RShift;
-          goto Lcommon;
-        default:
-          t.kind = TOK.Greater;
-          goto Lcommon2;
-        }
-        assert(0);
-      case '<': /* <  <=  <>  <>=  <<  <<= */
-        c = *++p;
-        switch (c)
-        {
-        case '=':
-          t.kind = TOK.LessEqual;
-          goto Lcommon;
-        case '<':
-          if (p[1] == '=') {
-            ++p;
-            t.kind = TOK.LShiftAssign;
-          }
-          else
-            t.kind = TOK.LShift;
-          goto Lcommon;
-        case '>':
-          if (p[1] == '=') {
-            ++p;
-            t.kind = TOK.LorEorG;
-          }
-          else
-            t.kind = TOK.LorG;
-          goto Lcommon;
-        default:
-          t.kind = TOK.Less;
-          goto Lcommon2;
-        }
-        assert(0);
-      case '!': /* !  !<  !>  !<=  !>=  !<>  !<>= */
-        c = *++p;
-        switch (c)
-        {
-        case '<':
-          c = *++p;
-          if (c == '>')
-          {
-            if (p[1] == '=') {
-              ++p;
-              t.kind = TOK.Unordered;
-            }
-            else
-              t.kind = TOK.UorE;
-          }
-          else if (c == '=')
-          {
-            t.kind = TOK.UorG;
-          }
-          else {
-            t.kind = TOK.UorGorE;
-            goto Lcommon2;
-          }
-          goto Lcommon;
-        case '>':
-          if (p[1] == '=')
-          {
-            ++p;
-            t.kind = TOK.UorL;
-          }
-          else
-            t.kind = TOK.UorLorE;
-          goto Lcommon;
-        case '=':
-          t.kind = TOK.NotEqual;
-          goto Lcommon;
-        default:
-          t.kind = TOK.Not;
-          goto Lcommon2;
-        }
-        assert(0);
-      case '.': /* .  .[0-9]  ..  ... */
-        if (p[1] == '.')
-        {
-          ++p;
-          if (p[1] == '.') {
-            ++p;
-            t.kind = TOK.Ellipses;
-          }
-          else
-            t.kind = TOK.Slice;
-        }
-        else if (isdigit(p[1]))
-        {
-          return scanReal(t);
-        }
-        else
-          t.kind = TOK.Dot;
-        goto Lcommon;
-      case '|': /* |  ||  |= */
-        c = *++p;
-        if (c == '=')
-          t.kind = TOK.OrAssign;
-        else if (c == '|')
-          t.kind = TOK.OrLogical;
-        else {
-          t.kind = TOK.OrBinary;
-          goto Lcommon2;
-        }
-        goto Lcommon;
-      case '&': /* &  &&  &= */
-        c = *++p;
-        if (c == '=')
-          t.kind = TOK.AndAssign;
-        else if (c == '&')
-          t.kind = TOK.AndLogical;
-        else {
-          t.kind = TOK.AndBinary;
-          goto Lcommon2;
-        }
-        goto Lcommon;
-      case '+': /* +  ++  += */
-        c = *++p;
-        if (c == '=')
-          t.kind = TOK.PlusAssign;
-        else if (c == '+')
-          t.kind = TOK.PlusPlus;
-        else {
-          t.kind = TOK.Plus;
-          goto Lcommon2;
-        }
-        goto Lcommon;
-      case '-': /* -  --  -= */
-        c = *++p;
-        if (c == '=')
-          t.kind = TOK.MinusAssign;
-        else if (c == '-')
-          t.kind = TOK.MinusMinus;
-        else {
-          t.kind = TOK.Minus;
-          goto Lcommon2;
-        }
-        goto Lcommon;
-      case '=': /* =  == */
-        if (p[1] == '=') {
-          ++p;
-          t.kind = TOK.Equal;
-        }
-        else
-          t.kind = TOK.Assign;
-        goto Lcommon;
-      case '~': /* ~  ~= */
-         if (p[1] == '=') {
-           ++p;
-           t.kind = TOK.CatAssign;
-         }
-         else
-           t.kind = TOK.Tilde;
-         goto Lcommon;
-      case '*': /* *  *= */
-         if (p[1] == '=') {
-           ++p;
-           t.kind = TOK.MulAssign;
-         }
-         else
-           t.kind = TOK.Mul;
-         goto Lcommon;
-      case '^': /* ^  ^= */
-         if (p[1] == '=') {
-           ++p;
-           t.kind = TOK.XorAssign;
-         }
-         else
-           t.kind = TOK.Xor;
-         goto Lcommon;
-      case '%': /* %  %= */
-         if (p[1] == '=') {
-           ++p;
-           t.kind = TOK.ModAssign;
-         }
-         else
-           t.kind = TOK.Mod;
-         goto Lcommon;
-      // Single character tokens:
-      case '(':
-        t.kind = TOK.LParen;
-        goto Lcommon;
-      case ')':
-        t.kind = TOK.RParen;
-        goto Lcommon;
-      case '[':
-        t.kind = TOK.LBracket;
-        goto Lcommon;
-      case ']':
-        t.kind = TOK.RBracket;
-        goto Lcommon;
-      case '{':
-        t.kind = TOK.LBrace;
-        goto Lcommon;
-      case '}':
-        t.kind = TOK.RBrace;
-        goto Lcommon;
-      case ':':
-        t.kind = TOK.Colon;
-        goto Lcommon;
-      case ';':
-        t.kind = TOK.Semicolon;
-        goto Lcommon;
-      case '?':
-        t.kind = TOK.Question;
-        goto Lcommon;
-      case ',':
-        t.kind = TOK.Comma;
-        goto Lcommon;
-      case '$':
-        t.kind = TOK.Dollar;
-      Lcommon:
-        ++p;
-      Lcommon2:
-        t.end = p;
-        return;
-      case '#':
-        return scanSpecialTokenSequence(t);
-      default:
-      }
-
-      // Check for EOF
-      if (isEOF(c))
-      {
-        assert(isEOF(*p), ""~*p);
-        t.kind = TOK.EOF;
-        t.end = p;
-        tail = &t;
-        assert(t.start == t.end);
-        return;
-      }
-
-      if (!isascii(c))
-      {
-        c = decodeUTF8();
-        if (isUniAlpha(c))
-          goto Lidentifier;
-      }
-
-      error(t.start, MID.IllegalCharacter, cast(dchar)c);
-
-      ++p;
-      t.kind = TOK.Illegal;
-      t.setWhitespaceFlag();
-      t.dchar_ = c;
-      t.end = p;
-      return;
-    }
-  }
-
-  /// Converts a string literal to an integer.
-  template toUint(char[] T)
-  {
-    static assert(0 < T.length && T.length <= 4);
-    static if (T.length == 1)
-      const uint toUint = T[0];
-    else
-      const uint toUint = (T[0] << ((T.length-1)*8)) | toUint!(T[1..$]);
-  }
-  static assert(toUint!("\xAA\xBB\xCC\xDD") == 0xAABBCCDD);
-
-  /// Constructs case statements. E.g.:
-  /// ---
-  //// // case_!("<", "Less", "Lcommon") ->
-  /// case 60u:
-  ///   t.kind = TOK.Less;
-  ///   goto Lcommon;
-  /// ---
-  /// Note:Can't use this yet due to a $(DMDBUG 1534, bug) in DMD.
-  template case_(char[] str, char[] kind, char[] label)
-  {
-    const char[] case_ =
-      `case `~toUint!(str).stringof~`:`
-        `t.kind = TOK.`~kind~`;`
-        `goto `~label~`;`;
-  }
-  //pragma(msg, case_!("<", "Less", "Lcommon"));
-
-  template case_L4(char[] str, TOK kind)
-  {
-    const char[] case_L4 = case_!(str, kind, "Lcommon_4");
-  }
-
-  template case_L3(char[] str, TOK kind)
-  {
-    const char[] case_L3 = case_!(str, kind, "Lcommon_3");
-  }
-
-  template case_L2(char[] str, TOK kind)
-  {
-    const char[] case_L2 = case_!(str, kind, "Lcommon_2");
-  }
-
-  template case_L1(char[] str, TOK kind)
-  {
-    const char[] case_L3 = case_!(str, kind, "Lcommon");
-  }
-
-  /// An alternative scan method.
-  /// Profiling shows it's a bit slower.
-  public void scan_(ref Token t)
-  in
-  {
-    assert(text.ptr <= p && p < end);
-  }
-  out
-  {
-    assert(text.ptr <= t.start && t.start < end, Token.toString(t.kind));
-    assert(text.ptr <= t.end && t.end <= end, Token.toString(t.kind));
-  }
-  body
-  {
-    // Scan whitespace.
-    if (isspace(*p))
-    {
-      t.ws = p;
-      while (isspace(*++p))
-      {}
-    }
-
-    // Scan a token.
-    t.start = p;
-    // Newline.
-    switch (*p)
-    {
-    case '\r':
-      if (p[1] == '\n')
-        ++p;
-    case '\n':
-      assert(isNewlineEnd(p));
-      ++p;
-      ++lineNum;
-      setLineBegin(p);
-//       this.newline = &t;
-      t.kind = TOK.Newline;
-      t.setWhitespaceFlag();
-      t.newline.filePaths = this.filePaths;
-      t.newline.oriLineNum = lineNum;
-      t.newline.setLineNum = lineNum_hline;
-      t.end = p;
-      return;
-    default:
-      if (isUnicodeNewline(p))
-      {
-        ++p; ++p;
-        goto case '\n';
-      }
-    }
-
-    uint c = *p;
-    assert(end - p != 0);
-    switch (end - p)
-    {
-    case 1:
-      goto L1character;
-    case 2:
-      c <<= 8; c |= p[1];
-      goto L2characters;
-    case 3:
-      c <<= 8; c |= p[1]; c <<= 8; c |= p[2];
-      goto L3characters;
-    default:
-      version(BigEndian)
-        c = *cast(uint*)p;
-      else
-      {
-        c <<= 8; c |= p[1]; c <<= 8; c |= p[2]; c <<= 8; c |= p[3];
-        /+
-        c = *cast(uint*)p;
-        asm
-        {
-          mov EDX, c;
-          bswap EDX;
-          mov c, EDX;
-        }
-        +/
-      }
-    }
-
-    // 4 character tokens.
-    switch (c)
-    {
-    case toUint!(">>>="):
-      t.kind = TOK.RShiftAssign;
-      goto Lcommon_4;
-    case toUint!("!<>="):
-      t.kind = TOK.Unordered;
-    Lcommon_4:
-      p += 4;
-      t.end = p;
-      return;
-    default:
-    }
-
-    c >>>= 8;
-  L3characters:
-    assert(p == t.start);
-    // 3 character tokens.
-    switch (c)
-    {
-    case toUint!(">>="):
-      t.kind = TOK.RShiftAssign;
-      goto Lcommon_3;
-    case toUint!(">>>"):
-      t.kind = TOK.URShift;
-      goto Lcommon_3;
-    case toUint!("<>="):
-      t.kind = TOK.LorEorG;
-      goto Lcommon_3;
-    case toUint!("<<="):
-      t.kind = TOK.LShiftAssign;
-      goto Lcommon_3;
-    case toUint!("!<="):
-      t.kind = TOK.UorG;
-      goto Lcommon_3;
-    case toUint!("!>="):
-      t.kind = TOK.UorL;
-      goto Lcommon_3;
-    case toUint!("!<>"):
-      t.kind = TOK.UorE;
-      goto Lcommon_3;
-    case toUint!("..."):
-      t.kind = TOK.Ellipses;
-    Lcommon_3:
-      p += 3;
-      t.end = p;
-      return;
-    default:
-    }
-
-    c >>>= 8;
-  L2characters:
-    assert(p == t.start);
-    // 2 character tokens.
-    switch (c)
-    {
-    case toUint!("/+"):
-      ++p; // Skip /
-      return scanNestedComment(t);
-    case toUint!("/*"):
-      ++p; // Skip /
-      return scanBlockComment(t);
-    case toUint!("//"):
-      ++p; // Skip /
-      assert(*p == '/');
-      while (!isEndOfLine(++p))
-        isascii(*p) || decodeUTF8();
-      t.kind = TOK.Comment;
-      t.setWhitespaceFlag();
-      t.end = p;
-      return;
-    case toUint!(">="):
-      t.kind = TOK.GreaterEqual;
-      goto Lcommon_2;
-    case toUint!(">>"):
-      t.kind = TOK.RShift;
-      goto Lcommon_2;
-    case toUint!("<<"):
-      t.kind = TOK.LShift;
-      goto Lcommon_2;
-    case toUint!("<="):
-      t.kind = TOK.LessEqual;
-      goto Lcommon_2;
-    case toUint!("<>"):
-      t.kind = TOK.LorG;
-      goto Lcommon_2;
-    case toUint!("!<"):
-      t.kind = TOK.UorGorE;
-      goto Lcommon_2;
-    case toUint!("!>"):
-      t.kind = TOK.UorLorE;
-      goto Lcommon_2;
-    case toUint!("!="):
-      t.kind = TOK.NotEqual;
-      goto Lcommon_2;
-    case toUint!(".."):
-      t.kind = TOK.Slice;
-      goto Lcommon_2;
-    case toUint!("&&"):
-      t.kind = TOK.AndLogical;
-      goto Lcommon_2;
-    case toUint!("&="):
-      t.kind = TOK.AndAssign;
-      goto Lcommon_2;
-    case toUint!("||"):
-      t.kind = TOK.OrLogical;
-      goto Lcommon_2;
-    case toUint!("|="):
-      t.kind = TOK.OrAssign;
-      goto Lcommon_2;
-    case toUint!("++"):
-      t.kind = TOK.PlusPlus;
-      goto Lcommon_2;
-    case toUint!("+="):
-      t.kind = TOK.PlusAssign;
-      goto Lcommon_2;
-    case toUint!("--"):
-      t.kind = TOK.MinusMinus;
-      goto Lcommon_2;
-    case toUint!("-="):
-      t.kind = TOK.MinusAssign;
-      goto Lcommon_2;
-    case toUint!("=="):
-      t.kind = TOK.Equal;
-      goto Lcommon_2;
-    case toUint!("~="):
-      t.kind = TOK.CatAssign;
-      goto Lcommon_2;
-    case toUint!("*="):
-      t.kind = TOK.MulAssign;
-      goto Lcommon_2;
-    case toUint!("/="):
-      t.kind = TOK.DivAssign;
-      goto Lcommon_2;
-    case toUint!("^="):
-      t.kind = TOK.XorAssign;
-      goto Lcommon_2;
-    case toUint!("%="):
-      t.kind = TOK.ModAssign;
-    Lcommon_2:
-      p += 2;
-      t.end = p;
-      return;
-    default:
-    }
-
-    c >>>= 8;
-  L1character:
-    assert(p == t.start);
-    assert(*p == c, Format("p={0},c={1}", *p, cast(dchar)c));
-    // 1 character tokens.
-    // TODO: consider storing the token type in ptable.
-    switch (c)
-    {
-    case '\'':
-      return scanCharacterLiteral(t);
-    case '`':
-      return scanRawStringLiteral(t);
-    case '"':
-      return scanNormalStringLiteral(t);
-    case '\\':
-      char[] buffer;
-      do
-      {
-        bool isBinary;
-        c = scanEscapeSequence(isBinary);
-        if (isascii(c) || isBinary)
-          buffer ~= c;
-        else
-          encodeUTF8(buffer, c);
-      } while (*p == '\\')
-      buffer ~= 0;
-      t.kind = TOK.String;
-      t.str = buffer;
-      t.end = p;
-      return;
-    case '<':
-      t.kind = TOK.Greater;
-      goto Lcommon;
-    case '>':
-      t.kind = TOK.Less;
-      goto Lcommon;
-    case '^':
-      t.kind = TOK.Xor;
-      goto Lcommon;
-    case '!':
-      t.kind = TOK.Not;
-      goto Lcommon;
-    case '.':
-      if (isdigit(p[1]))
-        return scanReal(t);
-      t.kind = TOK.Dot;
-      goto Lcommon;
-    case '&':
-      t.kind = TOK.AndBinary;
-      goto Lcommon;
-    case '|':
-      t.kind = TOK.OrBinary;
-      goto Lcommon;
-    case '+':
-      t.kind = TOK.Plus;
-      goto Lcommon;
-    case '-':
-      t.kind = TOK.Minus;
-      goto Lcommon;
-    case '=':
-      t.kind = TOK.Assign;
-      goto Lcommon;
-    case '~':
-      t.kind = TOK.Tilde;
-      goto Lcommon;
-    case '*':
-      t.kind = TOK.Mul;
-      goto Lcommon;
-    case '/':
-      t.kind = TOK.Div;
-      goto Lcommon;
-    case '%':
-      t.kind = TOK.Mod;
-      goto Lcommon;
-    case '(':
-      t.kind = TOK.LParen;
-      goto Lcommon;
-    case ')':
-      t.kind = TOK.RParen;
-      goto Lcommon;
-    case '[':
-      t.kind = TOK.LBracket;
-      goto Lcommon;
-    case ']':
-      t.kind = TOK.RBracket;
-      goto Lcommon;
-    case '{':
-      t.kind = TOK.LBrace;
-      goto Lcommon;
-    case '}':
-      t.kind = TOK.RBrace;
-      goto Lcommon;
-    case ':':
-      t.kind = TOK.Colon;
-      goto Lcommon;
-    case ';':
-      t.kind = TOK.Semicolon;
-      goto Lcommon;
-    case '?':
-      t.kind = TOK.Question;
-      goto Lcommon;
-    case ',':
-      t.kind = TOK.Comma;
-      goto Lcommon;
-    case '$':
-      t.kind = TOK.Dollar;
-    Lcommon:
-      ++p;
-      t.end = p;
-      return;
-    case '#':
-      return scanSpecialTokenSequence(t);
-    default:
-    }
-
-    assert(p == t.start);
-    assert(*p == c);
-
-    // TODO: consider moving isidbeg() and isdigit() up.
-    if (isidbeg(c))
-    {
-      if (c == 'r' && p[1] == '"' && ++p)
-        return scanRawStringLiteral(t);
-      if (c == 'x' && p[1] == '"')
-        return scanHexStringLiteral(t);
-    version(D2)
-    {
-      if (c == 'q' && p[1] == '"')
-        return scanDelimitedStringLiteral(t);
-      if (c == 'q' && p[1] == '{')
-        return scanTokenStringLiteral(t);
-    }
-      // Scan identifier.
-    Lidentifier:
-      do
-      { c = *++p; }
-      while (isident(c) || !isascii(c) && isUnicodeAlpha())
-
-      t.end = p;
-
-      auto id = IdTable.lookup(t.srcText);
-      t.kind = id.kind;
-      t.ident = id;
-
-      if (t.kind == TOK.Identifier || t.isKeyword)
-        return;
-      else if (t.isSpecialToken)
-        finalizeSpecialToken(t);
-      else if (t.kind == TOK.EOF)
-      {
-        tail = &t;
-        assert(t.srcText == "__EOF__");
-      }
-      else
-        assert(0, "unexpected token type: " ~ Token.toString(t.kind));
-      return;
-    }
-
-    if (isdigit(c))
-      return scanNumber(t);
-
-    // Check for EOF
-    if (isEOF(c))
-    {
-      assert(isEOF(*p), *p~"");
-      t.kind = TOK.EOF;
-      t.end = p;
-      tail = &t;
-      assert(t.start == t.end);
-      return;
-    }
-
-    if (!isascii(c))
-    {
-      c = decodeUTF8();
-      if (isUniAlpha(c))
-        goto Lidentifier;
-    }
-
-    error(t.start, MID.IllegalCharacter, cast(dchar)c);
-
-    ++p;
-    t.kind = TOK.Illegal;
-    t.setWhitespaceFlag();
-    t.dchar_ = c;
-    t.end = p;
-    return;
-  }
-
-  /// Scans a block comment.
-  ///
-  /// BlockComment := "/*" AnyChar* "*/"
-  void scanBlockComment(ref Token t)
-  {
-    assert(p[-1] == '/' && *p == '*');
-    auto tokenLineNum = lineNum;
-    auto tokenLineBegin = lineBegin;
-  Loop:
-    while (1)
-    {
-      switch (*++p)
-      {
-      case '*':
-        if (p[1] != '/')
-          continue;
-        p += 2;
-        break Loop;
-      case '\r':
-        if (p[1] == '\n')
-          ++p;
-      case '\n':
-        assert(isNewlineEnd(p));
-        ++lineNum;
-        setLineBegin(p+1);
-        break;
-      default:
-        if (!isascii(*p))
-        {
-          if (isUnicodeNewlineChar(decodeUTF8()))
-            goto case '\n';
-        }
-        else if (isEOF(*p))
-        {
-          error(tokenLineNum, tokenLineBegin, t.start, MID.UnterminatedBlockComment);
-          break Loop;
-        }
-      }
-    }
-    t.kind = TOK.Comment;
-    t.setWhitespaceFlag();
-    t.end = p;
-    return;
-  }
-
-  /// Scans a nested comment.
-  ///
-  /// NestedComment := "/+" (AnyChar* | NestedComment) "+/"
-  void scanNestedComment(ref Token t)
-  {
-    assert(p[-1] == '/' && *p == '+');
-    auto tokenLineNum = lineNum;
-    auto tokenLineBegin = lineBegin;
-    uint level = 1;
-  Loop:
-    while (1)
-    {
-      switch (*++p)
-      {
-      case '/':
-        if (p[1] == '+')
-          ++p, ++level;
-        continue;
-      case '+':
-        if (p[1] != '/')
-          continue;
-        ++p;
-        if (--level != 0)
-          continue;
-        ++p;
-        break Loop;
-      case '\r':
-        if (p[1] == '\n')
-          ++p;
-      case '\n':
-        assert(isNewlineEnd(p));
-        ++lineNum;
-        setLineBegin(p+1);
-        continue;
-      default:
-        if (!isascii(*p))
-        {
-          if (isUnicodeNewlineChar(decodeUTF8()))
-            goto case '\n';
-        }
-        else if (isEOF(*p))
-        {
-          error(tokenLineNum, tokenLineBegin, t.start, MID.UnterminatedNestedComment);
-          break Loop;
-        }
-      }
-    }
-    t.kind = TOK.Comment;
-    t.setWhitespaceFlag();
-    t.end = p;
-    return;
-  }
-
-  /// Scans the postfix character of a string literal.
-  ///
-  /// PostfixChar := "c" | "w" | "d"
-  char scanPostfix()
-  {
-    assert(p[-1] == '"' || p[-1] == '`' ||
-      { version(D2) return p[-1] == '}';
-               else return 0; }()
-    );
-    switch (*p)
-    {
-    case 'c':
-    case 'w':
-    case 'd':
-      return *p++;
-    default:
-      return 0;
-    }
-    assert(0);
-  }
-
-  /// Scans a normal string literal.
-  ///
-  /// NormalStringLiteral := "\"" Char* "\""
-  void scanNormalStringLiteral(ref Token t)
-  {
-    assert(*p == '"');
-    auto tokenLineNum = lineNum;
-    auto tokenLineBegin = lineBegin;
-    t.kind = TOK.String;
-    char[] buffer;
-    uint c;
-    while (1)
-    {
-      c = *++p;
-      switch (c)
-      {
-      case '"':
-        ++p;
-        t.pf = scanPostfix();
-      Lreturn:
-        t.str = buffer ~ '\0';
-        t.end = p;
-        return;
-      case '\\':
-        bool isBinary;
-        c = scanEscapeSequence(isBinary);
-        --p;
-        if (isascii(c) || isBinary)
-          buffer ~= c;
-        else
-          encodeUTF8(buffer, c);
-        continue;
-      case '\r':
-        if (p[1] == '\n')
-          ++p;
-      case '\n':
-        assert(isNewlineEnd(p));
-        c = '\n'; // Convert Newline to \n.
-        ++lineNum;
-        setLineBegin(p+1);
-        break;
-      case 0, _Z_:
-        error(tokenLineNum, tokenLineBegin, t.start, MID.UnterminatedString);
-        goto Lreturn;
-      default:
-        if (!isascii(c))
-        {
-          c = decodeUTF8();
-          if (isUnicodeNewlineChar(c))
-            goto case '\n';
-          encodeUTF8(buffer, c);
-          continue;
-        }
-      }
-      assert(isascii(c));
-      buffer ~= c;
-    }
-    assert(0);
-  }
-
-  /// Scans a character literal.
-  ///
-  /// CharLiteral := "'" Char "'"
-  void scanCharacterLiteral(ref Token t)
-  {
-    assert(*p == '\'');
-    ++p;
-    t.kind = TOK.CharLiteral;
-    switch (*p)
-    {
-    case '\\':
-      bool notused;
-      t.dchar_ = scanEscapeSequence(notused);
-      break;
-    case '\'':
-      error(t.start, MID.EmptyCharacterLiteral);
-      break;
-    default:
-      if (isEndOfLine(p))
-        break;
-      uint c = *p;
-      if (!isascii(c))
-        c = decodeUTF8();
-      t.dchar_ = c;
-      ++p;
-    }
-
-    if (*p == '\'')
-      ++p;
-    else
-      error(t.start, MID.UnterminatedCharacterLiteral);
-    t.end = p;
-  }
-
-  /// Scans a raw string literal.
-  ///
-  /// RawStringLiteral := "r\"" AnyChar* "\"" | "`" AnyChar* "`"
-  void scanRawStringLiteral(ref Token t)
-  {
-    assert(*p == '`' || *p == '"' && p[-1] == 'r');
-    auto tokenLineNum = lineNum;
-    auto tokenLineBegin = lineBegin;
-    t.kind = TOK.String;
-    uint delim = *p;
-    char[] buffer;
-    uint c;
-    while (1)
-    {
-      c = *++p;
-      switch (c)
-      {
-      case '\r':
-        if (p[1] == '\n')
-          ++p;
-      case '\n':
-        assert(isNewlineEnd(p));
-        c = '\n'; // Convert Newline to '\n'.
-        ++lineNum;
-        setLineBegin(p+1);
-        break;
-      case '`':
-      case '"':
-        if (c == delim)
-        {
-          ++p;
-          t.pf = scanPostfix();
-        Lreturn:
-          t.str = buffer ~ '\0';
-          t.end = p;
-          return;
-        }
-        break;
-      case 0, _Z_:
-        error(tokenLineNum, tokenLineBegin, t.start,
-          delim == 'r' ? MID.UnterminatedRawString : MID.UnterminatedBackQuoteString);
-        goto Lreturn;
-      default:
-        if (!isascii(c))
-        {
-          c = decodeUTF8();
-          if (isUnicodeNewlineChar(c))
-            goto case '\n';
-          encodeUTF8(buffer, c);
-          continue;
-        }
-      }
-      assert(isascii(c));
-      buffer ~= c;
-    }
-    assert(0);
-  }
-
-  /// Scans a hexadecimal string literal.
-  ///
-  /// HexStringLiteral := "x\"" (HexChar HexChar)* "\""
-  void scanHexStringLiteral(ref Token t)
-  {
-    assert(p[0] == 'x' && p[1] == '"');
-    t.kind = TOK.String;
-
-    auto tokenLineNum = lineNum;
-    auto tokenLineBegin = lineBegin;
-
-    uint c;
-    ubyte[] buffer;
-    ubyte h; // hex number
-    uint n; // number of hex digits
-
-    ++p;
-    assert(*p == '"');
-    while (1)
-    {
-      c = *++p;
-      switch (c)
-      {
-      case '"':
-        if (n & 1)
-          error(tokenLineNum, tokenLineBegin, t.start, MID.OddNumberOfDigitsInHexString);
-        ++p;
-        t.pf = scanPostfix();
-      Lreturn:
-        t.str = cast(string) (buffer ~= 0);
-        t.end = p;
-        return;
-      case '\r':
-        if (p[1] == '\n')
-          ++p;
-      case '\n':
-        assert(isNewlineEnd(p));
-        ++lineNum;
-        setLineBegin(p+1);
-        continue;
-      default:
-        if (ishexad(c))
-        {
-          if (c <= '9')
-            c -= '0';
-          else if (c <= 'F')
-            c -= 'A' - 10;
-          else
-            c -= 'a' - 10;
-
-          if (n & 1)
-          {
-            h <<= 4;
-            h |= c;
-            buffer ~= h;
-          }
-          else
-            h = cast(ubyte)c;
-          ++n;
-          continue;
-        }
-        else if (isspace(c))
-          continue; // Skip spaces.
-        else if (isEOF(c))
-        {
-          error(tokenLineNum, tokenLineBegin, t.start, MID.UnterminatedHexString);
-          t.pf = 0;
-          goto Lreturn;
-        }
-        else
-        {
-          auto errorAt = p;
-          if (!isascii(c))
-          {
-            c = decodeUTF8();
-            if (isUnicodeNewlineChar(c))
-              goto case '\n';
-          }
-          error(errorAt, MID.NonHexCharInHexString, cast(dchar)c);
-        }
-      }
-    }
-    assert(0);
-  }
-
-version(DDoc)
-{
-  /// Scans a delimited string literal.
-  void scanDelimitedStringLiteral(ref Token t);
-  /// Scans a token string literal.
-  ///
-  /// TokenStringLiteral := "q{" Token* "}"
-  void scanTokenStringLiteral(ref Token t);
-}
-else
-version(D2)
-{
-  void scanDelimitedStringLiteral(ref Token t)
-  {
-    assert(p[0] == 'q' && p[1] == '"');
-    t.kind = TOK.String;
-
-    auto tokenLineNum = lineNum;
-    auto tokenLineBegin = lineBegin;
-
-    char[] buffer;
-    dchar opening_delim = 0, // 0 if no nested delimiter or '[', '(', '<', '{'
-          closing_delim; // Will be ']', ')', '>', '},
-                         // the first character of an identifier or
-                         // any other Unicode/ASCII character.
-    char[] str_delim; // Identifier delimiter.
-    uint level = 1; // Counter for nestable delimiters.
-
-    ++p; ++p; // Skip q"
-    uint c = *p;
-    switch (c)
-    {
-    case '(':
-      opening_delim = c;
-      closing_delim = ')'; // c + 1
-      break;
-    case '[', '<', '{':
-      opening_delim = c;
-      closing_delim = c + 2; // Get to closing counterpart. Feature of ASCII table.
-      break;
-    default:
-      dchar scanNewline()
-      {
-        switch (*p)
-        {
-        case '\r':
-          if (p[1] == '\n')
-            ++p;
-        case '\n':
-          assert(isNewlineEnd(p));
-          ++p;
-          ++lineNum;
-          setLineBegin(p);
-          return '\n';
-        default:
-          if (isUnicodeNewline(p))
-          {
-            ++p; ++p;
-            goto case '\n';
-          }
-        }
-        return 0;
-      }
-      // Skip leading newlines:
-      while (scanNewline() != 0)
-      {}
-      assert(!isNewline(p));
-
-      char* begin = p;
-      c = *p;
-      closing_delim = c;
-      // TODO: Check for non-printable characters?
-      if (!isascii(c))
-      {
-        closing_delim = decodeUTF8();
-        if (!isUniAlpha(closing_delim))
-          break; // Not an identifier.
-      }
-      else if (!isidbeg(c))
-        break; // Not an identifier.
-
-      // Parse Identifier + EndOfLine
-      do
-      { c = *++p; }
-      while (isident(c) || !isascii(c) && isUnicodeAlpha())
-      // Store identifier
-      str_delim = begin[0..p-begin];
-      // Scan newline
-      if (scanNewline() == '\n')
-        --p; // Go back one because of "c = *++p;" in main loop.
-      else
-      {
-        // TODO: error(p, MID.ExpectedNewlineAfterIdentDelim);
-      }
-    }
-
-    bool checkStringDelim(char* p)
-    {
-      assert(str_delim.length != 0);
-      if (buffer[$-1] == '\n' && // Last character copied to buffer must be '\n'.
-          end-p >= str_delim.length && // Check remaining length.
-          p[0..str_delim.length] == str_delim) // Compare.
-        return true;
-      return false;
-    }
-
-    while (1)
-    {
-      c = *++p;
-      switch (c)
-      {
-      case '\r':
-        if (p[1] == '\n')
-          ++p;
-      case '\n':
-        assert(isNewlineEnd(p));
-        c = '\n'; // Convert Newline to '\n'.
-        ++lineNum;
-        setLineBegin(p+1);
-        break;
-      case 0, _Z_:
-        // TODO: error(tokenLineNum, tokenLineBegin, t.start, MID.UnterminatedDelimitedString);
-        goto Lreturn3;
-      default:
-        if (!isascii(c))
-        {
-          auto begin = p;
-          c = decodeUTF8();
-          if (isUnicodeNewlineChar(c))
-            goto case '\n';
-          if (c == closing_delim)
-          {
-            if (str_delim.length)
-            {
-              if (checkStringDelim(begin))
-              {
-                p = begin + str_delim.length;
-                goto Lreturn2;
-              }
-            }
-            else
-            {
-              assert(level == 1);
-              --level;
-              goto Lreturn;
-            }
-          }
-          encodeUTF8(buffer, c);
-          continue;
-        }
-        else
-        {
-          if (c == opening_delim)
-            ++level;
-          else if (c == closing_delim)
-          {
-            if (str_delim.length)
-            {
-              if (checkStringDelim(p))
-              {
-                p += str_delim.length;
-                goto Lreturn2;
-              }
-            }
-            else if (--level == 0)
-              goto Lreturn;
-          }
-        }
-      }
-      assert(isascii(c));
-      buffer ~= c;
-    }
-  Lreturn: // Character delimiter.
-    assert(c == closing_delim);
-    assert(level == 0);
-    ++p; // Skip closing delimiter.
-  Lreturn2: // String delimiter.
-    if (*p == '"')
-      ++p;
-    else
-    {
-      // TODO: error(p, MID.ExpectedDblQuoteAfterDelim, str_delim.length ? str_delim : closing_delim~"");
-    }
-
-    t.pf = scanPostfix();
-  Lreturn3: // Error.
-    t.str = buffer ~ '\0';
-    t.end = p;
-  }
-
-  void scanTokenStringLiteral(ref Token t)
-  {
-    assert(p[0] == 'q' && p[1] == '{');
-    t.kind = TOK.String;
-
-    auto tokenLineNum = lineNum;
-    auto tokenLineBegin = lineBegin;
-
-    // A guard against changes to particular members:
-    // this.lineNum_hline and this.errorPath
-    ++inTokenString;
-
-    uint lineNum = this.lineNum;
-    uint level = 1;
-
-    ++p; ++p; // Skip q{
-
-    auto prev_t = &t;
-    Token* token;
-    while (1)
-    {
-      token = new Token;
-      scan(*token);
-      // Save the tokens in a doubly linked list.
-      // Could be useful for various tools.
-      token.prev = prev_t;
-      prev_t.next = token;
-      prev_t = token;
-      switch (token.kind)
-      {
-      case TOK.LBrace:
-        ++level;
-        continue;
-      case TOK.RBrace:
-        if (--level == 0)
-        {
-          t.tok_str = t.next;
-          t.next = null;
-          break;
-        }
-        continue;
-      case TOK.EOF:
-        // TODO: error(tokenLineNum, tokenLineBegin, t.start, MID.UnterminatedTokenString);
-        t.tok_str = t.next;
-        t.next = token;
-        break;
-      default:
-        continue;
-      }
-      break; // Exit loop.
-    }
-
-    assert(token.kind == TOK.RBrace || token.kind == TOK.EOF);
-    assert(token.kind == TOK.RBrace && t.next is null ||
-           token.kind == TOK.EOF && t.next !is null);
-
-    char[] buffer;
-    // token points to } or EOF
-    if (token.kind == TOK.EOF)
-    {
-      t.end = token.start;
-      buffer = t.srcText[2..$].dup ~ '\0';
-    }
-    else
-    {
-      // Assign to buffer before scanPostfix().
-      t.end = p;
-      buffer = t.srcText[2..$-1].dup ~ '\0';
-      t.pf = scanPostfix();
-      t.end = p; // Assign again because of postfix.
-    }
-    // Convert newlines to '\n'.
-    if (lineNum != this.lineNum)
-    {
-      assert(buffer[$-1] == '\0');
-      uint i, j;
-      for (; i < buffer.length; ++i)
-        switch (buffer[i])
-        {
-        case '\r':
-          if (buffer[i+1] == '\n')
-            ++i;
-        case '\n':
-          assert(isNewlineEnd(buffer.ptr + i));
-          buffer[j++] = '\n'; // Convert Newline to '\n'.
-          break;
-        default:
-          if (isUnicodeNewline(buffer.ptr + i))
-          {
-            ++i; ++i;
-            goto case '\n';
-          }
-          buffer[j++] = buffer[i]; // Copy.
-        }
-      buffer.length = j; // Adjust length.
-    }
-    assert(buffer[$-1] == '\0');
-    t.str = buffer;
-
-    --inTokenString;
-  }
-} // version(D2)
-
-  /// Scans an escape sequence.
-  ///
-  /// EscapeSequence := "\" (Octal{1,3} | ("x" Hex{2}) |
-  ///                       ("u" Hex{4}) | ("U" Hex{8}) |
-  ///                       "'" | "\"" | "\\" | "?" | "a" |
-  ///                       "b" | "f" | "n" | "r" | "t" | "v")
-  /// Params:
-  ///   isBinary = set to true for octal and hexadecimal escapes.
-  /// Returns: the escape value.
-  dchar scanEscapeSequence(ref bool isBinary)
-  out(result)
-  { assert(isValidChar(result)); }
-  body
-  {
-    assert(*p == '\\');
-
-    auto sequenceStart = p; // Used for error reporting.
-
-    ++p;
-    uint c = char2ev(*p);
-    if (c)
-    {
-      ++p;
-      return c;
-    }
-
-    uint digits = 2;
-
-    switch (*p)
-    {
-    case 'x':
-      isBinary = true;
-    case_Unicode:
-      assert(c == 0);
-      assert(digits == 2 || digits == 4 || digits == 8);
-      while (1)
-      {
-        ++p;
-        if (ishexad(*p))
-        {
-          c *= 16;
-          if (*p <= '9')
-            c += *p - '0';
-          else if (*p <= 'F')
-            c += *p - 'A' + 10;
-          else
-            c += *p - 'a' + 10;
-
-          if (--digits == 0)
-          {
-            ++p;
-            if (isValidChar(c))
-              return c; // Return valid escape value.
-
-            error(sequenceStart, MID.InvalidUnicodeEscapeSequence,
-                  sequenceStart[0..p-sequenceStart]);
-            break;
-          }
-          continue;
-        }
-
-        error(sequenceStart, MID.InsufficientHexDigits,
-              sequenceStart[0..p-sequenceStart]);
-        break;
-      }
-      break;
-    case 'u':
-      digits = 4;
-      goto case_Unicode;
-    case 'U':
-      digits = 8;
-      goto case_Unicode;
-    default:
-      if (isoctal(*p))
-      {
-        isBinary = true;
-        assert(c == 0);
-        c += *p - '0';
-        ++p;
-        if (!isoctal(*p))
-          return c;
-        c *= 8;
-        c += *p - '0';
-        ++p;
-        if (!isoctal(*p))
-          return c;
-        c *= 8;
-        c += *p - '0';
-        ++p;
-        if (c > 0xFF)
-          error(sequenceStart, MSG.InvalidOctalEscapeSequence,
-                sequenceStart[0..p-sequenceStart]);
-        return c; // Return valid escape value.
-      }
-      else if(*p == '&')
-      {
-        if (isalpha(*++p))
-        {
-          auto begin = p;
-          while (isalnum(*++p))
-          {}
-
-          if (*p == ';')
-          {
-            // Pass entity excluding '&' and ';'.
-            c = entity2Unicode(begin[0..p - begin]);
-            ++p; // Skip ;
-            if (c != 0xFFFF)
-              return c; // Return valid escape value.
-            else
-              error(sequenceStart, MID.UndefinedHTMLEntity, sequenceStart[0 .. p - sequenceStart]);
-          }
-          else
-            error(sequenceStart, MID.UnterminatedHTMLEntity, sequenceStart[0 .. p - sequenceStart]);
-        }
-        else
-          error(sequenceStart, MID.InvalidBeginHTMLEntity);
-      }
-      else if (isEndOfLine(p))
-        error(sequenceStart, MID.UndefinedEscapeSequence,
-          isEOF(*p) ? `\EOF` : `\NewLine`);
-      else
-      {
-        char[] str = `\`;
-        if (isascii(c))
-          str ~= *p;
-        else
-          encodeUTF8(str, decodeUTF8());
-        ++p;
-        // TODO: check for unprintable character?
-        error(sequenceStart, MID.UndefinedEscapeSequence, str);
-      }
-    }
-    return REPLACEMENT_CHAR; // Error: return replacement character.
-  }
-
-  /// Scans a number literal.
-  ///
-  /// $(PRE
-  /// IntegerLiteral := (Dec|Hex|Bin|Oct)Suffix?
-  /// Dec := (0|[1-9][0-9_]*)
-  /// Hex := 0[xX][_]*[0-9a-zA-Z][0-9a-zA-Z_]*
-  /// Bin := 0[bB][_]*[01][01_]*
-  /// Oct := 0[0-7_]*
-  /// Suffix := (L[uU]?|[uU]L?)
-  /// )
-  /// Invalid: "0b_", "0x_", "._" etc.
-  void scanNumber(ref Token t)
-  {
-    ulong ulong_;
-    bool overflow;
-    bool isDecimal;
-    size_t digits;
-
-    if (*p != '0')
-      goto LscanInteger;
-    ++p; // skip zero
-    // check for xX bB ...
-    switch (*p)
-    {
-    case 'x','X':
-      goto LscanHex;
-    case 'b','B':
-      goto LscanBinary;
-    case 'L':
-      if (p[1] == 'i')
-        goto LscanReal; // 0Li
-      break; // 0L
-    case '.':
-      if (p[1] == '.')
-        break; // 0..
-      // 0.
-    case 'i','f','F', // Imaginary and float literal suffixes.
-         'e', 'E':    // Float exponent.
-      goto LscanReal;
-    default:
-      if (*p == '_')
-        goto LscanOctal; // 0_
-      else if (isdigit(*p))
-      {
-        if (*p == '8' || *p == '9')
-          goto Loctal_hasDecimalDigits; // 08 or 09
-        else
-          goto Loctal_enter_loop; // 0[0-7]
-      }
-    }
-
-    // Number 0
-    assert(p[-1] == '0');
-    assert(*p != '_' && !isdigit(*p));
-    assert(ulong_ == 0);
-    isDecimal = true;
-    goto Lfinalize;
-
-  LscanInteger:
-    assert(*p != 0 && isdigit(*p));
-    isDecimal = true;
-    goto Lenter_loop_int;
-    while (1)
-    {
-      if (*++p == '_')
-        continue;
-      if (!isdigit(*p))
-        break;
-    Lenter_loop_int:
-      if (ulong_ < ulong.max/10 || (ulong_ == ulong.max/10 && *p <= '5'))
-      {
-        ulong_ *= 10;
-        ulong_ += *p - '0';
-        continue;
-      }
-      // Overflow: skip following digits.
-      overflow = true;
-      while (isdigit(*++p)) {}
-      break;
-    }
-
-    // The number could be a float, so check overflow below.
-    switch (*p)
-    {
-    case '.':
-      if (p[1] != '.')
-        goto LscanReal;
-      break;
-    case 'L':
-      if (p[1] != 'i')
-        break;
-    case 'i', 'f', 'F', 'e', 'E':
-      goto LscanReal;
-    default:
-    }
-
-    if (overflow)
-      error(t.start, MID.OverflowDecimalNumber);
-
-    assert((isdigit(p[-1]) || p[-1] == '_') && !isdigit(*p) && *p != '_');
-    goto Lfinalize;
-
-  LscanHex:
-    assert(digits == 0);
-    assert(*p == 'x' || *p == 'X');
-    while (1)
-    {
-      if (*++p == '_')
-        continue;
-      if (!ishexad(*p))
-        break;
-      ++digits;
-      ulong_ *= 16;
-      if (*p <= '9')
-        ulong_ += *p - '0';
-      else if (*p <= 'F')
-        ulong_ += *p - 'A' + 10;
-      else
-        ulong_ += *p - 'a' + 10;
-    }
-
-    assert(ishexad(p[-1]) || p[-1] == '_' || p[-1] == 'x' || p[-1] == 'X');
-    assert(!ishexad(*p) && *p != '_');
-
-    switch (*p)
-    {
-    case '.':
-      if (p[1] == '.')
-        break;
-    case 'p', 'P':
-      return scanHexReal(t);
-    default:
-    }
-
-    if (digits == 0 || digits > 16)
-      error(t.start, digits == 0 ? MID.NoDigitsInHexNumber : MID.OverflowHexNumber);
-
-    goto Lfinalize;
-
-  LscanBinary:
-    assert(digits == 0);
-    assert(*p == 'b' || *p == 'B');
-    while (1)
-    {
-      if (*++p == '0')
-      {
-        ++digits;
-        ulong_ *= 2;
-      }
-      else if (*p == '1')
-      {
-        ++digits;
-        ulong_ *= 2;
-        ulong_ += *p - '0';
-      }
-      else if (*p == '_')
-        continue; 
-      else
-        break;
-    }
-
-    if (digits == 0 || digits > 64)
-      error(t.start, digits == 0 ? MID.NoDigitsInBinNumber : MID.OverflowBinaryNumber);
-
-    assert(p[-1] == '0' || p[-1] == '1' || p[-1] == '_' || p[-1] == 'b' || p[-1] == 'B', p[-1] ~ "");
-    assert( !(*p == '0' || *p == '1' || *p == '_') );
-    goto Lfinalize;
-
-  LscanOctal:
-    assert(*p == '_');
-    while (1)
-    {
-      if (*++p == '_')
-        continue;
-      if (!isoctal(*p))
-        break;
-    Loctal_enter_loop:
-      if (ulong_ < ulong.max/2 || (ulong_ == ulong.max/2 && *p <= '1'))
-      {
-        ulong_ *= 8;
-        ulong_ += *p - '0';
-        continue;
-      }
-      // Overflow: skip following digits.
-      overflow = true;
-      while (isoctal(*++p)) {}
-      break;
-    }
-
-    bool hasDecimalDigits;
-    if (isdigit(*p))
-    {
-    Loctal_hasDecimalDigits:
-      hasDecimalDigits = true;
-      while (isdigit(*++p)) {}
-    }
-
-    // The number could be a float, so check errors below.
-    switch (*p)
-    {
-    case '.':
-      if (p[1] != '.')
-        goto LscanReal;
-      break;
-    case 'L':
-      if (p[1] != 'i')
-        break;
-    case 'i', 'f', 'F', 'e', 'E':
-      goto LscanReal;
-    default:
-    }
-
-    if (hasDecimalDigits)
-      error(t.start, MID.OctalNumberHasDecimals);
-
-    if (overflow)
-      error(t.start, MID.OverflowOctalNumber);
-//     goto Lfinalize;
-
-  Lfinalize:
-    enum Suffix
-    {
-      None     = 0,
-      Unsigned = 1,
-      Long     = 2
-    }
-
-    // Scan optional suffix: L, Lu, LU, u, uL, U or UL.
-    Suffix suffix;
-    while (1)
-    {
-      switch (*p)
-      {
-      case 'L':
-        if (suffix & Suffix.Long)
-          break;
-        suffix |= Suffix.Long;
-        ++p;
-        continue;
-      case 'u', 'U':
-        if (suffix & Suffix.Unsigned)
-          break;
-        suffix |= Suffix.Unsigned;
-        ++p;
-        continue;
-      default:
-        break;
-      }
-      break;
-    }
-
-    // Determine type of Integer.
-    switch (suffix)
-    {
-    case Suffix.None:
-      if (ulong_ & 0x8000_0000_0000_0000)
-      {
-        if (isDecimal)
-          error(t.start, MID.OverflowDecimalSign);
-        t.kind = TOK.Uint64;
-      }
-      else if (ulong_ & 0xFFFF_FFFF_0000_0000)
-        t.kind = TOK.Int64;
-      else if (ulong_ & 0x8000_0000)
-        t.kind = isDecimal ? TOK.Int64 : TOK.Uint32;
-      else
-        t.kind = TOK.Int32;
-      break;
-    case Suffix.Unsigned:
-      if (ulong_ & 0xFFFF_FFFF_0000_0000)
-        t.kind = TOK.Uint64;
-      else
-        t.kind = TOK.Uint32;
-      break;
-    case Suffix.Long:
-      if (ulong_ & 0x8000_0000_0000_0000)
-      {
-        if (isDecimal)
-          error(t.start, MID.OverflowDecimalSign);
-        t.kind = TOK.Uint64;
-      }
-      else
-        t.kind = TOK.Int64;
-      break;
-    case Suffix.Unsigned | Suffix.Long:
-      t.kind = TOK.Uint64;
-      break;
-    default:
-      assert(0);
-    }
-    t.ulong_ = ulong_;
-    t.end = p;
-    return;
-  LscanReal:
-    scanReal(t);
-    return;
-  }
-
-  /// Scans a floating point number literal.
-  ///
-  /// $(PRE
-  /// FloatLiteral := Float[fFL]?i?
-  /// Float := DecFloat | HexFloat
-  /// DecFloat := ([0-9][0-9_]*[.][0-9_]*DecExponent?) |
-  ///             [.][0-9][0-9_]*DecExponent? | [0-9][0-9_]*DecExponent
-  /// DecExponent := [eE][+-]?[0-9][0-9_]*
-  /// HexFloat := 0[xX](HexDigits[.]HexDigits |
-  ///                   [.][0-9a-zA-Z]HexDigits? |
-  ///                   HexDigits)HexExponent
-  /// HexExponent := [pP][+-]?[0-9][0-9_]*
-  /// )
-  void scanReal(ref Token t)
-  {
-    if (*p == '.')
-    {
-      assert(p[1] != '.');
-      // This function was called by scan() or scanNumber().
-      while (isdigit(*++p) || *p == '_') {}
-    }
-    else
-      // This function was called by scanNumber().
-      assert(delegate ()
-        {
-          switch (*p)
-          {
-          case 'L':
-            if (p[1] != 'i')
-              return false;
-          case 'i', 'f', 'F', 'e', 'E':
-            return true;
-          default:
-          }
-          return false;
-        }()
-      );
-
-    // Scan exponent.
-    if (*p == 'e' || *p == 'E')
-    {
-      ++p;
-      if (*p == '-' || *p == '+')
-        ++p;
-      if (isdigit(*p))
-        while (isdigit(*++p) || *p == '_') {}
-      else
-        error(t.start, MID.FloatExpMustStartWithDigit);
-    }
-
-    // Copy whole number and remove underscores from buffer.
-    char[] buffer = t.start[0..p-t.start].dup;
-    uint j;
-    foreach (c; buffer)
-      if (c != '_')
-        buffer[j++] = c;
-    buffer.length = j; // Adjust length.
-    buffer ~= 0; // Terminate for C functions.
-
-    finalizeFloat(t, buffer);
-  }
-
-  /// Scans a hexadecimal floating point number literal.
-  void scanHexReal(ref Token t)
-  {
-    assert(*p == '.' || *p == 'p' || *p == 'P');
-    MID mid;
-    if (*p == '.')
-      while (ishexad(*++p) || *p == '_')
-      {}
-    // Decimal exponent is required.
-    if (*p != 'p' && *p != 'P')
-    {
-      mid = MID.HexFloatExponentRequired;
-      goto Lerr;
-    }
-    // Scan exponent
-    assert(*p == 'p' || *p == 'P');
-    ++p;
-    if (*p == '+' || *p == '-')
-      ++p;
-    if (!isdigit(*p))
-    {
-      mid = MID.HexFloatExpMustStartWithDigit;
-      goto Lerr;
-    }
-    while (isdigit(*++p) || *p == '_')
-    {}
-    // Copy whole number and remove underscores from buffer.
-    char[] buffer = t.start[0..p-t.start].dup;
-    uint j;
-    foreach (c; buffer)
-      if (c != '_')
-        buffer[j++] = c;
-    buffer.length = j; // Adjust length.
-    buffer ~= 0; // Terminate for C functions.
-    finalizeFloat(t, buffer);
-    return;
-  Lerr:
-    t.kind = TOK.Float32;
-    t.end = p;
-    error(t.start, mid);
-  }
-
-  /// Sets the value of the token.
-  /// Params:
-  ///   t = receives the value.
-  ///   buffer = the well-formed float number.
-  void finalizeFloat(ref Token t, string buffer)
-  {
-    assert(buffer[$-1] == 0);
-    // Float number is well-formed. Check suffixes and do conversion.
-    switch (*p)
-    {
-    case 'f', 'F':
-      t.kind = TOK.Float32;
-      t.float_ = strtof(buffer.ptr, null);
-      ++p;
-      break;
-    case 'L':
-      t.kind = TOK.Float80;
-      t.real_ = strtold(buffer.ptr, null);
-      ++p;
-      break;
-    default:
-      t.kind = TOK.Float64;
-      t.double_ = strtod(buffer.ptr, null);
-    }
-    if (*p == 'i')
-    {
-      ++p;
-      t.kind += 3; // Switch to imaginary counterpart.
-      assert(t.kind == TOK.Imaginary32 ||
-             t.kind == TOK.Imaginary64 ||
-             t.kind == TOK.Imaginary80);
-    }
-    if (errno() == ERANGE)
-      error(t.start, MID.OverflowFloatNumber);
-    t.end = p;
-  }
-
-  /// Scans a special token sequence.
-  ///
-  /// SpecialTokenSequence := "#line" Integer Filespec? EndOfLine
-  void scanSpecialTokenSequence(ref Token t)
-  {
-    assert(*p == '#');
-    t.kind = TOK.HashLine;
-    t.setWhitespaceFlag();
-
-    MID mid;
-    char* errorAtColumn = p;
-    char* tokenEnd = ++p;
-
-    if (!(p[0] == 'l' && p[1] == 'i' && p[2] == 'n' && p[3] == 'e'))
-    {
-      mid = MID.ExpectedIdentifierSTLine;
-      goto Lerr;
-    }
-    p += 3;
-    tokenEnd = p + 1;
-
-    // TODO: #line58"path/file" is legal. Require spaces?
-    //       State.Space could be used for that purpose.
-    enum State
-    { /+Space,+/ Integer, Filespec, End }
-
-    State state = State.Integer;
-
-    while (!isEndOfLine(++p))
-    {
-      if (isspace(*p))
-        continue;
-      if (state == State.Integer)
-      {
-        if (!isdigit(*p))
-        {
-          errorAtColumn = p;
-          mid = MID.ExpectedIntegerAfterSTLine;
-          goto Lerr;
-        }
-        t.tokLineNum = new Token;
-        scan(*t.tokLineNum);
-        tokenEnd = p;
-        if (t.tokLineNum.kind != TOK.Int32 && t.tokLineNum.kind != TOK.Uint32)
-        {
-          errorAtColumn = t.tokLineNum.start;
-          mid = MID.ExpectedIntegerAfterSTLine;
-          goto Lerr;
-        }
-        --p; // Go one back because scan() advanced p past the integer.
-        state = State.Filespec;
-      }
-      else if (state == State.Filespec && *p == '"')
-      { // MID.ExpectedFilespec is deprecated.
-        // if (*p != '"')
-        // {
-        //   errorAtColumn = p;
-        //   mid = MID.ExpectedFilespec;
-        //   goto Lerr;
-        // }
-        t.tokLineFilespec = new Token;
-        t.tokLineFilespec.start = p;
-        t.tokLineFilespec.kind = TOK.Filespec;
-        t.tokLineFilespec.setWhitespaceFlag();
-        while (*++p != '"')
-        {
-          if (isEndOfLine(p))
-          {
-            errorAtColumn = t.tokLineFilespec.start;
-            mid = MID.UnterminatedFilespec;
-            t.tokLineFilespec.end = p;
-            tokenEnd = p;
-            goto Lerr;
-          }
-          isascii(*p) || decodeUTF8();
-        }
-        auto start = t.tokLineFilespec.start +1; // +1 skips '"'
-        t.tokLineFilespec.str = start[0 .. p - start];
-        t.tokLineFilespec.end = p + 1;
-        tokenEnd = p + 1;
-        state = State.End;
-      }
-      else/+ if (state == State.End)+/
-      {
-        mid = MID.UnterminatedSpecialToken;
-        goto Lerr;
-      }
-    }
-    assert(isEndOfLine(p));
-
-    if (state == State.Integer)
-    {
-      errorAtColumn = p;
-      mid = MID.ExpectedIntegerAfterSTLine;
-      goto Lerr;
-    }
-
-    // Evaluate #line only when not in token string.
-    if (!inTokenString && t.tokLineNum)
-    {
-      this.lineNum_hline = this.lineNum - t.tokLineNum.uint_ + 1;
-      if (t.tokLineFilespec)
-        newFilePath(t.tokLineFilespec.str);
-    }
-    p = tokenEnd;
-    t.end = tokenEnd;
-
-    return;
-  Lerr:
-    p = tokenEnd;
-    t.end = tokenEnd;
-    error(errorAtColumn, mid);
-  }
-
-  /// Inserts an empty dummy token (TOK.Empty) before t.
-  ///
-  /// Useful in the parsing phase for representing a node in the AST
-  /// that doesn't consume an actual token from the source text.
-  Token* insertEmptyTokenBefore(Token* t)
-  {
-    assert(t !is null && t.prev !is null);
-    assert(text.ptr <= t.start && t.start < end, Token.toString(t.kind));
-    assert(text.ptr <= t.end && t.end <= end, Token.toString(t.kind));
-
-    auto prev_t = t.prev;
-    auto new_t = new Token;
-    new_t.kind = TOK.Empty;
-    new_t.start = new_t.end = prev_t.end;
-    // Link in new token.
-    prev_t.next = new_t;
-    new_t.prev = prev_t;
-    new_t.next = t;
-    t.prev = new_t;
-    return new_t;
-  }
-
-  /// Returns the error line number.
-  uint errorLineNumber(uint lineNum)
-  {
-    return lineNum - this.lineNum_hline;
-  }
-
-  /// Forwards error parameters.
-  void error(char* columnPos, char[] msg, ...)
-  {
-    error_(this.lineNum, this.lineBegin, columnPos, msg, _arguments, _argptr);
-  }
-
-  /// ditto
-  void error(char* columnPos, MID mid, ...)
-  {
-    error_(this.lineNum, this.lineBegin, columnPos, GetMsg(mid), _arguments, _argptr);
-  }
-
-  /// ditto
-  void error(uint lineNum, char* lineBegin, char* columnPos, MID mid, ...)
-  {
-    error_(lineNum, lineBegin, columnPos, GetMsg(mid), _arguments, _argptr);
-  }
-
-  /// Creates an error report and appends it to a list.
-  /// Params:
-  ///   lineNum = the line number.
-  ///   lineBegin = points to the first character of the current line.
-  ///   columnPos = points to the character where the error is located.
-  ///   msg = the message.
-  void error_(uint lineNum, char* lineBegin, char* columnPos, char[] msg,
-              TypeInfo[] _arguments, Arg _argptr)
-  {
-    lineNum = this.errorLineNumber(lineNum);
-    auto errorPath = this.filePaths.setPath;
-    auto location = new Location(errorPath, lineNum, lineBegin, columnPos);
-    msg = Format(_arguments, _argptr, msg);
-    auto error = new LexerError(location, msg);
-    errors ~= error;
-    if (infoMan !is null)
-      infoMan ~= error;
-  }
-
-  /// Scans the whole source text until EOF is encountered.
-  void scanAll()
-  {
-    while (nextToken() != TOK.EOF)
-    {}
-  }
-
-  /// Returns the first token of the source text.
-  /// This can be the EOF token.
-  /// Structure: HEAD -> Newline -> First Token
-  Token* firstToken()
-  {
-    return this.head.next.next;
-  }
-
-  /// Returns true if str is a valid D identifier.
-  static bool isIdentifierString(char[] str)
-  {
-    if (str.length == 0 || isdigit(str[0]))
-      return false;
-    size_t idx;
-    do
-    {
-      auto c = dil.Unicode.decode(str, idx);
-      if (c == ERROR_CHAR || !(isident(c) || !isascii(c) && isUniAlpha(c)))
-        return false;
-    } while (idx < str.length)
-    return true;
-  }
-
-  /// Returns true if str is a keyword or a special token (__FILE__, __LINE__ etc.)
-  static bool isReservedIdentifier(char[] str)
-  {
-    if (!isIdentifierString(str))
-      return false; // str is not a valid identifier.
-
-    auto id = IdTable.inStatic(str);
-    if (id is null || id.kind == TOK.Identifier)
-      return false; // str is not in the table or a normal identifier.
-
-    return true;
-  }
-
-  /// Returns true if the current character to be decoded is
-  /// a Unicode alpha character.
-  ///
-  /// The current pointer 'p' is not advanced if false is returned.
-  bool isUnicodeAlpha()
-  {
-    assert(!isascii(*p), "check for ASCII char before calling decodeUTF8().");
-    char* p = this.p;
-    dchar d = *p;
-    ++p; // Move to second byte.
-    // Error if second byte is not a trail byte.
-    if (!isTrailByte(*p))
-      return false;
-    // Check for overlong sequences.
-    switch (d)
-    {
-    case 0xE0, 0xF0, 0xF8, 0xFC:
-      if ((*p & d) == 0x80)
-        return false;
-    default:
-      if ((d & 0xFE) == 0xC0) // 1100000x
-        return false;
-    }
-    const char[] checkNextByte = "if (!isTrailByte(*++p))"
-                                 "  return false;";
-    const char[] appendSixBits = "d = (d << 6) | *p & 0b0011_1111;";
-    // Decode
-    if ((d & 0b1110_0000) == 0b1100_0000)
-    {
-      d &= 0b0001_1111;
-      mixin(appendSixBits);
-    }
-    else if ((d & 0b1111_0000) == 0b1110_0000)
-    {
-      d &= 0b0000_1111;
-      mixin(appendSixBits ~
-            checkNextByte ~ appendSixBits);
-    }
-    else if ((d & 0b1111_1000) == 0b1111_0000)
-    {
-      d &= 0b0000_0111;
-      mixin(appendSixBits ~
-            checkNextByte ~ appendSixBits ~
-            checkNextByte ~ appendSixBits);
-    }
-    else
-      return false;
-
-    assert(isTrailByte(*p));
-    if (!isValidChar(d) || !isUniAlpha(d))
-      return false;
-    // Only advance pointer if this is a Unicode alpha character.
-    this.p = p;
-    return true;
-  }
-
-  /// Decodes the next UTF-8 sequence.
-  dchar decodeUTF8()
-  {
-    assert(!isascii(*p), "check for ASCII char before calling decodeUTF8().");
-    char* p = this.p;
-    dchar d = *p;
-
-    ++p; // Move to second byte.
-    // Error if second byte is not a trail byte.
-    if (!isTrailByte(*p))
-      goto Lerr2;
-
-    // Check for overlong sequences.
-    switch (d)
-    {
-    case 0xE0, // 11100000 100xxxxx
-         0xF0, // 11110000 1000xxxx
-         0xF8, // 11111000 10000xxx
-         0xFC: // 11111100 100000xx
-      if ((*p & d) == 0x80)
-        goto Lerr;
-    default:
-      if ((d & 0xFE) == 0xC0) // 1100000x
-        goto Lerr;
-    }
-
-    const char[] checkNextByte = "if (!isTrailByte(*++p))"
-                                 "  goto Lerr2;";
-    const char[] appendSixBits = "d = (d << 6) | *p & 0b0011_1111;";
-
-    // Decode
-    if ((d & 0b1110_0000) == 0b1100_0000)
-    { // 110xxxxx 10xxxxxx
-      d &= 0b0001_1111;
-      mixin(appendSixBits);
-    }
-    else if ((d & 0b1111_0000) == 0b1110_0000)
-    { // 1110xxxx 10xxxxxx 10xxxxxx
-      d &= 0b0000_1111;
-      mixin(appendSixBits ~
-            checkNextByte ~ appendSixBits);
-    }
-    else if ((d & 0b1111_1000) == 0b1111_0000)
-    { // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
-      d &= 0b0000_0111;
-      mixin(appendSixBits ~
-            checkNextByte ~ appendSixBits ~
-            checkNextByte ~ appendSixBits);
-    }
-    else
-      // 5 and 6 byte UTF-8 sequences are not allowed yet.
-      // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
-      // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
-      goto Lerr;
-
-    assert(isTrailByte(*p));
-
-    if (!isValidChar(d))
-    {
-    Lerr:
-      // Three cases:
-      // *) the UTF-8 sequence was successfully decoded but the resulting
-      //    character is invalid.
-      //    p points to last trail byte in the sequence.
-      // *) the UTF-8 sequence is overlong.
-      //    p points to second byte in the sequence.
-      // *) the UTF-8 sequence has more than 4 bytes or starts with
-      //    a trail byte.
-      //    p points to second byte in the sequence.
-      assert(isTrailByte(*p));
-      // Move to next ASCII character or lead byte of a UTF-8 sequence.
-      while (p < (end-1) && isTrailByte(*p))
-        ++p;
-      --p;
-      assert(!isTrailByte(p[1]));
-    Lerr2:
-      d = REPLACEMENT_CHAR;
-      error(this.p, MID.InvalidUTF8Sequence, formatBytes(this.p, p));
-    }
-
-    this.p = p;
-    return d;
-  }
-
-  /// Encodes the character d and appends it to str.
-  static void encodeUTF8(ref char[] str, dchar d)
-  {
-    assert(!isascii(d), "check for ASCII char before calling encodeUTF8().");
-    assert(isValidChar(d), "check if character is valid before calling encodeUTF8().");
-
-    char[6] b = void;
-    if (d < 0x800)
-    {
-      b[0] = 0xC0 | (d >> 6);
-      b[1] = 0x80 | (d & 0x3F);
-      str ~= b[0..2];
-    }
-    else if (d < 0x10000)
-    {
-      b[0] = 0xE0 | (d >> 12);
-      b[1] = 0x80 | ((d >> 6) & 0x3F);
-      b[2] = 0x80 | (d & 0x3F);
-      str ~= b[0..3];
-    }
-    else if (d < 0x200000)
-    {
-      b[0] = 0xF0 | (d >> 18);
-      b[1] = 0x80 | ((d >> 12) & 0x3F);
-      b[2] = 0x80 | ((d >> 6) & 0x3F);
-      b[3] = 0x80 | (d & 0x3F);
-      str ~= b[0..4];
-    }
-    /+ // There are no 5 and 6 byte UTF-8 sequences yet.
-    else if (d < 0x4000000)
-    {
-      b[0] = 0xF8 | (d >> 24);
-      b[1] = 0x80 | ((d >> 18) & 0x3F);
-      b[2] = 0x80 | ((d >> 12) & 0x3F);
-      b[3] = 0x80 | ((d >> 6) & 0x3F);
-      b[4] = 0x80 | (d & 0x3F);
-      str ~= b[0..5];
-    }
-    else if (d < 0x80000000)
-    {
-      b[0] = 0xFC | (d >> 30);
-      b[1] = 0x80 | ((d >> 24) & 0x3F);
-      b[2] = 0x80 | ((d >> 18) & 0x3F);
-      b[3] = 0x80 | ((d >> 12) & 0x3F);
-      b[4] = 0x80 | ((d >> 6) & 0x3F);
-      b[5] = 0x80 | (d & 0x3F);
-      str ~= b[0..6];
-    }
-    +/
-    else
-     assert(0);
-  }
-
-  /// Formats the bytes between start and end.
-  /// Returns: e.g.: abc -> \x61\x62\x63
-  static char[] formatBytes(char* start, char* end)
-  {
-    auto strLen = end-start;
-    const formatLen = `\xXX`.length;
-    char[] result = new char[strLen*formatLen]; // Reserve space.
-    result.length = 0;
-    foreach (c; cast(ubyte[])start[0..strLen])
-      result ~= Format("\\x{:X}", c);
-    return result;
-  }
-
-  /// Searches for an invalid UTF-8 sequence in str.
-  /// Returns: a formatted string of the invalid sequence (e.g. \xC0\x80).
-  static string findInvalidUTF8Sequence(string str)
-  {
-    char* p = str.ptr, end = p + str.length;
-    while (p < end)
-    {
-      if (decode(p, end) == ERROR_CHAR)
-      {
-        auto begin = p;
-        // Skip trail-bytes.
-        while (++p < end && isTrailByte(*p))
-        {}
-        return Lexer.formatBytes(begin, p);
-      }
-    }
-    assert(p == end);
-    return "";
-  }
-}
-
-/// Tests the lexer with a list of tokens.
-unittest
-{
-  Stdout("Testing Lexer.\n");
-  struct Pair
-  {
-    char[] tokenText;
-    TOK kind;
-  }
-  static Pair[] pairs = [
-    {"#!äöüß",  TOK.Shebang},       {"\n",      TOK.Newline},
-    {"//çay",   TOK.Comment},       {"\n",      TOK.Newline},
-                                    {"&",       TOK.AndBinary},
-    {"/*çağ*/", TOK.Comment},       {"&&",      TOK.AndLogical},
-    {"/+çak+/", TOK.Comment},       {"&=",      TOK.AndAssign},
-    {">",       TOK.Greater},       {"+",       TOK.Plus},
-    {">=",      TOK.GreaterEqual},  {"++",      TOK.PlusPlus},
-    {">>",      TOK.RShift},        {"+=",      TOK.PlusAssign},
-    {">>=",     TOK.RShiftAssign},  {"-",       TOK.Minus},
-    {">>>",     TOK.URShift},       {"--",      TOK.MinusMinus},
-    {">>>=",    TOK.URShiftAssign}, {"-=",      TOK.MinusAssign},
-    {"<",       TOK.Less},          {"=",       TOK.Assign},
-    {"<=",      TOK.LessEqual},     {"==",      TOK.Equal},
-    {"<>",      TOK.LorG},          {"~",       TOK.Tilde},
-    {"<>=",     TOK.LorEorG},       {"~=",      TOK.CatAssign},
-    {"<<",      TOK.LShift},        {"*",       TOK.Mul},
-    {"<<=",     TOK.LShiftAssign},  {"*=",      TOK.MulAssign},
-    {"!",       TOK.Not},           {"/",       TOK.Div},
-    {"!=",      TOK.NotEqual},      {"/=",      TOK.DivAssign},
-    {"!<",      TOK.UorGorE},       {"^",       TOK.Xor},
-    {"!>",      TOK.UorLorE},       {"^=",      TOK.XorAssign},
-    {"!<=",     TOK.UorG},          {"%",       TOK.Mod},
-    {"!>=",     TOK.UorL},          {"%=",      TOK.ModAssign},
-    {"!<>",     TOK.UorE},          {"(",       TOK.LParen},
-    {"!<>=",    TOK.Unordered},     {")",       TOK.RParen},
-    {".",       TOK.Dot},           {"[",       TOK.LBracket},
-    {"..",      TOK.Slice},         {"]",       TOK.RBracket},
-    {"...",     TOK.Ellipses},      {"{",       TOK.LBrace},
-    {"|",       TOK.OrBinary},      {"}",       TOK.RBrace},
-    {"||",      TOK.OrLogical},     {":",       TOK.Colon},
-    {"|=",      TOK.OrAssign},      {";",       TOK.Semicolon},
-    {"?",       TOK.Question},      {",",       TOK.Comma},
-    {"$",       TOK.Dollar},        {"cam",     TOK.Identifier},
-    {"çay",     TOK.Identifier},    {".0",      TOK.Float64},
-    {"0",       TOK.Int32},         {"\n",      TOK.Newline},
-    {"\r",      TOK.Newline},       {"\r\n",    TOK.Newline},
-    {"\u2028",  TOK.Newline},       {"\u2029",  TOK.Newline}
-  ];
-
-  char[] src;
-
-  // Join all token texts into a single string.
-  foreach (i, pair; pairs)
-    if (pair.kind == TOK.Comment && pair.tokenText[1] == '/' || // Line comment.
-        pair.kind == TOK.Shebang)
-    {
-      assert(pairs[i+1].kind == TOK.Newline); // Must be followed by a newline.
-      src ~= pair.tokenText;
-    }
-    else
-      src ~= pair.tokenText ~ " ";
-
-  auto lx = new Lexer(new SourceText("", src));
-  auto token = lx.getTokens();
-
-  uint i;
-  assert(token == lx.head);
-  assert(token.next.kind == TOK.Newline);
-  token = token.next.next;
-  do
-  {
-    assert(i < pairs.length);
-    assert(token.srcText == pairs[i].tokenText, Format("Scanned '{0}' but expected '{1}'", token.srcText, pairs[i].tokenText));
-    ++i;
-    token = token.next;
-  } while (token.kind != TOK.EOF)
-}
-
-/// Tests the Lexer's peek() method.
-unittest
-{
-  Stdout("Testing method Lexer.peek()\n");
-  auto sourceText = new SourceText("", "unittest { }");
-  auto lx = new Lexer(sourceText, null);
-
-  auto next = lx.head;
-  lx.peek(next);
-  assert(next.kind == TOK.Newline);
-  lx.peek(next);
-  assert(next.kind == TOK.Unittest);
-  lx.peek(next);
-  assert(next.kind == TOK.LBrace);
-  lx.peek(next);
-  assert(next.kind == TOK.RBrace);
-  lx.peek(next);
-  assert(next.kind == TOK.EOF);
-
-  lx = new Lexer(new SourceText("", ""));
-  next = lx.head;
-  lx.peek(next);
-  assert(next.kind == TOK.Newline);
-  lx.peek(next);
-  assert(next.kind == TOK.EOF);
-}
-
-unittest
-{
-  // Numbers unittest
-  // 0L 0ULi 0_L 0_UL 0x0U 0x0p2 0_Fi 0_e2 0_F 0_i
-  // 0u 0U 0uL 0UL 0L 0LU 0Lu
-  // 0Li 0f 0F 0fi 0Fi 0i
-  // 0b_1_LU 0b1000u
-  // 0x232Lu
-}
--- a/trunk/src/dil/lexer/Token.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,400 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.lexer.Token;
-
-import dil.lexer.Identifier;
-import dil.lexer.Funcs;
-import dil.Location;
-import tango.stdc.stdlib : malloc, free;
-import tango.core.Exception;
-import common;
-
-public import dil.lexer.TokensEnum;
-
-/// A Token is a sequence of characters formed by the lexical analyzer.
-struct Token
-{ /// Flags set by the Lexer.
-  enum Flags : ushort
-  {
-    None,
-    Whitespace = 1, /// Tokens with this flag are ignored by the Parser.
-  }
-
-  TOK kind; /// The token kind.
-  Flags flags; /// The flags of the token.
-  /// Pointers to the next and previous tokens (doubly-linked list.)
-  Token* next, prev;
-
-  /// Start of whitespace characters before token. Null if no WS.
-  /// TODO: remove to save space; can be replaced by 'prev.end'.
-  char* ws;
-  char* start; /// Points to the first character of the token.
-  char* end;   /// Points one character past the end of the token.
-
-  /// Data associated with this token.
-  /// TODO: move data structures out; use only pointers here to keep Token.sizeof small.
-  union
-  {
-    /// For newline tokens.
-    NewlineData newline;
-    /// For #line tokens.
-    struct
-    {
-      Token* tokLineNum; /// #line number
-      Token* tokLineFilespec; /// #line number filespec
-    }
-    /// The value of a string token.
-    struct
-    {
-      string str; /// Zero-terminated string. (The zero is included in the length.)
-      char pf;    /// Postfix 'c', 'w', 'd' or 0 for none.
-    version(D2)
-      Token* tok_str; /++ Points to the contents of a token string stored as a
-                          doubly linked list. The last token is always '}' or
-                          EOF in case end of source text is "q{" EOF.
-                      +/
-    }
-    Identifier* ident; /// For keywords and identifiers.
-    dchar  dchar_;   /// A character value.
-    long   long_;    /// A long integer value.
-    ulong  ulong_;   /// An unsigned long integer value.
-    int    int_;     /// An integer value.
-    uint   uint_;    /// An unsigned integer value.
-    float  float_;   /// A float value.
-    double double_;  /// A double value.
-    real   real_;    /// A real value.
-  }
-
-  /// Returns the text of the token.
-  string srcText()
-  {
-    assert(start && end);
-    return start[0 .. end - start];
-  }
-
-  /// Returns the preceding whitespace of the token.
-  string wsChars()
-  {
-    assert(ws && start);
-    return ws[0 .. start - ws];
-  }
-
-  /// Finds the next non-whitespace token.
-  /// Returns: 'this' token if the next token is TOK.EOF or null.
-  Token* nextNWS()
-  out(token)
-  {
-    assert(token !is null);
-  }
-  body
-  {
-    auto token = next;
-    while (token !is null && token.isWhitespace)
-      token = token.next;
-    if (token is null || token.kind == TOK.EOF)
-      return this;
-    return token;
-  }
-
-  /// Finds the previous non-whitespace token.
-  /// Returns: 'this' token if the previous token is TOK.HEAD or null.
-  Token* prevNWS()
-  out(token)
-  {
-    assert(token !is null);
-  }
-  body
-  {
-    auto token = prev;
-    while (token !is null && token.isWhitespace)
-      token = token.prev;
-    if (token is null || token.kind == TOK.HEAD)
-      return this;
-    return token;
-  }
-
-  /// Returns the string for a token kind.
-  static string toString(TOK kind)
-  {
-    return tokToString[kind];
-  }
-
-  /// Adds Flags.Whitespace to this.flags.
-  void setWhitespaceFlag()
-  {
-    this.flags |= Flags.Whitespace;
-  }
-
-  /// Returns true if this is a token that can have newlines in it.
-  ///
-  /// These can be block and nested comments and any string literal
-  /// except for escape string literals.
-  bool isMultiline()
-  {
-    return kind == TOK.String && start[0] != '\\' ||
-           kind == TOK.Comment && start[1] != '/';
-  }
-
-  /// Returns true if this is a keyword token.
-  bool isKeyword()
-  {
-    return KeywordsBegin <= kind && kind <= KeywordsEnd;
-  }
-
-  /// Returns true if this is an integral type token.
-  bool isIntegralType()
-  {
-    return IntegralTypeBegin <= kind && kind <= IntegralTypeEnd;
-  }
-
-  /// Returns true if this is a whitespace token.
-  bool isWhitespace()
-  {
-    return !!(flags & Flags.Whitespace);
-  }
-
-  /// Returns true if this is a special token.
-  bool isSpecialToken()
-  {
-    return SpecialTokensBegin <= kind && kind <= SpecialTokensEnd;
-  }
-
-version(D2)
-{
-  /// Returns true if this is a token string literal.
-  bool isTokenStringLiteral()
-  {
-    return kind == TOK.String && tok_str !is null;
-  }
-}
-
-  /// Returns true if this token starts a DeclarationDefinition.
-  bool isDeclDefStart()
-  {
-    return isDeclDefStartToken(kind);
-  }
-
-  /// Returns true if this token starts a Statement.
-  bool isStatementStart()
-  {
-    return isStatementStartToken(kind);
-  }
-
-  /// Returns true if this token starts an AsmStatement.
-  bool isAsmStatementStart()
-  {
-    return isAsmStatementStartToken(kind);
-  }
-
-  int opEquals(TOK kind2)
-  {
-    return kind == kind2;
-  }
-
-  int opCmp(Token* rhs)
-  {
-    return start < rhs.start;
-  }
-
-  /// Returns the Location of this token.
-  Location getLocation(bool realLocation)()
-  {
-    auto search_t = this.prev;
-    // Find previous newline token.
-    while (search_t.kind != TOK.Newline)
-      search_t = search_t.prev;
-    static if (realLocation)
-    {
-      auto filePath  = search_t.newline.filePaths.oriPath;
-      auto lineNum   = search_t.newline.oriLineNum;
-    }
-    else
-    {
-      auto filePath  = search_t.newline.filePaths.setPath;
-      auto lineNum   = search_t.newline.oriLineNum - search_t.newline.setLineNum;
-    }
-    auto lineBegin = search_t.end;
-    // Determine actual line begin and line number.
-    while (1)
-    {
-      search_t = search_t.next;
-      if (search_t == this)
-        break;
-      // Multiline tokens must be rescanned for newlines.
-      if (search_t.isMultiline)
-      {
-        auto p = search_t.start, end = search_t.end;
-        while (p != end)
-        {
-          if (scanNewline(p) == '\n')
-          {
-            lineBegin = p;
-            ++lineNum;
-          }
-          else
-            ++p;
-        }
-      }
-    }
-    return new Location(filePath, lineNum, lineBegin, this.start);
-  }
-
-  alias getLocation!(true) getRealLocation;
-  alias getLocation!(false) getErrorLocation;
-
-  uint lineCount()
-  {
-    uint count = 1;
-    if (this.isMultiline)
-    {
-      auto p = this.start, end = this.end;
-      while (p != end)
-      {
-        if (scanNewline(p) == '\n')
-          ++count;
-        else
-          ++p;
-      }
-    }
-    return count;
-  }
-
-  /// Return the source text enclosed by the left and right token.
-  static char[] textSpan(Token* left, Token* right)
-  {
-    assert(left.end <= right.start || left is right );
-    return left.start[0 .. right.end - left.start];
-  }
-
-  /// Uses malloc() to allocate memory for a token.
-  new(size_t size)
-  {
-    void* p = malloc(size);
-    if (p is null)
-      throw new OutOfMemoryException(__FILE__, __LINE__);
-    // TODO: Token.init should be all zeros.
-    // Maybe use calloc() to avoid this line?
-    *cast(Token*)p = Token.init;
-    return p;
-  }
-
-  /// Deletes a token using free().
-  delete(void* p)
-  {
-    auto token = cast(Token*)p;
-    if (token)
-    {
-      if(token.kind == TOK.HashLine)
-        token.destructHashLineToken();
-      else
-      {
-      version(D2)
-        if (token.isTokenStringLiteral)
-          token.destructTokenStringLiteral();
-      }
-    }
-    free(p);
-  }
-
-  void destructHashLineToken()
-  {
-    assert(kind == TOK.HashLine);
-    delete tokLineNum;
-    delete tokLineFilespec;
-  }
-
-version(D2)
-{
-  void destructTokenStringLiteral()
-  {
-    assert(kind == TOK.String);
-    assert(start && *start == 'q' && start[1] == '{');
-    assert(tok_str !is null);
-    auto tok_it = tok_str;
-    auto tok_del = tok_str;
-    while (tok_it && tok_it.kind != TOK.EOF)
-    {
-      tok_it = tok_it.next;
-      assert(tok_del && tok_del.kind != TOK.EOF);
-      delete tok_del;
-      tok_del = tok_it;
-    }
-  }
-}
-}
-
-/// Data associated with newline tokens.
-struct NewlineData
-{
-  struct FilePaths
-  {
-    char[] oriPath;   /// Original path to the source text.
-    char[] setPath;   /// Path set by #line.
-  }
-  FilePaths* filePaths;
-  uint oriLineNum;  /// Actual line number in the source text.
-  uint setLineNum;  /// Delta line number set by #line.
-}
-
-/// Returns true if this token starts a DeclarationDefinition.
-bool isDeclDefStartToken(TOK tok)
-{
-  switch (tok)
-  {
-  alias TOK T;
-  case  T.Align, T.Pragma, T.Export, T.Private, T.Package, T.Protected,
-        T.Public, T.Extern, T.Deprecated, T.Override, T.Abstract,
-        T.Synchronized, T.Static, T.Final, T.Const, T.Invariant/*D 2.0*/,
-        T.Auto, T.Scope, T.Alias, T.Typedef, T.Import, T.Enum, T.Class,
-        T.Interface, T.Struct, T.Union, T.This, T.Tilde, T.Unittest, T.Debug,
-        T.Version, T.Template, T.New, T.Delete, T.Mixin, T.Semicolon,
-        T.Identifier, T.Dot, T.Typeof:
-    return true;
-  default:
-    if (IntegralTypeBegin <= tok && tok <= IntegralTypeEnd)
-      return true;
-  }
-  return false;
-}
-
-/// Returns true if this token starts a Statement.
-bool isStatementStartToken(TOK tok)
-{
-  switch (tok)
-  {
-  alias TOK T;
-  case  T.Align, T.Extern, T.Final, T.Const, T.Auto, T.Identifier, T.Dot,
-        T.Typeof, T.If, T.While, T.Do, T.For, T.Foreach, T.Foreach_reverse,
-        T.Switch, T.Case, T.Default, T.Continue, T.Break, T.Return, T.Goto,
-        T.With, T.Synchronized, T.Try, T.Throw, T.Scope, T.Volatile, T.Asm,
-        T.Pragma, T.Mixin, T.Static, T.Debug, T.Version, T.Alias, T.Semicolon,
-        T.Enum, T.Class, T.Interface, T.Struct, T.Union, T.LBrace, T.Typedef,
-        T.This, T.Super, T.Null, T.True, T.False, T.Int32, T.Int64, T.Uint32,
-        T.Uint64, T.Float32, T.Float64, T.Float80, T.Imaginary32,
-        T.Imaginary64, T.Imaginary80, T.CharLiteral, T.String, T.LBracket,
-        T.Function, T.Delegate, T.Assert, T.Import, T.Typeid, T.Is, T.LParen,
-        T.Traits/*D2.0*/, T.AndBinary, T.PlusPlus, T.MinusMinus, T.Mul,
-        T.Minus, T.Plus, T.Not, T.Tilde, T.New, T.Delete, T.Cast:
-    return true;
-  default:
-    if (IntegralTypeBegin <= tok && tok <= IntegralTypeEnd ||
-        SpecialTokensBegin <= tok && tok <= SpecialTokensEnd)
-      return true;
-  }
-  return false;
-}
-
-/// Returns true if this token starts an AsmStatement.
-bool isAsmStatementStartToken(TOK tok)
-{
-  switch(tok)
-  {
-  alias TOK T;
-  case T.In, T.Int, T.Out, T.Identifier, T.Align, T.Semicolon:
-    return true;
-  default:
-  }
-  return false;
-}
--- a/trunk/src/dil/lexer/TokensEnum.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,219 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.lexer.TokensEnum;
-
-import common;
-
-/// Enumeration of token kinds.
-enum TOK : ushort
-{
-  Invalid,
-
-  Illegal,
-  Comment,
-  Shebang,
-  HashLine,
-  Filespec,
-  Newline,
-  Empty,
-
-  Identifier,
-  String,
-  CharLiteral,
-
-  // Special tokens
-  FILE,
-  LINE,
-  DATE,
-  TIME,
-  TIMESTAMP,
-  VENDOR,
-  VERSION,
-
-  // Number literals
-  Int32, Int64, Uint32, Uint64,
-  // Floating point number scanner relies on this order. (FloatXY + 3 == ImaginaryXY)
-  Float32, Float64, Float80,
-  Imaginary32, Imaginary64, Imaginary80,
-
-
-  // Brackets
-  LParen,
-  RParen,
-  LBracket,
-  RBracket,
-  LBrace,
-  RBrace,
-
-  Dot, Slice, Ellipses,
-
-  // Floating point number operators
-  Unordered,
-  UorE,
-  UorG,
-  UorGorE,
-  UorL,
-  UorLorE,
-  LorEorG,
-  LorG,
-
-  // Normal operators
-  Assign, Equal, NotEqual, Not,
-  LessEqual, Less,
-  GreaterEqual, Greater,
-  LShiftAssign, LShift,
-  RShiftAssign,RShift,
-  URShiftAssign, URShift,
-  OrAssign, OrLogical, OrBinary,
-  AndAssign, AndLogical, AndBinary,
-  PlusAssign, PlusPlus, Plus,
-  MinusAssign, MinusMinus, Minus,
-  DivAssign, Div,
-  MulAssign, Mul,
-  ModAssign, Mod,
-  XorAssign, Xor,
-  CatAssign,
-  Tilde,
-
-  Colon,
-  Semicolon,
-  Question,
-  Comma,
-  Dollar,
-
-  /* Keywords:
-     NB.: Token.isKeyword() depends on this list being contiguous.
-  */
-  Abstract, Alias, Align, Asm, Assert, Auto, Body,
-  Break, Case, Cast, Catch,
-  Class, Const, Continue,
-  Debug, Default, Delegate, Delete, Deprecated, Do,
-  Else, Enum, Export, Extern, False, Final,
-  Finally, For, Foreach, Foreach_reverse, Function, Goto,
-  If, Import, In, Inout,
-  Interface, Invariant, Is, Lazy, Macro/+D2.0+/,
-  Mixin, Module, New, Nothrow/+D2.0+/, Null, Out, Override, Package,
-  Pragma, Private, Protected, Public, Pure/+D2.0+/, Ref, Return,
-  Scope, Static, Struct, Super, Switch, Synchronized,
-  Template, This, Throw, Traits/+D2.0+/, True, Try, Typedef, Typeid,
-  Typeof, Union, Unittest,
-  Version, Volatile, While, With,
-  // Integral types.
-  Char,   Wchar,   Dchar, Bool,
-  Byte,   Ubyte,   Short, Ushort,
-  Int,    Uint,    Long,  Ulong,
-  Cent,   Ucent,
-  Float,  Double,  Real,
-  Ifloat, Idouble, Ireal,
-  Cfloat, Cdouble, Creal, Void,
-
-  HEAD, // start of linked list
-  EOF,
-  MAX
-}
-
-alias TOK.Abstract KeywordsBegin;
-alias TOK.Void KeywordsEnd;
-alias TOK.Char IntegralTypeBegin;
-alias TOK.Void IntegralTypeEnd;
-alias TOK.FILE SpecialTokensBegin;
-alias TOK.VERSION SpecialTokensEnd;
-
-/// A table that maps each token kind to a string.
-const string[TOK.MAX] tokToString = [
-  "Invalid",
-
-  "Illegal",
-  "Comment",
-  "#! /shebang/",
-  "#line",
-  `"filespec"`,
-  "Newline",
-  "Empty",
-
-  "Identifier",
-  "String",
-  "CharLiteral",
-
-  "__FILE__",
-  "__LINE__",
-  "__DATE__",
-  "__TIME__",
-  "__TIMESTAMP__",
-  "__VENDOR__",
-  "__VERSION__",
-
-  "Int32", "Int64", "Uint32", "Uint64",
-  "Float32", "Float64", "Float80",
-  "Imaginary32", "Imaginary64", "Imaginary80",
-
-  "(",
-  ")",
-  "[",
-  "]",
-  "{",
-  "}",
-
-  ".", "..", "...",
-
-  "!<>=", // Unordered
-  "!<>",  // UorE
-  "!<=",  // UorG
-  "!<",   // UorGorE
-  "!>=",  // UorL
-  "!>",   // UorLorE
-  "<>=",  // LorEorG
-  "<>",   // LorG
-
-  "=", "==", "!=", "!",
-  "<=", "<",
-  ">=", ">",
-  "<<=", "<<",
-  ">>=",">>",
-  ">>>=", ">>>",
-  "|=", "||", "|",
-  "&=", "&&", "&",
-  "+=", "++", "+",
-  "-=", "--", "-",
-  "/=", "/",
-  "*=", "*",
-  "%=", "%",
-  "^=", "^",
-  "~=",
-  "~",
-
-  ":",
-  ";",
-  "?",
-  ",",
-  "$",
-
-  "abstract","alias","align","asm","assert","auto","body",
-  "break","case","cast","catch",
-  "class","const","continue",
-  "debug","default","delegate","delete","deprecated","do",
-  "else","enum","export","extern","false","final",
-  "finally","for","foreach","foreach_reverse","function","goto",
-  "if","import","in","inout",
-  "interface","invariant","is","lazy","macro",
-  "mixin","module","new","nothrow","null","out","override","package",
-  "pragma","private","protected","public","pure","ref","return",
-  "scope","static","struct","super","switch","synchronized",
-  "template","this","throw","__traits","true","try","typedef","typeid",
-  "typeof","union","unittest",
-  "version","volatile","while","with",
-  // Integral types.
-  "char",   "wchar",   "dchar", "bool",
-  "byte",   "ubyte",   "short", "ushort",
-  "int",    "uint",    "long",  "ulong",
-  "cent",   "ucent",
-  "float",  "double",  "real",
-  "ifloat", "idouble", "ireal",
-  "cfloat", "cdouble", "creal", "void",
-
-  "HEAD",
-  "EOF"
-];
-static assert(tokToString.length == TOK.EOF+1);
--- a/trunk/src/dil/parser/ImportParser.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,373 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.parser.ImportParser;
-
-import dil.parser.Parser;
-import dil.ast.Node;
-import dil.ast.Declarations;
-import dil.ast.Statements;
-import dil.SourceText;
-import dil.Enums;
-import common;
-
-private alias TOK T;
-
-/// A light-weight parser which looks only for import statements
-/// in the source text.
-class ImportParser : Parser
-{
-  this(SourceText srcText)
-  {
-    super(srcText);
-  }
-
-  override CompoundDeclaration start()
-  {
-    auto decls = new CompoundDeclaration;
-    super.init();
-    if (token.kind == T.Module)
-      decls ~= parseModuleDeclaration();
-    while (token.kind != T.EOF)
-      parseDeclarationDefinition(Protection.None);
-    return decls;
-  }
-
-  void parseDeclarationDefinitionsBlock(Protection prot)
-  {
-    skip(T.LBrace);
-    while (token.kind != T.RBrace && token.kind != T.EOF)
-      parseDeclarationDefinition(prot);
-    skip(T.RBrace);
-  }
-
-  void parseDeclarationsBlock(Protection prot)
-  {
-    switch (token.kind)
-    {
-    case T.LBrace:
-      parseDeclarationDefinitionsBlock(prot);
-      break;
-    case T.Colon:
-      nT();
-      while (token.kind != T.RBrace && token.kind != T.EOF)
-        parseDeclarationDefinition(prot);
-      break;
-    default:
-      parseDeclarationDefinition(prot);
-    }
-  }
-
-  bool skipToClosing(T opening, T closing)
-  {
-    alias token next;
-    uint level = 1;
-    while (1)
-    {
-      lexer.peek(next);
-      if (next.kind == opening)
-        ++level;
-      else if (next.kind == closing && --level == 0)
-        return true;
-      else if (next.kind == T.EOF)
-        break;
-    }
-    return false;
-  }
-
-  void skipToTokenAfterClosingParen()
-  {
-    skipToClosing(T.LParen, T.RParen);
-    nT();
-  }
-
-  void skipToTokenAfterClosingBrace()
-  {
-    skipToClosing(T.LBrace, T.RBrace);
-    nT();
-  }
-
-  void skip(TOK tok)
-  {
-    token.kind == tok && nT();
-  }
-
-  void parseProtectionAttribute()
-  {
-    Protection prot;
-    switch (token.kind)
-    {
-    case T.Private:
-      prot = Protection.Private; break;
-    case T.Package:
-      prot = Protection.Package; break;
-    case T.Protected:
-      prot = Protection.Protected; break;
-    case T.Public:
-      prot = Protection.Public; break;
-    case T.Export:
-      prot = Protection.Export; break;
-    default:
-      assert(0);
-    }
-    nT();
-    parseDeclarationsBlock(prot);
-  }
-
-  void parseDeclarationDefinition(Protection prot)
-  {
-    switch (token.kind)
-    {
-    case T.Align:
-      nT();
-      if (token.kind == T.LParen)
-        nT(), nT(), nT(); // ( Integer )
-      parseDeclarationsBlock(prot);
-      break;
-    case T.Pragma:
-      nT();
-      skipToTokenAfterClosingParen();
-      parseDeclarationsBlock(prot);
-      break;
-    case T.Export,
-         T.Private,
-         T.Package,
-         T.Protected,
-         T.Public:
-      parseProtectionAttribute();
-      break;
-    // Storage classes
-    case T.Extern:
-      nT();
-      token.kind == T.LParen && skipToTokenAfterClosingParen();
-      parseDeclarationsBlock(prot);
-      break;
-    case T.Const:
-    version(D2)
-    {
-      if (peekNext() == T.LParen)
-        goto case_Declaration;
-    }
-    case T.Override,
-         T.Deprecated,
-         T.Abstract,
-         T.Synchronized,
-         // T.Static,
-         T.Final,
-         T.Auto,
-         T.Scope:
-    case_StaticAttribute:
-    case_InvariantAttribute:
-      nT();
-      parseDeclarationsBlock(prot);
-      break;
-    // End of storage classes.
-    case T.Alias, T.Typedef:
-      nT();
-      goto case_Declaration;
-    case T.Static:
-      switch (peekNext())
-      {
-      case T.Import:
-        goto case_Import;
-      case T.This:
-        nT(), nT(); // static this
-        skipToTokenAfterClosingParen();
-        parseFunctionBody();
-        break;
-      case T.Tilde:
-        nT(), nT(), nT(), nT(), nT(); // static ~ this ( )
-        parseFunctionBody();
-        break;
-      case T.If:
-        nT(), nT();
-        skipToTokenAfterClosingParen();
-        parseDeclarationsBlock(prot);
-        if (token.kind == T.Else)
-          nT(), parseDeclarationsBlock(prot);
-        break;
-      case T.Assert:
-        nT(), nT(); // static assert
-        skipToTokenAfterClosingParen();
-        skip(T.Semicolon);
-        break;
-      default:
-        goto case_StaticAttribute;
-      }
-      break;
-    case T.Import:
-    case_Import:
-      auto decl = parseImportDeclaration();
-      decl.setProtection(prot); // Set the protection attribute.
-      imports ~= decl.to!(ImportDeclaration);
-      break;
-    case T.Enum:
-      nT();
-      token.kind == T.Identifier && nT();
-      if (token.kind == T.Colon)
-      {
-        nT();
-        while (token.kind != T.LBrace && token.kind != T.EOF)
-          nT();
-      }
-      if (token.kind == T.Semicolon)
-        nT();
-      else
-        skipToTokenAfterClosingBrace();
-      break;
-    case T.Class:
-    case T.Interface:
-      nT(), skip(T.Identifier); // class Identifier
-      token.kind == T.LParen && skipToTokenAfterClosingParen(); // Skip template params.
-      if (token.kind == T.Colon)
-      { // BaseClasses
-        nT();
-        while (token.kind != T.LBrace && token.kind != T.EOF)
-          if (token.kind == T.LParen) // Skip ( tokens... )
-            skipToTokenAfterClosingParen();
-          else
-            nT();
-      }
-      if (token.kind == T.Semicolon)
-        nT();
-      else
-        parseDeclarationDefinitionsBlock(Protection.None);
-      break;
-    case T.Struct, T.Union:
-      nT(); skip(T.Identifier);
-      token.kind == T.LParen && skipToTokenAfterClosingParen();
-      if (token.kind == T.Semicolon)
-        nT();
-      else
-        parseDeclarationDefinitionsBlock(Protection.None);
-      break;
-    case T.Tilde:
-      nT(); // ~
-    case T.This:
-      nT(); nT(); nT(); // this ( )
-      parseFunctionBody();
-      break;
-    case T.Invariant:
-    version(D2)
-    {
-      auto next = token;
-      if (peekAfter(next) == T.LParen)
-      {
-        if (peekAfter(next) != T.RParen)
-          goto case_Declaration;
-      }
-      else
-        goto case_InvariantAttribute;
-    }
-      nT();
-      token.kind == T.LParen && skipToTokenAfterClosingParen();
-      parseFunctionBody();
-      break;
-    case T.Unittest:
-      nT();
-      parseFunctionBody();
-      break;
-    case T.Debug:
-      nT();
-      if (token.kind == T.Assign)
-      {
-        nT(), nT(), nT(); // = Condition ;
-        break;
-      }
-      if (token.kind == T.LParen)
-        nT(), nT(), nT(); // ( Condition )
-      parseDeclarationsBlock(prot);
-      if (token.kind == T.Else)
-        nT(), parseDeclarationsBlock(prot);
-      break;
-    case T.Version:
-      nT();
-      if (token.kind == T.Assign)
-      {
-        nT(), nT(), nT(); // = Condition ;
-        break;
-      }
-      nT(), nT(), nT(); // ( Condition )
-      parseDeclarationsBlock(prot);
-      if (token.kind == T.Else)
-        nT(), parseDeclarationsBlock(prot);
-      break;
-    case T.Template:
-      nT();
-      skip(T.Identifier);
-      skipToTokenAfterClosingParen();
-      parseDeclarationDefinitionsBlock(Protection.None);
-      break;
-    case T.New:
-      nT();
-      skipToTokenAfterClosingParen();
-      parseFunctionBody();
-      break;
-    case T.Delete:
-      nT();
-      skipToTokenAfterClosingParen();
-      parseFunctionBody();
-      break;
-    case T.Mixin:
-      while (token.kind != T.Semicolon && token.kind != T.EOF)
-        if (token.kind == T.LParen)
-          skipToTokenAfterClosingParen();
-        else
-          nT();
-      skip(T.Semicolon);
-      break;
-    case T.Semicolon:
-      nT();
-      break;
-    // Declaration
-    case T.Identifier, T.Dot, T.Typeof:
-    case_Declaration:
-      while (token.kind != T.Semicolon && token.kind != T.EOF)
-        if (token.kind == T.LParen)
-          skipToTokenAfterClosingParen();
-        else if (token.kind == T.LBrace)
-          skipToTokenAfterClosingBrace();
-        else
-          nT();
-      skip(T.Semicolon);
-      break;
-    default:
-      if (token.isIntegralType)
-        goto case_Declaration;
-      nT();
-    }
-  }
-
-  FuncBodyStatement parseFunctionBody()
-  {
-    while (1)
-    {
-      switch (token.kind)
-      {
-      case T.LBrace:
-        skipToTokenAfterClosingBrace();
-        break;
-      case T.Semicolon:
-        nT();
-        break;
-      case T.In:
-        nT();
-        skipToTokenAfterClosingBrace();
-        continue;
-      case T.Out:
-        nT();
-        if (token.kind == T.LParen)
-          nT(), nT(), nT(); // ( Identifier )
-        skipToTokenAfterClosingBrace();
-        continue;
-      case T.Body:
-        nT();
-        goto case T.LBrace;
-      default:
-      }
-      break; // Exit loop.
-    }
-    return null;
-  }
-}
--- a/trunk/src/dil/parser/Parser.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4127 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.parser.Parser;
-
-import dil.lexer.Lexer;
-import dil.ast.Node;
-import dil.ast.Declarations;
-import dil.ast.Statements;
-import dil.ast.Expressions;
-import dil.ast.Types;
-import dil.ast.Parameters;
-import dil.lexer.IdTable;
-import dil.Messages;
-import dil.Information;
-import dil.Enums;
-import dil.CompilerInfo;
-import dil.SourceText;
-import dil.Unicode;
-import common;
-
-/// The Parser produces a full parse tree by examining
-/// the list of tokens provided by the Lexer.
-class Parser
-{
-  Lexer lexer; /// Used to lex the source code.
-  Token* token; /// Current non-whitespace token.
-  Token* prevToken; /// Previous non-whitespace token.
-
-  InfoManager infoMan;
-  ParserError[] errors;
-
-  ImportDeclaration[] imports; /// ImportDeclarations in the source text.
-
-  /// Attributes are evaluated in the parsing phase.
-  /// TODO: will be removed. SemanticPass1 takes care of attributes.
-  LinkageType linkageType;
-  Protection protection; /// ditto
-  StorageClass storageClass; /// ditto
-  uint alignSize = DEFAULT_ALIGN_SIZE; /// ditto
-
-  private alias TOK T; /// Used often in this class.
-  private alias TypeNode Type;
-
-  /// Constructs a Parser object.
-  /// Params:
-  ///   text     = the UTF-8 source code.
-  ///   infoMan  = used for collecting error messages.
-  this(SourceText srcText, InfoManager infoMan = null)
-  {
-    this.infoMan = infoMan;
-    lexer = new Lexer(srcText, infoMan);
-  }
-
-  /// Moves to the first token.
-  protected void init()
-  {
-    nT();
-    prevToken = token;
-  }
-
-  /// Moves to the next token.
-  void nT()
-  {
-    prevToken = token;
-    do
-    {
-      lexer.nextToken();
-      token = lexer.token;
-    } while (token.isWhitespace) // Skip whitespace
-  }
-
-  /// Start the parser and return the parsed Declarations.
-  CompoundDeclaration start()
-  {
-    init();
-    auto begin = token;
-    auto decls = new CompoundDeclaration;
-    if (token.kind == T.Module)
-      decls ~= parseModuleDeclaration();
-    decls.addOptChildren(parseDeclarationDefinitions());
-    set(decls, begin);
-    return decls;
-  }
-
-  /// Start the parser and return the parsed Expression.
-  Expression start2()
-  {
-    init();
-    return parseExpression();
-  }
-
-  // Members related to the method try_().
-  uint trying; /// Greater than 0 if Parser is in try_().
-  uint errorCount; /// Used to track nr. of errors while being in try_().
-
-  /// This method executes the delegate parseMethod and when an error occurred
-  /// the state of the lexer and parser are restored.
-  /// Returns: the return value of parseMethod().
-  ReturnType try_(ReturnType)(ReturnType delegate() parseMethod, out bool success)
-  {
-    // Save members.
-    auto oldToken     = this.token;
-    auto oldPrevToken = this.prevToken;
-    auto oldCount     = this.errorCount;
-
-    ++trying;
-    auto result = parseMethod();
-    --trying;
-    // Check if an error occurred.
-    if (errorCount != oldCount)
-    { // Restore members.
-      token       = oldToken;
-      prevToken   = oldPrevToken;
-      lexer.token = oldToken;
-      errorCount  = oldCount;
-      success = false;
-    }
-    else
-      success = true;
-    return result;
-  }
-
-  /// Sets the begin and end tokens of a syntax tree node.
-  Class set(Class)(Class node, Token* begin)
-  {
-    node.setTokens(begin, this.prevToken);
-    return node;
-  }
-
-  /// Sets the begin and end tokens of a syntax tree node.
-  Class set(Class)(Class node, Token* begin, Token* end)
-  {
-    node.setTokens(begin, end);
-    return node;
-  }
-
-  /// Returns true if set() has been called on a node.
-  static bool isNodeSet(Node node)
-  {
-    return node.begin !is null && node.end !is null;
-  }
-
-  /// Returns the token kind of the next token.
-  TOK peekNext()
-  {
-    Token* next = token;
-    do
-      lexer.peek(next);
-    while (next.isWhitespace) // Skip whitespace
-    return next.kind;
-  }
-
-  /// Returns the token kind of the token that comes after t.
-  TOK peekAfter(ref Token* t)
-  {
-    assert(t !is null);
-    do
-      lexer.peek(t);
-    while (t.isWhitespace) // Skip whitespace
-    return t.kind;
-  }
-
-  /// Consumes the current token if its kind matches k and returns true.
-  bool consumed()(TOK k) // Templatized, so it's inlined.
-  {
-    return token.kind == k ? (nT(), true) : false;
-  }
-
-  /// Asserts that the current token is of kind expectedKind,
-  /// and then moves to the next token.
-  void skip()(TOK expectedKind)
-  {
-    assert(token.kind == expectedKind /+|| *(int*).init+/, token.srcText());
-    nT();
-  }
-
-  /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  |                        Declaration parsing methods                        |
-   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
-
-  Declaration parseModuleDeclaration()
-  {
-    skip(T.Module);
-    auto begin = token;
-    ModuleFQN moduleFQN;
-    do
-      moduleFQN ~= requireIdentifier(MSG.ExpectedModuleIdentifier);
-    while (consumed(T.Dot))
-    require(T.Semicolon);
-    return set(new ModuleDeclaration(moduleFQN), begin);
-  }
-
-  /// Parses DeclarationDefinitions until the end of file is hit.
-  /// $(PRE
-  /// DeclDefs :=
-  ///     DeclDef
-  ///     DeclDefs
-  /// )
-  Declaration[] parseDeclarationDefinitions()
-  {
-    Declaration[] decls;
-    while (token.kind != T.EOF)
-      decls ~= parseDeclarationDefinition();
-    return decls;
-  }
-
-  /// Parse the body of a template, class, interface, struct or union.
-  /// $(PRE
-  /// DeclDefsBlock :=
-  ///     { }
-  ///     { DeclDefs }
-  /// )
-  CompoundDeclaration parseDeclarationDefinitionsBody()
-  {
-    // Save attributes.
-    auto linkageType  = this.linkageType;
-    auto protection   = this.protection;
-    auto storageClass = this.storageClass;
-    // Clear attributes.
-    this.linkageType  = LinkageType.None;
-    this.protection   = Protection.None;
-    this.storageClass = StorageClass.None;
-
-    // Parse body.
-    auto begin = token;
-    auto decls = new CompoundDeclaration;
-    require(T.LBrace);
-    while (token.kind != T.RBrace && token.kind != T.EOF)
-      decls ~= parseDeclarationDefinition();
-    require(T.RBrace);
-    set(decls, begin);
-
-    // Restore original values.
-    this.linkageType  = linkageType;
-    this.protection   = protection;
-    this.storageClass = storageClass;
-
-    return decls;
-  }
-
-  /// Parses a DeclarationDefinition.
-  Declaration parseDeclarationDefinition()
-  out(decl)
-  { assert(isNodeSet(decl)); }
-  body
-  {
-    auto begin = token;
-    Declaration decl;
-    switch (token.kind)
-    {
-    case T.Align,
-         T.Pragma,
-         // Protection attributes
-         T.Export,
-         T.Private,
-         T.Package,
-         T.Protected,
-         T.Public:
-      decl = parseAttributeSpecifier();
-      break;
-    // Storage classes
-    case T.Extern,
-         T.Deprecated,
-         T.Override,
-         T.Abstract,
-         T.Synchronized,
-         //T.Static,
-         T.Final,
-         T.Const,
-         //T.Invariant, // D 2.0
-         T.Auto,
-         T.Scope:
-    case_StaticAttribute:
-    case_InvariantAttribute: // D 2.0
-      return parseStorageAttribute();
-    case T.Alias:
-      nT();
-      decl = new AliasDeclaration(parseVariableOrFunction());
-      break;
-    case T.Typedef:
-      nT();
-      decl = new TypedefDeclaration(parseVariableOrFunction());
-      break;
-    case T.Static:
-      switch (peekNext())
-      {
-      case T.Import:
-        goto case_Import;
-      case T.This:
-        decl = parseStaticConstructorDeclaration();
-        break;
-      case T.Tilde:
-        decl = parseStaticDestructorDeclaration();
-        break;
-      case T.If:
-        decl = parseStaticIfDeclaration();
-        break;
-      case T.Assert:
-        decl = parseStaticAssertDeclaration();
-        break;
-      default:
-        goto case_StaticAttribute;
-      }
-      break;
-    case T.Import:
-    case_Import:
-      decl = parseImportDeclaration();
-      imports ~= decl.to!(ImportDeclaration);
-      // Handle specially. StorageClass mustn't be set.
-      decl.setProtection(this.protection);
-      return set(decl, begin);
-    case T.Enum:
-      decl = parseEnumDeclaration();
-      break;
-    case T.Class:
-      decl = parseClassDeclaration();
-      break;
-    case T.Interface:
-      decl = parseInterfaceDeclaration();
-      break;
-    case T.Struct, T.Union:
-      decl = parseStructOrUnionDeclaration();
-      break;
-    case T.This:
-      decl = parseConstructorDeclaration();
-      break;
-    case T.Tilde:
-      decl = parseDestructorDeclaration();
-      break;
-    case T.Invariant:
-    version(D2)
-    {
-      auto next = token;
-      if (peekAfter(next) == T.LParen)
-      {
-        if (peekAfter(next) != T.RParen)
-          goto case_Declaration;
-      }
-      else
-        goto case_InvariantAttribute;
-    }
-      decl = parseInvariantDeclaration();
-      break;
-    case T.Unittest:
-      decl = parseUnittestDeclaration();
-      break;
-    case T.Debug:
-      decl = parseDebugDeclaration();
-      break;
-    case T.Version:
-      decl = parseVersionDeclaration();
-      break;
-    case T.Template:
-      decl = parseTemplateDeclaration();
-      break;
-    case T.New:
-      decl = parseNewDeclaration();
-      break;
-    case T.Delete:
-      decl = parseDeleteDeclaration();
-      break;
-    case T.Mixin:
-      decl = parseMixin!(MixinDeclaration)();
-      break;
-    case T.Semicolon:
-      nT();
-      decl = new EmptyDeclaration();
-      break;
-    // Declaration
-    case T.Identifier, T.Dot, T.Typeof:
-    case_Declaration:
-      return parseVariableOrFunction(this.storageClass, this.protection, this.linkageType);
-    default:
-      if (token.isIntegralType)
-        goto case_Declaration;
-      else if (token.kind == T.Module)
-      {
-        decl = parseModuleDeclaration();
-        error(begin, MSG.ModuleDeclarationNotFirst);
-        return decl;
-      }
-
-      decl = new IllegalDeclaration();
-      // Skip to next valid token.
-      do
-        nT();
-      while (!token.isDeclDefStart &&
-              token.kind != T.RBrace &&
-              token.kind != T.EOF)
-      auto text = Token.textSpan(begin, this.prevToken);
-      error(begin, MSG.IllegalDeclaration, text);
-    }
-    decl.setProtection(this.protection);
-    decl.setStorageClass(this.storageClass);
-    assert(!isNodeSet(decl));
-    set(decl, begin);
-    return decl;
-  }
-
-  /// Parses a DeclarationsBlock.
-  /// $(PRE
-  /// DeclarationsBlock :=
-  ///     : DeclDefs
-  ///     { }
-  ///     { DeclDefs }
-  ///     DeclDef
-  /// )
-  Declaration parseDeclarationsBlock(/+bool noColon = false+/)
-  {
-    Declaration d;
-    switch (token.kind)
-    {
-    case T.LBrace:
-      auto begin = token;
-      nT();
-      auto decls = new CompoundDeclaration;
-      while (token.kind != T.RBrace && token.kind != T.EOF)
-        decls ~= parseDeclarationDefinition();
-      require(T.RBrace);
-      d = set(decls, begin);
-      break;
-    case T.Colon:
-      // if (noColon == true)
-      //   goto default;
-      nT();
-      auto begin = token;
-      auto decls = new CompoundDeclaration;
-      while (token.kind != T.RBrace && token.kind != T.EOF)
-        decls ~= parseDeclarationDefinition();
-      d = set(decls, begin);
-      break;
-    default:
-      d = parseDeclarationDefinition();
-    }
-    assert(isNodeSet(d));
-    return d;
-  }
-
-  // Declaration parseDeclarationsBlockNoColon()
-  // {
-  //   return parseDeclarationsBlock(true);
-  // }
-
-  /// Parses either a VariableDeclaration or a FunctionDeclaration.
-  /// Params:
-  ///   stc = previously parsed storage classes
-  ///   protection = previously parsed protection attribute
-  ///   linkType = previously parsed linkage type
-  ///   testAutoDeclaration = whether to check for an AutoDeclaration
-  ///   optionalParameterList = a hint for how to parse C-style function pointers
-  Declaration parseVariableOrFunction(StorageClass stc = StorageClass.None,
-                                      Protection protection = Protection.None,
-                                      LinkageType linkType = LinkageType.None,
-                                      bool testAutoDeclaration = false,
-                                      bool optionalParameterList = true)
-  {
-    auto begin = token;
-    Type type;
-    Identifier* name;
-
-    // Check for AutoDeclaration: StorageClasses Identifier =
-    if (testAutoDeclaration &&
-        token.kind == T.Identifier &&
-        peekNext() == T.Assign)
-    {
-      name = token.ident;
-      skip(T.Identifier);
-    }
-    else
-    {
-      type = parseType(); // VariableType or ReturnType
-      if (token.kind == T.LParen)
-      {
-        // C-style function pointers make the grammar ambiguous.
-        // We have to treat them specially at function scope.
-        // Example:
-        //   void foo() {
-        //     // A pointer to a function taking an integer and returning 'some_type'.
-        //     some_type (*p_func)(int);
-        //     // In the following case precedence is given to a CallExpression.
-        //     something(*p); // 'something' may be a function/method or an object having opCall overloaded.
-        //   }
-        //   // A pointer to a function taking no parameters and returning 'something'.
-        //   something(*p);
-        type = parseCFunctionPointerType(type, name, optionalParameterList);
-      }
-      else if (peekNext() == T.LParen)
-      { // Type FunctionName ( ParameterList ) FunctionBody
-        name = requireIdentifier(MSG.ExpectedFunctionName);
-        name || nT(); // Skip non-identifier token.
-        assert(token.kind == T.LParen);
-        // It's a function declaration
-        TemplateParameters tparams;
-        if (tokenAfterParenIs(T.LParen))
-          // ( TemplateParameterList ) ( ParameterList )
-          tparams = parseTemplateParameterList();
-
-        auto params = parseParameterList();
-      version(D2)
-      {
-        switch (token.kind)
-        {
-        case T.Const:
-          stc |= StorageClass.Const;
-          nT();
-          break;
-        case T.Invariant:
-          stc |= StorageClass.Invariant;
-          nT();
-          break;
-        default:
-        }
-      }
-        // ReturnType FunctionName ( ParameterList )
-        auto funcBody = parseFunctionBody();
-        auto fd = new FunctionDeclaration(type, name,/+ tparams,+/ params, funcBody);
-        fd.setStorageClass(stc);
-        fd.setLinkageType(linkType);
-        fd.setProtection(protection);
-        if (tparams)
-        {
-          auto d = putInsideTemplateDeclaration(begin, name, fd, tparams);
-          d.setStorageClass(stc);
-          d.setProtection(protection);
-          return set(d, begin);
-        }
-        return set(fd, begin);
-      }
-      else
-      { // Type VariableName DeclaratorSuffix
-        name = requireIdentifier(MSG.ExpectedVariableName);
-        type = parseDeclaratorSuffix(type);
-      }
-    }
-
-    // It's a variables declaration.
-    Identifier*[] names = [name]; // One identifier has been parsed already.
-    Expression[] values;
-    goto LenterLoop; // Enter the loop and check for an initializer.
-    while (consumed(T.Comma))
-    {
-      names ~= requireIdentifier(MSG.ExpectedVariableName);
-    LenterLoop:
-      if (consumed(T.Assign))
-        values ~= parseInitializer();
-      else
-        values ~= null;
-    }
-    require(T.Semicolon);
-    auto d = new VariablesDeclaration(type, names, values);
-    d.setStorageClass(stc);
-    d.setLinkageType(linkType);
-    d.setProtection(protection);
-    return set(d, begin);
-  }
-
-  /// Parses a variable initializer.
-  Expression parseInitializer()
-  {
-    if (token.kind == T.Void)
-    {
-      auto begin = token;
-      auto next = peekNext();
-      if (next == T.Comma || next == T.Semicolon)
-      {
-        skip(T.Void);
-        return set(new VoidInitExpression(), begin);
-      }
-    }
-    return parseNonVoidInitializer();
-  }
-
-  Expression parseNonVoidInitializer()
-  {
-    auto begin = token;
-    Expression init;
-    switch (token.kind)
-    {
-    case T.LBracket:
-      // ArrayInitializer:
-      //         [ ]
-      //         [ ArrayMemberInitializations ]
-      Expression[] keys;
-      Expression[] values;
-
-      skip(T.LBracket);
-      while (token.kind != T.RBracket)
-      {
-        auto e = parseNonVoidInitializer();
-        if (consumed(T.Colon))
-        {
-          keys ~= e;
-          values ~= parseNonVoidInitializer();
-        }
-        else
-        {
-          keys ~= null;
-          values ~= e;
-        }
-
-        if (!consumed(T.Comma))
-          break;
-      }
-      require(T.RBracket);
-      init = new ArrayInitExpression(keys, values);
-      break;
-    case T.LBrace:
-      // StructInitializer:
-      //         { }
-      //         { StructMemberInitializers }
-      Expression parseStructInitializer()
-      {
-        Identifier*[] idents;
-        Expression[] values;
-
-        skip(T.LBrace);
-        while (token.kind != T.RBrace)
-        {
-          if (token.kind == T.Identifier &&
-              // Peek for colon to see if this is a member identifier.
-              peekNext() == T.Colon)
-          {
-            idents ~= token.ident;
-            skip(T.Identifier), skip(T.Colon);
-          }
-          else
-            idents ~= null;
-
-          // NonVoidInitializer
-          values ~= parseNonVoidInitializer();
-
-          if (!consumed(T.Comma))
-            break;
-        }
-        require(T.RBrace);
-        return new StructInitExpression(idents, values);
-      }
-
-      bool success;
-      auto si = try_(&parseStructInitializer, success);
-      if (success)
-      {
-        init = si;
-        break;
-      }
-      assert(token.kind == T.LBrace);
-      //goto default;
-    default:
-      init = parseAssignExpression();
-    }
-    set(init, begin);
-    return init;
-  }
-
-  FuncBodyStatement parseFunctionBody()
-  {
-    auto begin = token;
-    auto func = new FuncBodyStatement;
-    while (1)
-    {
-      switch (token.kind)
-      {
-      case T.LBrace:
-        func.funcBody = parseStatements();
-        break;
-      case T.Semicolon:
-        nT();
-        break;
-      case T.In:
-        if (func.inBody)
-          error(MID.InContract);
-        nT();
-        func.inBody = parseStatements();
-        continue;
-      case T.Out:
-        if (func.outBody)
-          error(MID.OutContract);
-        nT();
-        if (consumed(T.LParen))
-        {
-          func.outIdent = requireIdentifier(MSG.ExpectedAnIdentifier);
-          require(T.RParen);
-        }
-        func.outBody = parseStatements();
-        continue;
-      case T.Body:
-        nT();
-        goto case T.LBrace;
-      default:
-        error(token, MSG.ExpectedFunctionBody, token.srcText);
-      }
-      break; // Exit loop.
-    }
-    set(func, begin);
-    func.finishConstruction();
-    return func;
-  }
-
-  LinkageType parseLinkageType()
-  {
-    LinkageType linkageType;
-
-    if (!consumed(T.LParen))
-      return linkageType;
-
-    if (consumed(T.RParen))
-    { // extern()
-      error(MID.MissingLinkageType);
-      return linkageType;
-    }
-
-    auto identTok = requireId();
-
-    IDK idKind = identTok ? identTok.ident.idKind : IDK.Null;
-
-    switch (idKind)
-    {
-    case IDK.C:
-      if (consumed(T.PlusPlus))
-      {
-        linkageType = LinkageType.Cpp;
-        break;
-      }
-      linkageType = LinkageType.C;
-      break;
-    case IDK.D:
-      linkageType = LinkageType.D;
-      break;
-    case IDK.Windows:
-      linkageType = LinkageType.Windows;
-      break;
-    case IDK.Pascal:
-      linkageType = LinkageType.Pascal;
-      break;
-    case IDK.System:
-      linkageType = LinkageType.System;
-      break;
-    default:
-      error(MID.UnrecognizedLinkageType, token.srcText);
-    }
-    require(T.RParen);
-    return linkageType;
-  }
-
-  void checkLinkageType(ref LinkageType prev_lt, LinkageType lt, Token* begin)
-  {
-    if (prev_lt == LinkageType.None)
-      prev_lt = lt;
-    else
-      error(begin, MSG.RedundantLinkageType, Token.textSpan(begin, this.prevToken));
-  }
-
-  Declaration parseStorageAttribute()
-  {
-    StorageClass stc, stc_tmp;
-    LinkageType prev_linkageType;
-
-    auto saved_storageClass = this.storageClass; // Save.
-    // Nested function.
-    Declaration parse()
-    {
-      Declaration decl;
-      auto begin = token;
-      switch (token.kind)
-      {
-      case T.Extern:
-        if (peekNext() != T.LParen)
-        {
-          stc_tmp = StorageClass.Extern;
-          goto Lcommon;
-        }
-
-        nT();
-        auto linkageType = parseLinkageType();
-        checkLinkageType(prev_linkageType, linkageType, begin);
-
-        auto saved = this.linkageType; // Save.
-        this.linkageType = linkageType; // Set.
-        decl = new LinkageDeclaration(linkageType, parse());
-        set(decl, begin);
-        this.linkageType = saved; // Restore.
-        break;
-      case T.Override:
-        stc_tmp = StorageClass.Override;
-        goto Lcommon;
-      case T.Deprecated:
-        stc_tmp = StorageClass.Deprecated;
-        goto Lcommon;
-      case T.Abstract:
-        stc_tmp = StorageClass.Abstract;
-        goto Lcommon;
-      case T.Synchronized:
-        stc_tmp = StorageClass.Synchronized;
-        goto Lcommon;
-      case T.Static:
-        stc_tmp = StorageClass.Static;
-        goto Lcommon;
-      case T.Final:
-        stc_tmp = StorageClass.Final;
-        goto Lcommon;
-      case T.Const:
-      version(D2)
-      {
-        if (peekNext() == T.LParen)
-          goto case_Declaration;
-      }
-        stc_tmp = StorageClass.Const;
-        goto Lcommon;
-      version(D2)
-      {
-      case T.Invariant: // D 2.0
-        auto next = token;
-        if (peekAfter(next) == T.LParen)
-        {
-          if (peekAfter(next) != T.RParen)
-            goto case_Declaration; // invariant ( Type )
-          decl = parseDeclarationDefinition(); // invariant ( )
-          decl.setStorageClass(stc);
-          break;
-        }
-        // invariant as StorageClass.
-        stc_tmp = StorageClass.Invariant;
-        goto Lcommon;
-      }
-      case T.Auto:
-        stc_tmp = StorageClass.Auto;
-        goto Lcommon;
-      case T.Scope:
-        stc_tmp = StorageClass.Scope;
-        goto Lcommon;
-      Lcommon:
-        // Issue error if redundant.
-        if (stc & stc_tmp)
-          error(MID.RedundantStorageClass, token.srcText);
-        else
-          stc |= stc_tmp;
-
-        nT();
-        decl = new StorageClassDeclaration(stc_tmp, parse());
-        set(decl, begin);
-        break;
-      case T.Identifier:
-      case_Declaration:
-        // This could be a normal Declaration or an AutoDeclaration
-        decl = parseVariableOrFunction(stc, this.protection, prev_linkageType, true);
-        break;
-      default:
-        this.storageClass = stc; // Set.
-        decl = parseDeclarationsBlock();
-        this.storageClass = saved_storageClass; // Reset.
-      }
-      assert(isNodeSet(decl));
-      return decl;
-    }
-    return parse();
-  }
-
-  uint parseAlignAttribute()
-  {
-    skip(T.Align);
-    uint size = DEFAULT_ALIGN_SIZE; // Global default.
-    if (consumed(T.LParen))
-    {
-      if (token.kind == T.Int32)
-        (size = token.int_), skip(T.Int32);
-      else
-        expected(T.Int32);
-      require(T.RParen);
-    }
-    return size;
-  }
-
-  Declaration parseAttributeSpecifier()
-  {
-    Declaration decl;
-
-    switch (token.kind)
-    {
-    case T.Align:
-      uint alignSize = parseAlignAttribute();
-      auto saved = this.alignSize; // Save.
-      this.alignSize = alignSize; // Set.
-      decl = new AlignDeclaration(alignSize, parseDeclarationsBlock());
-      this.alignSize = saved; // Restore.
-      break;
-    case T.Pragma:
-      // Pragma:
-      //     pragma ( Identifier )
-      //     pragma ( Identifier , ExpressionList )
-      nT();
-      Identifier* ident;
-      Expression[] args;
-
-      require(T.LParen);
-      ident = requireIdentifier(MSG.ExpectedPragmaIdentifier);
-
-      if (consumed(T.Comma))
-        args = parseExpressionList();
-      require(T.RParen);
-
-      decl = new PragmaDeclaration(ident, args, parseDeclarationsBlock());
-      break;
-    default:
-      // Protection attributes
-      Protection prot;
-      switch (token.kind)
-      {
-      case T.Private:
-        prot = Protection.Private; break;
-      case T.Package:
-        prot = Protection.Package; break;
-      case T.Protected:
-        prot = Protection.Protected; break;
-      case T.Public:
-        prot = Protection.Public; break;
-      case T.Export:
-        prot = Protection.Export; break;
-      default:
-        assert(0);
-      }
-      nT();
-      auto saved = this.protection; // Save.
-      this.protection = prot; // Set.
-      decl = new ProtectionDeclaration(prot, parseDeclarationsBlock());
-      this.protection = saved; // Restore.
-    }
-    return decl;
-  }
-
-  Declaration parseImportDeclaration()
-  {
-    bool isStatic = consumed(T.Static);
-    skip(T.Import);
-
-    ModuleFQN[] moduleFQNs;
-    Identifier*[] moduleAliases;
-    Identifier*[] bindNames;
-    Identifier*[] bindAliases;
-
-    do
-    {
-      ModuleFQN moduleFQN;
-      Identifier* moduleAlias;
-      // AliasName = ModuleName
-      if (peekNext() == T.Assign)
-      {
-        moduleAlias = requireIdentifier(MSG.ExpectedAliasModuleName);
-        skip(T.Assign);
-      }
-      // Identifier ("." Identifier)*
-      do
-        moduleFQN ~= requireIdentifier(MSG.ExpectedModuleIdentifier);
-      while (consumed(T.Dot))
-      // Push identifiers.
-      moduleFQNs ~= moduleFQN;
-      moduleAliases ~= moduleAlias;
-    } while (consumed(T.Comma))
-
-    if (consumed(T.Colon))
-    { // BindAlias "=" BindName ("," BindAlias "=" BindName)*;
-      // BindName ("," BindName)*;
-      do
-      {
-        Identifier* bindAlias;
-        // BindAlias = BindName
-        if (peekNext() == T.Assign)
-        {
-          bindAlias = requireIdentifier(MSG.ExpectedAliasImportName);
-          skip(T.Assign);
-        }
-        // Push identifiers.
-        bindNames ~= requireIdentifier(MSG.ExpectedImportName);
-        bindAliases ~= bindAlias;
-      } while (consumed(T.Comma))
-    }
-    require(T.Semicolon);
-
-    return new ImportDeclaration(moduleFQNs, moduleAliases, bindNames, bindAliases, isStatic);
-  }
-
-  Declaration parseEnumDeclaration()
-  {
-    skip(T.Enum);
-
-    Identifier* enumName;
-    Type baseType;
-    EnumMemberDeclaration[] members;
-    bool hasBody;
-
-    enumName = optionalIdentifier();
-
-    if (consumed(T.Colon))
-      baseType = parseBasicType();
-
-    if (enumName && consumed(T.Semicolon))
-    {}
-    else if (consumed(T.LBrace))
-    {
-      hasBody = true;
-      while (token.kind != T.RBrace)
-      {
-        auto begin = token;
-        auto name = requireIdentifier(MSG.ExpectedEnumMember);
-        Expression value;
-
-        if (consumed(T.Assign))
-          value = parseAssignExpression();
-        else
-          value = null;
-
-        members ~= set(new EnumMemberDeclaration(name, value), begin);
-
-        if (!consumed(T.Comma))
-          break;
-      }
-      require(T.RBrace);
-    }
-    else
-      error(token, MSG.ExpectedEnumBody, token.srcText);
-
-    return new EnumDeclaration(enumName, baseType, members, hasBody);
-  }
-
-  /// Wraps a declaration inside a template declaration.
-  /// Params:
-  ///   begin = begin token of decl.
-  ///   name = name of decl.
-  ///   decl = the declaration to be wrapped.
-  ///   tparams = the template parameters.
-  TemplateDeclaration putInsideTemplateDeclaration(Token* begin,
-                                                   Identifier* name,
-                                                   Declaration decl,
-                                                   TemplateParameters tparams)
-  {
-    set(decl, begin);
-    auto cd = new CompoundDeclaration;
-    cd ~= decl;
-    set(cd, begin);
-    return new TemplateDeclaration(name, tparams, cd);
-  }
-
-  Declaration parseClassDeclaration()
-  {
-    auto begin = token;
-    skip(T.Class);
-
-    Identifier* className;
-    TemplateParameters tparams;
-    BaseClassType[] bases;
-    CompoundDeclaration decls;
-
-    className = requireIdentifier(MSG.ExpectedClassName);
-
-    if (token.kind == T.LParen)
-      tparams = parseTemplateParameterList();
-
-    if (token.kind == T.Colon)
-      bases = parseBaseClasses();
-
-    if (bases.length == 0 && consumed(T.Semicolon))
-    {}
-    else if (token.kind == T.LBrace)
-      decls = parseDeclarationDefinitionsBody();
-    else
-      error(token, MSG.ExpectedClassBody, token.srcText);
-
-    Declaration d = new ClassDeclaration(className, /+tparams, +/bases, decls);
-    if (tparams)
-      d = putInsideTemplateDeclaration(begin, className, d, tparams);
-    return d;
-  }
-
-  BaseClassType[] parseBaseClasses(bool colonLeadsOff = true)
-  {
-    colonLeadsOff && skip(T.Colon);
-
-    BaseClassType[] bases;
-    do
-    {
-      Protection prot = Protection.Public;
-      switch (token.kind)
-      {
-      case T.Identifier, T.Dot, T.Typeof: goto LparseBasicType;
-      case T.Private:   prot = Protection.Private;   break;
-      case T.Protected: prot = Protection.Protected; break;
-      case T.Package:   prot = Protection.Package;   break;
-      case T.Public:  /*prot = Protection.Public;*/  break;
-      default:
-        error(MID.ExpectedBaseClasses, token.srcText);
-        return bases;
-      }
-      nT(); // Skip protection attribute.
-    LparseBasicType:
-      auto begin = token;
-      auto type = parseBasicType();
-      bases ~= set(new BaseClassType(prot, type), begin);
-    } while (consumed(T.Comma))
-    return bases;
-  }
-
-  Declaration parseInterfaceDeclaration()
-  {
-    auto begin = token;
-    skip(T.Interface);
-
-    Identifier* name;
-    TemplateParameters tparams;
-    BaseClassType[] bases;
-    CompoundDeclaration decls;
-
-    name = requireIdentifier(MSG.ExpectedInterfaceName);
-
-    if (token.kind == T.LParen)
-      tparams = parseTemplateParameterList();
-
-    if (token.kind == T.Colon)
-      bases = parseBaseClasses();
-
-    if (bases.length == 0 && consumed(T.Semicolon))
-    {}
-    else if (token.kind == T.LBrace)
-      decls = parseDeclarationDefinitionsBody();
-    else
-      error(token, MSG.ExpectedInterfaceBody, token.srcText);
-
-    Declaration d = new InterfaceDeclaration(name, /+tparams, +/bases, decls);
-    if (tparams)
-      d = putInsideTemplateDeclaration(begin, name, d, tparams);
-    return d;
-  }
-
-  Declaration parseStructOrUnionDeclaration()
-  {
-    assert(token.kind == T.Struct || token.kind == T.Union);
-    auto begin = token;
-    skip(token.kind);
-
-    Identifier* name;
-    TemplateParameters tparams;
-    CompoundDeclaration decls;
-
-    name = optionalIdentifier();
-
-    if (name && token.kind == T.LParen)
-      tparams = parseTemplateParameterList();
-
-    if (name && consumed(T.Semicolon))
-    {}
-    else if (token.kind == T.LBrace)
-      decls = parseDeclarationDefinitionsBody();
-    else
-      error(token, begin.kind == T.Struct ?
-                   MSG.ExpectedStructBody :
-                   MSG.ExpectedUnionBody, token.srcText);
-
-    Declaration d;
-    if (begin.kind == T.Struct)
-    {
-      auto sd = new StructDeclaration(name, /+tparams, +/decls);
-      sd.setAlignSize(this.alignSize);
-      d = sd;
-    }
-    else
-      d = new UnionDeclaration(name, /+tparams, +/decls);
-
-    if (tparams)
-      d = putInsideTemplateDeclaration(begin, name, d, tparams);
-    return d;
-  }
-
-  Declaration parseConstructorDeclaration()
-  {
-    skip(T.This);
-    auto parameters = parseParameterList();
-    auto funcBody = parseFunctionBody();
-    return new ConstructorDeclaration(parameters, funcBody);
-  }
-
-  Declaration parseDestructorDeclaration()
-  {
-    skip(T.Tilde);
-    require(T.This);
-    require(T.LParen);
-    require(T.RParen);
-    auto funcBody = parseFunctionBody();
-    return new DestructorDeclaration(funcBody);
-  }
-
-  Declaration parseStaticConstructorDeclaration()
-  {
-    skip(T.Static);
-    skip(T.This);
-    require(T.LParen);
-    require(T.RParen);
-    auto funcBody = parseFunctionBody();
-    return new StaticConstructorDeclaration(funcBody);
-  }
-
-  Declaration parseStaticDestructorDeclaration()
-  {
-    skip(T.Static);
-    skip(T.Tilde);
-    require(T.This);
-    require(T.LParen);
-    require(T.RParen);
-    auto funcBody = parseFunctionBody();
-    return new StaticDestructorDeclaration(funcBody);
-  }
-
-  Declaration parseInvariantDeclaration()
-  {
-    skip(T.Invariant);
-    // Optional () for getting ready porting to D 2.0
-    if (consumed(T.LParen))
-      require(T.RParen);
-    auto funcBody = parseFunctionBody();
-    return new InvariantDeclaration(funcBody);
-  }
-
-  Declaration parseUnittestDeclaration()
-  {
-    skip(T.Unittest);
-    auto funcBody = parseFunctionBody();
-    return new UnittestDeclaration(funcBody);
-  }
-
-  Token* parseIdentOrInt()
-  {
-    if (consumed(T.Int32) || consumed(T.Identifier))
-      return this.prevToken;
-    error(token, MSG.ExpectedIdentOrInt, token.srcText);
-    return null;
-  }
-
-  Declaration parseDebugDeclaration()
-  {
-    skip(T.Debug);
-
-    Token* spec;
-    Token* cond;
-    Declaration decls, elseDecls;
-
-    if (consumed(T.Assign))
-    { // debug = Integer ;
-      // debug = Identifier ;
-      spec = parseIdentOrInt();
-      require(T.Semicolon);
-    }
-    else
-    { // ( Condition )
-      if (consumed(T.LParen))
-      {
-        cond = parseIdentOrInt();
-        require(T.RParen);
-      }
-      // debug DeclarationsBlock
-      // debug ( Condition ) DeclarationsBlock
-      decls = parseDeclarationsBlock();
-      // else DeclarationsBlock
-      if (consumed(T.Else))
-        elseDecls = parseDeclarationsBlock();
-    }
-
-    return new DebugDeclaration(spec, cond, decls, elseDecls);
-  }
-
-  Declaration parseVersionDeclaration()
-  {
-    skip(T.Version);
-
-    Token* spec;
-    Token* cond;
-    Declaration decls, elseDecls;
-
-    if (consumed(T.Assign))
-    { // version = Integer ;
-      // version = Identifier ;
-      spec = parseIdentOrInt();
-      require(T.Semicolon);
-    }
-    else
-    { // ( Condition )
-      require(T.LParen);
-      cond = parseIdentOrInt();
-      require(T.RParen);
-      // version ( Condition ) DeclarationsBlock
-      decls = parseDeclarationsBlock();
-      // else DeclarationsBlock
-      if (consumed(T.Else))
-        elseDecls = parseDeclarationsBlock();
-    }
-
-    return new VersionDeclaration(spec, cond, decls, elseDecls);
-  }
-
-  Declaration parseStaticIfDeclaration()
-  {
-    skip(T.Static);
-    skip(T.If);
-
-    Expression condition;
-    Declaration ifDecls, elseDecls;
-
-    require(T.LParen);
-    condition = parseAssignExpression();
-    require(T.RParen);
-
-    ifDecls = parseDeclarationsBlock();
-
-    if (consumed(T.Else))
-      elseDecls = parseDeclarationsBlock();
-
-    return new StaticIfDeclaration(condition, ifDecls, elseDecls);
-  }
-
-  Declaration parseStaticAssertDeclaration()
-  {
-    skip(T.Static);
-    skip(T.Assert);
-    Expression condition, message;
-    require(T.LParen);
-    condition = parseAssignExpression();
-    if (consumed(T.Comma))
-      message = parseAssignExpression();
-    require(T.RParen);
-    require(T.Semicolon);
-    return new StaticAssertDeclaration(condition, message);
-  }
-
-  Declaration parseTemplateDeclaration()
-  {
-    skip(T.Template);
-    auto templateName = requireIdentifier(MSG.ExpectedTemplateName);
-    auto templateParams = parseTemplateParameterList();
-    auto decls = parseDeclarationDefinitionsBody();
-    return new TemplateDeclaration(templateName, templateParams, decls);
-  }
-
-  Declaration parseNewDeclaration()
-  {
-    skip(T.New);
-    auto parameters = parseParameterList();
-    auto funcBody = parseFunctionBody();
-    return new NewDeclaration(parameters, funcBody);
-  }
-
-  Declaration parseDeleteDeclaration()
-  {
-    skip(T.Delete);
-    auto parameters = parseParameterList();
-    auto funcBody = parseFunctionBody();
-    return new DeleteDeclaration(parameters, funcBody);
-  }
-
-  Type parseTypeofType()
-  {
-    auto begin = token;
-    skip(T.Typeof);
-    require(T.LParen);
-    Type type;
-    switch (token.kind)
-    {
-    version(D2)
-    {
-    case T.Return:
-      nT();
-      type = new TypeofType();
-      break;
-    }
-    default:
-      type = new TypeofType(parseExpression());
-    }
-    require(T.RParen);
-    set(type, begin);
-    return type;
-  }
-
-  /// Parses a MixinDeclaration or MixinStatement.
-  /// $(PRE
-  /// TemplateMixin :=
-  ///         mixin ( AssignExpression ) ;
-  ///         mixin TemplateIdentifier ;
-  ///         mixin TemplateIdentifier MixinIdentifier ;
-  ///         mixin TemplateIdentifier !( TemplateArguments ) ;
-  ///         mixin TemplateIdentifier !( TemplateArguments ) MixinIdentifier ;
-  /// )
-  Class parseMixin(Class)()
-  {
-  static assert(is(Class == MixinDeclaration) || is(Class == MixinStatement));
-    skip(T.Mixin);
-
-  static if (is(Class == MixinDeclaration))
-  {
-    if (consumed(T.LParen))
-    {
-      auto e = parseAssignExpression();
-      require(T.RParen);
-      require(T.Semicolon);
-      return new MixinDeclaration(e);
-    }
-  }
-
-    auto begin = token;
-    Expression e;
-    Identifier* mixinIdent;
-
-    if (consumed(T.Dot))
-      e = set(new ModuleScopeExpression(parseIdentifierExpression()), begin);
-    else
-      e = parseIdentifierExpression();
-
-    while (consumed(T.Dot))
-      e = set(new DotExpression(e, parseIdentifierExpression()), begin);
-
-    mixinIdent = optionalIdentifier();
-    require(T.Semicolon);
-
-    return new Class(e, mixinIdent);
-  }
-
-  /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  |                         Statement parsing methods                         |
-   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
-
-  CompoundStatement parseStatements()
-  {
-    auto begin = token;
-    require(T.LBrace);
-    auto statements = new CompoundStatement();
-    while (token.kind != T.RBrace && token.kind != T.EOF)
-      statements ~= parseStatement();
-    require(T.RBrace);
-    return set(statements, begin);
-  }
-
-  /// Parses a Statement.
-  Statement parseStatement()
-  {
-    auto begin = token;
-    Statement s;
-    Declaration d;
-
-    if (token.isIntegralType)
-    {
-      d = parseVariableOrFunction();
-      goto LreturnDeclarationStatement;
-    }
-
-    switch (token.kind)
-    {
-    case T.Align:
-      uint size = parseAlignAttribute();
-      // Restrict align attribute to structs in parsing phase.
-      StructDeclaration structDecl;
-      if (token.kind == T.Struct)
-      {
-        auto begin2 = token;
-        structDecl = parseStructOrUnionDeclaration().to!(StructDeclaration);
-        structDecl.setAlignSize(size);
-        set(structDecl, begin2);
-      }
-      else
-        expected(T.Struct);
-
-      d = new AlignDeclaration(size, structDecl ? cast(Declaration)structDecl : new CompoundDeclaration);
-      goto LreturnDeclarationStatement;
-      /+ Not applicable for statements.
-         T.Private, T.Package, T.Protected, T.Public, T.Export,
-         T.Deprecated, T.Override, T.Abstract,+/
-    case T.Extern,
-         T.Final,
-         T.Const,
-         T.Auto:
-         //T.Scope
-         //T.Static
-    case_parseAttribute:
-      s = parseAttributeStatement();
-      return s;
-    case T.Identifier:
-      if (peekNext() == T.Colon)
-      {
-        auto ident = token.ident;
-        skip(T.Identifier); skip(T.Colon);
-        s = new LabeledStatement(ident, parseNoScopeOrEmptyStatement());
-        break;
-      }
-      goto case T.Dot;
-    case T.Dot, T.Typeof:
-      bool success;
-      d = try_(delegate {
-          return parseVariableOrFunction(StorageClass.None,
-                                         Protection.None,
-                                         LinkageType.None, false, false);
-        }, success
-      );
-      if (success)
-        goto LreturnDeclarationStatement; // Declaration
-      else
-        goto case_parseExpressionStatement; // Expression
-
-    case T.If:
-      s = parseIfStatement();
-      break;
-    case T.While:
-      s = parseWhileStatement();
-      break;
-    case T.Do:
-      s = parseDoWhileStatement();
-      break;
-    case T.For:
-      s = parseForStatement();
-      break;
-    case T.Foreach, T.Foreach_reverse:
-      s = parseForeachStatement();
-      break;
-    case T.Switch:
-      s = parseSwitchStatement();
-      break;
-    case T.Case:
-      s = parseCaseStatement();
-      break;
-    case T.Default:
-      s = parseDefaultStatement();
-      break;
-    case T.Continue:
-      s = parseContinueStatement();
-      break;
-    case T.Break:
-      s = parseBreakStatement();
-      break;
-    case T.Return:
-      s = parseReturnStatement();
-      break;
-    case T.Goto:
-      s = parseGotoStatement();
-      break;
-    case T.With:
-      s = parseWithStatement();
-      break;
-    case T.Synchronized:
-      s = parseSynchronizedStatement();
-      break;
-    case T.Try:
-      s = parseTryStatement();
-      break;
-    case T.Throw:
-      s = parseThrowStatement();
-      break;
-    case T.Scope:
-      if (peekNext() != T.LParen)
-        goto case_parseAttribute;
-      s = parseScopeGuardStatement();
-      break;
-    case T.Volatile:
-      s = parseVolatileStatement();
-      break;
-    case T.Asm:
-      s = parseAsmBlockStatement();
-      break;
-    case T.Pragma:
-      s = parsePragmaStatement();
-      break;
-    case T.Mixin:
-      if (peekNext() == T.LParen)
-        goto case_parseExpressionStatement; // Parse as expression.
-      s = parseMixin!(MixinStatement)();
-      break;
-    case T.Static:
-      switch (peekNext())
-      {
-      case T.If:
-        s = parseStaticIfStatement();
-        break;
-      case T.Assert:
-        s = parseStaticAssertStatement();
-        break;
-      default:
-        goto case_parseAttribute;
-      }
-      break;
-    case T.Debug:
-      s = parseDebugStatement();
-      break;
-    case T.Version:
-      s = parseVersionStatement();
-      break;
-    // DeclDef
-    case T.Alias, T.Typedef:
-      d = parseDeclarationDefinition();
-      goto LreturnDeclarationStatement;
-    case T.Enum:
-      d = parseEnumDeclaration();
-      goto LreturnDeclarationStatement;
-    case T.Class:
-      d = parseClassDeclaration();
-      goto LreturnDeclarationStatement;
-    case T.Interface:
-      d = parseInterfaceDeclaration();
-      goto LreturnDeclarationStatement;
-    case T.Struct, T.Union:
-      d = parseStructOrUnionDeclaration();
-      // goto LreturnDeclarationStatement;
-    LreturnDeclarationStatement:
-      set(d, begin);
-      s = new DeclarationStatement(d);
-      break;
-    case T.LBrace:
-      s = parseScopeStatement();
-      break;
-    case T.Semicolon:
-      nT();
-      s = new EmptyStatement();
-      break;
-    // Parse an ExpressionStatement:
-    // Tokens that start a PrimaryExpression.
-    // case T.Identifier, T.Dot, T.Typeof:
-    case T.This:
-    case T.Super:
-    case T.Null:
-    case T.True, T.False:
-    // case T.Dollar:
-    case T.Int32, T.Int64, T.Uint32, T.Uint64:
-    case T.Float32, T.Float64, T.Float80,
-         T.Imaginary32, T.Imaginary64, T.Imaginary80:
-    case T.CharLiteral:
-    case T.String:
-    case T.LBracket:
-    // case T.LBrace:
-    case T.Function, T.Delegate:
-    case T.Assert:
-    // case T.Mixin:
-    case T.Import:
-    case T.Typeid:
-    case T.Is:
-    case T.LParen:
-    case T.Traits: // D2.0
-    // Tokens that can start a UnaryExpression:
-    case T.AndBinary, T.PlusPlus, T.MinusMinus, T.Mul, T.Minus,
-         T.Plus, T.Not, T.Tilde, T.New, T.Delete, T.Cast:
-    case_parseExpressionStatement:
-      s = new ExpressionStatement(parseExpression());
-      require(T.Semicolon);
-      break;
-    default:
-      if (token.isSpecialToken)
-        goto case_parseExpressionStatement;
-
-      if (token.kind != T.Dollar)
-        // Assert that this isn't a valid expression.
-        assert(delegate bool(){
-            bool success;
-            auto expression = try_(&parseExpression, success);
-            return success;
-          }() == false, "Didn't expect valid expression."
-        );
-
-      // Report error: it's an illegal statement.
-      s = new IllegalStatement();
-      // Skip to next valid token.
-      do
-        nT();
-      while (!token.isStatementStart &&
-              token.kind != T.RBrace &&
-              token.kind != T.EOF)
-      auto text = Token.textSpan(begin, this.prevToken);
-      error(begin, MSG.IllegalStatement, text);
-    }
-    assert(s !is null);
-    set(s, begin);
-    return s;
-  }
-
-  /// $(PRE
-  /// Parses a ScopeStatement.
-  /// ScopeStatement :=
-  ///     NoScopeStatement
-  /// )
-  Statement parseScopeStatement()
-  {
-    return new ScopeStatement(parseNoScopeStatement());
-  }
-
-  /// $(PRE
-  /// NoScopeStatement :=
-  ///     NonEmptyStatement
-  ///     BlockStatement
-  /// BlockStatement :=
-  ///     { }
-  ///     { StatementList }
-  /// )
-  Statement parseNoScopeStatement()
-  {
-    auto begin = token;
-    Statement s;
-    if (consumed(T.LBrace))
-    {
-      auto ss = new CompoundStatement();
-      while (token.kind != T.RBrace && token.kind != T.EOF)
-        ss ~= parseStatement();
-      require(T.RBrace);
-      s = set(ss, begin);
-    }
-    else if (token.kind == T.Semicolon)
-    {
-      error(token, MSG.ExpectedNonEmptyStatement);
-      nT();
-      s = set(new EmptyStatement(), begin);
-    }
-    else
-      s = parseStatement();
-    return s;
-  }
-
-  /// $(PRE
-  /// NoScopeOrEmptyStatement :=
-  ///     ;
-  ///     NoScopeStatement
-  /// )
-  Statement parseNoScopeOrEmptyStatement()
-  {
-    if (consumed(T.Semicolon))
-      return set(new EmptyStatement(), this.prevToken);
-    else
-      return parseNoScopeStatement();
-  }
-
-  Statement parseAttributeStatement()
-  {
-    StorageClass stc, stc_tmp;
-    LinkageType prev_linkageType;
-
-    Declaration parse() // Nested function.
-    {
-      auto begin = token;
-      Declaration d;
-      switch (token.kind)
-      {
-      case T.Extern:
-        if (peekNext() != T.LParen)
-        {
-          stc_tmp = StorageClass.Extern;
-          goto Lcommon;
-        }
-
-        nT();
-        auto linkageType = parseLinkageType();
-        checkLinkageType(prev_linkageType, linkageType, begin);
-
-        d = new LinkageDeclaration(linkageType, parse());
-        break;
-      case T.Static:
-        stc_tmp = StorageClass.Static;
-        goto Lcommon;
-      case T.Final:
-        stc_tmp = StorageClass.Final;
-        goto Lcommon;
-      case T.Const:
-      version(D2)
-      {
-        if (peekNext() == T.LParen)
-          goto case_Declaration;
-      }
-        stc_tmp = StorageClass.Const;
-        goto Lcommon;
-      version(D2)
-      {
-      case T.Invariant: // D 2.0
-        if (peekNext() == T.LParen)
-          goto case_Declaration;
-        stc_tmp = StorageClass.Invariant;
-        goto Lcommon;
-      }
-      case T.Auto:
-        stc_tmp = StorageClass.Auto;
-        goto Lcommon;
-      case T.Scope:
-        stc_tmp = StorageClass.Scope;
-        goto Lcommon;
-      Lcommon:
-        // Issue error if redundant.
-        if (stc & stc_tmp)
-          error(MID.RedundantStorageClass, token.srcText);
-        else
-          stc |= stc_tmp;
-
-        nT();
-        d = new StorageClassDeclaration(stc_tmp, parse());
-        break;
-      // TODO: allow "scope class", "abstract scope class" in function bodies?
-      //case T.Class:
-      default:
-      case_Declaration:
-        return parseVariableOrFunction(stc, Protection.None, prev_linkageType, true);
-      }
-      return set(d, begin);
-    }
-    return new DeclarationStatement(parse());
-  }
-
-  Statement parseIfStatement()
-  {
-    skip(T.If);
-
-    Statement variable;
-    Expression condition;
-    Statement ifBody, elseBody;
-
-    require(T.LParen);
-
-    Identifier* ident;
-    auto begin = token; // For start of AutoDeclaration or normal Declaration.
-    // auto Identifier = Expression
-    if (consumed(T.Auto))
-    {
-      ident = requireIdentifier(MSG.ExpectedVariableName);
-      require(T.Assign);
-      auto init = parseExpression();
-      auto v = new VariablesDeclaration(null, [ident], [init]);
-      set(v, begin.nextNWS);
-      auto d = new StorageClassDeclaration(StorageClass.Auto, v);
-      set(d, begin);
-      variable = new DeclarationStatement(d);
-      set(variable, begin);
-    }
-    else
-    { // Declarator = Expression
-      Type parseDeclaratorAssign()
-      {
-        auto type = parseDeclarator(ident);
-        require(T.Assign);
-        return type;
-      }
-      bool success;
-      auto type = try_(&parseDeclaratorAssign, success);
-      if (success)
-      {
-        auto init = parseExpression();
-        auto v = new VariablesDeclaration(type, [ident], [init]);
-        set(v, begin);
-        variable = new DeclarationStatement(v);
-        set(variable, begin);
-      }
-      else
-        condition = parseExpression();
-    }
-    require(T.RParen);
-    ifBody = parseScopeStatement();
-    if (consumed(T.Else))
-      elseBody = parseScopeStatement();
-    return new IfStatement(variable, condition, ifBody, elseBody);
-  }
-
-  Statement parseWhileStatement()
-  {
-    skip(T.While);
-    require(T.LParen);
-    auto condition = parseExpression();
-    require(T.RParen);
-    return new WhileStatement(condition, parseScopeStatement());
-  }
-
-  Statement parseDoWhileStatement()
-  {
-    skip(T.Do);
-    auto doBody = parseScopeStatement();
-    require(T.While);
-    require(T.LParen);
-    auto condition = parseExpression();
-    require(T.RParen);
-    return new DoWhileStatement(condition, doBody);
-  }
-
-  Statement parseForStatement()
-  {
-    skip(T.For);
-
-    Statement init, forBody;
-    Expression condition, increment;
-
-    require(T.LParen);
-    if (!consumed(T.Semicolon))
-      init = parseNoScopeStatement();
-    if (token.kind != T.Semicolon)
-      condition = parseExpression();
-    require(T.Semicolon);
-    if (token.kind != T.RParen)
-      increment = parseExpression();
-    require(T.RParen);
-    forBody = parseScopeStatement();
-    return new ForStatement(init, condition, increment, forBody);
-  }
-
-  Statement parseForeachStatement()
-  {
-    assert(token.kind == T.Foreach || token.kind == T.Foreach_reverse);
-    TOK tok = token.kind;
-    nT();
-
-    auto params = new Parameters;
-    Expression e; // Aggregate or LwrExpression
-
-    require(T.LParen);
-    auto paramsBegin = token;
-    do
-    {
-      auto paramBegin = token;
-      StorageClass stc;
-      Type type;
-      Identifier* ident;
-
-      switch (token.kind)
-      {
-      case T.Ref, T.Inout:
-        stc = StorageClass.Ref;
-        nT();
-        // fall through
-      case T.Identifier:
-        auto next = peekNext();
-        if (next == T.Comma || next == T.Semicolon || next == T.RParen)
-        {
-          ident = requireIdentifier(MSG.ExpectedVariableName);
-          break;
-        }
-        // fall through
-      default:
-        type = parseDeclarator(ident);
-      }
-
-      params ~= set(new Parameter(stc, type, ident, null), paramBegin);
-    } while (consumed(T.Comma))
-    set(params, paramsBegin);
-    require(T.Semicolon);
-    e = parseExpression();
-  version(D2)
-  { //Foreach (ForeachType; LwrExpression .. UprExpression ) ScopeStatement
-    if (consumed(T.Slice))
-    {
-      // if (params.length != 1)
-        // error(MID.XYZ); // TODO: issue error msg
-      auto upper = parseExpression();
-      require(T.RParen);
-      auto forBody = parseScopeStatement();
-      return new ForeachRangeStatement(tok, params, e, upper, forBody);
-    }
-  }
-    // Foreach (ForeachTypeList; Aggregate) ScopeStatement
-    require(T.RParen);
-    auto forBody = parseScopeStatement();
-    return new ForeachStatement(tok, params, e, forBody);
-  }
-
-  Statement parseSwitchStatement()
-  {
-    skip(T.Switch);
-    require(T.LParen);
-    auto condition = parseExpression();
-    require(T.RParen);
-    auto switchBody = parseScopeStatement();
-    return new SwitchStatement(condition, switchBody);
-  }
-
-  /// Helper function for parsing the body of a default or case statement.
-  Statement parseCaseOrDefaultBody()
-  {
-    // This function is similar to parseNoScopeStatement()
-    auto begin = token;
-    auto s = new CompoundStatement();
-    while (token.kind != T.Case &&
-           token.kind != T.Default &&
-           token.kind != T.RBrace &&
-           token.kind != T.EOF)
-      s ~= parseStatement();
-    set(s, begin);
-    return set(new ScopeStatement(s), begin);
-  }
-
-  Statement parseCaseStatement()
-  {
-    skip(T.Case);
-    auto values = parseExpressionList();
-    require(T.Colon);
-    auto caseBody = parseCaseOrDefaultBody();
-    return new CaseStatement(values, caseBody);
-  }
-
-  Statement parseDefaultStatement()
-  {
-    skip(T.Default);
-    require(T.Colon);
-    auto defaultBody = parseCaseOrDefaultBody();
-    return new DefaultStatement(defaultBody);
-  }
-
-  Statement parseContinueStatement()
-  {
-    skip(T.Continue);
-    auto ident = optionalIdentifier();
-    require(T.Semicolon);
-    return new ContinueStatement(ident);
-  }
-
-  Statement parseBreakStatement()
-  {
-    skip(T.Break);
-    auto ident = optionalIdentifier();
-    require(T.Semicolon);
-    return new BreakStatement(ident);
-  }
-
-  Statement parseReturnStatement()
-  {
-    skip(T.Return);
-    Expression expr;
-    if (token.kind != T.Semicolon)
-      expr = parseExpression();
-    require(T.Semicolon);
-    return new ReturnStatement(expr);
-  }
-
-  Statement parseGotoStatement()
-  {
-    skip(T.Goto);
-    Identifier* ident;
-    Expression caseExpr;
-    switch (token.kind)
-    {
-    case T.Case:
-      ident = token.ident;
-      nT();
-      if (token.kind == T.Semicolon)
-        break;
-      caseExpr = parseExpression();
-      break;
-    case T.Default:
-      ident = token.ident;
-      nT();
-      break;
-    default:
-      ident = requireIdentifier(MSG.ExpectedAnIdentifier);
-    }
-    require(T.Semicolon);
-    return new GotoStatement(ident, caseExpr);
-  }
-
-  Statement parseWithStatement()
-  {
-    skip(T.With);
-    require(T.LParen);
-    auto expr = parseExpression();
-    require(T.RParen);
-    return new WithStatement(expr, parseScopeStatement());
-  }
-
-  Statement parseSynchronizedStatement()
-  {
-    skip(T.Synchronized);
-    Expression expr;
-    if (consumed(T.LParen))
-    {
-      expr = parseExpression();
-      require(T.RParen);
-    }
-    return new SynchronizedStatement(expr, parseScopeStatement());
-  }
-
-  Statement parseTryStatement()
-  {
-    auto begin = token;
-    skip(T.Try);
-
-    auto tryBody = parseScopeStatement();
-    CatchStatement[] catchBodies;
-    FinallyStatement finBody;
-
-    while (consumed(T.Catch))
-    {
-      Parameter param;
-      if (consumed(T.LParen))
-      {
-        auto begin2 = token;
-        Identifier* ident;
-        auto type = parseDeclarator(ident, true);
-        param = new Parameter(StorageClass.None, type, ident, null);
-        set(param, begin2);
-        require(T.RParen);
-      }
-      catchBodies ~= set(new CatchStatement(param, parseNoScopeStatement()), begin);
-      if (param is null)
-        break; // This is a LastCatch
-      begin = token;
-    }
-
-    if (consumed(T.Finally))
-      finBody = set(new FinallyStatement(parseNoScopeStatement()), prevToken);
-
-    if (catchBodies.length == 0 && finBody is null)
-      assert(begin.kind == T.Try), error(begin, MSG.MissingCatchOrFinally);
-
-    return new TryStatement(tryBody, catchBodies, finBody);
-  }
-
-  Statement parseThrowStatement()
-  {
-    skip(T.Throw);
-    auto expr = parseExpression();
-    require(T.Semicolon);
-    return new ThrowStatement(expr);
-  }
-
-  Statement parseScopeGuardStatement()
-  {
-    skip(T.Scope);
-    skip(T.LParen);
-    auto condition = requireIdentifier(MSG.ExpectedScopeIdentifier);
-    if (condition)
-      switch (condition.idKind)
-      {
-      case IDK.exit, IDK.success, IDK.failure:
-        break;
-      default:
-        error(this.prevToken, MSG.InvalidScopeIdentifier, this.prevToken.srcText);
-      }
-    require(T.RParen);
-    Statement scopeBody;
-    if (token.kind == T.LBrace)
-      scopeBody = parseScopeStatement();
-    else
-      scopeBody = parseNoScopeStatement();
-    return new ScopeGuardStatement(condition, scopeBody);
-  }
-
-  Statement parseVolatileStatement()
-  {
-    skip(T.Volatile);
-    Statement volatileBody;
-    if (token.kind == T.Semicolon)
-      nT();
-    else if (token.kind == T.LBrace)
-      volatileBody = parseScopeStatement();
-    else
-      volatileBody = parseStatement();
-    return new VolatileStatement(volatileBody);
-  }
-
-  Statement parsePragmaStatement()
-  {
-    skip(T.Pragma);
-
-    Identifier* ident;
-    Expression[] args;
-    Statement pragmaBody;
-
-    require(T.LParen);
-    ident = requireIdentifier(MSG.ExpectedPragmaIdentifier);
-
-    if (consumed(T.Comma))
-      args = parseExpressionList();
-    require(T.RParen);
-
-    pragmaBody = parseNoScopeOrEmptyStatement();
-
-    return new PragmaStatement(ident, args, pragmaBody);
-  }
-
-  Statement parseStaticIfStatement()
-  {
-    skip(T.Static);
-    skip(T.If);
-    Expression condition;
-    Statement ifBody, elseBody;
-
-    require(T.LParen);
-    condition = parseExpression();
-    require(T.RParen);
-    ifBody = parseNoScopeStatement();
-    if (consumed(T.Else))
-      elseBody = parseNoScopeStatement();
-    return new StaticIfStatement(condition, ifBody, elseBody);
-  }
-
-  Statement parseStaticAssertStatement()
-  {
-    skip(T.Static);
-    skip(T.Assert);
-    Expression condition, message;
-
-    require(T.LParen);
-    condition = parseAssignExpression(); // Condition.
-    if (consumed(T.Comma))
-      message = parseAssignExpression(); // Error message.
-    require(T.RParen);
-    require(T.Semicolon);
-    return new StaticAssertStatement(condition, message);
-  }
-
-  Statement parseDebugStatement()
-  {
-    skip(T.Debug);
-    Token* cond;
-    Statement debugBody, elseBody;
-
-    // ( Condition )
-    if (consumed(T.LParen))
-    {
-      cond = parseIdentOrInt();
-      require(T.RParen);
-    }
-    // debug Statement
-    // debug ( Condition ) Statement
-    debugBody = parseNoScopeStatement();
-    // else Statement
-    if (consumed(T.Else))
-      elseBody = parseNoScopeStatement();
-
-    return new DebugStatement(cond, debugBody, elseBody);
-  }
-
-  Statement parseVersionStatement()
-  {
-    skip(T.Version);
-    Token* cond;
-    Statement versionBody, elseBody;
-
-    // ( Condition )
-    require(T.LParen);
-    cond = parseIdentOrInt();
-    require(T.RParen);
-    // version ( Condition ) Statement
-    versionBody = parseNoScopeStatement();
-    // else Statement
-    if (consumed(T.Else))
-      elseBody = parseNoScopeStatement();
-
-    return new VersionStatement(cond, versionBody, elseBody);
-  }
-
-  /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  |                         Assembler parsing methods                         |
-   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
-
-  /// Parses an AsmBlockStatement.
-  Statement parseAsmBlockStatement()
-  {
-    skip(T.Asm);
-    require(T.LBrace);
-    auto ss = new CompoundStatement;
-    while (token.kind != T.RBrace && token.kind != T.EOF)
-      ss ~= parseAsmStatement();
-    require(T.RBrace);
-    return new AsmBlockStatement(ss);
-  }
-
-  Statement parseAsmStatement()
-  {
-    auto begin = token;
-    Statement s;
-    Identifier* ident;
-    switch (token.kind)
-    {
-    // Keywords that are valid opcodes.
-    case T.In, T.Int, T.Out:
-      ident = token.ident;
-      nT();
-      goto LOpcode;
-    case T.Identifier:
-      ident = token.ident;
-      nT();
-      if (consumed(T.Colon))
-      { // Identifier : AsmStatement
-        s = new LabeledStatement(ident, parseAsmStatement());
-        break;
-      }
-
-    LOpcode:
-      // Opcode ;
-      // Opcode Operands ;
-      // Opcode
-      //     Identifier
-      Expression[] es;
-      if (token.kind != T.Semicolon)
-        do
-          es ~= parseAsmExpression();
-        while (consumed(T.Comma))
-      require(T.Semicolon);
-      s = new AsmStatement(ident, es);
-      break;
-    case T.Align:
-      // align Integer;
-      nT();
-      int number = -1;
-      if (token.kind == T.Int32)
-        (number = token.int_), skip(T.Int32);
-      else
-        error(token, MSG.ExpectedIntegerAfterAlign, token.srcText);
-      require(T.Semicolon);
-      s = new AsmAlignStatement(number);
-      break;
-    case T.Semicolon:
-      s = new EmptyStatement();
-      nT();
-      break;
-    default:
-      s = new IllegalAsmStatement();
-      // Skip to next valid token.
-      do
-        nT();
-      while (!token.isAsmStatementStart &&
-              token.kind != T.RBrace &&
-              token.kind != T.EOF)
-      auto text = Token.textSpan(begin, this.prevToken);
-      error(begin, MSG.IllegalAsmStatement, text);
-    }
-    set(s, begin);
-    return s;
-  }
-
-  Expression parseAsmExpression()
-  {
-    auto begin = token;
-    auto e = parseAsmOrOrExpression();
-    if (consumed(T.Question))
-    {
-      auto tok = this.prevToken;
-      auto iftrue = parseAsmExpression();
-      require(T.Colon);
-      auto iffalse = parseAsmExpression();
-      e = new CondExpression(e, iftrue, iffalse, tok);
-      set(e, begin);
-    }
-    // TODO: create AsmExpression that contains e?
-    return e;
-  }
-
-  Expression parseAsmOrOrExpression()
-  {
-    alias parseAsmAndAndExpression parseNext;
-    auto begin = token;
-    auto e = parseNext();
-    while (token.kind == T.OrLogical)
-    {
-      auto tok = token;
-      nT();
-      e = new OrOrExpression(e, parseNext(), tok);
-      set(e, begin);
-    }
-    return e;
-  }
-
-  Expression parseAsmAndAndExpression()
-  {
-    alias parseAsmOrExpression parseNext;
-    auto begin = token;
-    auto e = parseNext();
-    while (token.kind == T.AndLogical)
-    {
-      auto tok = token;
-      nT();
-      e = new AndAndExpression(e, parseNext(), tok);
-      set(e, begin);
-    }
-    return e;
-  }
-
-  Expression parseAsmOrExpression()
-  {
-    alias parseAsmXorExpression parseNext;
-    auto begin = token;
-    auto e = parseNext();
-    while (token.kind == T.OrBinary)
-    {
-      auto tok = token;
-      nT();
-      e = new OrExpression(e, parseNext(), tok);
-      set(e, begin);
-    }
-    return e;
-  }
-
-  Expression parseAsmXorExpression()
-  {
-    alias parseAsmAndExpression parseNext;
-    auto begin = token;
-    auto e = parseNext();
-    while (token.kind == T.Xor)
-    {
-      auto tok = token;
-      nT();
-      e = new XorExpression(e, parseNext(), tok);
-      set(e, begin);
-    }
-    return e;
-  }
-
-  Expression parseAsmAndExpression()
-  {
-    alias parseAsmCmpExpression parseNext;
-    auto begin = token;
-    auto e = parseNext();
-    while (token.kind == T.AndBinary)
-    {
-      auto tok = token;
-      nT();
-      e = new AndExpression(e, parseNext(), tok);
-      set(e, begin);
-    }
-    return e;
-  }
-
-  Expression parseAsmCmpExpression()
-  {
-    alias parseAsmShiftExpression parseNext;
-    auto begin = token;
-    auto e = parseNext();
-
-    auto operator = token;
-    switch (operator.kind)
-    {
-    case T.Equal, T.NotEqual:
-      nT();
-      e = new EqualExpression(e, parseNext(), operator);
-      break;
-    case T.LessEqual, T.Less, T.GreaterEqual, T.Greater:
-      nT();
-      e = new RelExpression(e, parseNext(), operator);
-      break;
-    default:
-      return e;
-    }
-    set(e, begin);
-    return e;
-  }
-
-  Expression parseAsmShiftExpression()
-  {
-    alias parseAsmAddExpression parseNext;
-    auto begin = token;
-    auto e = parseNext();
-    while (1)
-    {
-      auto operator = token;
-      switch (operator.kind)
-      {
-      case T.LShift:  nT(); e = new LShiftExpression(e, parseNext(), operator); break;
-      case T.RShift:  nT(); e = new RShiftExpression(e, parseNext(), operator); break;
-      case T.URShift: nT(); e = new URShiftExpression(e, parseNext(), operator); break;
-      default:
-        return e;
-      }
-      set(e, begin);
-    }
-    assert(0);
-  }
-
-  Expression parseAsmAddExpression()
-  {
-    alias parseAsmMulExpression parseNext;
-    auto begin = token;
-    auto e = parseNext();
-    while (1)
-    {
-      auto operator = token;
-      switch (operator.kind)
-      {
-      case T.Plus:  nT(); e = new PlusExpression(e, parseNext(), operator); break;
-      case T.Minus: nT(); e = new MinusExpression(e, parseNext(), operator); break;
-      // Not allowed in asm
-      //case T.Tilde: nT(); e = new CatExpression(e, parseNext(), operator); break;
-      default:
-        return e;
-      }
-      set(e, begin);
-    }
-    assert(0);
-  }
-
-  Expression parseAsmMulExpression()
-  {
-    alias parseAsmPostExpression parseNext;
-    auto begin = token;
-    auto e = parseNext();
-    while (1)
-    {
-      auto operator = token;
-      switch (operator.kind)
-      {
-      case T.Mul: nT(); e = new MulExpression(e, parseNext(), operator); break;
-      case T.Div: nT(); e = new DivExpression(e, parseNext(), operator); break;
-      case T.Mod: nT(); e = new ModExpression(e, parseNext(), operator); break;
-      default:
-        return e;
-      }
-      set(e, begin);
-    }
-    assert(0);
-  }
-
-  Expression parseAsmPostExpression()
-  {
-    auto begin = token;
-    auto e = parseAsmUnaryExpression();
-    while (consumed(T.LBracket))
-    {
-      e = new AsmPostBracketExpression(e, parseAsmExpression());
-      require(T.RBracket);
-      set(e, begin);
-    }
-    return e;
-  }
-
-  Expression parseAsmUnaryExpression()
-  {
-    auto begin = token;
-    Expression e;
-    switch (token.kind)
-    {
-    case T.Byte,  T.Short,  T.Int,
-         T.Float, T.Double, T.Real:
-      goto LAsmTypePrefix;
-    case T.Identifier:
-      switch (token.ident.idKind)
-      {
-      case IDK.near, IDK.far,/* "byte",  "short",  "int",*/
-           IDK.word, IDK.dword, IDK.qword/*, "float", "double", "real"*/:
-      LAsmTypePrefix:
-        nT();
-        if (token.kind == T.Identifier && token.ident is Ident.ptr)
-          skip(T.Identifier);
-        else
-          error(MID.ExpectedButFound, "ptr", token.srcText);
-        e = new AsmTypeExpression(parseAsmExpression());
-        break;
-      case IDK.offset:
-        nT();
-        e = new AsmOffsetExpression(parseAsmExpression());
-        break;
-      case IDK.seg:
-        nT();
-        e = new AsmSegExpression(parseAsmExpression());
-        break;
-      default:
-        goto LparseAsmPrimaryExpression;
-      }
-      break;
-    case T.Minus:
-    case T.Plus:
-      nT();
-      e = new SignExpression(parseAsmUnaryExpression());
-      break;
-    case T.Not:
-      nT();
-      e = new NotExpression(parseAsmUnaryExpression());
-      break;
-    case T.Tilde:
-      nT();
-      e = new CompExpression(parseAsmUnaryExpression());
-      break;
-    case T.Dot:
-      nT();
-      e = new ModuleScopeExpression(parseIdentifierExpression());
-      while (consumed(TOK.Dot))
-      {
-        e = new DotExpression(e, parseIdentifierExpression());
-        set(e, begin);
-      }
-      break;
-    default:
-    LparseAsmPrimaryExpression:
-      e = parseAsmPrimaryExpression();
-      return e;
-    }
-    set(e, begin);
-    return e;
-  }
-
-  Expression parseAsmPrimaryExpression()
-  {
-    auto begin = token;
-    Expression e;
-    switch (token.kind)
-    {
-    case T.Int32, T.Int64, T.Uint32, T.Uint64:
-      e = new IntExpression(token);
-      nT();
-      break;
-    case T.Float32, T.Float64, T.Float80,
-         T.Imaginary32, T.Imaginary64, T.Imaginary80:
-      e = new RealExpression(token);
-      nT();
-      break;
-    case T.Dollar:
-      e = new DollarExpression();
-      nT();
-      break;
-    case T.LBracket:
-      // [ AsmExpression ]
-      nT();
-      e = parseAsmExpression();
-      require(T.RBracket);
-      e = new AsmBracketExpression(e);
-      break;
-    case T.Identifier:
-      auto register = token.ident;
-      switch (register.idKind)
-      {
-      // __LOCAL_SIZE
-      case IDK.__LOCAL_SIZE:
-        nT();
-        e = new AsmLocalSizeExpression();
-        break;
-      // Register
-      case IDK.ST:
-        nT();
-        // (1) - (7)
-        int number = -1;
-        if (consumed(T.LParen))
-        {
-          if (token.kind == T.Int32)
-            (number = token.int_), skip(T.Int32);
-          else
-            expected(T.Int32);
-          require(T.RParen);
-        }
-        e = new AsmRegisterExpression(register, number);
-        break;
-      case IDK.FS:
-        nT();
-        // TODO: is the colon-number part optional?
-        int number = -1;
-        if (consumed(T.Colon))
-        {
-          // :0, :4, :8
-          if (token.kind == T.Int32)
-            (number = token.int_), skip(T.Int32);
-          if (number != 0 && number != 4 && number != 8)
-            error(MID.ExpectedButFound, "0, 4 or 8", token.srcText);
-        }
-        e = new AsmRegisterExpression(register, number);
-        break;
-      case IDK.AL, IDK.AH, IDK.AX, IDK.EAX,
-           IDK.BL, IDK.BH, IDK.BX, IDK.EBX,
-           IDK.CL, IDK.CH, IDK.CX, IDK.ECX,
-           IDK.DL, IDK.DH, IDK.DX, IDK.EDX,
-           IDK.BP, IDK.EBP, IDK.SP, IDK.ESP,
-           IDK.DI, IDK.EDI, IDK.SI, IDK.ESI,
-           IDK.ES, IDK.CS, IDK.SS, IDK.DS, IDK.GS,
-           IDK.CR0, IDK.CR2, IDK.CR3, IDK.CR4,
-           IDK.DR0, IDK.DR1, IDK.DR2, IDK.DR3, IDK.DR6, IDK.DR7,
-           IDK.TR3, IDK.TR4, IDK.TR5, IDK.TR6, IDK.TR7,
-           IDK.MM0, IDK.MM1, IDK.MM2, IDK.MM3,
-           IDK.MM4, IDK.MM5, IDK.MM6, IDK.MM7,
-           IDK.XMM0, IDK.XMM1, IDK.XMM2, IDK.XMM3,
-           IDK.XMM4, IDK.XMM5, IDK.XMM6, IDK.XMM7:
-        nT();
-        e = new AsmRegisterExpression(register);
-        break;
-      default:
-        e = parseIdentifierExpression();
-        while (consumed(TOK.Dot))
-        {
-          e = new DotExpression(e, parseIdentifierExpression());
-          set(e, begin);
-        }
-      } // end of switch
-      break;
-    default:
-      error(MID.ExpectedButFound, "Expression", token.srcText);
-      e = new IllegalExpression();
-      if (!trying)
-      { // Insert a dummy token and don't consume current one.
-        begin = lexer.insertEmptyTokenBefore(token);
-        this.prevToken = begin;
-      }
-    }
-    set(e, begin);
-    return e;
-  }
-
-  /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-  |                        Expression parsing methods                         |
-   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
-
-  /// Parses an Expression.
-  Expression parseExpression()
-  {
-    alias parseAssignExpression parseNext;
-    auto begin = token;
-    auto e = parseNext();
-    while (token.kind == T.Comma)
-    {
-      auto comma = token;
-      nT();
-      e = new CommaExpression(e, parseNext(), comma);
-      set(e, begin);
-    }
-    return e;
-  }
-
-  Expression parseAssignExpression()
-  {
-    alias parseAssignExpression parseNext;
-    auto begin = token;
-    auto e = parseCondExpression();
-    switch (token.kind)
-    {
-    case T.Assign:
-      nT(); e = new AssignExpression(e, parseNext()); break;
-    case T.LShiftAssign:
-      nT(); e = new LShiftAssignExpression(e, parseNext()); break;
-    case T.RShiftAssign:
-      nT(); e = new RShiftAssignExpression(e, parseNext()); break;
-    case T.URShiftAssign:
-      nT(); e = new URShiftAssignExpression(e, parseNext()); break;
-    case T.OrAssign:
-      nT(); e = new OrAssignExpression(e, parseNext()); break;
-    case T.AndAssign:
-      nT(); e = new AndAssignExpression(e, parseNext()); break;
-    case T.PlusAssign:
-      nT(); e = new PlusAssignExpression(e, parseNext()); break;
-    case T.MinusAssign:
-      nT(); e = new MinusAssignExpression(e, parseNext()); break;
-    case T.DivAssign:
-      nT(); e = new DivAssignExpression(e, parseNext()); break;
-    case T.MulAssign:
-      nT(); e = new MulAssignExpression(e, parseNext()); break;
-    case T.ModAssign:
-      nT(); e = new ModAssignExpression(e, parseNext()); break;
-    case T.XorAssign:
-      nT(); e = new XorAssignExpression(e, parseNext()); break;
-    case T.CatAssign:
-      nT(); e = new CatAssignExpression(e, parseNext()); break;
-    default:
-      return e;
-    }
-    set(e, begin);
-    return e;
-  }
-
-  Expression parseCondExpression()
-  {
-    auto begin = token;
-    auto e = parseOrOrExpression();
-    if (token.kind == T.Question)
-    {
-      auto tok = token;
-      nT();
-      auto iftrue = parseExpression();
-      require(T.Colon);
-      auto iffalse = parseCondExpression();
-      e = new CondExpression(e, iftrue, iffalse, tok);
-      set(e, begin);
-    }
-    return e;
-  }
-
-  Expression parseOrOrExpression()
-  {
-    alias parseAndAndExpression parseNext;
-    auto begin = token;
-    auto e = parseNext();
-    while (token.kind == T.OrLogical)
-    {
-      auto tok = token;
-      nT();
-      e = new OrOrExpression(e, parseNext(), tok);
-      set(e, begin);
-    }
-    return e;
-  }
-
-  Expression parseAndAndExpression()
-  {
-    alias parseOrExpression parseNext;
-    auto begin = token;
-    auto e = parseNext();
-    while (token.kind == T.AndLogical)
-    {
-      auto tok = token;
-      nT();
-      e = new AndAndExpression(e, parseNext(), tok);
-      set(e, begin);
-    }
-    return e;
-  }
-
-  Expression parseOrExpression()
-  {
-    alias parseXorExpression parseNext;
-    auto begin = token;
-    auto e = parseNext();
-    while (token.kind == T.OrBinary)
-    {
-      auto tok = token;
-      nT();
-      e = new OrExpression(e, parseNext(), tok);
-      set(e, begin);
-    }
-    return e;
-  }
-
-  Expression parseXorExpression()
-  {
-    alias parseAndExpression parseNext;
-    auto begin = token;
-    auto e = parseNext();
-    while (token.kind == T.Xor)
-    {
-      auto tok = token;
-      nT();
-      e = new XorExpression(e, parseNext(), tok);
-      set(e, begin);
-    }
-    return e;
-  }
-
-  Expression parseAndExpression()
-  {
-    alias parseCmpExpression parseNext;
-    auto begin = token;
-    auto e = parseNext();
-    while (token.kind == T.AndBinary)
-    {
-      auto tok = token;
-      nT();
-      e = new AndExpression(e, parseNext(), tok);
-      set(e, begin);
-    }
-    return e;
-  }
-
-  Expression parseCmpExpression()
-  {
-    alias parseShiftExpression parseNext;
-    auto begin = token;
-    auto e = parseShiftExpression();
-
-    auto operator = token;
-    switch (operator.kind)
-    {
-    case T.Equal, T.NotEqual:
-      nT();
-      e = new EqualExpression(e, parseNext(), operator);
-      break;
-    case T.Not:
-      if (peekNext() != T.Is)
-        break;
-      nT();
-      // fall through
-    case T.Is:
-      nT();
-      e = new IdentityExpression(e, parseNext(), operator);
-      break;
-    case T.LessEqual, T.Less, T.GreaterEqual, T.Greater,
-         T.Unordered, T.UorE, T.UorG, T.UorGorE,
-         T.UorL, T.UorLorE, T.LorEorG, T.LorG:
-      nT();
-      e = new RelExpression(e, parseNext(), operator);
-      break;
-    case T.In:
-      nT();
-      e = new InExpression(e, parseNext(), operator);
-      break;
-    default:
-      return e;
-    }
-    set(e, begin);
-    return e;
-  }
-
-  Expression parseShiftExpression()
-  {
-    alias parseAddExpression parseNext;
-    auto begin = token;
-    auto e = parseNext();
-    while (1)
-    {
-      auto operator = token;
-      switch (operator.kind)
-      {
-      case T.LShift:  nT(); e = new LShiftExpression(e, parseNext(), operator); break;
-      case T.RShift:  nT(); e = new RShiftExpression(e, parseNext(), operator); break;
-      case T.URShift: nT(); e = new URShiftExpression(e, parseNext(), operator); break;
-      default:
-        return e;
-      }
-      set(e, begin);
-    }
-    assert(0);
-  }
-
-  Expression parseAddExpression()
-  {
-    alias parseMulExpression parseNext;
-    auto begin = token;
-    auto e = parseNext();
-    while (1)
-    {
-      auto operator = token;
-      switch (operator.kind)
-      {
-      case T.Plus:  nT(); e = new PlusExpression(e, parseNext(), operator); break;
-      case T.Minus: nT(); e = new MinusExpression(e, parseNext(), operator); break;
-      case T.Tilde: nT(); e = new CatExpression(e, parseNext(), operator); break;
-      default:
-        return e;
-      }
-      set(e, begin);
-    }
-    assert(0);
-  }
-
-  Expression parseMulExpression()
-  {
-    alias parsePostExpression parseNext;
-    auto begin = token;
-    auto e = parseNext();
-    while (1)
-    {
-      auto operator = token;
-      switch (operator.kind)
-      {
-      case T.Mul: nT(); e = new MulExpression(e, parseNext(), operator); break;
-      case T.Div: nT(); e = new DivExpression(e, parseNext(), operator); break;
-      case T.Mod: nT(); e = new ModExpression(e, parseNext(), operator); break;
-      default:
-        return e;
-      }
-      set(e, begin);
-    }
-    assert(0);
-  }
-
-  Expression parsePostExpression()
-  {
-    auto begin = token;
-    auto e = parseUnaryExpression();
-    while (1)
-    {
-      while (consumed(T.Dot))
-      {
-        e = new DotExpression(e, parseNewOrIdentifierExpression());
-        set(e, begin);
-      }
-
-      switch (token.kind)
-      {
-      case T.PlusPlus:
-        e = new PostIncrExpression(e);
-        break;
-      case T.MinusMinus:
-        e = new PostDecrExpression(e);
-        break;
-      case T.LParen:
-        e = new CallExpression(e, parseArguments());
-        goto Lset;
-      case T.LBracket:
-        // parse Slice- and IndexExpression
-        nT();
-        // [] is a SliceExpression
-        if (token.kind == T.RBracket)
-        {
-          e = new SliceExpression(e, null, null);
-          break;
-        }
-
-        Expression[] es = [parseAssignExpression()];
-
-        // [ AssignExpression .. AssignExpression ]
-        if (consumed(T.Slice))
-        {
-          e = new SliceExpression(e, es[0], parseAssignExpression());
-          require(T.RBracket);
-          goto Lset;
-        }
-
-        // [ ExpressionList ]
-        if (consumed(T.Comma))
-           es ~= parseExpressionList();
-        require(T.RBracket);
-
-        e = new IndexExpression(e, es);
-        goto Lset;
-      default:
-        return e;
-      }
-      nT();
-    Lset: // Jumped here to skip nT().
-      set(e, begin);
-    }
-    assert(0);
-  }
-
-  Expression parseUnaryExpression()
-  {
-    auto begin = token;
-    Expression e;
-    switch (token.kind)
-    {
-    case T.AndBinary:
-      nT();
-      e = new AddressExpression(parseUnaryExpression());
-      break;
-    case T.PlusPlus:
-      nT();
-      e = new PreIncrExpression(parseUnaryExpression());
-      break;
-    case T.MinusMinus:
-      nT();
-      e = new PreDecrExpression(parseUnaryExpression());
-      break;
-    case T.Mul:
-      nT();
-      e = new DerefExpression(parseUnaryExpression());
-      break;
-    case T.Minus:
-    case T.Plus:
-      nT();
-      e = new SignExpression(parseUnaryExpression());
-      break;
-    case T.Not:
-      nT();
-      e = new NotExpression(parseUnaryExpression());
-      break;
-    case T.Tilde:
-      nT();
-      e = new CompExpression(parseUnaryExpression());
-      break;
-    case T.New:
-      e = parseNewExpression();
-      return e;
-    case T.Delete:
-      nT();
-      e = new DeleteExpression(parseUnaryExpression());
-      break;
-    case T.Cast:
-      requireNext(T.LParen);
-      Type type;
-      switch (token.kind)
-      {
-      version(D2)
-      {
-      auto begin2 = token;
-      case T.Const:
-        type = new ConstType(null);
-        goto case_break;
-      case T.Invariant:
-        type = new InvariantType(null);
-      case_break:
-        nT();
-        set(type, begin2);
-        break;
-      }
-      default:
-       type = parseType();
-      }
-      require(T.RParen);
-      e = new CastExpression(parseUnaryExpression(), type);
-      break;
-    case T.LParen:
-      // ( Type ) . Identifier
-      Type parseType_()
-      {
-        skip(T.LParen);
-        auto type = parseType();
-        require(T.RParen);
-        require(T.Dot);
-        return type;
-      }
-      bool success;
-      auto type = try_(&parseType_, success);
-      if (success)
-      {
-        auto ident = requireIdentifier(MSG.ExpectedIdAfterTypeDot);
-        e = new TypeDotIdExpression(type, ident);
-        break;
-      }
-      goto default;
-    case T.Dot:
-      nT();
-      e = new ModuleScopeExpression(parseIdentifierExpression());
-      break;
-    default:
-      e = parsePrimaryExpression();
-      return e;
-    }
-    assert(e !is null);
-    set(e, begin);
-    return e;
-  }
-
-  /// $(PRE
-  /// IdentifierExpression :=
-  ///         Identifier
-  ///         TemplateInstance
-  /// TemplateInstance :=
-  ///         Identifier !( TemplateArguments )
-  /// )
-  Expression parseIdentifierExpression()
-  {
-    auto begin = token;
-    auto ident = requireIdentifier(MSG.ExpectedAnIdentifier);
-    Expression e;
-    // Peek for '(' to avoid matching: id !is id
-    if (token.kind == T.Not && peekNext() == T.LParen)
-    { // Identifier !( TemplateArguments )
-      skip(T.Not);
-      auto tparams = parseTemplateArguments();
-      e = new TemplateInstanceExpression(ident, tparams);
-    }
-    else // Identifier
-      e = new IdentifierExpression(ident);
-    return set(e, begin);
-  }
-
-  Expression parseNewOrIdentifierExpression()
-  {
-    return token.kind == T.New ? parseNewExpression() :  parseIdentifierExpression();
-  }
-
-  Expression parsePrimaryExpression()
-  {
-    auto begin = token;
-    Expression e;
-    switch (token.kind)
-    {
-    case T.Identifier:
-      e = parseIdentifierExpression();
-      return e;
-    case T.Typeof:
-      e = new TypeofExpression(parseTypeofType());
-      break;
-    case T.This:
-      nT();
-      e = new ThisExpression();
-      break;
-    case T.Super:
-      nT();
-      e = new SuperExpression();
-      break;
-    case T.Null:
-      nT();
-      e = new NullExpression();
-      break;
-    case T.True, T.False:
-      nT();
-      e = new BoolExpression();
-      break;
-    case T.Dollar:
-      nT();
-      e = new DollarExpression();
-      break;
-    case T.Int32, T.Int64, T.Uint32, T.Uint64:
-      e = new IntExpression(token);
-      nT();
-      break;
-    case T.Float32, T.Float64, T.Float80,
-         T.Imaginary32, T.Imaginary64, T.Imaginary80:
-      e = new RealExpression(token);
-      nT();
-      break;
-    case T.CharLiteral:
-      e = new CharExpression(token.dchar_);
-      nT();
-      break;
-    case T.String:
-      char[] str = token.str;
-      char postfix = token.pf;
-      nT();
-      while (token.kind == T.String)
-      {
-        /+if (postfix == 0)
-            postfix = token.pf;
-        else+/
-        if (token.pf && token.pf != postfix)
-          error(token, MSG.StringPostfixMismatch);
-        str.length = str.length - 1; // Exclude '\0'.
-        str ~= token.str;
-        nT();
-      }
-      switch (postfix)
-      {
-      case 'w':
-        if (checkString(begin, str))
-          goto default;
-        e = new StringExpression(dil.Unicode.toUTF16(str)); break;
-      case 'd':
-        if (checkString(begin, str))
-          goto default;
-        e = new StringExpression(dil.Unicode.toUTF32(str)); break;
-      case 'c':
-      default:
-        // No checking done to allow for binary data.
-        e = new StringExpression(str); break;
-      }
-      break;
-    case T.LBracket:
-      Expression[] values;
-
-      nT();
-      if (!consumed(T.RBracket))
-      {
-        e = parseAssignExpression();
-        if (consumed(T.Colon))
-          goto LparseAssocArray;
-        if (consumed(T.Comma))
-          values = [e] ~ parseExpressionList();
-        require(T.RBracket);
-      }
-
-      e = new ArrayLiteralExpression(values);
-      break;
-
-    LparseAssocArray:
-      Expression[] keys = [e];
-
-      goto LenterLoop;
-      do
-      {
-        keys ~= parseAssignExpression();
-        require(T.Colon);
-      LenterLoop:
-        values ~= parseAssignExpression();
-      } while (consumed(T.Comma))
-      require(T.RBracket);
-      e = new AArrayLiteralExpression(keys, values);
-      break;
-    case T.LBrace:
-      // DelegateLiteral := { Statements }
-      auto funcBody = parseFunctionBody();
-      e = new FunctionLiteralExpression(funcBody);
-      break;
-    case T.Function, T.Delegate:
-      // FunctionLiteral := ("function"|"delegate") Type? "(" ArgumentList ")" FunctionBody
-      nT(); // Skip function or delegate keyword.
-      Type returnType;
-      Parameters parameters;
-      if (token.kind != T.LBrace)
-      {
-        if (token.kind != T.LParen) // Optional return type
-          returnType = parseType();
-        parameters = parseParameterList();
-      }
-      auto funcBody = parseFunctionBody();
-      e = new FunctionLiteralExpression(returnType, parameters, funcBody);
-      break;
-    case T.Assert:
-      Expression msg;
-      requireNext(T.LParen);
-      e = parseAssignExpression();
-      if (consumed(T.Comma))
-        msg = parseAssignExpression();
-      require(T.RParen);
-      e = new AssertExpression(e, msg);
-      break;
-    case T.Mixin:
-      requireNext(T.LParen);
-      e = parseAssignExpression();
-      require(T.RParen);
-      e = new MixinExpression(e);
-      break;
-    case T.Import:
-      requireNext(T.LParen);
-      e = parseAssignExpression();
-      require(T.RParen);
-      e = new ImportExpression(e);
-      break;
-    case T.Typeid:
-      requireNext(T.LParen);
-      auto type = parseType();
-      require(T.RParen);
-      e = new TypeidExpression(type);
-      break;
-    case T.Is:
-      requireNext(T.LParen);
-
-      Type type, specType;
-      Identifier* ident; // optional Identifier
-      Token* opTok, specTok;
-
-      type = parseDeclarator(ident, true);
-
-      switch (token.kind)
-      {
-      case T.Colon, T.Equal:
-        opTok = token;
-        nT();
-        switch (token.kind)
-        {
-        case T.Typedef,
-             T.Struct,
-             T.Union,
-             T.Class,
-             T.Interface,
-             T.Enum,
-             T.Function,
-             T.Delegate,
-             T.Super,
-             T.Return:
-        case_Const_Invariant:
-          specTok = token;
-          nT();
-          break;
-        case T.Const, T.Invariant:
-          if (peekNext() != T.LParen)
-            goto case_Const_Invariant;
-          // Fall through. It's a type.
-        default:
-          specType = parseType();
-        }
-      default:
-      }
-
-      TemplateParameters tparams;
-    version(D2)
-    {
-      // is ( Type Identifier : TypeSpecialization , TemplateParameterList )
-      // is ( Type Identifier == TypeSpecialization , TemplateParameterList )
-      if (ident && specType && token.kind == T.Comma)
-        tparams = parseTemplateParameterList2();
-    }
-      require(T.RParen);
-      e = new IsExpression(type, ident, opTok, specTok, specType, tparams);
-      break;
-    case T.LParen:
-      if (tokenAfterParenIs(T.LBrace)) // Check for "(...) {"
-      { // ( ParameterList ) FunctionBody
-        auto parameters = parseParameterList();
-        auto funcBody = parseFunctionBody();
-        e = new FunctionLiteralExpression(null, parameters, funcBody);
-      }
-      else
-      { // ( Expression )
-        skip(T.LParen);
-        e = parseExpression();
-        require(T.RParen);
-        e = new ParenExpression(e);
-      }
-      break;
-    version(D2)
-    {
-    case T.Traits:
-      requireNext(T.LParen);
-      auto id = requireIdentifier(MSG.ExpectedAnIdentifier);
-      TemplateArguments args;
-      if (token.kind == T.Comma)
-        args = parseTemplateArguments2();
-      else
-        require(T.RParen);
-      e = new TraitsExpression(id, args);
-      break;
-    }
-    default:
-      if (token.isIntegralType)
-      { // IntegralType . Identifier
-        auto type = new IntegralType(token.kind);
-        nT();
-        set(type, begin);
-        require(T.Dot);
-        auto ident = requireIdentifier(MSG.ExpectedIdAfterTypeDot);
-        e = new TypeDotIdExpression(type, ident);
-      }
-      else if (token.isSpecialToken)
-      {
-        e = new SpecialTokenExpression(token);
-        nT();
-      }
-      else
-      {
-        error(MID.ExpectedButFound, "Expression", token.srcText);
-        e = new IllegalExpression();
-        if (!trying)
-        { // Insert a dummy token and don't consume current one.
-          begin = lexer.insertEmptyTokenBefore(token);
-          this.prevToken = begin;
-        }
-      }
-    }
-    set(e, begin);
-    return e;
-  }
-
-  Expression parseNewExpression(/*Expression e*/)
-  {
-    auto begin = token;
-    skip(T.New);
-
-    Expression[] newArguments;
-    Expression[] ctorArguments;
-
-    if (token.kind == T.LParen)
-      newArguments = parseArguments();
-
-    // NewAnonClassExpression:
-    //         new (ArgumentList)opt class (ArgumentList)opt SuperClassopt InterfaceClassesopt ClassBody
-    if (consumed(T.Class))
-    {
-      if (token.kind == T.LParen)
-        ctorArguments = parseArguments();
-
-      BaseClassType[] bases = token.kind != T.LBrace ? parseBaseClasses(false) : null ;
-
-      auto decls = parseDeclarationDefinitionsBody();
-      return set(new NewAnonClassExpression(/*e, */newArguments, bases, ctorArguments, decls), begin);
-    }
-
-    // NewExpression:
-    //         NewArguments Type [ AssignExpression ]
-    //         NewArguments Type ( ArgumentList )
-    //         NewArguments Type
-    auto type = parseType();
-
-    if (token.kind == T.LParen)
-      ctorArguments = parseArguments();
-
-    return set(new NewExpression(/*e, */newArguments, type, ctorArguments), begin);
-  }
-
-  /// Parses a Type.
-  Type parseType()
-  {
-    return parseBasicType2(parseBasicType());
-  }
-
-  Type parseIdentifierType()
-  {
-    auto begin = token;
-    auto ident = requireIdentifier(MSG.ExpectedAnIdentifier);
-    Type t;
-    if (consumed(T.Not)) // Identifier !( TemplateArguments )
-      t = new TemplateInstanceType(ident, parseTemplateArguments());
-    else // Identifier
-      t = new IdentifierType(ident);
-    return set(t, begin);
-  }
-
-  Type parseQualifiedType()
-  {
-    auto begin = token;
-    Type type;
-    if (token.kind == T.Dot)
-      type = set(new ModuleScopeType(), begin, begin);
-    else if (token.kind == T.Typeof)
-      type = parseTypeofType();
-    else
-      type = parseIdentifierType();
-
-    while (consumed(T.Dot))
-      type = set(new QualifiedType(type, parseIdentifierType()), begin);
-    return type;
-  }
-
-  Type parseBasicType()
-  {
-    auto begin = token;
-    Type t;
-
-    if (token.isIntegralType)
-    {
-      t = new IntegralType(token.kind);
-      nT();
-    }
-    else
-    switch (token.kind)
-    {
-    case T.Identifier, T.Typeof, T.Dot:
-      t = parseQualifiedType();
-      return t;
-    version(D2)
-    {
-    case T.Const:
-      // const ( Type )
-      requireNext(T.LParen);
-      t = parseType();
-      require(T.RParen);
-      t = new ConstType(t);
-      break;
-    case T.Invariant:
-      // invariant ( Type )
-      requireNext(T.LParen);
-      t = parseType();
-      require(T.RParen);
-      t = new InvariantType(t);
-      break;
-    } // version(D2)
-    default:
-      error(MID.ExpectedButFound, "BasicType", token.srcText);
-      t = new IllegalType();
-      nT();
-    }
-    return set(t, begin);
-  }
-
-  Type parseBasicType2(Type t)
-  {
-    while (1)
-    {
-      auto begin = token;
-      switch (token.kind)
-      {
-      case T.Mul:
-        t = new PointerType(t);
-        nT();
-        break;
-      case T.LBracket:
-        t = parseArrayType(t);
-        continue;
-      case T.Function, T.Delegate:
-        TOK tok = token.kind;
-        nT();
-        auto parameters = parseParameterList();
-        if (tok == T.Function)
-          t = new FunctionType(t, parameters);
-        else
-          t = new DelegateType(t, parameters);
-        break;
-      default:
-        return t;
-      }
-      set(t, begin);
-    }
-    assert(0);
-  }
-
-  /// Returns true if the token after the closing parenthesis
-  /// is of kind tok.
-  bool tokenAfterParenIs(TOK tok)
-  {
-    // We count nested parentheses tokens because template types
-    // may appear inside parameter lists. E.g.: (int x, Foo!(int) y)
-    assert(token.kind == T.LParen);
-    Token* next = token;
-    uint level = 1;
-  Loop:
-    while (1)
-    {
-      lexer.peek(next);
-      switch (next.kind)
-      {
-      case T.RParen:
-        if (--level == 0)
-        { // Last, closing parentheses found.
-          do
-            lexer.peek(next);
-          while (next.isWhitespace)
-          break Loop;
-        }
-        break;
-      case T.LParen:
-        ++level;
-        break;
-      case T.EOF:
-        break Loop;
-      default:
-      }
-    }
-    return next.kind == tok;
-  }
-
-  /// Parse the array types after the declarator (C-style.) E.g.: int a[]
-  Type parseDeclaratorSuffix(Type lhsType)
-  {
-    // The Type chain should be as follows:
-    // int[3]* Identifier [][32]
-    //   <- <-             ->  -.
-    //       ^-----------------´
-    // Resulting chain: [][32]*[3]int
-    Type parseNext() // Nested function required to accomplish this.
-    {
-      if (token.kind != T.LBracket)
-        return lhsType; // Break recursion; return Type on the left hand side of the Identifier.
-
-      auto begin = token;
-      Type t;
-      skip(T.LBracket);
-      if (consumed(T.RBracket))
-        t = new ArrayType(parseNext()); // [ ]
-      else
-      {
-        bool success;
-        Type parseAAType()
-        {
-          auto type = parseType();
-          require(T.RBracket);
-          return type;
-        }
-        auto assocType = try_(&parseAAType, success);
-        if (success)
-          t = new ArrayType(parseNext(), assocType); // [ Type ]
-        else
-        {
-          Expression e = parseExpression(), e2;
-          if (consumed(T.Slice))
-            e2 = parseExpression();
-          require(T.RBracket);
-          t = new ArrayType(parseNext(), e, e2); // [ Expression .. Expression ]
-        }
-      }
-      set(t, begin);
-      return t;
-    }
-    return parseNext();
-  }
-
-  Type parseArrayType(Type t)
-  {
-    auto begin = token;
-    skip(T.LBracket);
-    if (consumed(T.RBracket))
-      t = new ArrayType(t);
-    else
-    {
-      bool success;
-      Type parseAAType()
-      {
-        auto type = parseType();
-        require(T.RBracket);
-        return type;
-      }
-      auto assocType = try_(&parseAAType, success);
-      if (success)
-        t = new ArrayType(t, assocType);
-      else
-      {
-        Expression e = parseExpression(), e2;
-        if (consumed(T.Slice))
-          e2 = parseExpression();
-        require(T.RBracket);
-        t = new ArrayType(t, e, e2);
-      }
-    }
-    set(t, begin);
-    return t;
-  }
-
-  Type parseCFunctionPointerType(Type type, ref Identifier* ident, bool optionalParamList)
-  {
-    assert(type !is null);
-    auto begin = token;
-    skip(T.LParen);
-
-    type = parseBasicType2(type);
-    if (token.kind == T.LParen)
-    { // Can be nested.
-      type = parseCFunctionPointerType(type, ident, true);
-    }
-    else if (token.kind == T.Identifier)
-    { // The identifier of the function pointer and the declaration.
-      ident = token.ident;
-      nT();
-      type = parseDeclaratorSuffix(type);
-    }
-    require(T.RParen);
-
-    Parameters params;
-    if (optionalParamList)
-      params = token.kind == T.LParen ? parseParameterList() : null;
-    else
-      params = parseParameterList();
-
-    type = new CFuncPointerType(type, params);
-    return set(type, begin);
-  }
-
-  Type parseDeclarator(ref Identifier* ident, bool identOptional = false)
-  {
-    auto t = parseType();
-
-    if (token.kind == T.LParen)
-      t = parseCFunctionPointerType(t, ident, true);
-    else if (token.kind == T.Identifier)
-    {
-      ident = token.ident;
-      nT();
-      t = parseDeclaratorSuffix(t);
-    }
-
-    if (ident is null && !identOptional)
-      error(token, MSG.ExpectedDeclaratorIdentifier, token.srcText);
-
-    return t;
-  }
-
-  /// Parses a list of AssignExpressions.
-  /// $(PRE
-  /// ExpressionList :=
-  ///   AssignExpression
-  ///   AssignExpression , ExpressionList
-  /// )
-  Expression[] parseExpressionList()
-  {
-    Expression[] expressions;
-    do
-      expressions ~= parseAssignExpression();
-    while(consumed(T.Comma))
-    return expressions;
-  }
-
-  /// Parses a list of Arguments.
-  /// $(PRE
-  /// Arguments :=
-  ///   ( )
-  ///   ( ExpressionList )
-  /// )
-  Expression[] parseArguments()
-  {
-    skip(T.LParen);
-    Expression[] args;
-    if (token.kind != T.RParen)
-      args = parseExpressionList();
-    require(T.RParen);
-    return args;
-  }
-
-  /// Parses a ParameterList.
-  Parameters parseParameterList()
-  out(params)
-  {
-    if (params.length > 1)
-      foreach (param; params.items[0..$-1])
-      {
-        if (param.isVariadic())
-          assert(0, "variadic arguments can only appear at the end of the parameter list.");
-      }
-  }
-  body
-  {
-    auto begin = token;
-    require(T.LParen);
-
-    auto params = new Parameters();
-
-    if (consumed(T.RParen))
-      return set(params, begin);
-
-    do
-    {
-      auto paramBegin = token;
-      StorageClass stc, stc_;
-      Type type;
-      Identifier* ident;
-      Expression defValue;
-
-      void pushParameter()
-      {
-        params ~= set(new Parameter(stc, type, ident, defValue), paramBegin);
-      }
-
-      if (consumed(T.Ellipses))
-      {
-        stc = StorageClass.Variadic;
-        pushParameter(); // type, ident and defValue will be null.
-        break;
-      }
-
-      while (1)
-      { // Parse storage classes.
-        switch (token.kind)
-        {
-      version(D2)
-      {
-        case T.Invariant: // D2.0
-          if (peekNext() == T.LParen)
-            break;
-          stc_ = StorageClass.Invariant;
-          goto Lcommon;
-        case T.Const: // D2.0
-          if (peekNext() == T.LParen)
-            break;
-          stc_ = StorageClass.Const;
-          goto Lcommon;
-        case T.Final: // D2.0
-          stc_ = StorageClass.Final;
-          goto Lcommon;
-        case T.Scope: // D2.0
-          stc_ = StorageClass.Scope;
-          goto Lcommon;
-        case T.Static: // D2.0
-          stc_ = StorageClass.Static;
-          goto Lcommon;
-      }
-        case T.In:
-          stc_ = StorageClass.In;
-          goto Lcommon;
-        case T.Out:
-          stc_ = StorageClass.Out;
-          goto Lcommon;
-        case T.Inout, T.Ref:
-          stc_ = StorageClass.Ref;
-          goto Lcommon;
-        case T.Lazy:
-          stc_ = StorageClass.Lazy;
-          goto Lcommon;
-        Lcommon:
-          // Check for redundancy.
-          if (stc & stc_)
-            error(MID.RedundantStorageClass, token.srcText);
-          else
-            stc |= stc_;
-          nT();
-        version(D2)
-          continue;
-        else
-          break; // In D1.0 the grammar only allows one storage class.
-        default:
-        }
-        break; // Break out of inner loop.
-      }
-      type = parseDeclarator(ident, true);
-
-      if (consumed(T.Assign))
-        defValue = parseAssignExpression();
-
-      if (consumed(T.Ellipses))
-      {
-        stc |= StorageClass.Variadic;
-        pushParameter();
-        break;
-      }
-      pushParameter();
-
-    } while (consumed(T.Comma))
-    require(T.RParen);
-    return set(params, begin);
-  }
-
-  TemplateArguments parseTemplateArguments()
-  {
-    TemplateArguments targs;
-    require(T.LParen);
-    if (token.kind != T.RParen)
-      targs = parseTemplateArguments_();
-    require(T.RParen);
-    return targs;
-  }
-
-version(D2)
-{
-  TemplateArguments parseTemplateArguments2()
-  {
-    skip(T.Comma);
-    TemplateArguments targs;
-    if (token.kind != T.RParen)
-      targs = parseTemplateArguments_();
-    else
-      error(token, MSG.ExpectedTypeOrExpression);
-    require(T.RParen);
-    return targs;
-  }
-} // version(D2)
-
-  TemplateArguments parseTemplateArguments_()
-  {
-    auto begin = token;
-    auto targs = new TemplateArguments;
-    do
-    {
-      Type parseType_()
-      {
-        auto type = parseType();
-        if (token.kind == T.Comma || token.kind == T.RParen)
-          return type;
-        errorCount++; // Cause try_() to fail.
-        return null;
-      }
-      bool success;
-      auto typeArgument = try_(&parseType_, success);
-      if (success)
-        // TemplateArgument:
-        //         Type
-        //         Symbol
-        targs ~= typeArgument;
-      else
-        // TemplateArgument:
-        //         AssignExpression
-        targs ~= parseAssignExpression();
-    } while (consumed(T.Comma))
-    set(targs, begin);
-    return targs;
-  }
-
-  TemplateParameters parseTemplateParameterList()
-  {
-    auto begin = token;
-    auto tparams = new TemplateParameters;
-    require(T.LParen);
-    if (token.kind != T.RParen)
-      parseTemplateParameterList_(tparams);
-    require(T.RParen);
-    return set(tparams, begin);
-  }
-
-version(D2)
-{
-  TemplateParameters parseTemplateParameterList2()
-  {
-    skip(T.Comma);
-    auto begin = token;
-    auto tparams = new TemplateParameters;
-    if (token.kind != T.RParen)
-      parseTemplateParameterList_(tparams);
-    else
-      error(token, MSG.ExpectedTemplateParameters);
-    return set(tparams, begin);
-  }
-} // version(D2)
-
-  /// Parses template parameters.
-  void parseTemplateParameterList_(TemplateParameters tparams)
-  {
-    do
-    {
-      auto paramBegin = token;
-      TemplateParameter tp;
-      Identifier* ident;
-      Type specType, defType;
-
-      void parseSpecAndOrDefaultType()
-      {
-        // : SpecializationType
-        if (consumed(T.Colon))
-          specType = parseType();
-        // = DefaultType
-        if (consumed(T.Assign))
-          defType = parseType();
-      }
-
-      switch (token.kind)
-      {
-      case T.Alias:
-        // TemplateAliasParameter:
-        //         alias Identifier
-        skip(T.Alias);
-        ident = requireIdentifier(MSG.ExpectedAliasTemplateParam);
-        parseSpecAndOrDefaultType();
-        tp = new TemplateAliasParameter(ident, specType, defType);
-        break;
-      case T.Identifier:
-        ident = token.ident;
-        switch (peekNext())
-        {
-        case T.Ellipses:
-          // TemplateTupleParameter:
-          //         Identifier ...
-          skip(T.Identifier); skip(T.Ellipses);
-          if (token.kind == T.Comma)
-            error(MID.TemplateTupleParameter);
-          tp = new TemplateTupleParameter(ident);
-          break;
-        case T.Comma, T.RParen, T.Colon, T.Assign:
-          // TemplateTypeParameter:
-          //         Identifier
-          skip(T.Identifier);
-          parseSpecAndOrDefaultType();
-          tp = new TemplateTypeParameter(ident, specType, defType);
-          break;
-        default:
-          // TemplateValueParameter:
-          //         Declarator
-          ident = null;
-          goto LTemplateValueParameter;
-        }
-        break;
-      version(D2)
-      {
-      case T.This:
-        // TemplateThisParameter
-        //         this TemplateTypeParameter
-        skip(T.This);
-        ident = requireIdentifier(MSG.ExpectedNameForThisTempParam);
-        parseSpecAndOrDefaultType();
-        tp = new TemplateThisParameter(ident, specType, defType);
-        break;
-      }
-      default:
-      LTemplateValueParameter:
-        // TemplateValueParameter:
-        //         Declarator
-        Expression specValue, defValue;
-        auto valueType = parseDeclarator(ident);
-        // : SpecializationValue
-        if (consumed(T.Colon))
-          specValue = parseCondExpression();
-        // = DefaultValue
-        if (consumed(T.Assign))
-          defValue = parseCondExpression();
-        tp = new TemplateValueParameter(valueType, ident, specValue, defValue);
-      }
-
-      // Push template parameter.
-      tparams ~= set(tp, paramBegin);
-
-    } while (consumed(T.Comma))
-  }
-
-  alias require expected;
-
-  /// Requires a token of kind tok.
-  void require(TOK tok)
-  {
-    if (token.kind == tok)
-      nT();
-    else
-      error(MID.ExpectedButFound, Token.toString(tok), token.srcText);
-  }
-
-  /// Requires the next token to be of kind tok.
-  void requireNext(TOK tok)
-  {
-    nT();
-    require(tok);
-  }
-
-  /// Optionally parses an identifier.
-  /// Returns: null or the identifier.
-  Identifier* optionalIdentifier()
-  {
-    Identifier* id;
-    if (token.kind == T.Identifier)
-      (id = token.ident), skip(T.Identifier);
-    return id;
-  }
-
-  Identifier* requireIdentifier()
-  {
-    Identifier* id;
-    if (token.kind == T.Identifier)
-      (id = token.ident), skip(T.Identifier);
-    else
-      error(MID.ExpectedButFound, "Identifier", token.srcText);
-    return id;
-  }
-
-  /// Reports an error if the current token is not an identifier.
-  /// Params:
-  ///   errorMsg = the error message to be used.
-  /// Returns: null or the identifier.
-  Identifier* requireIdentifier(char[] errorMsg)
-  {
-    Identifier* id;
-    if (token.kind == T.Identifier)
-      (id = token.ident), skip(T.Identifier);
-    else
-      error(token, errorMsg, token.srcText);
-    return id;
-  }
-
-  /// Reports an error if the current token is not an identifier.
-  /// Params:
-  ///   mid = the error message ID to be used.
-  /// Returns: null or the identifier.
-  Identifier* requireIdentifier(MID mid)
-  {
-    Identifier* id;
-    if (token.kind == T.Identifier)
-      (id = token.ident), skip(T.Identifier);
-    else
-      error(mid, token.srcText);
-    return id;
-  }
-
-  /// Reports an error if the current token is not an identifier.
-  /// Returns: null or the token.
-  Token* requireId()
-  {
-    Token* idtok;
-    if (token.kind == T.Identifier)
-      (idtok = token), skip(T.Identifier);
-    else
-      error(MID.ExpectedButFound, "Identifier", token.srcText);
-    return idtok;
-  }
-
-  Token* requireIdToken(char[] errorMsg)
-  {
-    Token* idtok;
-    if (token.kind == T.Identifier)
-      (idtok = token), skip(T.Identifier);
-    else
-    {
-      error(token, errorMsg, token.srcText);
-      idtok = lexer.insertEmptyTokenBefore(token);
-      this.prevToken = idtok;
-    }
-    return idtok;
-  }
-
-  /// Returns true if the string str has an invalid UTF-8 sequence.
-  bool checkString(Token* begin, string str)
-  {
-    auto utf8Seq = Lexer.findInvalidUTF8Sequence(str);
-    if (utf8Seq.length)
-      error(begin, MSG.InvalidUTF8SequenceInString, utf8Seq);
-    return utf8Seq.length != 0;
-  }
-
-  /// Forwards error parameters.
-  void error(Token* token, char[] formatMsg, ...)
-  {
-    error_(token, formatMsg, _arguments, _argptr);
-  }
-
-  /// ditto
-  void error(MID mid, ...)
-  {
-    error_(this.token, GetMsg(mid), _arguments, _argptr);
-  }
-
-  /// Creates an error report and appends it to a list.
-  /// Params:
-  ///   token = used to get the location of where the error is.
-  ///   formatMsg = the compiler error message.
-  void error_(Token* token, char[] formatMsg, TypeInfo[] _arguments, Arg _argptr)
-  {
-    if (trying)
-    {
-      ++errorCount;
-      return;
-    }
-    auto location = token.getErrorLocation();
-    auto msg = Format(_arguments, _argptr, formatMsg);
-    auto error = new ParserError(location, msg);
-    errors ~= error;
-    if (infoMan !is null)
-      infoMan ~= error;
-  }
-}
--- a/trunk/src/dil/semantic/Analysis.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.semantic.Analysis;
-
-import dil.ast.Node;
-import dil.ast.Expressions;
-import dil.semantic.Scope;
-import dil.lexer.IdTable;
-import dil.Compilation;
-import common;
-
-/// Common semantics for pragma declarations and statements.
-void pragmaSemantic(Scope scop, Token* pragmaLoc,
-                    Identifier* ident,
-                    Expression[] args)
-{
-  if (ident is Ident.msg)
-    pragma_msg(scop, pragmaLoc, args);
-  else if (ident is Ident.lib)
-    pragma_lib(scop, pragmaLoc, args);
-  // else
-  //   scop.error(begin, "unrecognized pragma");
-}
-
-/// Evaluates a msg pragma.
-void pragma_msg(Scope scop, Token* pragmaLoc, Expression[] args)
-{
-  if (args.length == 0)
-    return /*scop.error(pragmaLoc, "expected expression arguments to pragma")*/;
-
-  foreach (arg; args)
-  {
-    auto e = arg/+.evaluate()+/;
-    if (e is null)
-    {
-      // scop.error(e.begin, "expression is not evaluatable at compile time");
-    }
-    else if (auto stringExpr = e.Is!(StringExpression))
-      // Print string to standard output.
-      Stdout(stringExpr.getString());
-    else
-    {
-      // scop.error(e.begin, "expression must evaluate to a string");
-    }
-  }
-  // Print a newline at the end.
-  Stdout('\n');
-}
-
-/// Evaluates a lib pragma.
-void pragma_lib(Scope scop, Token* pragmaLoc, Expression[] args)
-{
-  if (args.length != 1)
-    return /*scop.error(pragmaLoc, "expected one expression argument to pragma")*/;
-
-  auto e = args[0]/+.evaluate()+/;
-  if (e is null)
-  {
-    // scop.error(e.begin, "expression is not evaluatable at compile time");
-  }
-  else if (auto stringExpr = e.Is!(StringExpression))
-  {
-    // TODO: collect library paths in Module?
-    // scop.modul.addLibrary(stringExpr.getString());
-  }
-  else
-  {
-    // scop.error(e.begin, "expression must evaluate to a string");
-  }
-}
-
-/// Returns true if the first branch (of a debug declaration/statement) or
-/// false if the else-branch should be compiled in.
-bool debugBranchChoice(Token* cond, CompilationContext context)
-{
-  if (cond)
-  {
-    if (cond.kind == TOK.Identifier)
-    {
-      if (context.findDebugId(cond.ident.str))
-        return true;
-    }
-    else if (cond.uint_ <= context.debugLevel)
-      return true;
-  }
-  else if (1 <= context.debugLevel)
-    return true;
-  return false;
-}
-
-/// Returns true if the first branch (of a version declaration/statement) or
-/// false if the else-branch should be compiled in.
-bool versionBranchChoice(Token* cond, CompilationContext context)
-{
-  assert(cond);
-  if (cond.kind == TOK.Identifier)
-  {
-    if (context.findVersionId(cond.ident.str))
-      return true;
-  }
-  else if (cond.uint_ >= context.versionLevel)
-    return true;
-  return false;
-}
--- a/trunk/src/dil/semantic/Interpreter.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.semantic.Interpreter;
-
-import dil.ast.Visitor;
-import dil.ast.Node,
-       dil.ast.Declarations,
-       dil.ast.Expressions,
-       dil.ast.Statements,
-       dil.ast.Types,
-       dil.ast.Parameters;
-
-import dil.semantic.Symbol,
-       dil.semantic.Symbols,
-       dil.semantic.Scope,
-       dil.semantic.Types;
-import dil.Information;
-
-/// Used for compile-time evaluation of expressions.
-class Interpreter : Visitor
-{
-  // Scope scop;
-  InfoManager infoMan;
-
-  static class Result : Expression
-  {
-    override Result copy(){return null;}
-  }
-
-  static const Result NAR; /// Not a Result. Similar to NAN in floating point arithmetics.
-
-  static this()
-  {
-    NAR = new Result;
-    NAR.type = Types.Error;
-  }
-
-  /// Evaluates the expression e.
-  /// Returns: NAR or a value.
-  static Expression interpret(Expression e, InfoManager infoMan/+, Scope scop+/)
-  {
-    return (new Interpreter(/+scop,+/ infoMan)).eval(e);
-  }
-
-  /// Constructs an Interpreter object.
-  this(/+Scope scop, +/InfoManager infoMan)
-  {
-    // this.scop = scop;
-    this.infoMan = infoMan;
-  }
-
-  /// Start evaluation.
-  Expression eval(Expression e)
-  {
-    return e;
-  }
-
-  /// Returns true if e is immutable.
-  bool isImmutable(Expression e)
-  {
-    switch (e.kind)
-    {
-    alias NodeKind NK;
-    case NK.IntExpression, NK.RealExpression,
-         NK.ComplexExpression, NK.CharExpression,
-         NK.BoolExpression, NK.StringExpression:
-      return true;
-    default:
-    }
-    return false;
-  }
-}
--- a/trunk/src/dil/semantic/Module.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.semantic.Module;
-
-import dil.ast.Node;
-import dil.ast.Declarations;
-import dil.parser.Parser;
-import dil.lexer.Lexer;
-import dil.semantic.Symbol;
-import dil.semantic.Symbols;
-import dil.Information;
-import dil.SourceText;
-import common;
-
-import tango.io.FilePath;
-import tango.io.FileConst;
-
-alias FileConst.PathSeparatorChar dirSep;
-
-/// Represents a semantic D module and a source file.
-class Module : ScopeSymbol
-{
-  SourceText sourceText; /// The source file of this module.
-  string moduleFQN; /// Fully qualified name of the module. E.g.: dil.ast.Node
-  string packageName; /// E.g.: dil.ast
-  string moduleName; /// E.g.: Node
-
-  CompoundDeclaration root; /// The root of the parse tree.
-  ImportDeclaration[] imports; /// ImportDeclarations found in this file.
-  ModuleDeclaration moduleDecl; /// The optional ModuleDeclaration in this file.
-  Parser parser; /// The parser used to parse this file.
-
-  // Module[] modules;
-
-  InfoManager infoMan; /// Collects error messages.
-
-  this()
-  {
-    super(SYM.Module, null, null);
-  }
-
-  /// Constructs a Module object.
-  /// Params:
-  ///   filePath = file path to the source text; loaded in the constructor.
-  ///   infoMan = used for collecting error messages.
-  this(string filePath, InfoManager infoMan = null)
-  {
-    this();
-    this.sourceText = new SourceText(filePath);
-    this.infoMan = infoMan;
-    this.sourceText.load(infoMan);
-  }
-
-  /// Returns the file path of the source text.
-  string filePath()
-  {
-    return sourceText.filePath;
-  }
-
-  /// Returns the file extension: "d" or "di".
-  string fileExtension()
-  {
-    foreach_reverse(i, c; filePath)
-      if (c == '.')
-        return filePath[i+1..$];
-    return "";
-  }
-
-  /// Sets the parser to be used for parsing the source text.
-  void setParser(Parser parser)
-  {
-    this.parser = parser;
-  }
-
-  /// Parses the module.
-  /// Throws:
-  ///   An Exception if the there's no ModuleDeclaration and
-  ///   the file name is an invalid or reserved D identifier.
-  void parse()
-  {
-    if (this.parser is null)
-      this.parser = new Parser(sourceText, infoMan);
-
-    this.root = parser.start();
-    this.imports = parser.imports;
-
-    if (root.children.length)
-    { // moduleDecl will be null if first node isn't a ModuleDeclaration.
-      this.moduleDecl = root.children[0].Is!(ModuleDeclaration);
-      if (this.moduleDecl)
-        this.setFQN(moduleDecl.getFQN());
-    }
-
-    if (!this.moduleFQN.length)
-    { // Take base name of file path as module name.
-      auto str = (new FilePath(filePath)).name();
-      if (Lexer.isReservedIdentifier(str))
-        throw new Exception("'"~str~"' is not a valid module name; it's a reserved or invalid D identifier.");
-      this.moduleFQN = this.moduleName = str;
-    }
-  }
-
-  /// Returns the first token of the module's source text.
-  Token* firstToken()
-  {
-    return parser.lexer.firstToken();
-  }
-
-  /// Returns true if there are errors in the source file.
-  bool hasErrors()
-  {
-    return parser.errors.length || parser.lexer.errors.length;
-  }
-
-  /// Returns a list of import paths.
-  /// E.g.: ["dil/ast/Node", "dil/semantic/Module"]
-  string[] getImportPaths()
-  {
-    string[] result;
-    foreach (import_; imports)
-      result ~= import_.getModuleFQNs(dirSep);
-    return result;
-  }
-
-  /// Returns the fully qualified name of this module.
-  /// E.g.: dil.ast.Node
-  string getFQN()
-  {
-    return moduleFQN;
-  }
-
-  /// Set's the module's FQN.
-  void setFQN(string moduleFQN)
-  {
-    uint i = moduleFQN.length;
-    if (i != 0) // Don't decrement if string has zero length.
-      i--;
-    // Find last dot.
-    for (; i != 0 && moduleFQN[i] != '.'; i--)
-    {}
-    this.moduleFQN = moduleFQN;
-    this.packageName = moduleFQN[0..i];
-    this.moduleName = moduleFQN[(i == 0 ? 0 : i+1) .. $];
-  }
-
-  /// Returns the module's FQN with slashes instead of dots.
-  /// E.g.: dil/ast/Node
-  string getFQNPath()
-  {
-    string FQNPath = moduleFQN.dup;
-    foreach (i, c; FQNPath)
-      if (c == '.')
-        FQNPath[i] = dirSep;
-    return FQNPath;
-  }
-}
--- a/trunk/src/dil/semantic/Package.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.semantic.Package;
-
-import dil.semantic.Symbol;
-
-class Package : Symbol
-{
-
-}
--- a/trunk/src/dil/semantic/Pass1.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,504 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.semantic.Pass1;
-
-import dil.ast.Visitor;
-import dil.ast.Node,
-       dil.ast.Declarations,
-       dil.ast.Expressions,
-       dil.ast.Statements,
-       dil.ast.Types,
-       dil.ast.Parameters;
-import dil.lexer.IdTable;
-import dil.semantic.Symbol,
-       dil.semantic.Symbols,
-       dil.semantic.Types,
-       dil.semantic.Scope,
-       dil.semantic.Module,
-       dil.semantic.Analysis;
-import dil.Compilation;
-import dil.Location;
-import dil.Information;
-import dil.Messages;
-import dil.Enums;
-import dil.CompilerInfo;
-import common;
-
-/// The first pass is the declaration pass.
-///
-/// The basic task of this class is to traverse the parse tree,
-/// find all kinds of declarations and add them
-/// to the symbol tables of their respective scopes.
-class SemanticPass1 : Visitor
-{
-  Scope scop; /// The current scope.
-  Module modul; /// The module to be semantically checked.
-  CompilationContext context; /// The compilation context.
-
-  // Attributes:
-  LinkageType linkageType; /// Current linkage type.
-  Protection protection; /// Current protection attribute.
-  StorageClass storageClass; /// Current storage classes.
-  uint alignSize; /// Current align size.
-
-  /// Constructs a SemanticPass1 object.
-  /// Params:
-  ///   modul = the module to be processed.
-  ///   context = the compilation context.
-  this(Module modul, CompilationContext context)
-  {
-    this.modul = modul;
-    this.context = new CompilationContext(context);
-    this.alignSize = context.structAlign;
-  }
-
-  /// Starts processing the module.
-  void start()
-  {
-    assert(modul.root !is null);
-    // Create module scope.
-    scop = new Scope(null, modul);
-    visit(modul.root);
-  }
-
-  /// Enters a new scope.
-  void enterScope(ScopeSymbol s)
-  {
-    scop = scop.enter(s);
-  }
-
-  /// Exits the current scope.
-  void exitScope()
-  {
-    scop = scop.exit();
-  }
-
-  /// Returns true if this is the module scope.
-  bool isModuleScope()
-  {
-    return scop.symbol.isModule();
-  }
-
-  /// Inserts a symbol into the current scope.
-  void insert(Symbol symbol, Identifier* name)
-  {
-    auto symX = scop.symbol.lookup(name);
-    if (symX)
-      reportSymbolConflict(symbol, symX, name);
-    else
-      scop.symbol.insert(symbol, name);
-    // Set the current scope symbol as the parent.
-    symbol.parent = scop.symbol;
-  }
-
-  /// Inserts a symbol into scopeSym.
-  void insert(Symbol symbol, ScopeSymbol scopeSym)
-  {
-    auto symX = scopeSym.lookup(symbol.name);
-    if (symX)
-      reportSymbolConflict(symbol, symX, symbol.name);
-    else
-      scopeSym.insert(symbol, symbol.name);
-    // Set the current scope symbol as the parent.
-    symbol.parent = scopeSym;
-  }
-
-  /// Inserts a symbol, overloading on the name, into the current scope.
-  void insertOverload(Symbol sym, Identifier* name)
-  {
-    auto sym2 = scop.symbol.lookup(name);
-    if (sym2)
-    {
-      if (sym2.isOverloadSet)
-        (cast(OverloadSet)cast(void*)sym2).add(sym);
-      else
-        reportSymbolConflict(sym, sym2, name);
-    }
-    else
-      // Create a new overload set.
-      scop.symbol.insert(new OverloadSet(name, sym.node), name);
-    // Set the current scope symbol as the parent.
-    sym.parent = scop.symbol;
-  }
-
-  /// Reports an error: new symbol s1 conflicts with existing symbol s2.
-  void reportSymbolConflict(Symbol s1, Symbol s2, Identifier* name)
-  {
-    auto loc = s2.node.begin.getErrorLocation();
-    auto locString = Format("{}({},{})", loc.filePath, loc.lineNum, loc.colNum);
-    error(s1.node.begin, MSG.DeclConflictsWithDecl, name.str, locString);
-  }
-
-  /// Creates an error report.
-  void error(Token* token, char[] formatMsg, ...)
-  {
-    if (!modul.infoMan)
-      return;
-    auto location = token.getErrorLocation();
-    auto msg = Format(_arguments, _argptr, formatMsg);
-    modul.infoMan ~= new SemanticError(location, msg);
-  }
-
-
-  /// Collects info about nodes which have to be evaluated later.
-  static class Deferred
-  {
-    Node node;
-    ScopeSymbol symbol;
-    // Saved attributes.
-    LinkageType linkageType;
-    Protection protection;
-    StorageClass storageClass;
-    uint alignSize;
-  }
-
-  /// List of mixin, static if, static assert and pragma(msg,...) declarations.
-  ///
-  /// Their analysis must be deferred because they entail
-  /// evaluation of expressions.
-  Deferred[] deferred;
-
-  /// Adds a deferred node to the list.
-  void addDeferred(Node node)
-  {
-    auto d = new Deferred;
-    d.node = node;
-    d.symbol = scop.symbol;
-    d.linkageType = linkageType;
-    d.protection = protection;
-    d.storageClass = storageClass;
-    d.alignSize = alignSize;
-    deferred ~= d;
-  }
-
-  private alias Declaration D; /// A handy alias. Saves typing.
-
-override
-{
-  D visit(CompoundDeclaration d)
-  {
-    foreach (decl; d.decls)
-      visitD(decl);
-    return d;
-  }
-
-  D visit(IllegalDeclaration)
-  { assert(0, "semantic pass on invalid AST"); return null; }
-
-  D visit(EmptyDeclaration ed)
-  { return ed; }
-
-  D visit(ModuleDeclaration)
-  { return null; }
-
-  D visit(ImportDeclaration d)
-  {
-    return d;
-  }
-
-  D visit(AliasDeclaration ad)
-  {
-    return ad;
-  }
-
-  D visit(TypedefDeclaration td)
-  {
-    return td;
-  }
-
-  D visit(EnumDeclaration d)
-  {
-    // Create the symbol.
-    d.symbol = new Enum(d.name, d);
-    auto isAnonymous = d.name is null;
-    if (isAnonymous)
-      d.symbol.name = IdTable.genAnonEnumID();
-    insert(d.symbol, d.symbol.name);
-    auto parentScopeSymbol = scop.symbol;
-    enterScope(d.symbol);
-    // Declare members.
-    foreach (member; d.members)
-    {
-      visitD(member);
-      if (isAnonymous) // Also insert into parent scope if enum is anonymous.
-        insert(member.symbol, parentScopeSymbol);
-      member.symbol.parent = d.symbol;
-    }
-    exitScope();
-    return d;
-  }
-
-  D visit(EnumMemberDeclaration d)
-  {
-    d.symbol = new EnumMember(d.name, protection, storageClass, linkageType, d);
-    insert(d.symbol, d.symbol.name);
-    return d;
-  }
-
-  D visit(ClassDeclaration d)
-  {
-    if (d.symbol)
-      return d;
-    d.symbol = new Class(d.name, d);
-    // Insert into current scope.
-    insert(d.symbol, d.name);
-    enterScope(d.symbol);
-    // Continue semantic analysis.
-    d.decls && visitD(d.decls);
-    exitScope();
-    return d;
-  }
-
-  D visit(InterfaceDeclaration d)
-  {
-    if (d.symbol)
-      return d;
-    d.symbol = new dil.semantic.Symbols.Interface(d.name, d);
-    // Insert into current scope.
-    insert(d.symbol, d.name);
-    enterScope(d.symbol);
-    // Continue semantic analysis.
-    d.decls && visitD(d.decls);
-    exitScope();
-    return d;
-  }
-
-  D visit(StructDeclaration d)
-  {
-    if (d.symbol)
-      return d;
-    d.symbol = new Struct(d.name, d);
-    // Insert into current scope.
-    if (d.name)
-      insert(d.symbol, d.name);
-    enterScope(d.symbol);
-    // Continue semantic analysis.
-    d.decls && visitD(d.decls);
-    exitScope();
-    return d;
-  }
-
-  D visit(UnionDeclaration d)
-  {
-    if (d.symbol)
-      return d;
-    d.symbol = new Union(d.name, d);
-    // Insert into current scope.
-    if (d.name)
-      insert(d.symbol, d.name);
-    enterScope(d.symbol);
-    // Continue semantic analysis.
-    d.decls && visitD(d.decls);
-    exitScope();
-    return d;
-  }
-
-  D visit(ConstructorDeclaration d)
-  {
-    auto func = new Function(Ident.__ctor, d);
-    insertOverload(func, func.name);
-    return d;
-  }
-
-  D visit(StaticConstructorDeclaration d)
-  {
-    auto func = new Function(Ident.__ctor, d);
-    insertOverload(func, func.name);
-    return d;
-  }
-
-  D visit(DestructorDeclaration d)
-  {
-    auto func = new Function(Ident.__dtor, d);
-    insertOverload(func, func.name);
-    return d;
-  }
-
-  D visit(StaticDestructorDeclaration d)
-  {
-    auto func = new Function(Ident.__dtor, d);
-    insertOverload(func, func.name);
-    return d;
-  }
-
-  D visit(FunctionDeclaration d)
-  {
-    auto func = new Function(d.name, d);
-    insertOverload(func, func.name);
-    return d;
-  }
-
-  D visit(VariablesDeclaration vd)
-  {
-    // Error if we are in an interface.
-    if (scop.symbol.isInterface && !vd.isStatic)
-      return error(vd.begin, MSG.InterfaceCantHaveVariables), vd;
-
-    // Insert variable symbols in this declaration into the symbol table.
-    foreach (i, name; vd.names)
-    {
-      auto variable = new Variable(name, protection, storageClass, linkageType, vd);
-      variable.value = vd.inits[i];
-      vd.variables ~= variable;
-      insert(variable, name);
-    }
-    return vd;
-  }
-
-  D visit(InvariantDeclaration d)
-  {
-    auto func = new Function(Ident.__invariant, d);
-    insert(func, func.name);
-    return d;
-  }
-
-  D visit(UnittestDeclaration d)
-  {
-    auto func = new Function(Ident.__unittest, d);
-    insertOverload(func, func.name);
-    return d;
-  }
-
-  D visit(DebugDeclaration d)
-  {
-    if (d.isSpecification)
-    {
-      if (!isModuleScope())
-        error(d.begin, MSG.DebugSpecModuleLevel, d.spec.srcText);
-      else if (d.spec.kind == TOK.Identifier)
-        context.addDebugId(d.spec.ident.str);
-      else
-        context.debugLevel = d.spec.uint_;
-    }
-    else
-    {
-      if (debugBranchChoice(d.cond, context))
-        d.compiledDecls = d.decls;
-      else
-        d.compiledDecls = d.elseDecls;
-      d.compiledDecls && visitD(d.compiledDecls);
-    }
-    return d;
-  }
-
-  D visit(VersionDeclaration d)
-  {
-    if (d.isSpecification)
-    {
-      if (!isModuleScope())
-        error(d.begin, MSG.VersionSpecModuleLevel, d.spec.srcText);
-      else if (d.spec.kind == TOK.Identifier)
-        context.addVersionId(d.spec.ident.str);
-      else
-        context.versionLevel = d.spec.uint_;
-    }
-    else
-    {
-      if (versionBranchChoice(d.cond, context))
-        d.compiledDecls = d.decls;
-      else
-        d.compiledDecls = d.elseDecls;
-      d.compiledDecls && visitD(d.compiledDecls);
-    }
-    return d;
-  }
-
-  D visit(TemplateDeclaration d)
-  {
-    if (d.symbol)
-      return d;
-    d.symbol = new Template(d.name, d);
-    // Insert into current scope.
-    insertOverload(d.symbol, d.name);
-    enterScope(d.symbol);
-    // Continue semantic analysis.
-    visitD(d.decls);
-    exitScope();
-    return d;
-  }
-
-  D visit(NewDeclaration d)
-  {
-    auto func = new Function(Ident.__new, d);
-    insert(func, func.name);
-    return d;
-  }
-
-  D visit(DeleteDeclaration d)
-  {
-    auto func = new Function(Ident.__delete, d);
-    insert(func, func.name);
-    return d;
-  }
-
-  D visit(ProtectionDeclaration d)
-  {
-    auto saved = protection; // Save.
-    protection = d.prot; // Set.
-    visitD(d.decls);
-    protection = saved; // Restore.
-    return d;
-  }
-
-  D visit(StorageClassDeclaration d)
-  {
-    auto saved = storageClass; // Save.
-    storageClass = d.storageClass; // Set.
-    visitD(d.decls);
-    storageClass = saved; // Restore.
-    return d;
-  }
-
-  D visit(LinkageDeclaration d)
-  {
-    auto saved = linkageType; // Save.
-    linkageType = d.linkageType; // Set.
-    visitD(d.decls);
-    linkageType = saved; // Restore.
-    return d;
-  }
-
-  D visit(AlignDeclaration d)
-  {
-    auto saved = alignSize; // Save.
-    alignSize = d.size; // Set.
-    visitD(d.decls);
-    alignSize = saved; // Restore.
-    return d;
-  }
-
-  // Deferred declarations:
-
-  D visit(StaticAssertDeclaration d)
-  {
-    addDeferred(d);
-    return d;
-  }
-
-  D visit(StaticIfDeclaration d)
-  {
-    addDeferred(d);
-    return d;
-  }
-
-  D visit(MixinDeclaration d)
-  {
-    addDeferred(d);
-    return d;
-  }
-
-  D visit(PragmaDeclaration d)
-  {
-    if (d.ident is Ident.msg)
-      addDeferred(d);
-    else
-    {
-      pragmaSemantic(scop, d.begin, d.ident, d.args);
-      visitD(d.decls);
-    }
-    return d;
-  }
-} // override
-}
--- a/trunk/src/dil/semantic/Pass2.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,436 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.semantic.Pass2;
-
-import dil.ast.DefaultVisitor;
-import dil.ast.Node,
-       dil.ast.Declarations,
-       dil.ast.Expressions,
-       dil.ast.Statements,
-       dil.ast.Types,
-       dil.ast.Parameters;
-import dil.lexer.Identifier;
-import dil.semantic.Symbol,
-       dil.semantic.Symbols,
-       dil.semantic.Types,
-       dil.semantic.Scope,
-       dil.semantic.Module,
-       dil.semantic.Analysis,
-       dil.semantic.Interpreter;
-import dil.parser.Parser;
-import dil.SourceText;
-import dil.Location;
-import dil.Information;
-import dil.Messages;
-import dil.Enums;
-import dil.CompilerInfo;
-import common;
-
-/// The second pass determines the types of symbols and the types
-/// of expressions and also evaluates them.
-class SemanticPass2 : DefaultVisitor
-{
-  Scope scop; /// The current scope.
-  Module modul; /// The module to be semantically checked.
-
-  /// Constructs a SemanticPass2 object.
-  /// Params:
-  ///   modul = the module to be checked.
-  this(Module modul)
-  {
-    this.modul = modul;
-  }
-
-  /// Start semantic analysis.
-  void start()
-  {
-    assert(modul.root !is null);
-    // Create module scope.
-    scop = new Scope(null, modul);
-    visit(modul.root);
-  }
-
-  /// Enters a new scope.
-  void enterScope(ScopeSymbol s)
-  {
-    scop = scop.enter(s);
-  }
-
-  /// Exits the current scope.
-  void exitScope()
-  {
-    scop = scop.exit();
-  }
-
-  /// Evaluates e and returns the result.
-  Expression interpret(Expression e)
-  {
-    return Interpreter.interpret(e, modul.infoMan/+, scop+/);
-  }
-
-  /// Creates an error report.
-  void error(Token* token, char[] formatMsg, ...)
-  {
-    auto location = token.getErrorLocation();
-    auto msg = Format(_arguments, _argptr, formatMsg);
-    modul.infoMan ~= new SemanticError(location, msg);
-  }
-
-  /// Some handy aliases.
-  private alias Declaration D;
-  private alias Expression E; /// ditto
-  private alias Statement S; /// ditto
-  private alias TypeNode T; /// ditto
-
-  /// The current scope symbol to use for looking up identifiers.
-  /// E.g.:
-  /// ---
-  /// object.method(); // *) object is looked up in the current scope.
-  ///                  // *) idScope is set if object is a ScopeSymbol.
-  ///                  // *) method will be looked up in idScope.
-  /// dil.ast.Node.Node node; // A fully qualified type.
-  /// ---
-  ScopeSymbol idScope;
-
-  /// Searches for a symbol.
-  Symbol search(Token* idTok)
-  {
-    assert(idTok.kind == TOK.Identifier);
-    auto id = idTok.ident;
-    Symbol symbol;
-
-    if (idScope is null)
-      for (auto sc = scop; sc; sc = sc.parent)
-      {
-        symbol = sc.lookup(id);
-        if (symbol)
-          return symbol;
-      }
-    else
-      symbol = idScope.lookup(id);
-
-    if (symbol is null)
-      error(idTok, MSG.UndefinedIdentifier, id.str);
-    else if (auto scopSymbol = cast(ScopeSymbol)symbol)
-      idScope = scopSymbol;
-
-    return symbol;
-  }
-
-override
-{
-  D visit(CompoundDeclaration d)
-  {
-    return super.visit(d);
-  }
-
-  D visit(EnumDeclaration d)
-  {
-    d.symbol.setCompleting();
-
-    Type type = Types.Int; // Default to int.
-    if (d.baseType)
-      type = visitT(d.baseType).type;
-    d.symbol.type = new TypeEnum(d.symbol, type);
-
-    enterScope(d.symbol);
-
-    foreach (member; d.members)
-    {
-      Expression finalValue;
-      member.symbol.setCompleting();
-      if (member.value)
-      {
-        member.value = visitE(member.value);
-        finalValue = interpret(member.value);
-        if (finalValue is Interpreter.NAR)
-          finalValue = new IntExpression(0, d.symbol.type);
-      }
-      //else
-        // TODO: increment a number variable and assign that to value.
-      member.symbol.type = d.symbol.type; // Assign TypeEnum.
-      member.symbol.value = finalValue;
-      member.symbol.setComplete();
-    }
-
-    exitScope();
-    d.symbol.setComplete();
-    return d;
-  }
-
-  D visit(MixinDeclaration md)
-  {
-    if (md.decls)
-      return md.decls;
-    if (md.isMixinExpression)
-    {
-      md.argument = visitE(md.argument);
-      auto expr = interpret(md.argument);
-      if (expr is Interpreter.NAR)
-        return md;
-      auto stringExpr = expr.Is!(StringExpression);
-      if (stringExpr is null)
-      {
-        error(md.begin, MSG.MixinArgumentMustBeString);
-        return md;
-      }
-      else
-      { // Parse the declarations in the string.
-        auto loc = md.begin.getErrorLocation();
-        auto filePath = loc.filePath;
-        auto sourceText = new SourceText(filePath, stringExpr.getString());
-        auto parser = new Parser(sourceText, modul.infoMan);
-        md.decls = parser.start();
-      }
-    }
-    else
-    {
-      // TODO: implement template mixin.
-    }
-    return md.decls;
-  }
-
-  // Type nodes:
-
-  T visit(TypeofType t)
-  {
-    t.e = visitE(t.e);
-    t.type = t.e.type;
-    return t;
-  }
-
-  T visit(ArrayType t)
-  {
-    auto baseType = visitT(t.next).type;
-    if (t.isAssociative)
-      t.type = baseType.arrayOf(visitT(t.assocType).type);
-    else if (t.isDynamic)
-      t.type = baseType.arrayOf();
-    else if (t.isStatic)
-    {}
-    else
-      assert(t.isSlice);
-    return t;
-  }
-
-  T visit(PointerType t)
-  {
-    t.type = visitT(t.next).type.ptrTo();
-    return t;
-  }
-
-  T visit(QualifiedType t)
-  {
-    if (t.lhs.Is!(QualifiedType) is null)
-      idScope = null; // Reset at left-most type.
-    visitT(t.lhs);
-    visitT(t.rhs);
-    t.type = t.rhs.type;
-    return t;
-  }
-
-  T visit(IdentifierType t)
-  {
-    auto idToken = t.begin;
-    auto symbol = search(idToken);
-    // TODO: save symbol or its type in t.
-    return t;
-  }
-
-  T visit(TemplateInstanceType t)
-  {
-    auto idToken = t.begin;
-    auto symbol = search(idToken);
-    // TODO: save symbol or its type in t.
-    return t;
-  }
-
-  T visit(ModuleScopeType t)
-  {
-    idScope = modul;
-    return t;
-  }
-
-  T visit(IntegralType t)
-  {
-    // A table mapping the kind of a token to its corresponding semantic Type.
-    TypeBasic[TOK] tok2Type = [
-      TOK.Char : Types.Char,   TOK.Wchar : Types.Wchar,   TOK.Dchar : Types.Dchar, TOK.Bool : Types.Bool,
-      TOK.Byte : Types.Byte,   TOK.Ubyte : Types.Ubyte,   TOK.Short : Types.Short, TOK.Ushort : Types.Ushort,
-      TOK.Int : Types.Int,    TOK.Uint : Types.Uint,    TOK.Long : Types.Long,  TOK.Ulong : Types.Ulong,
-      TOK.Cent : Types.Cent,   TOK.Ucent : Types.Ucent,
-      TOK.Float : Types.Float,  TOK.Double : Types.Double,  TOK.Real : Types.Real,
-      TOK.Ifloat : Types.Ifloat, TOK.Idouble : Types.Idouble, TOK.Ireal : Types.Ireal,
-      TOK.Cfloat : Types.Cfloat, TOK.Cdouble : Types.Cdouble, TOK.Creal : Types.Creal, TOK.Void : Types.Void
-    ];
-    assert(t.tok in tok2Type);
-    t.type = tok2Type[t.tok];
-    return t;
-  }
-
-  // Expression nodes:
-
-  E visit(ParenExpression e)
-  {
-    if (!e.type)
-    {
-      e.next = visitE(e.next);
-      e.type = e.next.type;
-    }
-    return e;
-  }
-
-  E visit(CommaExpression e)
-  {
-    if (!e.type)
-    {
-      e.lhs = visitE(e.lhs);
-      e.rhs = visitE(e.rhs);
-      e.type = e.rhs.type;
-    }
-    return e;
-  }
-
-  E visit(OrOrExpression)
-  { return null; }
-
-  E visit(AndAndExpression)
-  { return null; }
-
-  E visit(SpecialTokenExpression e)
-  {
-    if (e.type)
-      return e.value;
-    switch (e.specialToken.kind)
-    {
-    case TOK.LINE, TOK.VERSION:
-      e.value = new IntExpression(e.specialToken.uint_, Types.Uint);
-      break;
-    case TOK.FILE, TOK.DATE, TOK.TIME, TOK.TIMESTAMP, TOK.VENDOR:
-      e.value = new StringExpression(e.specialToken.str);
-      break;
-    default:
-      assert(0);
-    }
-    e.type = e.value.type;
-    return e.value;
-  }
-
-  E visit(DollarExpression e)
-  {
-    if (e.type)
-      return e;
-    e.type = Types.Size_t;
-    // if (!inArraySubscript)
-    //   error("$ can only be in an array subscript.");
-    return e;
-  }
-
-  E visit(NullExpression e)
-  {
-    if (!e.type)
-      e.type = Types.Void_ptr;
-    return e;
-  }
-
-  E visit(BoolExpression e)
-  {
-    if (e.type)
-      return e;
-    e.value = new IntExpression(e.toBool(), Types.Bool);
-    e.type = Types.Bool;
-    return e;
-  }
-
-  E visit(IntExpression e)
-  {
-    if (e.type)
-      return e;
-
-    if (e.number & 0x8000_0000_0000_0000)
-      e.type = Types.Ulong; // 0xFFFF_FFFF_FFFF_FFFF
-    else if (e.number & 0xFFFF_FFFF_0000_0000)
-      e.type = Types.Long; // 0x7FFF_FFFF_FFFF_FFFF
-    else if (e.number & 0x8000_0000)
-      e.type = Types.Uint; // 0xFFFF_FFFF
-    else
-      e.type = Types.Int; // 0x7FFF_FFFF
-    return e;
-  }
-
-  E visit(RealExpression e)
-  {
-    if (!e.type)
-      e.type = Types.Double;
-    return e;
-  }
-
-  E visit(ComplexExpression e)
-  {
-    if (!e.type)
-      e.type = Types.Cdouble;
-    return e;
-  }
-
-  E visit(CharExpression e)
-  {
-    if (e.type)
-      return e;
-    if (e.character <= 0xFF)
-      e.type = Types.Char;
-    else if (e.character <= 0xFFFF)
-      e.type = Types.Wchar;
-    else
-      e.type = Types.Dchar;
-    return e;
-  }
-
-  E visit(StringExpression e)
-  {
-    return e;
-  }
-
-  E visit(MixinExpression me)
-  {
-    if (me.type)
-      return me.expr;
-    me.expr = visitE(me.expr);
-    auto expr = interpret(me.expr);
-    if (expr is Interpreter.NAR)
-      return me;
-    auto stringExpr = expr.Is!(StringExpression);
-    if (stringExpr is null)
-     error(me.begin, MSG.MixinArgumentMustBeString);
-    else
-    {
-      auto loc = me.begin.getErrorLocation();
-      auto filePath = loc.filePath;
-      auto sourceText = new SourceText(filePath, stringExpr.getString());
-      auto parser = new Parser(sourceText, modul.infoMan);
-      expr = parser.start2();
-      expr = visitE(expr); // Check expression.
-    }
-    me.expr = expr;
-    me.type = expr.type;
-    return me.expr;
-  }
-
-  E visit(ImportExpression ie)
-  {
-    if (ie.type)
-      return ie.expr;
-    ie.expr = visitE(ie.expr);
-    auto expr = interpret(ie.expr);
-    if (expr is Interpreter.NAR)
-      return ie;
-    auto stringExpr = expr.Is!(StringExpression);
-    //if (stringExpr is null)
-    //  error(me.begin, MSG.ImportArgumentMustBeString);
-    // TODO: load file
-    //ie.expr = new StringExpression(loadImportFile(stringExpr.getString()));
-    return ie.expr;
-  }
-}
-}
--- a/trunk/src/dil/semantic/Scope.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.semantic.Scope;
-
-import dil.semantic.Symbol;
-import dil.semantic.Symbols;
-import dil.lexer.Identifier;
-import common;
-
-/// Builds a hierarchy of environments.
-class Scope
-{
-  Scope parent; /// The surrounding scope, or null if this is the root scope.
-
-  ScopeSymbol symbol; /// The current symbol with the symbol table.
-
-  this(Scope parent, ScopeSymbol symbol)
-  {
-    this.parent = parent;
-    this.symbol = symbol;
-  }
-
-  /// Find a symbol in this scope.
-  /// Params:
-  ///   name = the name of the symbol.
-  Symbol lookup(Identifier* name)
-  {
-    return symbol.lookup(name);
-  }
-
-  /// Create a new inner scope and return that.
-  Scope enter(ScopeSymbol symbol)
-  {
-    return new Scope(this, symbol);
-  }
-
-  /// Destroy this scope and return the outer scope.
-  Scope exit()
-  {
-    auto sc = parent;
-    // delete this;
-    return sc;
-  }
-
-  /// Search for the enclosing Class scope.
-  Scope classScope()
-  {
-    auto scop = this;
-    do
-    {
-      if (scop.symbol.isClass)
-        return scop;
-      scop = scop.parent;
-    } while (scop)
-    return null;
-  }
-
-  /// Search for the enclosing Module scope.
-  Scope moduleScope()
-  {
-    auto scop = this;
-    do
-    {
-      if (scop.symbol.isModule)
-        return scop;
-      scop = scop.parent;
-    } while (scop)
-    return null;
-  }
-}
--- a/trunk/src/dil/semantic/Symbol.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.semantic.Symbol;
-
-import dil.ast.Node;
-import dil.lexer.Identifier;
-import common;
-
-/// Enumeration of Symbol IDs.
-enum SYM
-{
-  Module,
-  Class,
-  Interface,
-  Struct,
-  Union,
-  Enum,
-  EnumMember,
-  Template,
-  Variable,
-  Function,
-  Alias,
-  OverloadSet,
-//   Type,
-}
-
-/// A symbol represents an object with semantic code information.
-class Symbol
-{ /// Enumeration of symbol statuses.
-  enum Status : ushort
-  {
-    Declared,   /// The symbol has been declared.
-    Completing, /// The symbol is being processed.
-    Complete    /// The symbol is complete.
-  }
-
-  SYM sid; /// The ID of this symbol.
-  Status status; /// The semantic status of this symbol.
-  Symbol parent; /// The parent this symbol belongs to.
-  Identifier* name; /// The name of this symbol.
-  /// The syntax tree node that produced this symbol.
-  /// Useful for source code location info and retrieval of doc comments.
-  Node node;
-
-  /// Constructs a Symbol object.
-  /// Params:
-  ///   sid = the symbol's ID.
-  ///   name = the symbol's name.
-  ///   node = the symbol's node.
-  this(SYM sid, Identifier* name, Node node)
-  {
-    this.sid = sid;
-    this.name = name;
-    this.node = node;
-  }
-
-  /// Change the status to Status.Completing.
-  void setCompleting()
-  { status = Status.Completing; }
-
-  /// Change the status to Status.Complete.
-  void setComplete()
-  { status = Status.Complete; }
-
-  /// Returns true if the symbol is being completed.
-  bool isCompleting()
-  { return status == Status.Completing; }
-
-  /// Returns true if the symbols is complete.
-  bool isComplete()
-  { return status == Status.Complete; }
-
-  /// A template macro for building isXYZ() methods.
-  private template isX(char[] kind)
-  {
-    const char[] isX = `bool is`~kind~`(){ return sid == SYM.`~kind~`; }`;
-  }
-  mixin(isX!("Module"));
-  mixin(isX!("Class"));
-  mixin(isX!("Interface"));
-  mixin(isX!("Struct"));
-  mixin(isX!("Union"));
-  mixin(isX!("Enum"));
-  mixin(isX!("EnumMember"));
-  mixin(isX!("Template"));
-  mixin(isX!("Variable"));
-  mixin(isX!("Function"));
-  mixin(isX!("Alias"));
-  mixin(isX!("OverloadSet"));
-//   mixin(isX!("Type"));
-
-  /// Casts the symbol to Class.
-  Class to(Class)()
-  {
-    assert(mixin(`this.sid == mixin("SYM." ~ typeof(Class).stringof)`));
-    return cast(Class)cast(void*)this;
-  }
-
-  /// Returns: the fully qualified name of this symbol.
-  /// E.g.: dil.semantic.Symbol.Symbol.getFQN
-  char[] getFQN()
-  {
-    if (!name)
-      return parent ? parent.getFQN() : "";
-    if (parent)
-      return parent.getFQN() ~ '.' ~ name.str;
-    return name.str;
-  }
-}
--- a/trunk/src/dil/semantic/SymbolTable.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.semantic.SymbolTable;
-
-import dil.semantic.Symbol;
-import dil.lexer.Identifier;
-import common;
-
-/// Maps an identifier string to a Symbol.
-struct SymbolTable
-{
-  Symbol[char[]] table; /// The table data structure.
-
-  /// Looks up ident in the table.
-  /// Returns: the symbol if there, otherwise null.
-  Symbol lookup(Identifier* ident)
-  {
-    assert(ident !is null);
-    auto psym = ident.str in table;
-    return psym ? *psym : null;
-  }
-
-  /// Inserts a symbol into the table.
-  void insert(Symbol symbol, Identifier* ident)
-  {
-    table[ident.str] = symbol;
-  }
-}
--- a/trunk/src/dil/semantic/Symbols.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,206 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.semantic.Symbols;
-
-import dil.ast.Expression;
-import dil.semantic.Symbol;
-import dil.semantic.SymbolTable;
-import dil.semantic.Types;
-import dil.ast.Node;
-import dil.lexer.IdTable;
-import dil.Enums;
-import common;
-
-/// A symbol that has its own scope with a symbol table.
-class ScopeSymbol : Symbol
-{
-  SymbolTable symbolTable; /// The symbol table.
-  Symbol[] members; /// The member symbols (in lexical order.)
-
-  this(SYM sid, Identifier* name, Node node)
-  {
-    super(sid, name, node);
-  }
-
-  /// Look up name in the table.
-  Symbol lookup(Identifier* name)
-  {
-    return symbolTable.lookup(name);
-  }
-
-  /// Look up name in the table.
-  Symbol lookup(string name)
-  {
-    auto id = IdTable.lookup(name);
-    return id ? symbolTable.lookup(id) : null;
-  }
-
-  /// Insert a symbol into the table.
-  void insert(Symbol s, Identifier* name)
-  {
-    symbolTable.insert(s, name);
-    members ~= s;
-  }
-}
-
-/// Aggregates have function and field members.
-abstract class Aggregate : ScopeSymbol
-{
-  Function[] funcs;
-  Variable[] fields;
-
-  this(SYM sid, Identifier* name, Node node)
-  {
-    super(sid, name, node);
-  }
-
-  override void insert(Symbol s, Identifier* ident)
-  {
-    if (s.isVariable)
-      // Append variable to fields.
-      fields ~= cast(Variable)cast(void*)s;
-    else if (s.isFunction)
-      // Append function to funcs.
-      funcs ~= cast(Function)cast(void*)s;
-    super.insert(s, ident);
-  }
-}
-
-/// A class symbol.
-class Class : Aggregate
-{
-  this(Identifier* name, Node classNode)
-  {
-    super(SYM.Class, name, classNode);
-  }
-}
-
-/// An interface symbol.
-class Interface : Aggregate
-{
-  this(Identifier* name, Node interfaceNode)
-  {
-    super(SYM.Interface, name, interfaceNode);
-  }
-}
-
-/// A union symbol.
-class Union : Aggregate
-{
-  this(Identifier* name, Node unionNode)
-  {
-    super(SYM.Union, name, unionNode);
-  }
-}
-
-/// A struct symbol.
-class Struct : Aggregate
-{
-  this(Identifier* name, Node structNode)
-  {
-    super(SYM.Struct, name, structNode);
-  }
-}
-
-/// An enum symbol.
-class Enum : ScopeSymbol
-{
-  TypeEnum type;
-  this(Identifier* name, Node enumNode)
-  {
-    super(SYM.Enum, name, enumNode);
-  }
-
-  void setType(TypeEnum type)
-  {
-    this.type = type;
-  }
-}
-
-/// A template symbol.
-class Template : ScopeSymbol
-{
-  this(Identifier* name, Node templateNode)
-  {
-    super(SYM.Template, name, templateNode);
-  }
-}
-
-/// A function symbol.
-class Function : ScopeSymbol
-{
-  Protection prot; /// The protection.
-  StorageClass stc; /// The storage classes.
-  LinkageType linkType; /// The linkage type.
-
-  Type returnType;
-  Variable[] params;
-
-  this(Identifier* name, Node functionNode)
-  {
-    super(SYM.Function, name, functionNode);
-  }
-}
-
-/// A variable symbol.
-class Variable : Symbol
-{
-  Protection prot; /// The protection.
-  StorageClass stc; /// The storage classes.
-  LinkageType linkType; /// The linkage type.
-
-  Type type; /// The type of this variable.
-  Expression value; /// The value of this variable.
-
-  this(Identifier* name,
-       Protection prot, StorageClass stc, LinkageType linkType,
-       Node variableNode)
-  {
-    super(SYM.Variable, name, variableNode);
-
-    this.prot = prot;
-    this.stc = stc;
-    this.linkType = linkType;
-  }
-}
-
-/// An enum member symbol.
-class EnumMember : Variable
-{
-  this(Identifier* name,
-       Protection prot, StorageClass stc, LinkageType linkType,
-       Node enumMemberNode)
-  {
-    super(name, prot, stc, linkType, enumMemberNode);
-    this.sid = SYM.EnumMember;
-  }
-}
-
-/// An alias symbol.
-class Alias : Symbol
-{
-  this(Identifier* name, Node aliasNode)
-  {
-    super(SYM.Alias, name, aliasNode);
-  }
-}
-
-/// A list of symbols that share the same identifier.
-///
-/// These can be functions, templates and aggregates with template parameter lists.
-class OverloadSet : Symbol
-{
-  Symbol[] symbols;
-
-  this(Identifier* name, Node node)
-  {
-    super(SYM.OverloadSet, name, node);
-  }
-
-  void add(Symbol s)
-  {
-    symbols ~= s;
-  }
-}
--- a/trunk/src/dil/semantic/Types.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,403 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.semantic.Types;
-
-import dil.semantic.Symbol;
-import dil.semantic.TypesEnum;
-import dil.lexer.Identifier;
-import dil.CompilerInfo;
-
-/// The base type for all type structures.
-abstract class Type/* : Symbol*/
-{
-  Type next;     /// The next type in the type structure.
-  TYP tid;       /// The ID of the type.
-  Symbol symbol; /// Not null if this type has a symbol.
-
-  this(){}
-
-  /// Constructs a Type object.
-  /// Params:
-  ///   next = the type's next type.
-  ///   tid = the type's ID.
-  this(Type next, TYP tid)
-  {
-//     this.sid = SYM.Type;
-
-    this.next = next;
-    this.tid = tid;
-  }
-
-  /// Returns a pointer type to this type.
-  TypePointer ptrTo()
-  {
-    return new TypePointer(this);
-  }
-
-  /// Returns a dynamic array type using this type as its base.
-  TypeDArray arrayOf()
-  {
-    return new TypeDArray(this);
-  }
-
-  /// Returns an associative array type using this type as its base.
-  /// Params:
-  ///   key = the key type.
-  TypeAArray arrayOf(Type key)
-  {
-    return new TypeAArray(this, key);
-  }
-
-  /// Returns the byte size of this type.
-  final size_t sizeOf()
-  {
-    return MITable.getSize(this);
-  }
-
-  /// Size is not in MITable. Find out via virtual method.
-  size_t sizeOf_()
-  {
-    return sizeOf();
-  }
-
-  /// Returns true if this type has a symbol.
-  bool hasSymbol()
-  {
-    return symbol !is null;
-  }
-}
-
-/// All basic types. E.g.: int, char, real etc.
-class TypeBasic : Type
-{
-  this(TYP typ)
-  {
-    super(null, typ);
-  }
-}
-
-/// Dynamic array type.
-class TypeDArray : Type
-{
-  this(Type next)
-  {
-    super(next, TYP.DArray);
-  }
-}
-
-/// Associative array type.
-class TypeAArray : Type
-{
-  Type keyType;
-  this(Type next, Type keyType)
-  {
-    super(next, TYP.AArray);
-    this.keyType = keyType;
-  }
-}
-
-/// Static array type.
-class TypeSArray : Type
-{
-  size_t dimension;
-  this(Type next, size_t dimension)
-  {
-    super(next, TYP.SArray);
-    this.dimension = dimension;
-  }
-}
-
-/// Pointer type.
-class TypePointer : Type
-{
-  this(Type next)
-  {
-    super(next, TYP.Pointer);
-  }
-}
-
-/// Reference type.
-class TypeReference : Type
-{
-  this(Type next)
-  {
-    super(next, TYP.Reference);
-  }
-}
-
-/// Enum type.
-class TypeEnum : Type
-{
-  this(Symbol symbol, Type baseType)
-  {
-    super(baseType, TYP.Enum);
-    this.symbol = symbol;
-  }
-
-  Type baseType()
-  {
-    return next;
-  }
-}
-
-/// Struct type.
-class TypeStruct : Type
-{
-  this(Symbol symbol)
-  {
-    super(null, TYP.Struct);
-    this.symbol = symbol;
-  }
-}
-
-/// Class type.
-class TypeClass : Type
-{
-  this(Symbol symbol)
-  {
-    super(null, TYP.Class);
-    this.symbol = symbol;
-  }
-}
-
-/// Typedef type.
-class TypeTypedef : Type
-{
-  this(Type next)
-  {
-    super(next, TYP.Typedef);
-  }
-}
-
-/// Function type.
-class TypeFunction : Type
-{
-  this(Type next)
-  {
-    super(next, TYP.Function);
-  }
-}
-
-/// Delegate type.
-class TypeDelegate : Type
-{
-  this(Type next)
-  {
-    super(next, TYP.Delegate);
-  }
-}
-
-/// Identifier type.
-class TypeIdentifier : Type
-{
-  Identifier* ident;
-  this(Identifier* ident)
-  {
-    super(null, TYP.Identifier);
-  }
-}
-
-/// Template instantiation type.
-class TypeTemplInstance : Type
-{
-  this()
-  {
-    super(null, TYP.TInstance);
-  }
-}
-
-/// Template tuple type.
-class TypeTuple : Type
-{
-  this(Type next)
-  {
-    super(next, TYP.Tuple);
-  }
-}
-
-/// Constant type. D2.0
-class TypeConst : Type
-{
-  this(Type next)
-  {
-    super(next, TYP.Const);
-  }
-}
-
-/// Invariant type. D2.0
-class TypeInvariant : Type
-{
-  this(Type next)
-  {
-    super(next, TYP.Const);
-  }
-}
-
-/// Represents a value related to a Type.
-union Value
-{
-  void*  pvoid;
-  bool   bool_;
-  dchar  dchar_;
-  long   long_;
-  ulong  ulong_;
-  int    int_;
-  uint   uint_;
-  float  float_;
-  double double_;
-  real   real_;
-  creal  creal_;
-}
-
-/// Information related to a Type.
-struct TypeMetaInfo
-{
-  char mangle; /// Mangle character of the type.
-  ushort size; /// Byte size of the type.
-  Value* defaultInit; /// Default initialization value.
-}
-
-/// Namespace for the meta info table.
-struct MITable
-{
-static:
-  const ushort SIZE_NOT_AVAILABLE = 0; /// Size not available.
-  const Value VZERO = {int_:0}; /// Value 0.
-  const Value VNULL = {pvoid:null}; /// Value null.
-  const Value V0xFF = {dchar_:0xFF}; /// Value 0xFF.
-  const Value V0xFFFF = {dchar_:0xFFFF}; /// Value 0xFFFF.
-  const Value VFALSE = {bool_:false}; /// Value false.
-  const Value VNAN = {float_:float.nan}; /// Value NAN.
-  const Value VCNAN = {creal_:creal.nan}; /// Value complex NAN.
-  private alias SIZE_NOT_AVAILABLE SNA;
-  private alias PTR_SIZE PS;
-  /// The meta info table.
-  private const TypeMetaInfo metaInfoTable[] = [
-    {'?', SNA}, // Error
-
-    {'a', 1, &V0xFF},   // Char
-    {'u', 2, &V0xFFFF},   // Wchar
-    {'w', 4, &V0xFFFF},   // Dchar
-    {'b', 1, &VFALSE},   // Bool
-    {'g', 1, &VZERO},   // Byte
-    {'h', 1, &VZERO},   // Ubyte
-    {'s', 2, &VZERO},   // Short
-    {'t', 2, &VZERO},   // Ushort
-    {'i', 4, &VZERO},   // Int
-    {'k', 4, &VZERO},   // Uint
-    {'l', 8, &VZERO},   // Long
-    {'m', 8, &VZERO},   // Ulong
-    {'?', 16, &VZERO},  // Cent
-    {'?', 16, &VZERO},  // Ucent
-    {'f', 4, &VNAN},   // Float
-    {'d', 8, &VNAN},   // Double
-    {'e', 12, &VNAN},  // Real
-    {'o', 4, &VNAN},   // Ifloat
-    {'p', 8, &VNAN},   // Idouble
-    {'j', 12, &VNAN},  // Ireal
-    {'q', 8, &VCNAN},   // Cfloat
-    {'r', 16, &VCNAN},  // Cdouble
-    {'c', 24, &VCNAN},  // Creal
-    {'v', 1},   // void
-
-    {'n', SNA},  // None
-
-    {'A', PS*2, &VNULL}, // Dynamic array
-    {'G', PS*2, &VNULL}, // Static array
-    {'H', PS*2, &VNULL}, // Associative array
-
-    {'E', SNA}, // Enum
-    {'S', SNA}, // Struct
-    {'C', PS, &VNULL},  // Class
-    {'T', SNA}, // Typedef
-    {'F', PS},  // Function
-    {'D', PS*2, &VNULL}, // Delegate
-    {'P', PS, &VNULL},  // Pointer
-    {'R', PS, &VNULL},  // Reference
-    {'I', SNA}, // Identifier
-    {'?', SNA}, // Template instance
-    {'B', SNA}, // Tuple
-    {'x', SNA}, // Const, D2
-    {'y', SNA}, // Invariant, D2
-  ];
-  static assert(metaInfoTable.length == TYP.max+1);
-
-  /// Returns the size of a type.
-  size_t getSize(Type type)
-  {
-    auto size = metaInfoTable[type.tid].size;
-    if (size == SIZE_NOT_AVAILABLE)
-      return type.sizeOf_();
-    return size;
-  }
-}
-
-/// Namespace for a set of predefined types.
-struct Types
-{
-static:
-  /// Predefined basic types.
-  TypeBasic Char,   Wchar,   Dchar, Bool,
-            Byte,   Ubyte,   Short, Ushort,
-            Int,    Uint,    Long,  Ulong,
-            Cent,   Ucent,
-            Float,  Double,  Real,
-            Ifloat, Idouble, Ireal,
-            Cfloat, Cdouble, Creal, Void;
-
-  TypeBasic Size_t; /// The size type.
-  TypeBasic Ptrdiff_t; /// The pointer difference type.
-  TypePointer Void_ptr; /// The void pointer type.
-  TypeBasic Error; /// The error type.
-  TypeBasic Undefined; /// The undefined type.
-
-  /// Allocates an instance of TypeBasic and assigns it to typeName.
-  template newTB(char[] typeName)
-  {
-    const newTB = mixin(typeName~" = new TypeBasic(TYP."~typeName~")");
-  }
-
-  /// Initializes predefined types.
-  static this()
-  {
-    newTB!("Char");
-    newTB!("Wchar");
-    newTB!("Dchar");
-    newTB!("Bool");
-    newTB!("Byte");
-    newTB!("Ubyte");
-    newTB!("Short");
-    newTB!("Ushort");
-    newTB!("Int");
-    newTB!("Uint");
-    newTB!("Long");
-    newTB!("Ulong");
-    newTB!("Cent");
-    newTB!("Ucent");
-    newTB!("Float");
-    newTB!("Double");
-    newTB!("Real");
-    newTB!("Ifloat");
-    newTB!("Idouble");
-    newTB!("Ireal");
-    newTB!("Cfloat");
-    newTB!("Cdouble");
-    newTB!("Creal");
-    newTB!("Void");
-    version(X86_64)
-    {
-      Size_t = Ulong;
-      Ptrdiff_t = Long;
-    }
-    else
-    {
-      Size_t = Uint;
-      Ptrdiff_t = Int;
-    }
-    Void_ptr = Void.ptrTo;
-    Error = new TypeBasic(TYP.Error);
-    Undefined = new TypeBasic(TYP.Error);
-  }
-}
--- a/trunk/src/dil/semantic/TypesEnum.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.semantic.TypesEnum;
-
-/// Enumeration of Type IDs.
-enum TYP
-{
-  Error,
-  // Basic types.
-  Char,    /// char
-  Wchar,   /// wchar
-  Dchar,   /// dchar
-  Bool,    /// bool
-  Byte,    /// int8
-  Ubyte,   /// uint8
-  Short,   /// int16
-  Ushort,  /// uint16
-  Int,     /// int32
-  Uint,    /// uint32
-  Long,    /// int64
-  Ulong,   /// uint64
-  Cent,    /// int128
-  Ucent,   /// uint128
-  Float,   /// float32
-  Double,  /// float64
-  Real,    /// float80
-  Ifloat,  /// imaginary float32
-  Idouble, /// imaginary float64
-  Ireal,   /// imaginary float80
-  Cfloat,  /// complex float32
-  Cdouble, /// complex float64
-  Creal,   /// complex float80
-  Void,    /// void
-
-  None,   /// TypeNone in the specs. Why?
-
-  DArray, /// Dynamic array.
-  SArray, /// Static array.
-  AArray, /// Associative array.
-
-  Enum,       /// An enum.
-  Struct,     /// A struct.
-  Class,      /// A class.
-  Typedef,    /// A typedef.
-  Function,   /// A function.
-  Delegate,   /// A delegate.
-  Pointer,    /// A pointer.
-  Reference,  /// A reference.
-  Identifier, /// An identifier.
-  TInstance,  /// Template instance.
-  Tuple,      /// A template tuple.
-  Const,      /// A constant type. D2.0
-  Invariant,  /// An invariant type. D2.0
-}
--- a/trunk/src/dil/translator/German.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,340 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module dil.translator.German;
-
-import dil.ast.DefaultVisitor;
-import dil.ast.Node;
-import dil.ast.Declarations,
-       dil.ast.Statements,
-       dil.ast.Types,
-       dil.ast.Parameters;
-import tango.io.Print;
-
-private alias Declaration D;
-
-/// Translates a syntax tree into German.
-class GermanTranslator : DefaultVisitor
-{
-  Print!(char) put; /// Output buffer.
-
-  char[] indent; /// Current indendation string.
-  char[] indentStep; /// Appended to indent at each indendation level.
-
-  Declaration inAggregate; /// Current aggregate.
-  Declaration inFunc; /// Current function.
-
-  bool pluralize; /// Whether to use the plural when printing the next types.
-  bool pointer; /// Whether next types should consider the previous pointer.
-
-  /// Construct a GermanTranslator.
-  /// Params:
-  ///   put = buffer to print to.
-  ///   indentStep = added at every indendation step.
-  this(Print!(char) put, char[] indentStep)
-  {
-    this.put = put;
-    this.indentStep = indentStep;
-  }
-
-  /// Start translation.
-  void translate(Node root)
-  {
-    visitN(root);
-  }
-
-  /// Increases the indentation when instantiated.
-  /// The indentation is restored when the instance goes out of scope.
-  scope class Indent
-  {
-    char[] old_indent;
-    this()
-    {
-      old_indent = this.outer.indent;
-      this.outer.indent ~= this.outer.indentStep;
-    }
-
-    ~this()
-    { this.outer.indent = old_indent; }
-
-    char[] toString()
-    { return this.outer.indent; }
-  }
-
-  /// Saves an outer member when instantiated.
-  /// It is restored when the instance goes out of scope.
-  scope class Enter(T)
-  {
-    T t_save;
-    this(T t)
-    {
-      auto t_save = t;
-      static if (is(T == ClassDeclaration) ||
-                 is(T == InterfaceDeclaration) ||
-                 is(T == StructDeclaration) ||
-                 is(T == UnionDeclaration))
-        this.outer.inAggregate = t;
-      static if (is(T == FunctionDeclaration) ||
-                 is(T == ConstructorDeclaration))
-        this.outer.inFunc = t;
-    }
-
-    ~this()
-    {
-      static if (is(T == ClassDeclaration) ||
-                 is(T == InterfaceDeclaration) ||
-                 is(T == StructDeclaration) ||
-                 is(T == UnionDeclaration))
-        this.outer.inAggregate = t_save;
-      static if (is(T == FunctionDeclaration) ||
-                 is(T == ConstructorDeclaration))
-        this.outer.inFunc = t_save;
-    }
-  }
-
-  alias Enter!(ClassDeclaration) EnteredClass;
-  alias Enter!(InterfaceDeclaration) EnteredInterface;
-  alias Enter!(StructDeclaration) EnteredStruct;
-  alias Enter!(UnionDeclaration) EnteredUnion;
-  alias Enter!(FunctionDeclaration) EnteredFunction;
-  alias Enter!(ConstructorDeclaration) EnteredConstructor;
-
-  /// Prints the location of a node: @(lin,col)
-  void printLoc(Node node)
-  {
-    auto loc = node.begin.getRealLocation();
-    put(indent).formatln("@({},{})",/+ loc.filePath,+/ loc.lineNum, loc.colNum);
-  }
-
-override:
-  D visit(ModuleDeclaration n)
-  {
-    printLoc(n);
-    put.format("Dies ist das Modul '{}'", n.moduleName.str);
-    if (n.packages.length)
-      put.format(" im Paket '{}'", n.getPackageName('.'));
-    put(".").newline;
-    return n;
-  }
-
-  D visit(ImportDeclaration n)
-  {
-    printLoc(n);
-    put("Importiert Symbole aus einem anderen Modul bzw. Module.").newline;
-    return n;
-  }
-
-  D visit(ClassDeclaration n)
-  {
-    printLoc(n);
-    scope E = new EnteredClass(n);
-    put(indent).formatln("'{}' is eine Klasse mit den Eigenschaften:", n.name.str);
-    scope I = new Indent();
-    n.decls && visitD(n.decls);
-    return n;
-  }
-
-  D visit(InterfaceDeclaration n)
-  {
-    printLoc(n);
-    scope E = new EnteredInterface(n);
-    put(indent).formatln("'{}' is ein Interface mit den Eigenschaften:", n.name.str);
-    scope I = new Indent();
-    n.decls && visitD(n.decls);
-    return n;
-  }
-
-  D visit(StructDeclaration n)
-  {
-    printLoc(n);
-    scope E = new EnteredStruct(n);
-    put(indent).formatln("'{}' is eine Datenstruktur mit den Eigenschaften:", n.name.str);
-    scope I = new Indent();
-    n.decls && visitD(n.decls);
-    return n;
-  }
-
-  D visit(UnionDeclaration n)
-  {
-    printLoc(n);
-    scope E = new EnteredUnion(n);
-    put(indent).formatln("'{}' is eine Datenunion mit den Eigenschaften:", n.name.str);
-    scope I = new Indent();
-    n.decls && visitD(n.decls);
-    return n;
-  }
-
-  D visit(VariablesDeclaration n)
-  {
-    printLoc(n);
-    char[] was;
-    if (inAggregate)
-      was = "Membervariable";
-    else if (inFunc)
-      was = "lokale Variable";
-    else
-      was = "globale Variable";
-    foreach (name; n.names)
-    {
-      put(indent).format("'{}' ist eine {} des Typs: ", name.str, was);
-      if (n.typeNode)
-        visitT(n.typeNode);
-      else
-        put("auto");
-      put.newline;
-    }
-    return n;
-  }
-
-  D visit(FunctionDeclaration n)
-  {
-    printLoc(n);
-    char[] was;
-    if (inAggregate)
-      was = "Methode";
-    else if(inFunc)
-      was = "geschachtelte Funktion";
-    else
-      was = "Funktion";
-    scope E = new EnteredFunction(n);
-    put(indent).format("'{}' ist eine {} ", n.name.str, was);
-    if (n.params.length == 1)
-      put("mit dem Argument "), visitN(n.params);
-    else if (n.params.length > 1)
-      put("mit den Argumenten "), visitN(n.params);
-    else
-      put("ohne Argumente");
-    put(".").newline;
-    scope I = new Indent();
-    return n;
-  }
-
-  D visit(ConstructorDeclaration n)
-  {
-    printLoc(n);
-    scope E = new EnteredConstructor(n);
-    put(indent)("Ein Konstruktor ");
-    if (n.params.length == 1)
-      put("mit dem Argument "), visitN(n.params);
-    else if (n.params.length > 1)
-      put("mit den Argumenten "), visitN(n.params);
-    else
-      put("ohne Argumente");
-    put(".").newline;
-    return n;
-  }
-
-  D visit(StaticConstructorDeclaration n)
-  {
-    printLoc(n);
-    put(indent)("Ein statischer Konstruktor.").newline;
-    return n;
-  }
-
-  D visit(DestructorDeclaration n)
-  {
-    printLoc(n);
-    put(indent)("Ein Destruktor.").newline;
-    return n;
-  }
-
-  D visit(StaticDestructorDeclaration n)
-  {
-    printLoc(n);
-    put(indent)("Ein statischer Destruktor.").newline;
-    return n;
-  }
-
-  D visit(InvariantDeclaration n)
-  {
-    printLoc(n);
-    put(indent)("Eine Unveränderliche.").newline;
-    return n;
-  }
-
-  D visit(UnittestDeclaration n)
-  {
-    printLoc(n);
-    put(indent)("Ein Komponententest.").newline;
-    return n;
-  }
-
-  Node visit(Parameter n)
-  {
-    put.format("'{}' des Typs \"", n.name ? n.name.str : "unbenannt");
-    n.type && visitN(n.type);
-    put(\");
-    return n;
-  }
-
-  Node visit(Parameters n)
-  {
-    if (n.length > 1)
-    {
-      visitN(n.children[0]);
-      foreach (node; n.children[1..$])
-        put(", "), visitN(node);
-    }
-    else
-      super.visit(n);
-    return n;
-  }
-
-  TypeNode visit(ArrayType n)
-  {
-    char[] c1 = "s", c2 = "";
-    if (pluralize)
-      (c1 = pointer ? ""[] : "n"), (c2 = "s");
-    pointer = false;
-    if (n.assocType)
-      put.format("assoziative{} Array{} von ", c1, c2);
-//       visitT(n.assocType);
-    else if (n.e1)
-    {
-      if (n.e2)
-        put.format("gescheibte{} Array{} von ", c1, c2);
-      else
-        put.format("statische{} Array{} von ", c1, c2);
-//       visitE(n.e), n.e2 && visitE(n.e2);
-    }
-    else
-      put.format("dynamische{} Array{} von ", c1, c2);
-    // Types following arrays should be in plural.
-    pluralize = true;
-    visitT(n.next);
-    pluralize = false;
-    return n;
-  }
-
-  TypeNode visit(PointerType n)
-  {
-    char[] c = pluralize ? (pointer ? ""[] : "n") : "";
-    pointer = true;
-    put.format("Zeiger{} auf ", c), visitT(n.next);
-    return n;
-  }
-
-  TypeNode visit(QualifiedType n)
-  {
-    visitT(n.lhs);
-    put(".");
-    visitT(n.rhs);
-    return n;
-  }
-
-  TypeNode visit(IdentifierType n)
-  {
-    put(n.ident.str);
-    return n;
-  }
-
-  TypeNode visit(IntegralType n)
-  {
-    char[] c = pluralize ? "s"[] : "";
-    if (n.tok == TOK.Void) // Avoid pluralizing "void"
-      c = "";
-    put.format("{}{}", n.begin.srcText, c);
-    return n;
-  }
-}
--- a/trunk/src/docgen/archdoc.xmi	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1066 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<XMI xmlns:UML="http://schema.omg.org/spec/UML/1.3" verified="false" timestamp="2007-10-15T23:59:30" xmi.version="1.2" >
- <XMI.header>
-  <XMI.documentation>
-   <XMI.exporter>umbrello uml modeller http://uml.sf.net</XMI.exporter>
-   <XMI.exporterVersion>1.5.8</XMI.exporterVersion>
-   <XMI.exporterEncoding>UnicodeUTF8</XMI.exporterEncoding>
-  </XMI.documentation>
-  <XMI.metamodel xmi.name="UML" href="UML.xml" xmi.version="1.3" />
- </XMI.header>
- <XMI.content>
-  <UML:Model isSpecification="false" isLeaf="false" isRoot="false" xmi.id="m1" isAbstract="false" name="Umbrello UML mallintaja" >
-   <UML:Namespace.ownedElement>
-    <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="folder" isRoot="false" isAbstract="false" name="folder" />
-    <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="datatype" isRoot="false" isAbstract="false" name="datatype" />
-    <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="enum" isRoot="false" isAbstract="false" name="enum" />
-    <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="interface" isRoot="false" isAbstract="false" name="interface" />
-    <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Logical View" isRoot="false" isAbstract="false" name="Logical View" >
-     <UML:Namespace.ownedElement>
-      <UML:Package stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="Datatypes" isRoot="false" isAbstract="false" name="Datatypes" >
-       <UML:Namespace.ownedElement>
-        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="wMWsornjU1NO" isRoot="false" isAbstract="false" name="int" />
-        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="MGwAYPpykhTm" isRoot="false" isAbstract="false" name="char" />
-        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="EaC7G8UkzGbk" isRoot="false" isAbstract="false" name="bool" />
-        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="z3jKRbJnqFxM" isRoot="false" isAbstract="false" name="float" />
-        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="clKKQl7eLHlZ" isRoot="false" isAbstract="false" name="double" />
-        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="NFJMWv4VyoqO" isRoot="false" isAbstract="false" name="short" />
-        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="N7BDN7YzqsIG" isRoot="false" isAbstract="false" name="long" />
-        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="cPuvefV1toMN" isRoot="false" isAbstract="false" name="unsigned int" />
-        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="hQqeEe2cmDn9" isRoot="false" isAbstract="false" name="unsigned short" />
-        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="IL68COOolGjP" isRoot="false" isAbstract="false" name="unsigned long" />
-        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="wERn1lAgB0KQ" isRoot="false" isAbstract="false" name="string" />
-        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="tblJnk8mwuii" isRoot="false" isAbstract="false" name="GraphNode[]" elementReference="FVtbgO8sd2ii" />
-        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="zgj70ST7PbVQ" isRoot="false" isAbstract="false" name="undef" >
-         <UML:GeneralizableElement.generalization>
-          <UML:Generalization xmi.idref="1dmVIJyonUEn" />
-          <UML:Generalization xmi.idref="p27xKs3wyvpN" />
-          <UML:Generalization xmi.idref="lO9c3UK3Ot3L" />
-          <UML:Generalization xmi.idref="ns2H6KLVJ9Xb" />
-         </UML:GeneralizableElement.generalization>
-        </UML:DataType>
-        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="UGpWCc0uWy3g" isRoot="false" isAbstract="false" name="Vertex[]" elementReference="FVtbgO8sd2ii" />
-        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="QXgD4zE4FsCt" isRoot="false" isAbstract="false" name="GraphWriterOptions *" />
-        <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="DaFOT7jBVtui" isRoot="false" isAbstract="false" name="CodeListerOptions *" />
-       </UML:Namespace.ownedElement>
-      </UML:Package>
-      <UML:Class comment="CodeLister " isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="gGNje78ValnI" isRoot="false" isAbstract="true" name="AbstractListingWriter" >
-       <UML:Classifier.feature>
-        <UML:Attribute isSpecification="false" visibility="protected" xmi.id="hcALY1fmWlEG" type="DdhFJyNQcQSm" name="factory" />
-        <UML:Attribute isSpecification="false" visibility="protected" xmi.id="9QXgkpqgA1Du" type="3qQutO5Yhxt6" name="outputs" />
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="Aa3THxJUbPoV" isRoot="false" isAbstract="false" isQuery="false" name="this" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="BqUI126Bc7cr" value="" type="DdhFJyNQcQSm" name="factory" />
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="UJXlWuv0im5m" value="" type="3qQutO5Yhxt6" name="outputs" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="UY72E0ULeXyT" isRoot="false" isAbstract="false" name="Parser" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="KASRlJWedAvi" client="gGNje78ValnI" name="" supplier="UY72E0ULeXyT" />
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="OcpJQugxHW8F" isRoot="false" isAbstract="false" name="ListingOptions" >
-       <UML:Classifier.feature>
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="gOHG3iCLbStZ" type="58hyBKGITKzU" name="docFormat" />
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="uYIB5OPcbNSb" client="gGNje78ValnI" name="" supplier="OcpJQugxHW8F" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="dw4fHleozmt5" client="gGNje78ValnI" name="" supplier="zgj70ST7PbVQ" />
-      <UML:Enumeration stereotype="enum" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="58hyBKGITKzU" isRoot="false" isAbstract="false" name="DocFormat" >
-       <UML:EnumerationLiteral comment="LaTeX + listings currently" isSpecification="false" isLeaf="false" visibility="public" namespace="58hyBKGITKzU" xmi.id="jnhozkQ1UqIp" isRoot="false" isAbstract="false" name="LaTeX" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="58hyBKGITKzU" xmi.id="DhN6TjTmtUai" isRoot="false" isAbstract="false" name="XML" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="58hyBKGITKzU" xmi.id="eyKevtlegQQd" isRoot="false" isAbstract="false" name="HTML" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="58hyBKGITKzU" xmi.id="9qedeuTpcot5" isRoot="false" isAbstract="false" name="PlainText" />
-      </UML:Enumeration>
-      <UML:Enumeration stereotype="enum" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="o5RT7D5TyDem" isRoot="false" isAbstract="false" name="CommentFormat" >
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="o5RT7D5TyDem" xmi.id="pCzlo8cW1N0o" isRoot="false" isAbstract="false" name="ddoc" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="o5RT7D5TyDem" xmi.id="FS23UTFrinBx" isRoot="false" isAbstract="false" name="doxygen" />
-      </UML:Enumeration>
-      <UML:Interface stereotype="interface" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="zhVfgpENwAeN" isRoot="false" isAbstract="true" name="ListingWriter" >
-       <UML:Classifier.feature>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="eGKXDits9Kho" isRoot="false" isAbstract="false" isQuery="false" name="generateListing" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="KNIleVffDrUP" value="" type="yBk69LKYzyaX" name="stream" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="fA2So7Re6pf2" isRoot="false" isAbstract="false" isQuery="false" name="generateListing" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="Au5dZofnQ9Fm" value="" type="UY72E0ULeXyT" name="parser" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-       </UML:Classifier.feature>
-      </UML:Interface>
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="qxq04A8rywIb" isRoot="false" isAbstract="false" name="XMLWriter" >
-       <UML:GeneralizableElement.generalization>
-        <UML:Generalization xmi.idref="u534X7uMBIy5" />
-       </UML:GeneralizableElement.generalization>
-       <UML:Classifier.feature>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="KoEO9zJwTXuD" isRoot="false" isAbstract="false" isQuery="false" name="generateListing" />
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="w884b40YcIag" isRoot="false" isAbstract="false" name="HTMLWriter" >
-       <UML:GeneralizableElement.generalization>
-        <UML:Generalization xmi.idref="1tZ6hQ3Znq07" />
-       </UML:GeneralizableElement.generalization>
-       <UML:Classifier.feature>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="mBRaST74dftD" isRoot="false" isAbstract="false" isQuery="false" name="generateListing" />
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="B92ON93E7uE9" isRoot="false" isAbstract="false" name="LatexWriter" >
-       <UML:GeneralizableElement.generalization>
-        <UML:Generalization xmi.idref="FbDTu6ZqYxZ5" />
-       </UML:GeneralizableElement.generalization>
-       <UML:Classifier.feature>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="JpwoOQQ4RzaO" isRoot="false" isAbstract="false" isQuery="false" name="generateListing" />
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2MyyGGXAPfEy" isRoot="false" isAbstract="false" name="PlainTextWriter" >
-       <UML:GeneralizableElement.generalization>
-        <UML:Generalization xmi.idref="jNbdqaYMr5vR" />
-       </UML:GeneralizableElement.generalization>
-       <UML:Classifier.feature>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="VRgNwkJTDt0B" isRoot="false" isAbstract="false" isQuery="false" name="generateListing" />
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="haoxC1oM2QVz" isRoot="false" isAbstract="false" name="DefaultListingFactory" >
-       <UML:GeneralizableElement.generalization>
-        <UML:Generalization xmi.idref="0zf0YojVOJsY" />
-       </UML:GeneralizableElement.generalization>
-       <UML:Classifier.feature>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="2SrUGMptabML" isRoot="false" isAbstract="false" isQuery="false" name="createListingWriter" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter kind="return" xmi.id="TMA6Ge0zQMX6" type="zhVfgpENwAeN" />
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="GYFWlYNnmcE7" value="" type="3qQutO5Yhxt6" name="outputs" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="pOOtPyR4YD1i" client="gGNje78ValnI" name="" supplier="zhVfgpENwAeN" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="Hf6nfAgadb4K" client="gGNje78ValnI" name="" supplier="haoxC1oM2QVz" />
-      <UML:Abstraction isSpecification="false" visibility="public" namespace="Logical View" xmi.id="Zq72H2CSpWXa" client="2MyyGGXAPfEy" name="" supplier="zhVfgpENwAeN" />
-      <UML:Abstraction isSpecification="false" visibility="public" namespace="Logical View" xmi.id="A6N2elCBKnZO" client="B92ON93E7uE9" name="" supplier="zhVfgpENwAeN" />
-      <UML:Abstraction isSpecification="false" visibility="public" namespace="Logical View" xmi.id="eumL2kguvB4r" client="w884b40YcIag" name="" supplier="zhVfgpENwAeN" />
-      <UML:Abstraction isSpecification="false" visibility="public" namespace="Logical View" xmi.id="4EmCZ7If6KdF" client="qxq04A8rywIb" name="" supplier="zhVfgpENwAeN" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="lPLNpCYn0pMy" client="haoxC1oM2QVz" name="" supplier="qxq04A8rywIb" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="vlcHfpQlYKr7" client="haoxC1oM2QVz" name="" supplier="w884b40YcIag" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="Kg5HoKskzFEv" client="haoxC1oM2QVz" name="" supplier="B92ON93E7uE9" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="9Vk40Voo7HZw" client="haoxC1oM2QVz" name="" supplier="2MyyGGXAPfEy" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="PsKBU0u8FFdQ" client="zhVfgpENwAeN" name="" supplier="zgj70ST7PbVQ" />
-      <UML:Abstraction isSpecification="false" visibility="public" namespace="Logical View" xmi.id="xxCyboRg8fju" client="gGNje78ValnI" name="" supplier="zhVfgpENwAeN" />
-      <UML:Generalization isSpecification="false" child="2MyyGGXAPfEy" visibility="public" namespace="Logical View" xmi.id="jNbdqaYMr5vR" parent="gGNje78ValnI" discriminator="" name="" />
-      <UML:Generalization isSpecification="false" child="B92ON93E7uE9" visibility="public" namespace="Logical View" xmi.id="FbDTu6ZqYxZ5" parent="gGNje78ValnI" discriminator="" name="" />
-      <UML:Generalization isSpecification="false" child="w884b40YcIag" visibility="public" namespace="Logical View" xmi.id="1tZ6hQ3Znq07" parent="gGNje78ValnI" discriminator="" name="" />
-      <UML:Generalization isSpecification="false" child="qxq04A8rywIb" visibility="public" namespace="Logical View" xmi.id="u534X7uMBIy5" parent="gGNje78ValnI" discriminator="" name="" />
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="098RWfwZqN4L" isRoot="false" isAbstract="false" name="ModuleGraphFactory" >
-       <UML:Classifier.feature>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="CMMapfT5KiQP" isRoot="false" isAbstract="false" isQuery="false" name="createGraphWriter" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter kind="return" xmi.id="R9UhhTPng6id" type="2Mzl2VgeffI0" />
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="r5Ijnmvx8HYv" value="" type="Ug6grrz7llbI" name="modules" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Enumeration stereotype="enum" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="4F09aHCjljSA" isRoot="false" isAbstract="false" name="GraphFormat" >
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="4F09aHCjljSA" xmi.id="Uhfew917nyad" isRoot="false" isAbstract="false" name="Dot" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="4F09aHCjljSA" xmi.id="Jy1fqRBSwrTe" isRoot="false" isAbstract="false" name="ModuleNames" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="4F09aHCjljSA" xmi.id="aow2SW2oUhRP" isRoot="false" isAbstract="false" name="ModulePaths" />
-      </UML:Enumeration>
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="pwXaDeUXVlRv" isRoot="false" isAbstract="false" name="ClassGraphFactory" >
-       <UML:Classifier.feature>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="RDl3vCbldkit" isRoot="false" isAbstract="false" isQuery="false" name="createGraphWriter" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter kind="return" xmi.id="juNjzfHRzPXE" type="2Mzl2VgeffI0" />
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="eZGRSI3D44ZH" value="" type="Ug6grrz7llbI" name="modules" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="FVtbgO8sd2ii" isRoot="false" isAbstract="false" name="Vertex" >
-       <UML:GeneralizableElement.generalization>
-        <UML:Generalization xmi.idref="rtOV4FVf7iPk" />
-       </UML:GeneralizableElement.generalization>
-       <UML:Classifier.feature>
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="cf98eu4OpFbX" type="cPuvefV1toMN" name="id" />
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="hgsYJ2YnnaVS" type="wERn1lAgB0KQ" name="name" />
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="sBVGlTogVHfE" type="wERn1lAgB0KQ" name="location" />
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="ajeRzBpBzXm2" type="XjtDAoectTTH" name="incomingEdges" />
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="hTSa11gAdwIE" type="XjtDAoectTTH" name="outgoingEdges" />
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="VXmaXhPeKk9I" type="BQqAv02HTM6x" name="type" />
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="2fXtbb2YF7TG" isRoot="false" isAbstract="false" isQuery="false" name="this" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="yejRa2Oznwhc" value="" type="wERn1lAgB0KQ" name="name" />
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="659S1872M8Cd" value="" type="wERn1lAgB0KQ" name="loc" />
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="QSb02dspK6xX" value="" type="cPuvefV1toMN" name="id" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="PX2Y1eFKtaj6" isRoot="false" isAbstract="false" isQuery="false" name="isCyclic" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter kind="return" xmi.id="1XBPtiTIpxzU" type="EaC7G8UkzGbk" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Generalization isSpecification="false" child="zgj70ST7PbVQ" visibility="public" namespace="Logical View" xmi.id="1dmVIJyonUEn" parent="FVtbgO8sd2ii" discriminator="" name="" />
-      <UML:Generalization isSpecification="false" child="zgj70ST7PbVQ" visibility="public" namespace="Logical View" xmi.id="p27xKs3wyvpN" parent="FVtbgO8sd2ii" discriminator="" name="" />
-      <UML:Generalization isSpecification="false" child="zgj70ST7PbVQ" visibility="public" namespace="Logical View" xmi.id="lO9c3UK3Ot3L" parent="FVtbgO8sd2ii" discriminator="" name="" />
-      <UML:Generalization isSpecification="false" child="zgj70ST7PbVQ" visibility="public" namespace="Logical View" xmi.id="ns2H6KLVJ9Xb" parent="FVtbgO8sd2ii" discriminator="" name="" />
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="taceG4p7AY1k" isRoot="false" isAbstract="true" name="AbstractGraphWriter" >
-       <UML:Classifier.feature>
-        <UML:Attribute isSpecification="false" visibility="protected" xmi.id="jYgSGEsqagKv" type="H9NLXsg0Hncp" name="factory" />
-        <UML:Attribute isSpecification="false" visibility="protected" xmi.id="4Bqtwxx8p0pI" type="3qQutO5Yhxt6" name="outputs" />
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="RhFDP34VCWM4" isRoot="false" isAbstract="false" isQuery="false" name="this" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="tBvamRjPCFGt" value="" type="H9NLXsg0Hncp" name="factory" />
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="9EFHJ6ymPiIf" value="" type="3qQutO5Yhxt6" name="outputs" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="672lM6F9KhcI" isRoot="false" isAbstract="false" name="GraphOptions" >
-       <UML:Classifier.feature>
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="zRuotD7A5ZEx" type="4F09aHCjljSA" name="format" />
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="dMwwhlSnUoPh" type="VDAdlQhZ750q" name="imageFormat" />
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="E1vnjmQdHkkv" type="58hyBKGITKzU" name="docFormat" />
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="cGQrznU4axXm" type="cPuvefV1toMN" name="depth" />
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="UirRcvN0JEsV" type="EaC7G8UkzGbk" name="IncludeUnlocatableModules" />
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="AQlvQmLLBkXo" type="EaC7G8UkzGbk" name="GroupByFullPackageName" />
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="vOQEdHhXSPF8" type="EaC7G8UkzGbk" name="GroupByPackageNames" />
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="TrfH97Bbn23Q" type="EaC7G8UkzGbk" name="HighlightCyclicVertices" />
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="uBkkfpbvggDX" type="EaC7G8UkzGbk" name="HighlightCyclicEdges" />
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Interface stereotype="interface" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2Mzl2VgeffI0" isRoot="false" isAbstract="true" name="GraphWriter" >
-       <UML:Classifier.feature>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="kluUKuajlkAu" isRoot="false" isAbstract="false" isQuery="false" name="generateGraph" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="fREmiJ7UKXFJ" value="" type="UGpWCc0uWy3g" name="vertices" />
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="OVLa6NXYfSPa" value="" type="XjtDAoectTTH" name="edges" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-       </UML:Classifier.feature>
-      </UML:Interface>
-      <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="QrZyyaltfezo" name="" >
-       <UML:Association.connection>
-        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="kdwMLV8h83sE" aggregation="composite" type="zgj70ST7PbVQ" name="" />
-        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="Sii687Npp9vE" aggregation="none" type="FVtbgO8sd2ii" name="" />
-       </UML:Association.connection>
-      </UML:Association>
-      <UML:Generalization isSpecification="false" child="FVtbgO8sd2ii" visibility="public" namespace="Logical View" xmi.id="rtOV4FVf7iPk" parent="zgj70ST7PbVQ" discriminator="" name="" />
-      <UML:Abstraction isSpecification="false" visibility="public" namespace="Logical View" xmi.id="YFH3CyxPGsNY" client="taceG4p7AY1k" name="" supplier="2Mzl2VgeffI0" />
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="ZUDChgtO8jSy" isRoot="false" isAbstract="false" name="DotWriter" >
-       <UML:GeneralizableElement.generalization>
-        <UML:Generalization xmi.idref="gO9JCUKh4zz7" />
-       </UML:GeneralizableElement.generalization>
-       <UML:Classifier.feature>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="nXwHg6RtyC4B" isRoot="false" isAbstract="false" isQuery="false" name="generateGraph" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="L3a5zNEcbuwz" value="" type="UGpWCc0uWy3g" name="vertices" />
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="FX185qpx9hBY" value="" type="XjtDAoectTTH" name="edges" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Generalization isSpecification="false" child="ZUDChgtO8jSy" visibility="public" namespace="Logical View" xmi.id="gO9JCUKh4zz7" parent="taceG4p7AY1k" discriminator="" name="" />
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="Ug6grrz7llbI" isRoot="false" isAbstract="false" name="Parser[]" />
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="85ASUVIYu8Rm" isRoot="false" isAbstract="false" name="ClassGraphWriter" />
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="R1LMLXi8zBZD" isRoot="false" isAbstract="false" name="ModuleGraphWriter" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="eIi8xlOA51aq" client="zgj70ST7PbVQ" name="" supplier="ZUDChgtO8jSy" />
-      <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="xcuomSYFMuc3" name="" >
-       <UML:Association.connection>
-        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="Yxf0JQYnYv4n" aggregation="none" type="zgj70ST7PbVQ" name="" />
-        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="CZfvIVeFD72m" aggregation="none" type="ZUDChgtO8jSy" name="" />
-       </UML:Association.connection>
-      </UML:Association>
-      <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="KxhR786WWKiA" name="" >
-       <UML:Association.connection>
-        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="e0bOstNQo1O8" aggregation="none" type="haoxC1oM2QVz" name="" />
-        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="Pwtxqxi0ULvm" aggregation="none" type="2MyyGGXAPfEy" name="" />
-       </UML:Association.connection>
-      </UML:Association>
-      <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="036VnHDG2xBH" name="" >
-       <UML:Association.connection>
-        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="rY12d3mG4Neu" aggregation="none" type="haoxC1oM2QVz" name="" />
-        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="GzI5yhBNb2IP" aggregation="none" type="B92ON93E7uE9" name="" />
-       </UML:Association.connection>
-      </UML:Association>
-      <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="MPnzJ9f0egCU" name="" >
-       <UML:Association.connection>
-        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="xyPRKJE9rFBS" aggregation="none" type="haoxC1oM2QVz" name="" />
-        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="HxgLLIDbGVeE" aggregation="none" type="w884b40YcIag" name="" />
-       </UML:Association.connection>
-      </UML:Association>
-      <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="qQ8ZNcL54wHR" name="" >
-       <UML:Association.connection>
-        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="CnampsBkrbC9" aggregation="none" type="haoxC1oM2QVz" name="" />
-        <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="sQIhdT9uOqDj" aggregation="none" type="qxq04A8rywIb" name="" />
-       </UML:Association.connection>
-      </UML:Association>
-      <UML:Enumeration stereotype="enum" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="BQqAv02HTM6x" isRoot="false" isAbstract="false" name="VertexType" >
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="BQqAv02HTM6x" xmi.id="UWXR1uwj6Xht" isRoot="false" isAbstract="false" name="module" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="BQqAv02HTM6x" xmi.id="KZH8gthgkYAr" isRoot="false" isAbstract="false" name="package" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="BQqAv02HTM6x" xmi.id="GvOp2iAWCfvE" isRoot="false" isAbstract="false" name="class" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="BQqAv02HTM6x" xmi.id="XsxdPcUh9joq" isRoot="false" isAbstract="false" name="interface" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="BQqAv02HTM6x" xmi.id="dTUN2eCIZb6Z" isRoot="false" isAbstract="false" name="trait" />
-      </UML:Enumeration>
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="PILb9kCQnOZd" isRoot="false" isAbstract="false" name="Edge" >
-       <UML:Classifier.feature>
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="Aq7LuhClDFeB" type="FVtbgO8sd2ii" name="incoming" />
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="xg3pIv6gVUUO" type="FVtbgO8sd2ii" name="outgoing" />
-        <UML:Attribute isSpecification="false" visibility="private" xmi.id="eaFFJAnvNrxh" type="uzw9DITFgRm2" name="type" />
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="p2AAWOx6E09l" isRoot="false" isAbstract="false" isQuery="false" name="this" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="mN7gwLT6JP4I" value="" type="FVtbgO8sd2ii" name="o" />
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="WNmYYSfW1HTL" value="" type="FVtbgO8sd2ii" name="i" />
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="ITeVbCmrH3BN" value="" type="BQqAv02HTM6x" name="type" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="faPqILFpZIBc" isRoot="false" isAbstract="false" isQuery="false" name="isCyclic" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter kind="return" xmi.id="ONF2RwfAq0sn" type="EaC7G8UkzGbk" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Enumeration stereotype="enum" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="uzw9DITFgRm2" isRoot="false" isAbstract="false" name="EdgeType" >
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="uzw9DITFgRm2" xmi.id="Gv3YsqBCKi6E" isRoot="false" isAbstract="false" name="unspecified" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="uzw9DITFgRm2" xmi.id="A1QhopWR6xzK" isRoot="false" isAbstract="false" name="aggregation" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="uzw9DITFgRm2" xmi.id="OVYO1FWE3aSP" isRoot="false" isAbstract="false" name="association" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="uzw9DITFgRm2" xmi.id="uXTHm0iw18dq" isRoot="false" isAbstract="false" name="composition" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="uzw9DITFgRm2" xmi.id="3Mv6vLTpsw6c" isRoot="false" isAbstract="false" name="cyclicDependency" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="uzw9DITFgRm2" xmi.id="0BPEtKs5X9EB" isRoot="false" isAbstract="false" name="dependency" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="uzw9DITFgRm2" xmi.id="w8F05EKRiqqj" isRoot="false" isAbstract="false" name="generalization" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="uzw9DITFgRm2" xmi.id="OQEcUiDMf7Wr" isRoot="false" isAbstract="false" name="inheritance" />
-      </UML:Enumeration>
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="YjondCVQ8s2U" client="2Mzl2VgeffI0" name="" supplier="zgj70ST7PbVQ" />
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="XjtDAoectTTH" isRoot="false" isAbstract="false" name="Edge[]" />
-      <UML:Interface stereotype="interface" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="H9NLXsg0Hncp" isRoot="false" isAbstract="true" name="GraphWriterFactory" >
-       <UML:Classifier.feature>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="FYgiWJyDqrhK" isRoot="false" isAbstract="false" isQuery="false" name="options" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter kind="return" xmi.id="e9EdXlpWG0u7" type="672lM6F9KhcI" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="L1C3szmMnzpw" isRoot="false" isAbstract="false" isQuery="false" name="createGraphWriter" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="YLOGwvBFuNIk" value="" type="3qQutO5Yhxt6" name="outputs" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-       </UML:Classifier.feature>
-      </UML:Interface>
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="GIPhxHkszygs" isRoot="false" isAbstract="true" name="AbstractGraphWriterFactory" >
-       <UML:Classifier.feature>
-        <UML:Attribute isSpecification="false" visibility="protected" xmi.id="ZmI5M1aN978M" type="672lM6F9KhcI" name="m_options" />
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="liEDYXNQ5pTO" isRoot="false" isAbstract="false" isQuery="false" name="options" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter kind="return" xmi.id="gNPWJNyfiEi9" type="QXgD4zE4FsCt" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="m7wwiwCSxVGR" client="2Mzl2VgeffI0" name="" supplier="FVtbgO8sd2ii" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="R79vj31U6PK0" client="2Mzl2VgeffI0" name="" supplier="PILb9kCQnOZd" />
-      <UML:Abstraction isSpecification="false" visibility="public" namespace="Logical View" xmi.id="Pef9sSrIGFql" client="GIPhxHkszygs" name="" supplier="H9NLXsg0Hncp" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="p0keVPRrye6f" client="H9NLXsg0Hncp" name="" supplier="672lM6F9KhcI" />
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="vJ8WmfZPiVQE" isRoot="false" isAbstract="false" name="DefaultGraphWriterFactory" >
-       <UML:GeneralizableElement.generalization>
-        <UML:Generalization xmi.idref="kOBlgJz6y2Lz" />
-       </UML:GeneralizableElement.generalization>
-       <UML:Classifier.feature>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="rSVt3npBuRwI" isRoot="false" isAbstract="false" isQuery="false" name="this" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="o4PMZ16oEaaK" value="" type="672lM6F9KhcI" name="options" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="qt3yjRHa0HmR" isRoot="false" isAbstract="false" isQuery="false" name="createGraphWriter" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="37SmulDSCnBM" value="" type="3qQutO5Yhxt6" name="outputs" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="leYQpk5LWBlE" isRoot="false" isAbstract="false" name="ModuleNameWriter" >
-       <UML:GeneralizableElement.generalization>
-        <UML:Generalization xmi.idref="51RZVXixdhgF" />
-       </UML:GeneralizableElement.generalization>
-       <UML:Classifier.feature>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="VR6VNEtfCgkY" isRoot="false" isAbstract="false" isQuery="false" name="generateGraph" />
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="cQGGEupKkEKw" isRoot="false" isAbstract="false" name="ModulePathWriter" >
-       <UML:GeneralizableElement.generalization>
-        <UML:Generalization xmi.idref="Z4ZHkEV03W4k" />
-       </UML:GeneralizableElement.generalization>
-       <UML:Classifier.feature>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="wEWZIkURw0Kn" isRoot="false" isAbstract="false" isQuery="false" name="generateGraph" />
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Generalization isSpecification="false" child="cQGGEupKkEKw" visibility="public" namespace="Logical View" xmi.id="Z4ZHkEV03W4k" parent="taceG4p7AY1k" discriminator="" name="" />
-      <UML:Generalization isSpecification="false" child="leYQpk5LWBlE" visibility="public" namespace="Logical View" xmi.id="51RZVXixdhgF" parent="taceG4p7AY1k" discriminator="" name="" />
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="3qQutO5Yhxt6" isRoot="false" isAbstract="false" name="OutputStream[]" />
-      <UML:Interface stereotype="interface" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="QbirDWtuKiBS" isRoot="false" isAbstract="true" name="OutputStream" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="0e7qU7vxuugt" client="H9NLXsg0Hncp" name="" supplier="QbirDWtuKiBS" />
-      <UML:Generalization isSpecification="false" child="vJ8WmfZPiVQE" visibility="public" namespace="Logical View" xmi.id="kOBlgJz6y2Lz" parent="GIPhxHkszygs" discriminator="" name="" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="jUfTITIIjhSw" client="vJ8WmfZPiVQE" name="" supplier="leYQpk5LWBlE" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="ntBujkSHp8rF" client="vJ8WmfZPiVQE" name="" supplier="cQGGEupKkEKw" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="oG7IcloUW5iz" client="vJ8WmfZPiVQE" name="" supplier="ZUDChgtO8jSy" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="6E5Os60E5bNw" client="taceG4p7AY1k" name="" supplier="QbirDWtuKiBS" />
-      <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="m1ftLgsc5LXQ" isRoot="false" isAbstract="true" name="AbstractListingFactory" >
-       <UML:Classifier.feature>
-        <UML:Attribute isSpecification="false" visibility="protected" xmi.id="xswAJre2CrPi" type="OcpJQugxHW8F" name="m_options" />
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="mZ1wtQujXunn" isRoot="false" isAbstract="false" isQuery="false" name="options" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter kind="return" xmi.id="ANIyMAl0H0bm" type="DaFOT7jBVtui" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-       </UML:Classifier.feature>
-      </UML:Class>
-      <UML:Interface stereotype="interface" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="DdhFJyNQcQSm" isRoot="false" isAbstract="true" name="ListingFactory" >
-       <UML:Classifier.feature>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="QR4frQ4pllIy" isRoot="false" isAbstract="false" isQuery="false" name="options" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter kind="return" xmi.id="jPJ0PB74YVap" type="OcpJQugxHW8F" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-        <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="GL3CAg7Qy0PF" isRoot="false" isAbstract="false" isQuery="false" name="createListingWriter" >
-         <UML:BehavioralFeature.parameter>
-          <UML:Parameter kind="return" xmi.id="qWVYkDfsYxos" type="zhVfgpENwAeN" />
-          <UML:Parameter isSpecification="false" visibility="private" xmi.id="rlp4XIxd1W9V" value="" type="3qQutO5Yhxt6" name="outputs" />
-         </UML:BehavioralFeature.parameter>
-        </UML:Operation>
-       </UML:Classifier.feature>
-      </UML:Interface>
-      <UML:Abstraction isSpecification="false" visibility="public" namespace="Logical View" xmi.id="M1DRAGcxqQmM" client="m1ftLgsc5LXQ" name="" supplier="DdhFJyNQcQSm" />
-      <UML:Generalization isSpecification="false" child="haoxC1oM2QVz" visibility="public" namespace="Logical View" xmi.id="0zf0YojVOJsY" parent="m1ftLgsc5LXQ" discriminator="" name="" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="6bs0V3Pr6aVg" client="DdhFJyNQcQSm" name="" supplier="OcpJQugxHW8F" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="yQFLdIs4FB5E" client="DdhFJyNQcQSm" name="" supplier="3qQutO5Yhxt6" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="ykj8Siycsv3x" client="gGNje78ValnI" name="" supplier="3qQutO5Yhxt6" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="YFeUspY6csTF" client="zhVfgpENwAeN" name="" supplier="UY72E0ULeXyT" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="8nWBoU6zOpZ6" client="gGNje78ValnI" name="" supplier="QbirDWtuKiBS" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="0RBqSjye7dsd" client="DdhFJyNQcQSm" name="" supplier="QbirDWtuKiBS" />
-      <UML:Interface stereotype="interface" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="yBk69LKYzyaX" isRoot="false" isAbstract="true" name="InputStream" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Logical View" xmi.id="veycFmCVOnie" client="zhVfgpENwAeN" name="" supplier="yBk69LKYzyaX" />
-      <UML:Enumeration stereotype="enum" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="VDAdlQhZ750q" isRoot="false" isAbstract="false" name="ImageFormat" >
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="VDAdlQhZ750q" xmi.id="NPNgtZqJFAtE" isRoot="false" isAbstract="false" name="PNG" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="VDAdlQhZ750q" xmi.id="2W24K4edixcf" isRoot="false" isAbstract="false" name="SVG" />
-       <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="VDAdlQhZ750q" xmi.id="kjad3bVP0s5s" isRoot="false" isAbstract="false" name="GIF" />
-      </UML:Enumeration>
-     </UML:Namespace.ownedElement>
-     <XMI.extension xmi.extender="umbrello" >
-      <diagrams>
-       <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1042" snapy="10" showatts="1" xmi.id="VfRLtV4Z9Ptg" documentation="" type="1" showops="1" showpackage="0" name="Source listing classes" localid="" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="860" >
-        <widgets>
-         <classwidget usesdiagramfillcolor="0" width="428" showattsigs="601" x="504" fillcolor="#ffffc0" y="464" drawascircle="0" showopsigs="601" linewidth="none" height="72" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="gGNje78ValnI" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
-         <classwidget usesdiagramfillcolor="1" width="62" showattsigs="601" x="862" fillcolor="none" y="200" showopsigs="601" linewidth="none" height="36" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="UY72E0ULeXyT" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-         <classwidget usesdiagramfillcolor="0" width="175" showattsigs="601" x="135" fillcolor="#ffffc0" y="236" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="OcpJQugxHW8F" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
-         <interfacewidget usesdiagramfillcolor="0" width="368" x="643" fillcolor="#ffffc0" y="291" drawascircle="0" showopsigs="601" linewidth="none" height="81" usefillcolor="1" showpubliconly="0" isinstance="0" xmi.id="zhVfgpENwAeN" showoperations="1" showpackage="0" showscope="1" showstereotype="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
-         <classwidget usesdiagramfillcolor="0" width="145" showattsigs="601" x="404" fillcolor="#ffffc0" y="747" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="qxq04A8rywIb" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
-         <classwidget usesdiagramfillcolor="0" width="145" showattsigs="601" x="559" fillcolor="#ffffc0" y="747" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="w884b40YcIag" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
-         <classwidget usesdiagramfillcolor="0" width="145" showattsigs="601" x="714" fillcolor="#ffffc0" y="747" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="B92ON93E7uE9" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
-         <classwidget usesdiagramfillcolor="0" width="145" showattsigs="601" x="869" fillcolor="#ffffc0" y="747" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="2MyyGGXAPfEy" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
-         <classwidget usesdiagramfillcolor="0" width="411" showattsigs="601" x="17" fillcolor="#ffffc0" y="582" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="haoxC1oM2QVz" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
-         <classwidget usesdiagramfillcolor="0" width="226" showattsigs="601" x="109" fillcolor="#ffffc0" y="482" drawascircle="0" showopsigs="601" linewidth="none" height="54" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="m1ftLgsc5LXQ" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
-         <interfacewidget usesdiagramfillcolor="0" width="411" x="17" fillcolor="#ffffc0" y="355" drawascircle="0" showopsigs="601" linewidth="none" height="81" usefillcolor="1" showpubliconly="0" isinstance="0" xmi.id="DdhFJyNQcQSm" showoperations="1" showpackage="0" showscope="1" showstereotype="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
-         <interfacewidget usesdiagramfillcolor="1" width="127" x="498" fillcolor="none" y="324" drawascircle="0" showopsigs="601" linewidth="none" height="54" usefillcolor="1" showpubliconly="0" isinstance="0" xmi.id="QbirDWtuKiBS" showoperations="1" showpackage="0" showscope="1" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-         <interfacewidget usesdiagramfillcolor="1" width="113" x="690" fillcolor="none" y="182" drawascircle="0" showopsigs="601" linewidth="none" height="54" usefillcolor="1" showpubliconly="0" isinstance="0" xmi.id="yBk69LKYzyaX" showoperations="1" showpackage="0" showscope="1" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-        </widgets>
-        <messages/>
-        <associations>
-         <assocwidget totalcounta="4" indexa="3" totalcountb="2" indexb="1" linewidth="none" widgetbid="zhVfgpENwAeN" widgetaid="gGNje78ValnI" xmi.id="xxCyboRg8fju" type="511" linecolor="none" >
-          <linepath>
-           <startpoint startx="825" starty="464" />
-           <endpoint endx="827" endy="372" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="2" totalcountb="5" indexb="4" linewidth="none" widgetbid="gGNje78ValnI" widgetaid="2MyyGGXAPfEy" xmi.id="jNbdqaYMr5vR" type="500" linecolor="none" >
-          <linepath>
-           <startpoint startx="965" starty="747" />
-           <endpoint endx="846" endy="536" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="2" totalcountb="5" indexb="3" linewidth="none" widgetbid="gGNje78ValnI" widgetaid="B92ON93E7uE9" xmi.id="FbDTu6ZqYxZ5" type="500" linecolor="none" >
-          <linepath>
-           <startpoint startx="810" starty="747" />
-           <endpoint endx="760" endy="536" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="2" totalcountb="5" indexb="2" linewidth="none" widgetbid="gGNje78ValnI" widgetaid="w884b40YcIag" xmi.id="1tZ6hQ3Znq07" type="500" linecolor="none" >
-          <linepath>
-           <startpoint startx="655" starty="747" />
-           <endpoint endx="675" endy="536" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="2" totalcountb="5" indexb="1" linewidth="none" widgetbid="gGNje78ValnI" widgetaid="qxq04A8rywIb" xmi.id="u534X7uMBIy5" type="500" linecolor="none" >
-          <linepath>
-           <startpoint startx="500" starty="747" />
-           <endpoint endx="589" endy="536" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="5" indexa="4" totalcountb="3" indexb="1" linewidth="none" widgetbid="2MyyGGXAPfEy" widgetaid="haoxC1oM2QVz" xmi.id="KxhR786WWKiA" type="512" linecolor="none" >
-          <linepath>
-           <startpoint startx="345" starty="627" />
-           <endpoint endx="917" endy="747" />
-           <point x="846" y="686" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="5" indexa="3" totalcountb="3" indexb="1" linewidth="none" widgetbid="B92ON93E7uE9" widgetaid="haoxC1oM2QVz" xmi.id="036VnHDG2xBH" type="512" linecolor="none" >
-          <linepath>
-           <startpoint startx="263" starty="627" />
-           <endpoint endx="762" endy="747" />
-           <point x="693" y="689" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="5" indexa="2" totalcountb="3" indexb="1" linewidth="none" widgetbid="w884b40YcIag" widgetaid="haoxC1oM2QVz" xmi.id="MPnzJ9f0egCU" type="512" linecolor="none" >
-          <linepath>
-           <startpoint startx="181" starty="627" />
-           <endpoint endx="607" endy="747" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="5" indexa="1" totalcountb="3" indexb="1" linewidth="none" widgetbid="qxq04A8rywIb" widgetaid="haoxC1oM2QVz" xmi.id="qQ8ZNcL54wHR" type="512" linecolor="none" >
-          <linepath>
-           <startpoint startx="99" starty="627" />
-           <endpoint endx="452" endy="747" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="4" indexa="1" visibilityB="200" totalcountb="3" indexb="2" linewidth="none" widgetbid="DdhFJyNQcQSm" widgetaid="gGNje78ValnI" xmi.id="hcALY1fmWlEG" type="510" changeabilityA="900" changeabilityB="900" linecolor="none" visibilityA="200" >
-          <linepath>
-           <startpoint startx="611" starty="464" />
-           <endpoint endx="428" endy="409" />
-           <point x="541" y="409" />
-          </linepath>
-          <floatingtext usesdiagramfillcolor="1" width="66" x="448" fillcolor="none" y="410" linewidth="none" posttext="" role="710" height="22" usefillcolor="1" pretext="#" isinstance="0" xmi.id="vasmP4T4bt7x" text="factory" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-         </assocwidget>
-         <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="DdhFJyNQcQSm" widgetaid="m1ftLgsc5LXQ" xmi.id="M1DRAGcxqQmM" type="511" linecolor="none" >
-          <linepath>
-           <startpoint startx="222" starty="482" />
-           <endpoint endx="222" endy="436" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="m1ftLgsc5LXQ" widgetaid="haoxC1oM2QVz" xmi.id="0zf0YojVOJsY" type="500" linecolor="none" >
-          <linepath>
-           <startpoint startx="222" starty="582" />
-           <endpoint endx="222" endy="536" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="OcpJQugxHW8F" widgetaid="DdhFJyNQcQSm" xmi.id="6bs0V3Pr6aVg" type="502" linecolor="none" >
-          <linepath>
-           <startpoint startx="222" starty="355" />
-           <endpoint endx="222" endy="281" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="2" totalcountb="2" indexb="1" linewidth="none" widgetbid="UY72E0ULeXyT" widgetaid="zhVfgpENwAeN" xmi.id="YFeUspY6csTF" type="502" linecolor="none" >
-          <linepath>
-           <startpoint startx="888" starty="291" />
-           <endpoint endx="893" endy="236" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="4" indexa="2" totalcountb="2" indexb="1" linewidth="none" widgetbid="QbirDWtuKiBS" widgetaid="gGNje78ValnI" xmi.id="8nWBoU6zOpZ6" type="502" linecolor="none" >
-          <linepath>
-           <startpoint startx="718" starty="464" />
-           <endpoint endx="561" endy="378" />
-           <point x="604" y="432" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="QbirDWtuKiBS" widgetaid="DdhFJyNQcQSm" xmi.id="0RBqSjye7dsd" type="502" linecolor="none" >
-          <linepath>
-           <startpoint startx="428" starty="382" />
-           <endpoint endx="498" endy="351" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="yBk69LKYzyaX" widgetaid="zhVfgpENwAeN" xmi.id="veycFmCVOnie" type="502" linecolor="none" >
-          <linepath>
-           <startpoint startx="765" starty="291" />
-           <endpoint endx="746" endy="236" />
-          </linepath>
-         </assocwidget>
-        </associations>
-       </diagram>
-       <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1042" snapy="10" showatts="1" xmi.id="BbQfy5JEWUGf" documentation="" type="1" showops="1" showpackage="0" name="Class graph classes" localid="" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="860" >
-        <widgets>
-         <classwidget usesdiagramfillcolor="0" width="386" showattsigs="601" x="304" fillcolor="#ffffc0" y="533" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="pwXaDeUXVlRv" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
-         <classwidget usesdiagramfillcolor="0" width="168" showattsigs="601" x="201" fillcolor="#ffffc0" y="283" showopsigs="601" linewidth="none" height="36" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="85ASUVIYu8Rm" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
-        </widgets>
-        <messages/>
-        <associations/>
-       </diagram>
-       <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1042" snapy="10" showatts="1" xmi.id="PnEBEL9IihdQ" documentation="" type="1" showops="1" showpackage="0" name="Module doc classes" localid="" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="860" >
-        <widgets/>
-        <messages/>
-        <associations/>
-       </diagram>
-       <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1042" snapy="10" showatts="1" xmi.id="i9im14LKfTmZ" documentation="" type="1" showops="1" showpackage="0" name="Module graph classes" localid="" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="860" >
-        <widgets>
-         <classwidget usesdiagramfillcolor="0" width="386" showattsigs="601" x="307" fillcolor="#ffffc0" y="545" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="098RWfwZqN4L" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
-         <classwidget usesdiagramfillcolor="0" width="194" showattsigs="601" x="197" fillcolor="#ffffc0" y="276" showopsigs="601" linewidth="none" height="36" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="R1LMLXi8zBZD" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
-        </widgets>
-        <messages/>
-        <associations/>
-       </diagram>
-       <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1042" snapy="10" showatts="1" xmi.id="HBjs7fL0WfO5" documentation="" type="1" showops="1" showpackage="0" name="General classes" localid="" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="860" >
-        <widgets>
-         <enumwidget usesdiagramfillcolor="0" width="162" x="98" fillcolor="#ffffc0" y="44" linewidth="none" height="108" usefillcolor="1" isinstance="0" xmi.id="58hyBKGITKzU" showpackage="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
-         <enumwidget usesdiagramfillcolor="0" width="183" x="300" fillcolor="#ffffc0" y="44" linewidth="none" height="72" usefillcolor="1" isinstance="0" xmi.id="o5RT7D5TyDem" showpackage="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
-        </widgets>
-        <messages/>
-        <associations/>
-       </diagram>
-       <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1042" snapy="10" showatts="1" xmi.id="37Q7pvtspjUI" documentation="" type="1" showops="1" showpackage="0" name="Graph classes" localid="" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="860" >
-        <widgets>
-         <classwidget usesdiagramfillcolor="0" width="330" showattsigs="601" x="324" fillcolor="#ffffc0" y="228" showopsigs="601" linewidth="none" height="162" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="FVtbgO8sd2ii" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
-         <enumwidget usesdiagramfillcolor="0" width="172" x="62" fillcolor="#ffffc0" y="90" linewidth="none" height="90" usefillcolor="1" isinstance="0" xmi.id="4F09aHCjljSA" showpackage="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
-         <interfacewidget usesdiagramfillcolor="0" width="375" x="622" fillcolor="#ffffc0" y="433" drawascircle="0" showopsigs="601" linewidth="none" height="63" usefillcolor="1" showpubliconly="0" isinstance="0" xmi.id="2Mzl2VgeffI0" showoperations="1" showpackage="0" showscope="1" showstereotype="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
-         <classwidget usesdiagramfillcolor="0" width="436" showattsigs="601" x="481" fillcolor="#ffffc0" y="546" drawascircle="0" showopsigs="601" linewidth="none" height="72" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="taceG4p7AY1k" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
-         <classwidget usesdiagramfillcolor="0" width="236" showattsigs="601" x="70" fillcolor="#ffffc0" y="228" showopsigs="601" linewidth="none" height="189" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="672lM6F9KhcI" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
-         <classwidget usesdiagramfillcolor="0" width="375" showattsigs="601" x="623" fillcolor="#ffffc0" y="766" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="ZUDChgtO8jSy" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
-         <enumwidget usesdiagramfillcolor="0" width="110" x="434" fillcolor="#ffffc0" y="54" linewidth="none" height="126" usefillcolor="1" isinstance="0" xmi.id="BQqAv02HTM6x" showpackage="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
-         <classwidget usesdiagramfillcolor="0" width="309" showattsigs="601" x="729" fillcolor="#ffffc0" y="234" showopsigs="601" linewidth="none" height="108" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="PILb9kCQnOZd" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
-         <enumwidget usesdiagramfillcolor="0" width="136" x="815" fillcolor="#ffffc0" y="0" linewidth="none" height="180" usefillcolor="1" isinstance="0" xmi.id="uzw9DITFgRm2" showpackage="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
-         <interfacewidget usesdiagramfillcolor="0" width="338" x="19" fillcolor="#ffffc0" y="440" drawascircle="0" showopsigs="601" linewidth="none" height="81" usefillcolor="1" showpubliconly="0" isinstance="0" xmi.id="H9NLXsg0Hncp" showoperations="1" showpackage="0" showscope="1" showstereotype="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
-         <classwidget usesdiagramfillcolor="0" width="250" showattsigs="601" x="63" fillcolor="#ffffc0" y="554" drawascircle="0" showopsigs="601" linewidth="none" height="54" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="GIPhxHkszygs" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
-         <classwidget usesdiagramfillcolor="0" width="319" showattsigs="601" x="29" fillcolor="#ffffc0" y="646" showopsigs="601" linewidth="none" height="63" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="vJ8WmfZPiVQE" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
-         <classwidget usesdiagramfillcolor="0" width="156" showattsigs="601" x="296" fillcolor="#ffffc0" y="766" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="leYQpk5LWBlE" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
-         <classwidget usesdiagramfillcolor="0" width="147" showattsigs="601" x="464" fillcolor="#ffffc0" y="766" showopsigs="601" linewidth="none" height="45" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="cQGGEupKkEKw" showoperations="1" showpackage="0" showscope="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,0,0,0,0,0" linecolor="#ff0000" />
-         <interfacewidget usesdiagramfillcolor="1" width="127" x="426" fillcolor="none" y="423" drawascircle="0" showopsigs="601" linewidth="none" height="54" usefillcolor="1" showpubliconly="0" isinstance="0" xmi.id="QbirDWtuKiBS" showoperations="1" showpackage="0" showscope="1" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-         <enumwidget usesdiagramfillcolor="0" width="112" x="259" fillcolor="#ffffc0" y="90" linewidth="none" height="90" usefillcolor="1" isinstance="0" xmi.id="VDAdlQhZ750q" showpackage="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" />
-        </widgets>
-        <messages/>
-        <associations>
-         <assocwidget totalcounta="4" indexa="3" totalcountb="2" indexb="1" linewidth="none" widgetbid="2Mzl2VgeffI0" widgetaid="taceG4p7AY1k" xmi.id="YFH3CyxPGsNY" type="511" linecolor="none" >
-          <linepath>
-           <startpoint startx="808" starty="546" />
-           <endpoint endx="809" endy="496" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="2" totalcountb="4" indexb="3" linewidth="none" widgetbid="taceG4p7AY1k" widgetaid="ZUDChgtO8jSy" xmi.id="gO9JCUKh4zz7" type="500" linecolor="none" >
-          <linepath>
-           <startpoint startx="873" starty="766" />
-           <endpoint endx="808" endy="618" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="1" visibilityB="200" totalcountb="4" indexb="1" linewidth="none" widgetbid="FVtbgO8sd2ii" widgetaid="PILb9kCQnOZd" xmi.id="Aq7LuhClDFeB" type="510" changeabilityA="900" changeabilityB="900" linecolor="none" visibilityA="200" >
-          <linepath>
-           <startpoint startx="729" starty="270" />
-           <endpoint endx="654" endy="268" />
-          </linepath>
-          <floatingtext usesdiagramfillcolor="1" width="76" x="653" fillcolor="none" y="246" linewidth="none" posttext="" role="710" height="22" usefillcolor="1" pretext="-" isinstance="0" xmi.id="6iFUQNA8O29G" text="incoming" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-         </assocwidget>
-         <assocwidget totalcounta="2" indexa="1" visibilityB="200" totalcountb="2" indexb="1" linewidth="none" widgetbid="uzw9DITFgRm2" widgetaid="PILb9kCQnOZd" xmi.id="eaFFJAnvNrxh" type="510" changeabilityA="900" changeabilityB="900" linecolor="none" visibilityA="200" >
-          <linepath>
-           <startpoint startx="883" starty="234" />
-           <endpoint endx="883" endy="180" />
-          </linepath>
-          <floatingtext usesdiagramfillcolor="1" width="43" x="838" fillcolor="none" y="182" linewidth="none" posttext="" role="710" height="22" usefillcolor="1" pretext="-" isinstance="0" xmi.id="37WQwMtpwlbJ" text="type" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="2" visibilityB="200" totalcountb="4" indexb="2" linewidth="none" widgetbid="FVtbgO8sd2ii" widgetaid="PILb9kCQnOZd" xmi.id="xg3pIv6gVUUO" type="510" changeabilityA="900" changeabilityB="900" linecolor="none" visibilityA="200" >
-          <linepath>
-           <startpoint startx="729" starty="306" />
-           <endpoint endx="654" endy="309" />
-          </linepath>
-          <floatingtext usesdiagramfillcolor="1" width="75" x="649" fillcolor="none" y="309" linewidth="none" posttext="" role="710" height="22" usefillcolor="1" pretext="-" isinstance="0" xmi.id="n4MMwRI29XWX" text="outgoing" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="1" totalcountb="4" indexb="3" linewidth="none" widgetbid="FVtbgO8sd2ii" widgetaid="2Mzl2VgeffI0" xmi.id="m7wwiwCSxVGR" type="502" linecolor="none" >
-          <linepath>
-           <startpoint startx="747" starty="433" />
-           <endpoint endx="654" endy="349" />
-           <point x="714" y="385" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="2" totalcountb="2" indexb="1" linewidth="none" widgetbid="PILb9kCQnOZd" widgetaid="2Mzl2VgeffI0" xmi.id="R79vj31U6PK0" type="502" linecolor="none" >
-          <linepath>
-           <startpoint startx="872" starty="433" />
-           <endpoint endx="883" endy="342" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="H9NLXsg0Hncp" widgetaid="GIPhxHkszygs" xmi.id="Pef9sSrIGFql" type="511" linecolor="none" >
-          <linepath>
-           <startpoint startx="188" starty="554" />
-           <endpoint endx="188" endy="521" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="4" indexa="1" visibilityB="200" totalcountb="3" indexb="2" linewidth="none" widgetbid="H9NLXsg0Hncp" widgetaid="taceG4p7AY1k" xmi.id="jYgSGEsqagKv" type="510" changeabilityA="900" changeabilityB="900" linecolor="none" visibilityA="200" >
-          <linepath>
-           <startpoint startx="590" starty="546" />
-           <endpoint endx="357" endy="494" />
-           <point x="516" y="494" />
-          </linepath>
-          <floatingtext usesdiagramfillcolor="1" width="66" x="359" fillcolor="none" y="496" linewidth="none" posttext="" role="710" height="22" usefillcolor="1" pretext="#" isinstance="0" xmi.id="uefHfmXit36n" text="factory" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-         </assocwidget>
-         <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="672lM6F9KhcI" widgetaid="H9NLXsg0Hncp" xmi.id="p0keVPRrye6f" type="502" linecolor="none" >
-          <linepath>
-           <startpoint startx="188" starty="440" />
-           <endpoint endx="188" endy="417" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="2" totalcountb="4" indexb="2" linewidth="none" widgetbid="taceG4p7AY1k" widgetaid="cQGGEupKkEKw" xmi.id="Z4ZHkEV03W4k" type="500" linecolor="none" >
-          <linepath>
-           <startpoint startx="562" starty="766" />
-           <endpoint endx="699" endy="618" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="2" totalcountb="4" indexb="1" linewidth="none" widgetbid="taceG4p7AY1k" widgetaid="leYQpk5LWBlE" xmi.id="51RZVXixdhgF" type="500" linecolor="none" >
-          <linepath>
-           <startpoint startx="400" starty="766" />
-           <endpoint endx="590" endy="618" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="QbirDWtuKiBS" widgetaid="H9NLXsg0Hncp" xmi.id="0e7qU7vxuugt" type="502" linecolor="none" >
-          <linepath>
-           <startpoint startx="357" starty="467" />
-           <endpoint endx="426" endy="450" />
-           <point x="409" y="467" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="GIPhxHkszygs" widgetaid="vJ8WmfZPiVQE" xmi.id="kOBlgJz6y2Lz" type="500" linecolor="none" >
-          <linepath>
-           <startpoint startx="188" starty="646" />
-           <endpoint endx="188" endy="608" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="1" totalcountb="3" indexb="1" linewidth="none" widgetbid="leYQpk5LWBlE" widgetaid="vJ8WmfZPiVQE" xmi.id="jUfTITIIjhSw" type="502" linecolor="none" >
-          <linepath>
-           <startpoint startx="135" starty="709" />
-           <endpoint endx="348" endy="766" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="2" totalcountb="3" indexb="1" linewidth="none" widgetbid="cQGGEupKkEKw" widgetaid="vJ8WmfZPiVQE" xmi.id="ntBujkSHp8rF" type="502" linecolor="none" >
-          <linepath>
-           <startpoint startx="241" starty="709" />
-           <endpoint endx="513" endy="766" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="2" indexa="1" totalcountb="3" indexb="1" linewidth="none" widgetbid="ZUDChgtO8jSy" widgetaid="vJ8WmfZPiVQE" xmi.id="oG7IcloUW5iz" type="502" linecolor="none" >
-          <linepath>
-           <startpoint startx="348" starty="677" />
-           <endpoint endx="748" endy="766" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="4" indexa="2" totalcountb="2" indexb="1" linewidth="none" widgetbid="QbirDWtuKiBS" widgetaid="taceG4p7AY1k" xmi.id="6E5Os60E5bNw" type="502" linecolor="none" >
-          <linepath>
-           <startpoint startx="699" starty="546" />
-           <endpoint endx="553" endy="450" />
-           <point x="679" y="524" />
-           <point x="597" y="524" />
-           <point x="597" y="494" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="2" indexa="1" visibilityB="200" totalcountb="2" indexb="1" linewidth="none" widgetbid="BQqAv02HTM6x" widgetaid="FVtbgO8sd2ii" xmi.id="VXmaXhPeKk9I" type="510" changeabilityA="900" changeabilityB="900" linecolor="none" visibilityA="200" >
-          <linepath>
-           <startpoint startx="489" starty="228" />
-           <endpoint endx="489" endy="180" />
-          </linepath>
-          <floatingtext usesdiagramfillcolor="1" width="41" x="446" fillcolor="none" y="182" linewidth="none" posttext="" role="710" height="22" usefillcolor="1" pretext="-" isinstance="0" xmi.id="PzcKiCdTExqA" text="type" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="1" visibilityB="200" totalcountb="2" indexb="1" linewidth="none" widgetbid="4F09aHCjljSA" widgetaid="672lM6F9KhcI" xmi.id="zRuotD7A5ZEx" type="510" changeabilityA="900" changeabilityB="900" linecolor="none" visibilityA="200" >
-          <linepath>
-           <startpoint startx="148" starty="228" />
-           <endpoint endx="148" endy="180" />
-          </linepath>
-          <floatingtext usesdiagramfillcolor="1" width="56" x="150" fillcolor="none" y="182" linewidth="none" posttext="" role="710" height="22" usefillcolor="1" pretext="-" isinstance="0" xmi.id="O8CVfg2XLio0" text="format" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="2" visibilityB="200" totalcountb="2" indexb="1" linewidth="none" widgetbid="VDAdlQhZ750q" widgetaid="672lM6F9KhcI" xmi.id="dMwwhlSnUoPh" type="510" changeabilityA="900" changeabilityB="900" linecolor="none" visibilityA="200" >
-          <linepath>
-           <startpoint startx="227" starty="228" />
-           <endpoint endx="315" endy="180" />
-          </linepath>
-          <floatingtext usesdiagramfillcolor="1" width="99" x="273" fillcolor="none" y="196" linewidth="none" posttext="" role="710" height="22" usefillcolor="1" pretext="-" isinstance="0" xmi.id="SJgKMk7kki2Q" text="imageFormat" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-         </assocwidget>
-        </associations>
-       </diagram>
-       <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1042" snapy="10" showatts="1" xmi.id="cZsSOYL0vMYc" documentation="" type="3" showops="1" showpackage="0" name="Graph generation" localid="fNm3GNcdo5oo" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="860" >
-        <widgets>
-         <objectwidget usesdiagramfillcolor="0" width="191" x="432" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="vJ8WmfZPiVQE" decon="0" localid="xkkShjnglZDn" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
-         <objectwidget usesdiagramfillcolor="0" width="82" x="846" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="ZUDChgtO8jSy" decon="0" localid="5sYVesgRYawR" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
-         <objectwidget usesdiagramfillcolor="0" width="144" x="37" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="R1LMLXi8zBZD" decon="0" localid="8k1etAbDCjb4" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
-         <notewidget usesdiagramfillcolor="1" width="130" x="558" fillcolor="none" y="105" linewidth="none" height="63" usefillcolor="1" isinstance="0" xmi.id="mi9i1VrBEe8P" text="Common graph settings are bound first." usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-         <notewidget usesdiagramfillcolor="1" width="205" x="241" fillcolor="none" y="207" linewidth="none" height="50" usefillcolor="1" isinstance="0" xmi.id="AvASsvve1luo" text="A new writer is usually created for each graph file." usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-         <notewidget usesdiagramfillcolor="1" width="194" x="214" fillcolor="none" y="455" linewidth="none" height="50" usefillcolor="1" isinstance="0" xmi.id="pnt8L3mW94H6" text="Writer can be used to generate several graphs." usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-        </widgets>
-        <messages>
-         <messagewidget usesdiagramfillcolor="1" width="426" x="123" fillcolor="none" y="98" operation="rSVt3npBuRwI" linewidth="none" widgetbid="xkkShjnglZDn" height="32" usefillcolor="1" seqnum="" textid="17kr4cTMN71P" widgetaid="8k1etAbDCjb4" isinstance="0" xmi.id="rSVt3npBuRwI" sequencemessagetype="1000" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
-          <floatingtext usesdiagramfillcolor="1" width="233" x="128" fillcolor="none" y="76" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="17kr4cTMN71P" text=": this(options : GraphOptions)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-         </messagewidget>
-         <messagewidget usesdiagramfillcolor="1" width="426" x="123" fillcolor="none" y="284" operation="qt3yjRHa0HmR" linewidth="none" widgetbid="xkkShjnglZDn" height="73" usefillcolor="1" seqnum="" textid="8R7413dyF3lY" widgetaid="8k1etAbDCjb4" isinstance="0" xmi.id="qt3yjRHa0HmR" sequencemessagetype="1000" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
-          <floatingtext usesdiagramfillcolor="1" width="306" x="128" fillcolor="none" y="262" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="8R7413dyF3lY" text=": createGraphWriter(outputs : OutputStream[])" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-         </messagewidget>
-         <messagewidget usesdiagramfillcolor="1" width="368" x="527" fillcolor="none" y="304" operation="RhFDP34VCWM4" linewidth="none" widgetbid="5sYVesgRYawR" height="32" usefillcolor="1" seqnum="" textid="KpN7JYvOVJ7T" widgetaid="xkkShjnglZDn" isinstance="0" xmi.id="RhFDP34VCWM4" sequencemessagetype="1000" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
-          <floatingtext usesdiagramfillcolor="1" width="399" x="532" fillcolor="none" y="282" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="KpN7JYvOVJ7T" text=": this(factory : GraphWriterFactory, outputs : OutputStream[])" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-         </messagewidget>
-         <messagewidget usesdiagramfillcolor="1" width="786" x="123" fillcolor="none" y="537" operation="nXwHg6RtyC4B" linewidth="none" widgetbid="5sYVesgRYawR" height="32" usefillcolor="1" seqnum="" textid="CUWS73hkulgU" widgetaid="8k1etAbDCjb4" isinstance="0" xmi.id="nXwHg6RtyC4B" sequencemessagetype="1000" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
-          <floatingtext usesdiagramfillcolor="1" width="338" x="249" fillcolor="none" y="515" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="CUWS73hkulgU" text=": generateGraph(vertices : Vertex[], edges : Edge[])" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
-         </messagewidget>
-        </messages>
-        <associations/>
-       </diagram>
-      </diagrams>
-     </XMI.extension>
-    </UML:Model>
-    <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Use Case View" isRoot="false" isAbstract="false" name="Use Case View" >
-     <UML:Namespace.ownedElement/>
-    </UML:Model>
-    <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Component View" isRoot="false" isAbstract="false" name="Component View" >
-     <UML:Namespace.ownedElement>
-      <UML:Component executable="0" isSpecification="false" isLeaf="false" visibility="public" namespace="Component View" xmi.id="3XF2INiTN1r0" isRoot="false" isAbstract="false" name="DocumentGenerator" />
-      <UML:Component executable="0" isSpecification="false" isLeaf="false" visibility="public" namespace="Component View" xmi.id="JrRpdxcmaX5Z" isRoot="false" isAbstract="false" name="ModuleDoc" />
-      <UML:Component executable="0" isSpecification="false" isLeaf="false" visibility="public" namespace="Component View" xmi.id="oCHM2Pm3w15E" isRoot="false" isAbstract="false" name="SourceListing" />
-      <UML:Component executable="0" isSpecification="false" isLeaf="false" visibility="public" namespace="Component View" xmi.id="OmgklXk4NCu0" isRoot="false" isAbstract="false" name="ModuleGraph" />
-      <UML:Component executable="0" isSpecification="false" isLeaf="false" visibility="public" namespace="Component View" xmi.id="9Wmh3pGp1WC1" isRoot="false" isAbstract="false" name="ClassGraph" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Component View" xmi.id="9zv0am0s4p3H" client="3XF2INiTN1r0" name="" supplier="9Wmh3pGp1WC1" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Component View" xmi.id="7Qg9DhQeLLiC" client="3XF2INiTN1r0" name="" supplier="OmgklXk4NCu0" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Component View" xmi.id="TCboYJyLq3UQ" client="3XF2INiTN1r0" name="" supplier="JrRpdxcmaX5Z" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Component View" xmi.id="3BrrELHlDrWv" client="3XF2INiTN1r0" name="" supplier="oCHM2Pm3w15E" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Component View" xmi.id="G51CBWFaF9t3" client="3XF2INiTN1r0" name="" supplier="9Wmh3pGp1WC1" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Component View" xmi.id="sgHau3wyChzY" client="3XF2INiTN1r0" name="" supplier="OmgklXk4NCu0" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Component View" xmi.id="8Xdyj7yz61iY" client="3XF2INiTN1r0" name="" supplier="JrRpdxcmaX5Z" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Component View" xmi.id="YbwqcMQKAE7f" client="3XF2INiTN1r0" name="" supplier="oCHM2Pm3w15E" />
-      <UML:Component executable="0" isSpecification="false" isLeaf="false" visibility="public" namespace="Component View" xmi.id="JeCajbMGRVUn" isRoot="false" isAbstract="false" name="Parser&amp;Lexer" />
-      <UML:Dependency isSpecification="false" visibility="public" namespace="Component View" xmi.id="ZZ3AIK4OAcIw" client="3XF2INiTN1r0" name="" supplier="JeCajbMGRVUn" />
-     </UML:Namespace.ownedElement>
-     <XMI.extension xmi.extender="umbrello" >
-      <diagrams>
-       <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1042" snapy="10" showatts="1" xmi.id="9cvLzH7kYq8S" documentation="" type="7" showops="1" showpackage="0" name="high level components" localid="" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="860" >
-        <widgets>
-         <componentwidget usesdiagramfillcolor="1" width="223" x="380" fillcolor="none" y="310" linewidth="none" height="66" usefillcolor="1" isinstance="0" xmi.id="3XF2INiTN1r0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,75,0,0,0,0,0" linecolor="none" />
-         <componentwidget usesdiagramfillcolor="0" width="230" x="183" fillcolor="#ffffc0" y="447" linewidth="none" height="66" usefillcolor="1" isinstance="0" xmi.id="JrRpdxcmaX5Z" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
-         <componentwidget usesdiagramfillcolor="0" width="201" x="568" fillcolor="#ffffc0" y="447" linewidth="none" height="66" usefillcolor="1" isinstance="0" xmi.id="oCHM2Pm3w15E" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
-         <componentwidget usesdiagramfillcolor="0" width="247" x="166" fillcolor="#ffffc0" y="158" linewidth="none" height="66" usefillcolor="1" isinstance="0" xmi.id="OmgklXk4NCu0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
-         <componentwidget usesdiagramfillcolor="0" width="279" x="568" fillcolor="#ffffc0" y="158" linewidth="none" height="66" usefillcolor="1" isinstance="0" xmi.id="9Wmh3pGp1WC1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
-         <componentwidget usesdiagramfillcolor="1" width="159" x="98" fillcolor="none" y="310" linewidth="none" height="66" usefillcolor="1" isinstance="0" xmi.id="JeCajbMGRVUn" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,75,0,0,0,0,0" linecolor="none" />
-        </widgets>
-        <messages/>
-        <associations>
-         <assocwidget totalcounta="3" indexa="2" totalcountb="2" indexb="1" linewidth="none" widgetbid="9Wmh3pGp1WC1" widgetaid="3XF2INiTN1r0" xmi.id="G51CBWFaF9t3" type="502" linecolor="none" >
-          <linepath>
-           <startpoint startx="528" starty="310" />
-           <endpoint endx="707" endy="224" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="OmgklXk4NCu0" widgetaid="3XF2INiTN1r0" xmi.id="sgHau3wyChzY" type="502" linecolor="none" >
-          <linepath>
-           <startpoint startx="454" starty="310" />
-           <endpoint endx="289" endy="224" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="JrRpdxcmaX5Z" widgetaid="3XF2INiTN1r0" xmi.id="8Xdyj7yz61iY" type="502" linecolor="none" >
-          <linepath>
-           <startpoint startx="454" starty="376" />
-           <endpoint endx="298" endy="447" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="3" indexa="2" totalcountb="2" indexb="1" linewidth="none" widgetbid="oCHM2Pm3w15E" widgetaid="3XF2INiTN1r0" xmi.id="YbwqcMQKAE7f" type="502" linecolor="none" >
-          <linepath>
-           <startpoint startx="528" starty="376" />
-           <endpoint endx="668" endy="447" />
-          </linepath>
-         </assocwidget>
-         <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="JeCajbMGRVUn" widgetaid="3XF2INiTN1r0" xmi.id="ZZ3AIK4OAcIw" type="502" linecolor="none" >
-          <linepath>
-           <startpoint startx="380" starty="343" />
-           <endpoint endx="257" endy="343" />
-          </linepath>
-         </assocwidget>
-        </associations>
-       </diagram>
-      </diagrams>
-     </XMI.extension>
-    </UML:Model>
-    <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Deployment View" isRoot="false" isAbstract="false" name="Deployment View" >
-     <UML:Namespace.ownedElement/>
-    </UML:Model>
-    <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Entity Relationship Model" isRoot="false" isAbstract="false" name="Entity Relationship Model" >
-     <UML:Namespace.ownedElement/>
-    </UML:Model>
-   </UML:Namespace.ownedElement>
-  </UML:Model>
- </XMI.content>
- <XMI.extensions xmi.extender="umbrello" >
-  <docsettings viewid="37Q7pvtspjUI" documentation="" uniqueid="qWVYkDfsYxos" />
-  <listview>
-   <listitem open="1" type="800" label="Näytöt" >
-    <listitem open="1" type="801" id="Logical View" >
-     <listitem open="0" type="807" id="BbQfy5JEWUGf" label="Class graph classes" />
-     <listitem open="0" type="807" id="HBjs7fL0WfO5" label="General classes" />
-     <listitem open="0" type="807" id="37Q7pvtspjUI" label="Graph classes" />
-     <listitem open="0" type="807" id="PnEBEL9IihdQ" label="Module doc classes" />
-     <listitem open="0" type="807" id="i9im14LKfTmZ" label="Module graph classes" />
-     <listitem open="0" type="807" id="VfRLtV4Z9Ptg" label="Source listing classes" />
-     <listitem open="0" type="810" id="cZsSOYL0vMYc" label="Graph generation" />
-     <listitem open="0" type="813" id="taceG4p7AY1k" >
-      <listitem open="0" type="814" id="jYgSGEsqagKv" />
-      <listitem open="0" type="814" id="4Bqtwxx8p0pI" />
-      <listitem open="0" type="815" id="RhFDP34VCWM4" />
-     </listitem>
-     <listitem open="0" type="813" id="GIPhxHkszygs" >
-      <listitem open="0" type="814" id="ZmI5M1aN978M" />
-      <listitem open="0" type="815" id="liEDYXNQ5pTO" />
-     </listitem>
-     <listitem open="0" type="813" id="m1ftLgsc5LXQ" >
-      <listitem open="0" type="814" id="xswAJre2CrPi" />
-      <listitem open="0" type="815" id="mZ1wtQujXunn" />
-     </listitem>
-     <listitem open="0" type="813" id="gGNje78ValnI" >
-      <listitem open="0" type="814" id="hcALY1fmWlEG" />
-      <listitem open="0" type="814" id="9QXgkpqgA1Du" />
-      <listitem open="0" type="815" id="Aa3THxJUbPoV" />
-     </listitem>
-     <listitem open="0" type="813" id="pwXaDeUXVlRv" >
-      <listitem open="0" type="815" id="RDl3vCbldkit" />
-     </listitem>
-     <listitem open="0" type="813" id="85ASUVIYu8Rm" />
-     <listitem open="1" type="813" id="vJ8WmfZPiVQE" >
-      <listitem open="0" type="815" id="rSVt3npBuRwI" />
-      <listitem open="0" type="815" id="qt3yjRHa0HmR" />
-     </listitem>
-     <listitem open="0" type="813" id="haoxC1oM2QVz" >
-      <listitem open="0" type="815" id="2SrUGMptabML" />
-     </listitem>
-     <listitem open="0" type="813" id="ZUDChgtO8jSy" >
-      <listitem open="0" type="815" id="nXwHg6RtyC4B" />
-     </listitem>
-     <listitem open="1" type="813" id="PILb9kCQnOZd" >
-      <listitem open="0" type="814" id="Aq7LuhClDFeB" />
-      <listitem open="0" type="814" id="xg3pIv6gVUUO" />
-      <listitem open="0" type="814" id="eaFFJAnvNrxh" />
-      <listitem open="0" type="815" id="p2AAWOx6E09l" />
-      <listitem open="0" type="815" id="faPqILFpZIBc" />
-     </listitem>
-     <listitem open="0" type="813" id="XjtDAoectTTH" />
-     <listitem open="1" type="813" id="672lM6F9KhcI" >
-      <listitem open="0" type="814" id="zRuotD7A5ZEx" />
-      <listitem open="0" type="814" id="dMwwhlSnUoPh" />
-      <listitem open="0" type="814" id="E1vnjmQdHkkv" />
-      <listitem open="0" type="814" id="cGQrznU4axXm" />
-      <listitem open="0" type="814" id="UirRcvN0JEsV" />
-      <listitem open="0" type="814" id="AQlvQmLLBkXo" />
-      <listitem open="0" type="814" id="vOQEdHhXSPF8" />
-      <listitem open="0" type="814" id="TrfH97Bbn23Q" />
-      <listitem open="0" type="814" id="uBkkfpbvggDX" />
-     </listitem>
-     <listitem open="0" type="813" id="w884b40YcIag" >
-      <listitem open="0" type="815" id="mBRaST74dftD" />
-     </listitem>
-     <listitem open="0" type="813" id="B92ON93E7uE9" >
-      <listitem open="0" type="815" id="JpwoOQQ4RzaO" />
-     </listitem>
-     <listitem open="1" type="813" id="OcpJQugxHW8F" >
-      <listitem open="0" type="814" id="gOHG3iCLbStZ" />
-     </listitem>
-     <listitem open="0" type="813" id="098RWfwZqN4L" >
-      <listitem open="0" type="815" id="CMMapfT5KiQP" />
-     </listitem>
-     <listitem open="0" type="813" id="R1LMLXi8zBZD" />
-     <listitem open="1" type="813" id="leYQpk5LWBlE" >
-      <listitem open="0" type="815" id="VR6VNEtfCgkY" />
-     </listitem>
-     <listitem open="1" type="813" id="cQGGEupKkEKw" >
-      <listitem open="0" type="815" id="wEWZIkURw0Kn" />
-     </listitem>
-     <listitem open="0" type="813" id="3qQutO5Yhxt6" />
-     <listitem open="0" type="813" id="UY72E0ULeXyT" />
-     <listitem open="0" type="813" id="Ug6grrz7llbI" />
-     <listitem open="0" type="813" id="2MyyGGXAPfEy" >
-      <listitem open="0" type="815" id="VRgNwkJTDt0B" />
-     </listitem>
-     <listitem open="1" type="813" id="FVtbgO8sd2ii" >
-      <listitem open="0" type="814" id="cf98eu4OpFbX" />
-      <listitem open="0" type="814" id="hgsYJ2YnnaVS" />
-      <listitem open="0" type="814" id="sBVGlTogVHfE" />
-      <listitem open="0" type="814" id="ajeRzBpBzXm2" />
-      <listitem open="0" type="814" id="hTSa11gAdwIE" />
-      <listitem open="0" type="814" id="VXmaXhPeKk9I" />
-      <listitem open="0" type="815" id="2fXtbb2YF7TG" />
-      <listitem open="0" type="815" id="PX2Y1eFKtaj6" />
-     </listitem>
-     <listitem open="0" type="813" id="qxq04A8rywIb" >
-      <listitem open="0" type="815" id="KoEO9zJwTXuD" />
-     </listitem>
-     <listitem open="0" type="817" id="2Mzl2VgeffI0" >
-      <listitem open="0" type="815" id="kluUKuajlkAu" />
-     </listitem>
-     <listitem open="0" type="817" id="H9NLXsg0Hncp" >
-      <listitem open="0" type="815" id="FYgiWJyDqrhK" />
-      <listitem open="0" type="815" id="L1C3szmMnzpw" />
-     </listitem>
-     <listitem open="0" type="817" id="yBk69LKYzyaX" />
-     <listitem open="0" type="817" id="DdhFJyNQcQSm" >
-      <listitem open="0" type="815" id="QR4frQ4pllIy" />
-      <listitem open="0" type="815" id="GL3CAg7Qy0PF" />
-     </listitem>
-     <listitem open="0" type="817" id="zhVfgpENwAeN" >
-      <listitem open="0" type="815" id="eGKXDits9Kho" />
-      <listitem open="0" type="815" id="fA2So7Re6pf2" />
-     </listitem>
-     <listitem open="0" type="817" id="QbirDWtuKiBS" />
-     <listitem open="0" type="830" id="Datatypes" >
-      <listitem open="1" type="829" id="DaFOT7jBVtui" />
-      <listitem open="1" type="829" id="tblJnk8mwuii" />
-      <listitem open="1" type="829" id="QXgD4zE4FsCt" />
-      <listitem open="1" type="829" id="UGpWCc0uWy3g" />
-      <listitem open="1" type="829" id="EaC7G8UkzGbk" />
-      <listitem open="1" type="829" id="MGwAYPpykhTm" />
-      <listitem open="1" type="829" id="clKKQl7eLHlZ" />
-      <listitem open="1" type="829" id="z3jKRbJnqFxM" />
-      <listitem open="1" type="829" id="wMWsornjU1NO" />
-      <listitem open="1" type="829" id="N7BDN7YzqsIG" />
-      <listitem open="1" type="829" id="NFJMWv4VyoqO" />
-      <listitem open="1" type="829" id="wERn1lAgB0KQ" />
-      <listitem open="0" type="829" id="zgj70ST7PbVQ" />
-      <listitem open="1" type="829" id="cPuvefV1toMN" />
-      <listitem open="1" type="829" id="IL68COOolGjP" />
-      <listitem open="1" type="829" id="hQqeEe2cmDn9" />
-     </listitem>
-     <listitem open="0" type="831" id="o5RT7D5TyDem" >
-      <listitem open="0" type="839" id="pCzlo8cW1N0o" />
-      <listitem open="0" type="839" id="FS23UTFrinBx" />
-     </listitem>
-     <listitem open="0" type="831" id="58hyBKGITKzU" >
-      <listitem open="0" type="839" id="jnhozkQ1UqIp" />
-      <listitem open="0" type="839" id="DhN6TjTmtUai" />
-      <listitem open="0" type="839" id="eyKevtlegQQd" />
-      <listitem open="0" type="839" id="9qedeuTpcot5" />
-     </listitem>
-     <listitem open="0" type="831" id="uzw9DITFgRm2" >
-      <listitem open="0" type="839" id="Gv3YsqBCKi6E" />
-      <listitem open="0" type="839" id="A1QhopWR6xzK" />
-      <listitem open="0" type="839" id="OVYO1FWE3aSP" />
-      <listitem open="0" type="839" id="uXTHm0iw18dq" />
-      <listitem open="0" type="839" id="3Mv6vLTpsw6c" />
-      <listitem open="0" type="839" id="0BPEtKs5X9EB" />
-      <listitem open="0" type="839" id="w8F05EKRiqqj" />
-      <listitem open="0" type="839" id="OQEcUiDMf7Wr" />
-     </listitem>
-     <listitem open="0" type="831" id="4F09aHCjljSA" >
-      <listitem open="0" type="839" id="Uhfew917nyad" />
-      <listitem open="0" type="839" id="Jy1fqRBSwrTe" />
-      <listitem open="0" type="839" id="aow2SW2oUhRP" />
-     </listitem>
-     <listitem open="1" type="831" id="VDAdlQhZ750q" >
-      <listitem open="0" type="839" id="NPNgtZqJFAtE" />
-      <listitem open="0" type="839" id="2W24K4edixcf" />
-      <listitem open="0" type="839" id="kjad3bVP0s5s" />
-     </listitem>
-     <listitem open="0" type="831" id="BQqAv02HTM6x" >
-      <listitem open="0" type="839" id="UWXR1uwj6Xht" />
-      <listitem open="0" type="839" id="KZH8gthgkYAr" />
-      <listitem open="0" type="839" id="GvOp2iAWCfvE" />
-      <listitem open="0" type="839" id="XsxdPcUh9joq" />
-      <listitem open="0" type="839" id="dTUN2eCIZb6Z" />
-     </listitem>
-    </listitem>
-    <listitem open="1" type="802" id="Use Case View" />
-    <listitem open="1" type="821" id="Component View" >
-     <listitem open="0" type="819" id="9cvLzH7kYq8S" label="high level components" />
-     <listitem open="1" type="822" id="9Wmh3pGp1WC1" />
-     <listitem open="1" type="822" id="3XF2INiTN1r0" />
-     <listitem open="1" type="822" id="JrRpdxcmaX5Z" />
-     <listitem open="1" type="822" id="OmgklXk4NCu0" />
-     <listitem open="1" type="822" id="JeCajbMGRVUn" />
-     <listitem open="1" type="822" id="oCHM2Pm3w15E" />
-    </listitem>
-    <listitem open="1" type="827" id="Deployment View" />
-    <listitem open="1" type="836" id="Entity Relationship Model" />
-   </listitem>
-  </listview>
-  <codegeneration>
-   <codegenerator language="C++" />
-  </codegeneration>
- </XMI.extensions>
-</XMI>
--- a/trunk/src/docgen/config/configurator.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.config.configurator;
-
-import docgen.config.reader;
-import docgen.config.reflection;
-import docgen.misc.options;
-
-import Integer = tango.text.convert.Integer;
-import tango.io.stream.FileStream;
-import tango.io.Stdout;
-
-/**
- * Class for handling and merging doc generator options.
- */
-interface Configurator {
-  /**
-   * Merges configuration options from the given file.
-   */
-  void mergeConfiguration(char[] cfgFile);
-  
-  /**
-   * Returns a hierarchical structure of configuration options.
-   */
-  DocGeneratorOptions *getConfiguration();
-}
-
-private DocGeneratorOptions options;
-private Struct!(options) opt;
-private const cases = makeTypeStringForStruct!(opt);
-
-class DefaultConfigurator : Configurator {
-  private:
-    
-  DocGeneratorOptions options;
-
-  public:
-
-  const defaultProfileLocation = "docgen/config/default.cfg";
-
-  this() {
-    mergeConfiguration(defaultProfileLocation);
-  }
-
-  this(char[] cfgFile) {
-    this();
-    mergeConfiguration(cfgFile);
-  }
-
-  void mergeConfiguration(char[] cfgFile) {
-    
-    auto inputStream = new FileInput(cfgFile);
-    auto content = new char[inputStream.length];
-    auto bytesRead = inputStream.read (content);
-    
-    assert(bytesRead == inputStream.length, "Error reading configuration file");
-
-    auto tokens = lex(content);
-    auto configuration = parse(tokens);
-
-    foreach(key, val; configuration) {
-      bool err() {
-        throw new Exception(
-          "Configurator: Invalid key-val pair " ~ key ~
-          "=" ~ (val.length ? val[0] : "null"));
-      }
-
-      // cuteness, lul
-      mixin(_switch(
-        mixin(cases) ~
-        `default: throw new Exception("Illegal configuration key " ~ key);`
-      ));
-    }
-  }
-
-  DocGeneratorOptions *getConfiguration() {
-    return &options;
-  }
-}
--- a/trunk/src/docgen/config/default.cfg	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-#
-# This file contains the default configuration. You don't need to
-# worry about this, the system will load the settings automatically.
-#
-# If you need to customize settings, just take a copy of this or
-# write one from scratch and pass the new file location as a
-# command line parameter.
-#
-
-
-(options
-  (graph
-    (imageFormat PNG)
-    (depth -1)
-    (nodeColor white)
-    (cyclicNodeColor tomato)
-    (unlocatableNodeColor gray)
-    (depColor black)
-    (cyclicDepColor red)
-    (publicDepColor blue)
-    (clusterColor blue)
-    (includeUnlocatableModules true)
-    (highlightCyclicEdges true)
-    (highlightCyclicVertices true)
-    (groupByPackageNames true)
-    (groupByFullPackageName false)
-  )
-  (listing
-    (literateStyle true)
-    (enableListings true)
-  )
-  (templates
-    (title "Test project")
-    (versionString 1.0)
-    (copyright "Crashtest dummy")
-    (paperSize a4paper)
-    (shortFileNames false)
-    (templateStyle default)
-  )
-  (parser
-    (importPaths)
-    (rootPaths)
-    (strRegexps)
-    (commentFormat Doxygen)
-    (depth -1)
-  )
-  (outputFormats LaTeX HTML PlainText)
-  (outputDir tmp/)
-)
--- a/trunk/src/docgen/config/reader.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.config.reader;
-
-debug import tango.io.Stdout;
-
-/**
- * Lexes a s-exp like input
- */
-char[][] lex(char[] input) {
-  char[][] tokens;
-
-  uint state = 0, level = 0;
-  size_t sidx = 0;
-
-  void err(size_t i, int type = 0) {
-    auto b = input[i<20 ? 0 : i-20..i];
-    auto e = input[i+1..i+21>$ ? $ : i+21];
-
-    throw new Exception("Lex: " ~ 
-      (type == 0 ? "Illegal character" :
-      type == 1 ? "Wrong number of parenthesis" :
-      "Unexpected end of input") ~
-      ": " ~ b ~ "  >>>" ~ input[i] ~ "<<<  " ~ e ~ "."
-    );
-  }
-  void begin(size_t i) { sidx = i; }
-  void end(size_t i) { tokens ~= input[sidx..i]; }
-
-  foreach(size_t i, c; input) {
-    if (sidx > i) continue;
-    switch(c) { // states space, token, textEnd
-      case '"': // starts a ""-string
-        switch(state) {
-          case 0:
-            char[] buf;
-            bool escape;
-            char d;
-            sidx = i;
-            while(!((d = input[++sidx]) == '"' && !escape) && sidx<input.length)
-              if (escape) {
-                if (d != '"' && d != '\\') buf ~= '\\';
-                buf ~= d;
-                escape = false;
-              } else if (d == '\\')
-                escape = true;
-              else
-                buf ~= d;
-
-            sidx++;
-            tokens ~= buf;
-            state = 2;
-            continue;
-          default: err(i);
-        }
-      case '\\':
-        switch(state) {
-          case 0: begin(i); state = 1; continue;
-          case 1: continue;
-          case 2: err(i);
-        }
-      case '#': // starts a comment
-        sidx = i;
-        while (++sidx<input.length && input[sidx] != '\n') {}
-        continue;
-      case ' ': // whitespace
-      case '\t':
-      case '\n':
-      case '(': // begins a block
-      case ')': // ends a block
-        switch(state) {
-          case 1: end(i);
-          case 0:
-          case 2:
-            switch(c) {
-              case '(': tokens ~= "("; level++; state = 0; break;
-              case ')': tokens ~= ")"; if (!level--) err(i,1);
-              default: state = 0;
-            }
-        }
-        break;
-      default:
-        switch(state) {
-          case 0: begin(i);
-          case 1: state = 1; continue;
-          case 2: err(i);
-        }
-     }
-  }
-
-  if (state == 3 || level != 0) err(input.length-1,2);
-  if (state > 0) end(input.length);
-
-  debug {
-    foreach(i, tok; tokens)
-      Stdout.format("{}{}", tok, (i != tokens.length-1 ? " " : ""));
-    Stdout.newline;
-  }
-
-  return tokens;
-}
-
-/**
- * Parser a s-exp like input used by the config files.
- */
-char[][][char[]] parse(char[][] tokens) {
-  char[][][char[]] values;
-  size_t i = 1;
-
-  void err(size_t j) {
-    auto b = tokens[j < 5 ? 0 : j-5..j];
-    auto e = tokens[j+1..j+6>$ ? $ : j+6];
-    char[] tmp;
-    foreach(t; b) tmp ~= t ~ " ";
-    tmp ~= ">>>" ~ tokens[j] ~ "<<< ";
-    foreach(t; e) tmp ~= t ~ " ";
-
-    throw new Exception(
-      "Parse: Illegal token: " ~ tmp ~ "."
-    );
-  }
-
-  if (tokens[0] != "(") err(0);
-
-  void doParse(char[] prefix = null) {
-    if (tokens[i] == "(" ||
-        tokens[i] == ")") err(i);
-    if (prefix) prefix ~= ".";
-    auto v = prefix ~ tokens[i++];
-    //values[v] = null;
-    while (tokens[i] != ")")
-      if (tokens[i++] == "(")
-        doParse(v);
-      else
-        values[v] ~= tokens[i-1];
-    i++;
-  }
-
-  doParse();
-
-  return values;
-}
--- a/trunk/src/docgen/config/reflection.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,275 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.config.reflection;
-
-import docgen.misc.meta;
-import docgen.misc.options;
-
-////
-//
-// Macros for reading input
-//
-////
-
-char[] _wrong(char[] key) {
-  return `if (val.length != 1) throw new Exception(
-    "Wrong number of arguments for `~key~`");`;
-}
-
-char[] _switch(char[] stuff) {
-  return "switch(key) {" ~ stuff ~ "}";
-}
-
-char[] _parseI(char[] key) {
-  return `case "` ~ key ~ `":` ~ _wrong(key) ~ key ~
-    `= Integer.parse(val[0]); continue;`;
-}
-
-char[] _parseS(char[] key) {
-  return `case "` ~ key ~ `":` ~ _wrong(key) ~ key ~
-    `= val[0]; continue;`;
-}
-
-char[] _parseB(char[] key) {
-  return `case "` ~ key ~ `":` ~ _wrong(key) ~ key ~
-    `= val[0] == "true" ? true : val[0] == "false" ? false : err(); continue;`;
-}
-
-char[] _parseList(char[] key) {
-  return `case "` ~ key ~ `":foreach(v; val) ` ~
-    key ~ `~= v; continue;`;
-}
-
-template _parseEnum_(bool list, char[] key, V...) {
-  static if (V.length>1)
-    const char[] _parseEnum_ =
-      `case "` ~ V[0] ~ `":` ~ key ~ (list ? "~" : "") ~ `=` ~ V[1] ~ `; continue;` \n ~
-      _parseEnum_!(list, key, V[2..$]);
-  else
-    const char[] _parseEnum_ = "";
-}
-
-template _parseEnum(char[] key, V...) {
-  const char[] _parseEnum = `case "` ~ key ~
-    `":` ~ _wrong(key) ~ `switch(val[0]) {` ~
-    _parseEnum_!(false, key, V) ~
-      `default: err(); } continue;`;
-}
-
-template _parseEnumList(char[] key, V...) {
-  const char[] _parseEnumList = `case "` ~ key ~
-    `":` ~ `foreach (item; val) switch(item) {` ~
-    _parseEnum_!(true, key, V) ~
-      `default: err(); } continue;`;
-}
-
-////
-//
-// Reflection for properties. This code will hopefully get better when the dmdfe bugs get fixed.
-//
-////
-
-// dmdfe bug -- Seriously WTF?
-char[] fixType(char[] type) {
-  return type[$-1] == ' ' ? type[0..$-1] : type;
-}
-
-// take the last part of field name
-char[] getLastName(char[] field) {
-  if (field.length == 0) return "";
-  int t = 0;
-  // dmdfe bug: a while loop causes index out of bounds error
-  for (int i=field.length-1; i >= 0; i--)
-    if (field[i] == '.') { t = i+1; break; }
-  return field[t..$];
-}
-
-// dmdfe bug: cannot return evalType alias
-template _evalType(char[] type) {
-  mixin("alias "~type~" value;");
-}
-
-// Note: stuple wrappers needed for tuples, otherwise:
-// dmdfe bug: cc1d: ../.././gcc/d/dmd/expression.c:4865: virtual Expression* DotIdExp::semantic(Scope*): Assertion `0' failed.
-template evalType(char[] type) {
-  alias _evalType!(type).value evalType;
-}
-
-// wraps the reflected struct and enum data inside struct because otherwise the handling becomes impossibly hard
-template getType(T) {
-  static if(is(T == struct))
-    alias Struct!(T) getType;
-  else static if(is(T == enum))
-    alias Enum!(T) getType;
-  else static if(isEnumList!(T))
-    alias Enum!(enumListType!(T), true) getType;
-  else
-    alias T getType;
-}
-
-template getTypes(alias S, int idx = S.tupleof.length) {
-  static if(idx)
-    alias Tuple!(getTypes!(S, idx-1), getType!(typeof(S.tupleof[idx-1]))) getTypes;
-  else
-    alias Tuple!() getTypes;
-}
-
-/**
- * Extracts the comma separated struct field names using .tupleof.stringof.
- * This is needed since the struct.tupleof[n].stringof is broken for enums and tuples in dmdfe.
- *
- * Bugs: handling of tuples
- */
-char[] __getNames(char[] type) {
-  char[] tmp;
-  bool end = false;
-
-  foreach(c; type[5..$]) {
-    if (c != ' ' && c != '(' && c != ')' && end) tmp ~= c;
-    if (c == ',') end = false;
-    if (c == '.') end = true;
-  }
-
-  return tmp;
-}
-
-template _getNames(char[] str, T...) {
-  static if (str.length) {
-    static if (str[0] == ',')
-      alias _getNames!(str[1..$], T, "") _getNames;
-    else
-      alias _getNames!(str[1..$], T[0..$-1], T[$-1] ~ str[0]) _getNames;
-  } else
-    alias T _getNames;
-}
-
-template getNames(char[] str) {
-  alias _getNames!(__getNames(str), "") getNames;
-}
-
-struct Struct(alias T) {
-  const type = "struct"; // used for pattern matching... apparently there's no other way
-  const name = fixType(T.stringof); // dmdfe bug: trailing space
-  alias STuple!(getNames!(T.tupleof.stringof)) names;
-  alias STuple!(getTypes!(T)) types;
-}
-
-struct Enum(alias T, bool list = false) {
-  const type = list ? "enumlist" : "enum"; // used for pattern matching... apparently there's no other way
-  const name =  T.stringof[1..$]; // dmdfe bug: returns enum base type instead enum type
-  alias evalType!("___"~name).tuple elements;
-}
-
-// determines the enumtype[] type
-template isEnumList(T : T[]) {
-  const isEnumList = T.stringof[0] == '_';
-}
-
-template isEnumList(T) {
-  const isEnumList = false;
-}
-
-template enumListType(T : T[]) {
-  alias T enumListType;
-}
-
-template enumListType(T) {
-  static assert(false, "Not enum list type!");
-}
-
-char[] createIParser(char[] field) {
-  return `_parseI("` ~ field ~ `") ~` \n;
-}
-
-char[] createBParser(char[] field) {
-  return `_parseB("` ~ field ~ `") ~` \n;
-}
- 
-char[] createSParser(char[] field) {
-  return `_parseS("` ~ field ~ `") ~` \n;
-}
- 
-char[] createLParser(char[] field) {
-  return `_parseList("` ~ field ~ `") ~` \n;
-}
-
-char[] createEParser(char[] field, char[] contents) {
-  return `_parseEnum!("` ~ field ~ `",` ~ contents ~ `) ~` \n;
-}
-
-char[] createELParser(char[] field, char[] contents) {
-  return `_parseEnumList!("` ~ field ~ `",` ~ contents ~ `) ~` \n;
-}
-
-template _makeEnumString(char[] t, E...) {
-  static if (E.length)
-    const _makeEnumString = `"` ~ E[0] ~ `", "` ~ t ~ "." ~ E[0] ~ `",` ~
-                            _makeEnumString!(t, E[1..$]);
-  else
-    const _makeEnumString = "";
-}
-
-// avoids the following dmdfe bugs:
-//  - Error: elements is not a type (typeof(T).elements)
-//  - Error: tuple is not a valid template value argument (T.elements where T is the complex type def)
-template makeEnumString(char[] t, T) {
-  const makeEnumString = _makeEnumString!(t, T.elements);
-}
-
-/**
- * Generates code for parsing data from the configuration data structure.
- */
-template makeTypeString(int i, N, T, char[] prefix) {
-  static assert(N.tuple.length == T.tuple.length);
-  static if (i < N.tuple.length) {
-    static if (is(T.tuple[i] == bool))
-      const makeTypeString = createBParser(prefix ~ N.tuple[i]) ~ makeTypeString!(i+1, N, T, prefix);
-    else static if (is(T.tuple[i] : int))
-      const makeTypeString = createIParser(prefix ~ N.tuple[i]) ~ makeTypeString!(i+1, N, T, prefix);
-    else static if (is(T.tuple[i] == char[]))
-      const makeTypeString = createSParser(prefix ~ N.tuple[i]) ~ makeTypeString!(i+1, N, T, prefix);
-    else static if (is(T.tuple[i] == char[][]))
-      const makeTypeString = createLParser(prefix ~ N.tuple[i]) ~ makeTypeString!(i+1, N, T, prefix);
-    else static if (is(T.tuple[i] == struct)) {
-      static if (T.tuple[i].type == "struct")
-        const makeTypeString = makeTypeString!(0, typeof(T.tuple[i].names),
-                               typeof(T.tuple[i].types), prefix~N.tuple[i]~".") ~
-                               makeTypeString!(i+1, N, T, prefix);
-      else static if (T.tuple[i].type == "enum")
-        const makeTypeString = createEParser(prefix ~ N.tuple[i],
-                               makeEnumString!(T.tuple[i].name, T.tuple[i])[0..$-1]) ~
-                               makeTypeString!(i+1, N, T, prefix);
-      else static if (T.tuple[i].type == "enumlist")
-        const makeTypeString = createELParser(prefix ~ N.tuple[i],
-                               makeEnumString!(T.tuple[i].name, T.tuple[i])[0..$-1]) ~
-                               makeTypeString!(i+1, N, T, prefix);
-      else {
-        const makeTypeString = "?" ~ makeTypeString!(i+1, N, T, prefix);
-        static assert(false, "Unknown type");
-      }
-    } else {
-      const makeTypeString = "?" ~ makeTypeString!(i+1, N, T, prefix);
-      static assert(false, "Unknown type");
-    }
-  } else
-    const makeTypeString = "";
-}
-
-template makeTypeStringForStruct(alias opt) {
-  const makeTypeStringForStruct = makeTypeString!(0, opt.names, opt.types, opt.name~".")[0..$-2];
-}
-
-/* some leftovers 
-template handleType(T, char[] prefix="") {
-  static if(is(typeof(T) == struct)) {
-    static if(T.type == "enum")
-      // another dmdfe weirdness: T.stringof == "Enum!(Type)" here, but if do
-      // alias T handleType;, the result.stringof is "struct Enum".
-      alias T handleType;
-  } else
-    alias T handleType;
-}
-*/
-
--- a/trunk/src/docgen/docgen.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.docgen;
-
-import docgen.graphutils.writers;
-import docgen.config.configurator;
-import docgen.document.latexgenerator;
-import docgen.document.htmlgenerator;
-import docgen.document.xmlgenerator;
-import docgen.document.plaintextgenerator;
-
-//import dil.Settings;
-import dil.SettingsLoader;
-
-import tango.core.Array;
-import tango.text.Text;
-import tango.io.Stdout;
-
-void usage() {
-  Stdout(
-    "Usage: docgen rootpath importpath_1 ... importpath_n outputdir"
-  ).newline;
-}
-
-void main(char[][] args) {
-  dil.SettingsLoader.loadSettings();
-
-  Stdout(docgen_version).newline.newline;
-
-  if (args.length<3) {
-    usage();
-    return;
-  }
-
-  Configurator config = new DefaultConfigurator();
-
-  auto options = config.getConfiguration();
-  options.parser.rootPaths = [ args[1] ];
-  options.parser.importPaths = args[2..$-1];
-  options.outputDir = args[$-1];
-
-  alias DepGraph.Vertex Vertex;
-  alias DepGraph.Edge Edge;
-
-  Module[] cachedModules;
-  DepGraph cachedGraph;
-
-  void parser(ref Module[] modules, ref DepGraph depGraph) {
-    Edge[] edges;
-    Vertex[char[]] vertices;
-
-    if (cachedGraph !is null) {
-      modules = cachedModules;
-      depGraph = cachedGraph;
-      return;
-    }
-
-    int id = 1;
-
-    Parser.loadModules(
-      options.parser.rootPaths,
-      options.parser.importPaths,
-      options.parser.strRegexps,
-      options.graph.includeUnlocatableModules,
-      options.parser.depth,
-      (char[] fqn, char[] path, Module m) {
-        if (m is null) {
-          if (fqn in vertices) {
-            debug Stdout.format("{} already set.\n", fqn);
-            return;
-          }
-          auto vertex = new Vertex(fqn, path, id++);
-          vertices[fqn] = vertex;
-          debug Stdout.format("Setting {} = {}.\n", fqn, path);
-        } else {
-          vertices[m.moduleFQN] = new Vertex(m.moduleFQN, m.filePath, id++);
-          debug Stdout.format("Setting {} = {}.\n", m.moduleFQN, m.filePath);
-        }
-      },
-      (Module imported, Module importer, bool isPublic, bool isStatic) {
-        debug Stdout.format("Connecting {} - {}.\n", imported.moduleFQN, importer.moduleFQN);
-        auto edge = vertices[imported.moduleFQN].addChild(vertices[importer.moduleFQN]);
-        edge.isPublic = isPublic;
-        edge.isStatic = isStatic;
-        edges ~= edge;
-      },
-      modules
-    );
-
-    modules.sort(
-      (Module a, Module b) { return ((new Text!(char)(a.moduleFQN)).compare(b.moduleFQN)) < 0; }
-    );
-
-    depGraph.edges = edges;
-    depGraph.vertices = vertices.values;
-
-    cachedGraph = depGraph;
-    cachedModules = modules;
-  }
-  
-  GraphCache graphcache = new DefaultGraphCache();
-
-  foreach(format; options.outputFormats) {
-    DocGenerator generator;
-
-    switch(format) {
-      case DocFormat.LaTeX:
-        Stdout("Generating LaTeX docs..");
-        generator = new LaTeXDocGenerator(*options, &parser, graphcache);
-        break;
-      case DocFormat.HTML:
-        Stdout("Generating HTML docs..");
-        generator = new HTMLDocGenerator(*options, &parser, graphcache);
-        break;
-      case DocFormat.XML:
-        Stdout("Generating XML docs..");
-        generator = new XMLDocGenerator(*options, &parser);
-        break;
-      case DocFormat.PlainText:
-        Stdout("Generating plain text docs..");
-        generator = new PlainTextDocGenerator(*options, &parser, graphcache);
-        break;
-      default: throw new Exception("Format not supported");
-    }
-
-    generator.generate();
-    Stdout("done.").newline;
-  }
-}
--- a/trunk/src/docgen/document/generator.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,147 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.document.generator;
-
-import docgen.misc.misc;
-import docgen.misc.parser;
-public import docgen.misc.options;
-import docgen.page.writers;
-import docgen.moduledoc.writers;
-import docgen.graphutils.writers;
-import docgen.sourcelisting.writers;
-import docgen.config.configurator;
-import tango.io.stream.FileStream;
-import tango.io.FilePath;
-import tango.io.FileScan;
-debug import tango.io.Stdout;
-
-
-alias void delegate(ref Module[], ref DepGraph) ParserDg;
-
-abstract class DefaultDocGenerator : DocGenerator {
-  protected:
-
-  DocFormat docFormat;
-  auto makeFile = "make.sh";
-  char[] genDir;
-
-  DocGeneratorOptions m_options;
-  ParserDg m_parser;
-  PageWriter docWriter;
-
-  GraphWriterFactory graphFactory;
-  PageWriterFactory pageFactory;
-  ListingWriterFactory listingFactory;
-  ModuleDocWriterFactory moduleDocFactory;
-  
-  Module[] modules;
-  DepGraph depGraph;
-
-  public:
-
-  this(DocGeneratorOptions options, ParserDg parser) {
-    m_options = options;
-    m_parser = parser;
-
-    createGraphWriterFactory();
-    createPageWriterFactory();
-    createListingWriterFactory();
-    createModuleDocWriterFactory();
-
-    // create output dir
-    (new FilePath(options.outputDir ~ "/" ~ genDir)).create();
-
-    // copy static files
-    copyStaticContent();
-  }
-
-  DocGeneratorOptions *options() {
-    return &m_options;
-  }
-
-  protected:
-
-  void createGraphWriterFactory() {
-    graphFactory = new DefaultGraphWriterFactory(this);
-  }
-
-  void createPageWriterFactory() {
-    pageFactory = new DefaultPageWriterFactory(this);
-  }
-
-  void createListingWriterFactory() {
-    listingFactory = new DefaultListingWriterFactory(this);
-  }
-
-  void createModuleDocWriterFactory() {
-    moduleDocFactory = new DefaultModuleDocWriterFactory(this);
-  }
-
-  char[] outPath(char[] file) {
-    return options.outputDir ~ "/" ~ genDir ~ "/" ~ file;
-  }
-
-  void copyStaticContent() {
-    auto scan = new FileScan();
-    scan(templateDir~options.templates.templateStyle~"/"~formatDirs[docFormat]~"/static/");
-
-    foreach(filePath; scan.files) {
-      (new FilePath(outPath(filePath.file))).copy(filePath.toString());
-    }
-
-    debug Stdout(scan.files.length)(" static files copied.\n");
-  }
-
-  FileOutput outputFile(char[] fname) {
-    return new FileOutput(outPath(fname));
-  }
-
-  void parseSources() {
-    depGraph = new DepGraph();
-    m_parser(modules, depGraph);
-  }
-
-  //---
-
-  void writeSimpleFile(char[] fname, void delegate() dg) {
-    auto docFile = outputFile(fname);
-
-    docWriter.setOutput([docFile]);
-    dg();
-
-    docFile.close();
-  }
-
-  /**
-   * Generates "makefile" for processing e.g. .dot files.
-   */
-  void generateMakeFile(char[][] args ...) {
-    writeSimpleFile(makeFile, { docWriter.generateCustomPage("makefile", args); } );
-  }
-  
-}
-
-abstract class DefaultCachingDocGenerator : DefaultDocGenerator, CachingDocGenerator {
-  private:
-    
-  GraphCache m_graphCache;
-
-  public:
-
-  this(DocGeneratorOptions options, ParserDg parser, GraphCache graphCache) {
-    super(options, parser);
-    m_graphCache = graphCache;
-  }
-  
-  GraphCache graphCache() {
-    return m_graphCache;
-  }
-
-  protected:
-
-  void createGraphWriterFactory() {
-    graphFactory = new DefaultCachingGraphWriterFactory(this);
-  }
-}
--- a/trunk/src/docgen/document/htmlgenerator.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.document.htmlgenerator;
-
-import docgen.document.generator;
-import docgen.misc.misc;
-import tango.io.stream.FileStream;
-import tango.text.Util : replace;
-
-class HTMLDocGenerator : DefaultCachingDocGenerator {
-  private:
-
-  auto docFileNames = [
-    "index.html"[], "toc.html"[], "classes.html"[],
-    "modules.html"[], "files.html"[]
-  ];
-
-  auto depGraphFile = "depgraph.dot";
-  auto depGraphDocFile = "depgraph.html";
-  auto styleSheetFile = "default.css";
-
-  public:
-
-  this(DocGeneratorOptions options, ParserDg parser, GraphCache graphcache) {
-    genDir = "html";
-    docFormat = DocFormat.HTML;
-    super(options, parser, graphcache);
-  }
-
-  /**
-   * Generates the documentation.
-   */
-  void generate() {
-    parseSources();
-
-    docWriter = pageFactory.createPageWriter( null, docFormat );
-
-    // stylesheet needs to be created first to propagate the css file name
-    generateStyleSheet();
-
-    generateDoc();
-
-    if (options.listing.enableListings)
-      generateListings();
-
-    generateClasses();
-    generateModules();
-    generateDependencies();
-    generateMakeFile(imageFormatExts[options.graph.imageFormat]);
-  }
-
-  protected:
-
-  /**
-   * Generates document skeleton.
-   */
-  void generateDoc() {
-    writeSimpleFile(docFileNames[0], {
-      docWriter.generateFirstPage();
-    });
-    /*
-    writeSimpleFile(docFileNames[1], {
-      docWriter.generateTOC(modules);
-      docWriter.generateCustomPage("pagetemplate2", docgen_version);
-    });*/
-  }
-
-  /**
-   * Generates a global style sheet.
-   */
-  void generateStyleSheet() {
-    writeSimpleFile(styleSheetFile, {
-      docWriter.generateCustomPage("stylesheet");
-    });
-  }
-
-  /**
-   * Generates documentation for classes.
-   */
-  void generateClasses() {
-    writeSimpleFile(docFileNames[2], {
-      docWriter.generateClassSection();
-      docWriter.generateCustomPage("pagetemplate2", docgen_version);
-    });
-  }
-
-  /**
-   * Generates documentation for modules.
-   */
-  void generateModules() {
-    writeSimpleFile(docFileNames[3], {
-      docWriter.generateModuleSection(modules);
-      docWriter.generateCustomPage("pagetemplate2", docgen_version);
-    });
-    
-//    auto mdw = moduleDocFactory.createModuleDocWriter(docWriter, docFormat);
-
-  }
-
-  /**
-   * Generates source file listings.
-   */
-  void generateListings() {
-    writeSimpleFile(docFileNames[4], {
-      docWriter.generateListingSection(modules);
-
-      char[][] contents;
-
-      contents ~= "(";
-
-      foreach(mod; modules) {
-        auto FQN = mod.moduleFQN;
-        auto dstFname = replace(mod.moduleFQN.dup, '.', '_') ~ ".html";
-        contents ~= `<a href="` ~ dstFname ~ `">` ~ FQN ~ "</a>";
-      }
-
-      contents ~= ")";
-
-      docWriter.addList(contents, false);
-
-      docWriter.generateCustomPage("pagetemplate2", docgen_version);
-    });
-
-    auto writer = listingFactory.createListingWriter(docWriter, docFormat);
-
-    foreach(mod; modules) {
-      auto dstFname = replace(mod.moduleFQN.dup, '.', '_') ~ ".html";
-
-      writeSimpleFile(dstFname, {
-        auto srcFile = new FileInput(mod.filePath);
-        writer.generateListing(srcFile, null, mod.moduleFQN);
-        srcFile.close();
-      });
-    }
-  }
-
-  /**
-   * Generates dependency graphs.
-   */
-  void generateDependencies() {
-    writeSimpleFile(depGraphDocFile, {
-      docWriter.generateDepGraphSection();
-
-      auto imgFile = outputFile(depGraphFile);
-
-      auto writer = graphFactory.createGraphWriter( docWriter, GraphFormat.Dot );
-      writer.generateDepGraph(depGraph, imgFile);
-
-      imgFile.close();
-
-      docWriter.generateCustomPage("pagetemplate2", docgen_version);
-    });
-  }
-}
--- a/trunk/src/docgen/document/latexgenerator.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.document.latexgenerator;
-
-import docgen.document.generator;
-import docgen.misc.misc;
-import tango.io.stream.FileStream;
-import tango.text.Util : replace;
-
-/**
- * Main routine for LaTeX doc generation.
- */
-class LaTeXDocGenerator : DefaultCachingDocGenerator {
-  private:
-
-  auto docFileName = "document.tex";
-  auto depGraphDocFile = "dependencies.tex";
-  auto depGraphFile = "depgraph.dot";
-  auto listingFile = "files.tex";
-  auto modulesFile = "modules.tex";
-
-  public:
-
-  this(DocGeneratorOptions options, ParserDg parser, GraphCache graphcache) {
-    genDir = "latex";
-    docFormat = DocFormat.LaTeX;
-
-    super(options, parser, graphcache);
-  }
-
-  /**
-   * Generates the documentation.
-   */
-  void generate() {
-    parseSources();
-
-    generateDoc();
-
-    if (options.listing.enableListings)
-      generateListings();
-
-    generateClasses();
-    generateModules();
-    generateDependencies();
-    generateMakeFile(docFileName, "pdf");
-  }
-
-  protected:
-
-  /**
-   * Generates document skeleton.
-   */
-  void generateDoc() {
-    auto docFile = outputFile(docFileName);
-    docWriter = pageFactory.createPageWriter( [ docFile ], docFormat );
-
-    docWriter.generateFirstPage();
-    docWriter.generateTOC(modules);
-    docWriter.generateClassSection();
-    docWriter.generateModuleSection(modules);
-    docWriter.generateListingSection(modules);
-    docWriter.generateDepGraphSection();
-    docWriter.generateIndexSection();
-    docWriter.generateLastPage();
-
-    docFile.close();
-  }
-
-  /**
-   * Generates documentation for classes.
-   */
-  void generateClasses() {
-    auto docFile = outputFile(modulesFile);
-    docFile.close();
-  }
-
-  /**
-   * Generates documentation for modules.
-   */
-  void generateModules() {
-    auto docFile = outputFile(modulesFile);
-    docFile.close();
-  }
-
-  /**
-   * Generates source file listings.
-   */
-  void generateListings() {
-    writeSimpleFile(listingFile, {
-      auto writer = listingFactory.createListingWriter(docWriter, docFormat);
-
-      foreach(mod; modules) {
-        auto dstFname = replace(mod.moduleFQN.dup, '.', '_') ~ ".d";
-        
-        auto srcFile = new FileInput(mod.filePath);
-        auto dstFile = outputFile(dstFname);
-        
-        writer.generateListing(srcFile, dstFile, mod.moduleFQN);
-
-        srcFile.close();
-        dstFile.close();
-      }
-    });
-  }
-
-  /**
-   * Generates dependency graphs.
-   */
-  void generateDependencies() {
-    writeSimpleFile(depGraphDocFile, {
-      auto imgFile = outputFile(depGraphFile);
-
-      auto writer = graphFactory.createGraphWriter( docWriter, GraphFormat.Dot );
-      writer.generateDepGraph(depGraph, imgFile);
-
-      imgFile.close();
-    });
-  }
-}
--- a/trunk/src/docgen/document/plaintextgenerator.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.document.plaintextgenerator;
-
-import docgen.document.generator;
-import docgen.misc.misc;
-import tango.io.stream.FileStream;
-import tango.io.FilePath;
-import tango.text.Util : replace;
-
-class PlainTextDocGenerator : DefaultCachingDocGenerator {
-  private:
-
-  auto docFileNames = [
-    "index.txt"[], "toc.txt"[], "classes.txt"[],
-    "modules.txt"[], "files.txt"[]
-  ];
-
-  auto depGraphFile = "depgraph.dot";
-  auto depGraphDocFile = "depgraph.txt";
-
-  public:
-
-  this(DocGeneratorOptions options, ParserDg parser, GraphCache graphcache) {
-    genDir = "txt";
-    docFormat = DocFormat.PlainText;
-    
-    super(options, parser, graphcache);
-  }
-
-  /**
-   * Generates the documentation.
-   */
-  void generate() {
-    parseSources();
-
-    docWriter = pageFactory.createPageWriter( null, docFormat );
-
-    generateDoc();
-
-    if (options.listing.enableListings)
-      generateListings();
-
-    generateClasses();
-    generateModules();
-    generateDependencies();
-    generateMakeFile(imageFormatExts[options.graph.imageFormat]);
-  }
-
-  protected:
-
-  /**
-   * Generates document skeleton.
-   */
-  void generateDoc() {
-    writeSimpleFile(docFileNames[0], {
-      docWriter.generateFirstPage();
-    });
-    
-    writeSimpleFile(docFileNames[1], {
-      docWriter.generateTOC(modules);
-    });
-  }
-
-  /**
-   * Generates documentation for classes.
-   */
-  void generateClasses() {
-    writeSimpleFile(docFileNames[2], {
-      docWriter.generateClassSection();
-    });
-  }
-
-  /**
-   * Generates documentation for modules.
-   */
-  void generateModules() {
-    writeSimpleFile(docFileNames[3], {
-      docWriter.generateModuleSection(modules);
-    });
-  }
-
-  /**
-   * Generates source file listings.
-   */
-  void generateListings() {
-    writeSimpleFile(docFileNames[4], {
-      docWriter.generateListingSection(modules);
-
-      char[][] contents;
-
-      foreach(mod; modules) {
-        auto FQN = mod.moduleFQN;
-        contents ~= FQN ~ " (see " ~ replace(FQN.dup, '.', '_') ~ ".d)";
-      }
-
-      docWriter.addList(contents, false);
-    });
-
-    foreach(mod; modules)
-      (new FilePath(outPath(replace(mod.moduleFQN.dup, '.', '_') ~ ".d"))).copy(mod.filePath);
-  }
-
-  /**
-   * Generates dependency graphs.
-   */
-  void generateDependencies() {
-    writeSimpleFile(depGraphDocFile, {
-      docWriter.generateDepGraphSection();
-
-      auto imgFile = outputFile(depGraphFile);
-
-      auto writer = graphFactory.createGraphWriter( docWriter, GraphFormat.Dot );
-      writer.generateDepGraph(depGraph, imgFile);
-
-      imgFile.close();
-    });
-  }
-}
--- a/trunk/src/docgen/document/xmlgenerator.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.document.xmlgenerator;
-
-import docgen.document.generator;
-import docgen.misc.misc;
-import tango.io.stream.FileStream;
-import tango.text.Util : replace;
-
-class XMLDocGenerator : DefaultDocGenerator {
-  public:
-
-  this(DocGeneratorOptions options, ParserDg parser) {
-    genDir = "xml";
-    docFormat = DocFormat.XML;
-
-    super(options, parser);
-  }
-
-  void generate() { /* TODO */ }
-}
--- a/trunk/src/docgen/graphutils/dotwriter.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,170 +0,0 @@
-/**
- * Author: Aziz Köksal & Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.graphutils.dotwriter;
-import docgen.graphutils.writer;
-
-import tango.io.Print: Print;
-import tango.text.convert.Layout : Layout;
-import tango.io.FilePath;
-import tango.text.Util;
-import tango.text.convert.Sprint;
-debug import tango.io.Stdout;
-
-/**
- * Creates a graph rule file for the dot utility.
- */
-class DotWriter : AbstractGraphWriter {
-  public:
-
-  this(GraphWriterFactory factory, PageWriter writer) {
-    super(factory, writer);
-  }
-
-  void generateDepGraph(DepGraph depGraph, OutputStream imageFile) {
-    generateImageTag(imageFile);
-    
-    auto image = generateDepImageFile(depGraph);
-    auto printer = new Print!(char)(new Layout!(char), imageFile);
-    printer(image);
-  }
-
-  protected:
-
-  char[] generateDepImageFile(DepGraph depGraph) {
-    char[] image;
-    auto sprint = new Sprint!(char);
-    
-    auto edges = depGraph.edges;
-    auto vertices = depGraph.vertices;
-
-    DepGraph.Vertex[][char[]] verticesByPckgName;
-    if (factory.options.graph.groupByFullPackageName ||
-        factory.options.graph.groupByPackageNames) {
-      foreach (mod; vertices) {
-        auto parts = mod.name.delimit(".");
-
-        if (parts.length>1) {
-          auto pkg = parts[0..$-1].join(".");
-          verticesByPckgName[pkg] ~= mod;
-        }
-      }
-    }
-
-    if (factory.options.graph.highlightCyclicVertices ||
-        factory.options.graph.highlightCyclicEdges)
-      depGraph.markCycles();
-
-    image ~= "Digraph ModuleDependencies {\n";
-
-    foreach (module_; vertices) {
-      auto nodeName = 
-        factory.options.graph.groupByPackageNames ?
-        module_.name.split(".")[$-1] :
-        module_.name;
-
-      image ~= sprint.format(
-        `  n{} [label="{}",style=filled,fillcolor={}];`\n,
-        module_.id,
-        nodeName,
-        module_.cyclic && factory.options.graph.highlightCyclicVertices ?
-          factory.options.graph.cyclicNodeColor :
-        module_.incoming.length == 0 && module_.outgoing.length == 0 ?
-          factory.options.graph.unlocatableNodeColor :
-          factory.options.graph.nodeColor
-      );
-    }
-
-    foreach (edge; edges)
-      image ~= sprint.format(
-        `  n{} -> n{}[color={}];`\n,
-        edge.outgoing.id,
-        edge.incoming.id,
-        edge.cyclic ?
-          factory.options.graph.cyclicDepColor :
-        edge.isPublic ?
-          factory.options.graph.publicDepColor ~ ",style=bold" :
-          factory.options.graph.depColor
-      );
-
-    if (factory.options.graph.groupByPackageNames)
-
-      if (!factory.options.graph.groupByFullPackageName) {
-        foreach (packageName, vertices; verticesByPckgName) {
-          auto name = packageName.split(".");
-
-          if (name.length > 1) {
-            char[] pkg;
-            foreach(part; name) {
-              pkg ~= part ~ ".";
-              image ~= sprint.format(
-                `subgraph "cluster_{0}" {{`\n`  label="{0}"`\n,
-                pkg[0..$-1],
-                pkg[0..$-1]
-              );
-            }
-            for (int i=0; i< name.length; i++) {
-              image ~= "}\n";
-            }
-          }
-        }
-      }
-      foreach (packageName, vertices; verticesByPckgName) {
-        image ~= sprint.format(
-          `  subgraph "cluster_{0}" {{`\n`  label="{0}";color=`
-          ~ factory.options.graph.clusterColor ~ `;`\n`  `,
-          packageName,
-          packageName
-        );
-
-        foreach (module_; vertices)
-          image ~= sprint.format(`n{0};`, module_.id);
-        image ~= "\n  }\n";
-      }
-
-    image ~= "}";
-
-    return image;
-  }
-        
-  void generateImageTag(OutputStream imageFile) {
-    // name of the .dot file
-    char[] fn = (cast(Object)imageFile.conduit).toString();
-    fn = FilePath(fn).file;
-
-    fn = fn[0..$-3] ~ imageFormatExts[factory.options.graph.imageFormat];
-    
-    writer.addGraphics(fn);
-  } 
-}
-
-class CachingDotWriter : DotWriter {
-  private:
-
-  CachingGraphWriterFactory factory;
-
-  public:
-
-  this(CachingGraphWriterFactory factory, PageWriter writer) {
-    super(factory, writer);
-    this.factory = factory;
-  }
-
-  override void generateDepGraph(DepGraph depGraph, OutputStream imageFile) {
-    generateImageTag(imageFile);
-
-    auto cached = factory.graphCache.getCachedGraph(depGraph, GraphFormat.Dot);
-
-    auto printer = new Print!(char)(new Layout!(char), imageFile);
-    
-    if (cached) {
-      printer(cached);
-    } else {
-      auto image = generateDepImageFile(depGraph);
-      factory.graphCache.setCachedGraph(depGraph, GraphFormat.Dot, image);
-      printer(image);
-    }
-  }
-}
-
--- a/trunk/src/docgen/graphutils/modulenamewriter.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/**
- * Author: Aziz Köksal & Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.graphutils.modulenamewriter;
-import docgen.graphutils.writer;
-
-import tango.io.Print: Print;
-import tango.text.convert.Layout : Layout;
-
-class ModuleNameWriter : AbstractGraphWriter {
-  public:
-
-  this(GraphWriterFactory factory, PageWriter writer) {
-    super(factory, writer);
-  }
-
-  void generateDepGraph(DepGraph depGraph, OutputStream imageFile) {
-    char[][] contents;
-
-    auto edges = depGraph.edges;
-    auto vertices = depGraph.vertices;
-
-    void doList(DepGraph.Vertex[] v, uint level) {
-      if (!level) return;
-
-      contents ~= "(";
-
-      foreach (vertex; v) {
-        contents ~= vertex.name;
-        if (vertex.outgoing.length)
-          doList(vertex.outgoing, level-1);
-      }
-
-      contents ~= ")";
-    }
-
-    doList(vertices, factory.options.graph.depth);
-
-    writer.addList(contents, false);
-  }
-}
--- a/trunk/src/docgen/graphutils/modulepathwriter.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/**
- * Author: Aziz Köksal & Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.graphutils.modulepathwriter;
-import docgen.graphutils.writer;
-
-import tango.io.Print: Print;
-import tango.text.convert.Layout : Layout;
-
-class ModulePathWriter : AbstractGraphWriter {
-  public:
-
-  this(GraphWriterFactory factory, PageWriter writer) {
-    super(factory, writer);
-  }
-
-  void generateDepGraph(DepGraph depGraph, OutputStream imageFile) {
-    char[][] contents;
-
-    auto edges = depGraph.edges;
-    auto vertices = depGraph.vertices;
-
-    void doList(DepGraph.Vertex[] v, uint level) {
-      if (!level) return;
-
-      contents ~= "(";
-
-      foreach (vertex; v) {
-        contents ~= vertex.location;
-        if (vertex.outgoing.length)
-          doList(vertex.outgoing, level-1);
-      }
-
-      contents ~= ")";
-    }
-
-    doList(vertices, factory.options.graph.depth);
-
-    writer.addList(contents, false);
-  }
-}
--- a/trunk/src/docgen/graphutils/primitives.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/**
- * Author: Aziz Köksal & Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.graphutils.primitives;
-
-/**
- * Extendible graph class. Should support separation of concerns now better with mixins.
- * Provides a method for cycle marking.
- */
-class Graph(alias V, alias E, int capacity = 1) {
-  static class Edge {
-    Vertex outgoing, incoming;
-    //bool cyclic = true;
-
-    this(Vertex o, Vertex i) {
-      outgoing = o;
-      incoming = i;
-      o.outgoingEdges ~= this;
-      i.incomingEdges ~= this;
-    }
-
-    bool cyclic() {
-      return outgoing.cyclic && incoming.cyclic;
-    }
-
-    mixin E;
-  }
-
-  static class Vertex {
-    Edge[] incomingEdges;
-    Edge[] outgoingEdges;
-    bool cyclic = true;
-
-    Edge addChild(Vertex v) {
-      return new Edge(v, this);
-    }
-
-    Edge addParent(Vertex v) {
-      return v.addChild(this);
-    }
-
-    Vertex[] incoming() {
-      Vertex[] tmp;
-
-      foreach(edge; incomingEdges)
-        tmp ~= edge.outgoing;
-
-      return tmp;
-    }
-
-    Vertex[] outgoing() {
-      Vertex[] tmp;
-
-      foreach(edge; outgoingEdges)
-        tmp ~= edge.incoming;
-
-      return tmp;
-    }
-
-    mixin V;
-  }
-
-  Vertex[] vertices;
-  Edge[] edges;
-
-  this() {
-    vertices.length = capacity;
-    vertices.length = 0;
-    edges.length = capacity;
-    edges.length = 0;
-  }
-
-  void add(Vertex vertex) { vertices ~= vertex; }
-
-  void add(Edge edge) { edges ~= edge; }
-
-  void connect(Vertex from, Vertex to) { edges ~= from.addParent(to); }
-
-  void connect(int from, int to) { connect(vertices[from], vertices[to]); }
-
-  /**
-   * Starts from non-cyclic nodes and propagates two both directions.
-   * Bugs: marks non-cyclic imports between two cycles as cyclic. Could be fixed later if it's really needed (slow)
-   */
-  void markCycles() {
-    void mark(Vertex v) {
-      v.cyclic = false;
-      foreach(o; v.outgoing) {
-        if (!o.cyclic) continue;
-
-        // propagate
-        bool cyclic = false;
-        foreach(p; o.incoming) if (p.cyclic) { cyclic = true; break; }
-        if (!cyclic) mark(o);
-      }
-    }
-
-    void mark2(Vertex v) {
-      v.cyclic = false;
-      foreach(o; v.incoming) {
-        if (!o.cyclic) continue;
-
-        // propagate
-        bool cyclic = false;
-        foreach(p; o.outgoing) if (p.cyclic) { cyclic = true; break; }
-        if (!cyclic) mark2(o);
-      }
-    }
-
-    foreach(e; vertices)
-      if (e.cyclic) {
-        if (!e.incoming.length) mark(e);
-        if (!e.outgoing.length) mark2(e);
-      }
-  }
-}
-
-template Empty() {}
-
-
-// graph elements used in dep graphs
-
-
-template DepEdge() {
-  bool isPublic; /// Public import.
-  bool isStatic; /// Static import.
-}
-
-template DepVertex() {
-  char[] name;
-  char[] location;
-  uint id;
-
-  this(char[] name, char[] location, uint id = 0) {
-    this.name = name;
-    this.location = location;
-    this.id = id;
-  }
-}
-
-alias Graph!(DepVertex, DepEdge, 100) DepGraph;
--- a/trunk/src/docgen/graphutils/writer.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.graphutils.writer;
-
-public import docgen.misc.misc;
-public import docgen.graphutils.primitives;
-public import docgen.page.writer;
-debug import tango.io.Stdout;
-
-interface GraphWriter {
-  void generateDepGraph(DepGraph depGraph, OutputStream imageFile);
-}
-
-interface GraphWriterFactory : WriterFactory {
-  GraphWriter createGraphWriter(PageWriter writer, GraphFormat outputFormat);
-}
-
-interface CachingGraphWriterFactory : GraphWriterFactory {
-  GraphCache graphCache();
-}
-/+
-/**
- * Marks all cycles in the graph.
- *
- * May have bugs, but is a bit simpler than the previous version.
- */
-void findCycles(Vertex[] vertices, Edge[] edges) {
-  debug void p() {
-    foreach(e; edges) Stderr(e.type)(" "c);
-    Stderr.newline;
-  }
-
-  bool visit(Edge edge) {
-    if (edge.cycleType == CycleType.Reserved) {
-      edge.cycleType = CycleType.Cyclic;
-      version(VerboseDebug) p();
-      return true;
-    }
-
-    bool wasCyclic = edge.isCyclic();
-    edge.cycleType = CycleType.Reserved;
-    version(VerboseDebug) p();
-
-    foreach(edge2; edge.incoming.outgoingEdges)
-      if (visit(edge2)) {
-        if (edge.isCyclic()) {
-          edge.cycleType = CycleType.Reserved;
-          wasCyclic = true;
-          version(VerboseDebug) p();
-          continue;
-        }
-        edge.cycleType = CycleType.Cyclic;
-        return true;
-      }
-
-    edge.cycleType = wasCyclic ? CycleType.Cyclic : CycleType.Cyclefree;
-    version(VerboseDebug) p();
-    return false;
-  }
-
-  foreach(vertex; vertices)
-    foreach(edge; vertex.outgoingEdges)
-      if (edge.cycleType == CycleType.Unspecified) {
-        visit(edge);
-        debug Stderr("*\n");
-      }
-}
-+/
-
-abstract class AbstractGraphWriter : AbstractWriter!(GraphWriterFactory), GraphWriter {
-  protected:
-
-  PageWriter writer;
-  
-  public:
-
-  this(GraphWriterFactory factory, PageWriter writer) {
-    super(factory);
-    this.writer = writer;
-  }
-}
-
-class DefaultGraphCache : GraphCache {
-  private:
-    
-  char[][Object][GraphFormat] m_graphCache;
-
-  public:
-
-  char[] getCachedGraph(Object graph, GraphFormat format) {
-    debug Stdout("Starting graph lookup\n");
-    debug Stdout(&graph, format).newline;
-    debug Stdout(&m_graphCache).newline;
-    
-    auto lookup1 = format in m_graphCache;
-    if (lookup1) {
-      auto lookup2 = graph in *lookup1;
-      if (lookup2) {
-          return *lookup2;
-      }
-    }
-    debug Stdout("Graph cache miss!\n");
-    return null;
-  }
-
-  void setCachedGraph(Object graph, GraphFormat format, char[]
-      contents) {
-    m_graphCache[format][graph] = contents;
-    debug Stdout("Graph cache updated!\n");
-  }
-}
--- a/trunk/src/docgen/graphutils/writers.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.graphutils.writers;
-
-public import docgen.graphutils.writer;
-import docgen.graphutils.dotwriter;
-import docgen.graphutils.modulepathwriter;
-import docgen.graphutils.modulenamewriter;
-
-class DefaultGraphWriterFactory : AbstractWriterFactory, GraphWriterFactory {
-  public:
-
-  this(DocGenerator generator) {
-    super(generator);
-  }
-
-  GraphWriter createGraphWriter(PageWriter writer, GraphFormat outputFormat) {
-    switch (outputFormat) {
-      case GraphFormat.Dot:
-        return new DotWriter(this, writer);
-      case GraphFormat.ModuleNames:
-        return new ModuleNameWriter(this, writer);
-      case GraphFormat.ModulePaths:
-        return new ModulePathWriter(this, writer);
-      default:
-        throw new Exception("Graph writer type does not exist!");
-    }
-  }
-}
-
-class DefaultCachingGraphWriterFactory : AbstractWriterFactory, CachingGraphWriterFactory {
-  public:
-
-  CachingDocGenerator generator;
-
-  this(CachingDocGenerator generator) {
-    super(generator);
-    this.generator = generator;
-  }
-
-  GraphCache graphCache() {
-    return generator.graphCache;
-  }
-
-  override GraphWriter createGraphWriter(PageWriter writer, GraphFormat outputFormat) {
-    switch (outputFormat) {
-      case GraphFormat.Dot:
-        return new CachingDotWriter(this, writer);
-      case GraphFormat.ModuleNames:
-        return new ModuleNameWriter(this, writer);
-      case GraphFormat.ModulePaths:
-        return new ModulePathWriter(this, writer);
-      default:
-        throw new Exception("Graph writer type does not exist!");
-    }
-  }
-}
--- a/trunk/src/docgen/lstlang0.sty	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-%%
-%% D definition (c) 2007 Jari-Matti Mäkelä
-%%
-\lst@definelanguage{D}%
-  {morekeywords={abstract,alias,align,asm,assert,auto,body,bool,break,%
-      byte,case,cast,catch,cdouble,cent,cfloat,char,class,const,continue,%
-      creal,dchar,debug,default,delegate,delete,deprecated,do,double,%
-      else,enum,export,extern,false,final,finally,float,for,foreach,%
-      foreach_reverse,function,goto,idouble,if,ifloat,import,in,inout,%
-      int,interface,invariant,ireal,is,lazy,long,macro,mixin,module,new,%
-      null,out,override,package,pragma,private,protected,public,real,ref,%
-      return,scope,short,static,struct,super,switch,synchronized,template,%
-      this,throw,true,try,typedef,typeid,typeof,ubyte,ucent,uint,ulong,%
-      union,unittest,ushort,version,void,volatile,wchar,while,with},%
-   sensitive,%
-   morecomment=[s]{/*}{*/},%
-   morecomment=[n]{/+}{+/},%
-   morecomment=[l]//,%
-   morestring=[b]",%
-   morestring=[b]`%
-  }[keywords,comments,strings]%
\ No newline at end of file
--- a/trunk/src/docgen/misc/meta.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.misc.meta;
-
-/// tuple literal workaround
-template Tuple(T...) { alias T Tuple; }
-
-/// another tuple literal workaround (can be nested & avoids at least one dmdfe bug)
-struct STuple(T...) { alias T tuple; }
-
-
-// (a -> b), [a] -> [b]
-template map(alias S, T...) {
-  static if (T.length)
-    alias Tuple!(S!(T[0]), map!(S, T[1..$])) map;
-  else
-    alias T map;
-}
-
-/// (a -> Bool), [a] -> [a]
-template filter(alias S, T...) {
-  static if (!T.length)
-    alias Tuple!() filter;
-  else static if (S!(T[0]))
-    alias Tuple!(T[0], filter!(S, T[1..$])) filter;
-  else
-    alias filter!(S, T[1..$]) filter;
-}
-
-/// Int -> Bool
-template odd(int T) {
-  const odd = T%2 == 1;
-}
-
-/// Int -> Bool
-template even(int T) {
-  const even = !odd!(T);
-}
-
-/// a [a] -> a  -- max x y = max2 x (max y)
-T max(T, U...)(T a, U b) {
-  static if (b.length)
-    return a > max(b) ? a : max(b);
-  else
-    return a;
-}
-
-/// a [a] -> a  -- min x y = min2 x (min y)
-T min(T, U...)(T a, U b) {
-  static if (b.length)
-    return a < min(b) ? a : min(b);
-  else
-    return a;
-}
-
-/// Upcasts derivatives of B to B
-template UpCast(B, T) { alias T UpCast; }
-template UpCast(B, T : B) { alias B UpCast; }
-
-/// converts integer to ascii, base 10
-char[] itoa(int i) {
-  char[] ret;
-  auto numbers = "0123456789ABCDEF";
-
-  do {
-    ret = numbers[i%10] ~ ret;
-    i /= 10;
-  } while (i)
-
-  return ret;
-}
-
-/// Enum stuff
-
-template _genList(char[] pre, char[] post, T...) {
-  static if (T.length)
-    const _genList = pre ~ T[0] ~ post ~ (T.length>1 ? "," : "") ~
-                     _genList!(pre, post, T[1..$]);
-  else
-    const _genList = ``;
-}
-
-/**
- * Creates
- *   - a typedef for enum (workaround for .tupleof.stringof)
- *   - the enum structure
- *   - string array of enum items (for runtime programming)
- *   - string tuple of enum items (for metaprogramming - char[][] doesn't work)
- */
-template createEnum(char[] tName, char[] eName, char[] arName, char[] alName, T...) {
-  const createEnum =
-    "typedef int " ~ tName ~ ";" ~
-    "enum " ~ eName ~ ":" ~ tName ~ "{" ~ _genList!("", "", T) ~ "};" ~
-    "char[][] " ~ arName ~ "=[" ~ _genList!(`"`, `"[]`, T) ~ "];" ~
-    "alias STuple!(" ~ _genList!(`"`, `"`, T) ~ ") " ~ alName ~ ";";
-}
--- a/trunk/src/docgen/misc/misc.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.misc.misc;
-import docgen.misc.options;
-import tango.io.model.IConduit : OutputStream;
-
-char[] docgen_version = "Dil document generator 0.1";
-
-interface DocGenerator {
-  DocGeneratorOptions *options();
-  void generate();
-}
-
-interface GraphCache {  
-  char[] getCachedGraph(Object graph, GraphFormat format);
-  void setCachedGraph(Object graph, GraphFormat format, char[] contents);
-}
-
-interface CachingDocGenerator : DocGenerator {
-  GraphCache graphCache();
-}
-
-interface WriterFactory {
-  DocGeneratorOptions *options();
-}
-
-abstract class AbstractWriterFactory : WriterFactory {
-  protected DocGenerator generator;
-
-  public:
-  
-  DocGeneratorOptions *options() {
-    return generator.options;
-  }
-
-  this(DocGenerator generator) {
-    this.generator = generator;
-  }
-}
-
-
-template AbstractWriter(T, int n = 0) {
-  abstract class AbstractWriter {
-    protected T factory;
-    protected OutputStream[] outputs;
-  
-    static if (n > 0) {
-      this(T factory, OutputStream[] outputs) {
-        this.factory = factory;
-        this.outputs = outputs;
-        assert(outputs.length == n, "Incorrect number of outputs");
-      }
-    }
-
-    this(T factory) {
-      this.factory = factory;
-    }
-  }
-}
--- a/trunk/src/docgen/misc/options.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.misc.options;
-
-import docgen.misc.meta;
-
-/** creates reflective enums, syntax: enum name + list of elements */
-template optionEnum(char[] name, T...) {
-  const optionEnum = createEnum!("_" ~ name, name, "__" ~ name, "___" ~ name, T);
-}
-
-/** Supported document output formats. */
-mixin(optionEnum!("DocFormat", "LaTeX", "XML", "HTML", "PlainText"));
-
-/**
- * Supported comment formats.
- * 
- * http://www.stack.nl/~dimitri/doxygen/docblocks.html
- * http://www.digitalmars.com/d/ddoc.html
- */
-mixin(optionEnum!("CommentFormat", "Ddoc", "Doxygen"));
-
-/** Supported image formats. */
-mixin(optionEnum!("ImageFormat", "PNG", "SVG", "GIF", "PDF"));
-
-/** Image format extensions. */
-const imageFormatExts = [ "png", "svg", "gif", "pdf" ];
-
-/** Supported graph writers. */
-mixin(optionEnum!("GraphFormat", "Dot", "ModuleNames", "ModulePaths"));
-
-struct GraphOptions {
-  /// image format to use for graphs
-  ImageFormat imageFormat;
-  /// maximum depth of dependencies in graphs
-  uint depth;
-  /// color of normal modules
-  char[] nodeColor;
-  /// color of the modules in cyclic dep relation
-  char[] cyclicNodeColor;
-  /// unlocatable module color
-  char[] unlocatableNodeColor;
-  /// color of the dependencies
-  char[] depColor;
-  /// color of the dependencies in cyclic dep relation
-  char[] cyclicDepColor;
-  /// color of the public dependencies
-  char[] publicDepColor;
-  /// package color
-  char[] clusterColor;
-  /// include unlocatable modules to the dep graph
-  bool includeUnlocatableModules;
-  /// highlight imports in cyclic dep relation
-  bool highlightCyclicEdges;
-  /// highlight modules in cyclic dep relation
-  bool highlightCyclicVertices;
-  /// group modules by package names in dep graph
-  bool groupByPackageNames;
-  /// group modules hierarchically or by full package name
-  bool groupByFullPackageName;
-}
-
-struct ListingOptions {
-  /// use literate programming symbols [LaTeX]
-  bool literateStyle;
-  /// enable source code listings
-  bool enableListings;
-}
-
-struct TemplateOptions {
-  /// project title
-  char[] title;
-  /// project version
-  char[] versionString;
-  /// copyright notice
-  char[] copyright;
-  /// paper size [LaTeX]
-  char[] paperSize;
-  /// use short file names [HTML]
-  bool shortFileNames;
-  /// page template style to use, customizable via docgen/templates
-  char[] templateStyle;
-}
-
-struct ParserOptions {
-  /// paths to search for imports 
-  char[][] importPaths;
-  /// paths to "root files"
-  char[][] rootPaths;
-  /// regexps for excluding modules
-  char[][] strRegexps;
-  /// comment format [comment parser]
-  CommentFormat commentFormat;
-  /// maximum depth of dependencies
-  uint depth;
-}
-
-struct DocGeneratorOptions {
-  /// location for the generated output
-  char[] outputDir;
-
-  /// list of document formats to be generated
-  DocFormat[] outputFormats;
- 
-  GraphOptions graph;
-  ListingOptions listing;
-  TemplateOptions templates;
-  ParserOptions parser;
-}
-
--- a/trunk/src/docgen/misc/parser.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-/**
- * Author: Aziz Köksal & Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.misc.parser;
-
-import dil.parser.Parser;
-import dil.parser.ImportParser;
-import dil.File;
-import dil.Settings;
-public import dil.semantic.Module;
-import tango.text.Regex : RegExp = Regex;
-import tango.io.FilePath;
-import tango.io.FileSystem;
-import tango.core.Array : remove;
-import tango.text.Util;
-import docgen.misc.meta;
-debug import tango.io.Stdout;
-
-alias void delegate (char[] fqn, char[] path, Module module_) modDg;
-alias void delegate (Module imported, Module importer, bool isPublic, bool isStatic) importDg;
-
-class Parser {
-  protected:
-
-//  ParserOptions m_options;
-
-    
-  static char[] findModuleFilePath(char[] moduleFQNPath, char[][] importPaths) {
-    auto filePath = new FilePath();
-    foreach (importPath; importPaths) {
-      filePath.set(importPath);
-      filePath.append(moduleFQNPath);
-
-      foreach (moduleSuffix; [".d", ".di"/*interface file*/])
-      {
-        filePath.suffix(moduleSuffix);
-        debug Stdout("Trying ")(filePath.toString()).newline;
-        if (filePath.exists())
-          return filePath.toString();
-      }
-    }
-
-    debug Stdout("  * ")(moduleFQNPath)(" does not exist in imports\n")();
-    return null;
-  }
-
-  public:
-
-  /**
-   * Imports the transitive closure of imports starting from "filePath",
-   * limited by recursionDepth.
-   *
-   * The search can be filtered by providing a list of regexps that match the
-   * FQNs of modules to be ignored.
-   *
-   * Params:
-   *     filePath = Path of the file to parse
-   *     importPaths = Directories to look for imports
-   *     strRegexps = Filter regexps
-   *     IncludeUnlocatableModules = Call the delegate also for unlocatable files
-   *     recursionDepth = How many levels of imports to follow (-1 = no limit)
-   *     mdg = Delegate that gets called for every module found
-   *     idg = Delegate that gets called for every import found
-   *     modules = List of parsed modules
-   */
-  static void loadModules(char[] filePath, char[][] importPaths, char[][] strRegexps,
-                          bool IncludeUnlocatableModules, int recursionDepth,
-                          modDg mdg, importDg idg, out Module[] modules) {
-
-    loadModules([filePath], importPaths, strRegexps, IncludeUnlocatableModules,
-      recursionDepth, mdg, idg, modules);
-  }
-
-  /**
-   * Imports the transitive closure of imports starting from "filePath",
-   * limited by recursionDepth.
-   *
-   * The search can be filtered by providing a list of regexps that match the
-   * FQNs of modules to be ignored.
-   *
-   * Params:
-   *     filePaths = Paths of the files to parse
-   *     importPaths = Directories to look for imports
-   *     strRegexps = Filter regexps
-   *     IncludeUnlocatableModules = Call the delegate also for unlocatable files
-   *     recursionDepth = How many levels of imports to follow (-1 = no limit)
-   *     mdg = Delegate that gets called for every module found
-   *     idg = Delegate that gets called for every import found
-   *     modules = List of parsed modules
-   */
-  static void loadModules(char[][] filePaths, char[][] importPaths, char[][] strRegexps,
-                          bool IncludeUnlocatableModules, int recursionDepth,
-                          modDg mdg, importDg idg, out Module[] modules) {
-
-    // Initialize regular expressions.
-    RegExp[] regexps;
-    foreach (strRegexp; strRegexps)
-      regexps ~= new RegExp(strRegexp);
-
-    importPaths ~= ".";
-
-    // Add directory of file and global directories to import paths.
-    foreach(filePath; filePaths) {
-      auto fileDir = (new FilePath(filePath)).folder();
-      if (fileDir.length)
-        importPaths ~= fileDir;
-    }
-
-//    importPaths ~= GlobalSettings.importPaths;
-
-    debug foreach(path; importPaths) {
-      Stdout("Import path: ")(path).newline;
-    }
-
-    Module[char[]] loadedModules;
-
-    Module loadModule(char[] moduleFQNPath, int depth) {
-      if (depth == 0) return null;
-      
-      debug Stdout("Loading ")(moduleFQNPath).newline;
-
-      // Return already loaded module.
-      auto mod_ = moduleFQNPath in loadedModules;
-      if (mod_ !is null) {
-        debug Stdout("  Already loaded.")(moduleFQNPath).newline;
-        return *mod_;
-      }
-
-      auto FQN = replace(moduleFQNPath.dup, dirSep, '.');
-      
-      // Ignore module names matching regular expressions.
-      foreach (rx; regexps)
-        if (rx.test(FQN)) return null;
-
-      auto moduleFilePath = findModuleFilePath(moduleFQNPath, importPaths);
-
-      debug Stdout("  FQN ")(FQN).newline;
-      debug Stdout("  Module path ")(moduleFilePath).newline;
-
-      Module mod = null;
-
-      if (moduleFilePath is null) {
-        if (IncludeUnlocatableModules)
-          mdg(FQN, moduleFQNPath, null);
-      } else {
-        mod = new Module(moduleFilePath);
-        
-        // Use lightweight ImportParser.
-//        mod.parser = new ImportParser(loadFile(moduleFilePath), moduleFilePath);
-        mod.parse();
-
-        debug Stdout("  Parsed FQN ")(mod.getFQN()).newline;
-
-        // autoinclude dirs (similar to Java)
-        // running docgen in foo/bar/abc/ also finds foo/xyz/zzz.d if module names are right
-        {
-          // foo.bar.mod -> [ "foo", "bar" ]
-          auto modPackage = split(mod.getFQN, ".")[0..$-1];
-          auto modDir = split(FileSystem.toAbsolute(new FilePath(moduleFilePath)).standard().folder(), "/");
-          auto modLocation = modDir[0..modDir.remove(".")];
-
-          bool matches = false;
-          int i;
-
-          for(i = 1; i <= min(modPackage.length, modLocation.length); i++) {
-            matches = true;
-            debug Stdout("  Decl: ")(modPackage[$-i]).newline;
-            debug Stdout("  Path: ")(modLocation[$-i]).newline;
-            if (modPackage[$-i] != modLocation[$-i]) {
-              matches = false;
-              break;
-            }
-          }
-          if (matches) {
-            auto loc = modLocation[0..$-i+1].join("/");
-            debug Stdout("  Autoadding import: ")(loc).newline;
-            importPaths ~= loc;
-          }
-        }
-
-        mdg(FQN, moduleFQNPath, mod);
-        loadedModules[moduleFQNPath] = mod;
-
-        foreach (importDecl; mod.imports)
-          foreach(moduleFQN_; importDecl.getModuleFQNs(dirSep)) {
-            auto loaded_mod = loadModule(moduleFQN_, depth == -1 ? depth : depth-1);
-
-            if (loaded_mod !is null) {
-              idg(loaded_mod, mod, importDecl.isPublic(), importDecl.isStatic());
-            } else if (IncludeUnlocatableModules) {
-              auto tmp = new Module(null);
-              tmp.setFQN(replace(moduleFQN_.dup, dirSep, '.'));
-              idg(tmp, mod, importDecl.isPublic(), importDecl.isStatic());
-            }
-          }
-      }
-
-      return mod;
-    } // loadModule
-
-    foreach(filePath; filePaths)
-      loadModule(filePath, recursionDepth);
-
-    // Finished loading modules.
-
-    // Ordered list of loaded modules.
-    modules = loadedModules.values;
-  }
-}
--- a/trunk/src/docgen/misc/textutils.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/**
- * Author: Aziz Köksal & Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.misc.textutils;
-
-// copied from Generate.d
-char[] xml_escape(char[] text)
-{
-  char[] result;
-  result.length = text.length;
-  result.length = 0;
-  foreach(c; text)
-    switch(c)
-    {
-      case '<': result ~= "&lt;";  break;
-      case '>': result ~= "&gt;";  break;
-      case '&': result ~= "&amp;"; break;
-      default:  result ~= c;
-    }
-  return result;
-}
-
-char[] plainTextHeading(char[] s) {
-  char[] line;
-  line.length = 80;
-  line[] = '=';
-
-  return s ~ \n ~ line[0..s.length].dup ~ \n ~ \n;
-}
-
-char[] plainTextHorizLine(int l = 80) {
-  char[] line;
-  line.length = 80;
-  line[] = '-';
-  
-  return line[0..l].dup ~ \n;
-}
--- a/trunk/src/docgen/moduledoc/htmlwriter.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.moduledoc.htmlwriter;
-
-import docgen.moduledoc.writer;
-import docgen.misc.textutils;
-
-
-/**
- * TODO
- */
-class HTMLWriter : AbstractWriter!(ModuleDocWriterFactory), ModuleDocWriter {
-  PageWriter writer;
-  
-  this(ModuleDocWriterFactory factory, PageWriter writer) {
-    super(factory);
-    this.writer = writer;
-  }
-  
-  void generateModuleDoc(Module mod, OutputStream output) {
-    
-					/*
-    auto inputStream = cast(FileInput)input;
-    auto content = new char[inputStream.length];
-    auto bytesRead = inputStream.read (content);
-    
-    assert(bytesRead == inputStream.length, "Error reading source file");
-    assert(output == null);
-    
-    writer.addListing(
-      moduleName,
-      xml_escape(content)
-    );*/
-  }
-}
-
--- a/trunk/src/docgen/moduledoc/writer.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.moduledoc.writer;
-
-import docgen.misc.misc;
-public import docgen.page.writer;
-import tango.io.model.IConduit : OutputStream, InputStream;
-
-interface ModuleDocWriter {
-  void generateModuleDoc(Module mod, OutputStream output);
-}
-
-interface ModuleDocWriterFactory : WriterFactory {
-  ModuleDocWriter createModuleDocWriter(PageWriter writer, DocFormat outputFormat);
-}
--- a/trunk/src/docgen/moduledoc/writers.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.moduledoc.writers;
-
-public import docgen.moduledoc.writer;
-//import docgen.moduledoc.latexwriter;
-import docgen.moduledoc.htmlwriter;
-//import docgen.moduledoc.xmlwriter;
-
-class DefaultModuleDocWriterFactory : AbstractWriterFactory, ModuleDocWriterFactory {
-  this(DocGenerator generator) {
-    super(generator);
-  }
-
-  ModuleDocWriter createModuleDocWriter(PageWriter writer, DocFormat outputFormat) {
-    switch (outputFormat) {/*
-      case DocFormat.LaTeX:
-        return new LaTeXWriter(this, writer);
-      case DocFormat.XML:
-        return new XMLWriter(this, writer);*/
-      case DocFormat.HTML:
-        return new HTMLWriter(this, writer);
-      default:
-        throw new Exception("Moduledoc writer type does not exist!");
-    }
-  }
-}
-
--- a/trunk/src/docgen/page/htmlwriter.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.page.htmlwriter;
-
-import docgen.page.writer;
-import docgen.misc.textutils;
-import tango.io.FileConduit : FileConduit;
-import tango.text.convert.Sprint;
-import tango.io.FilePath;
-
-/**
- * Writes a HTML document skeleton.
- */
-class HTMLWriter : AbstractPageWriter!("html") {
-  private:
-
-  char[] styleSheetFile;
-
-  public:
-  
-  this(PageWriterFactory factory, OutputStream[] outputs) {
-    super(factory);
-  }
-
-  override void generateClassSection() {
-    print.format(getTemplate("classes"), factory.options.templates.title);
-  }
-
-  override void generateModuleSection(Module[] modules) {
-    print.format(getTemplate("modules"), factory.options.templates.title);
-  }
-
-  override void generateListingSection(Module[] modules) {
-    print.format(getTemplate("listings"), factory.options.templates.title);
-  }
-
-  override void generateDepGraphSection() {
-    print.format(getTemplate("dependencies"), factory.options.templates.title);
-  }
-
-  void generateFirstPage() {
-    print.format(
-      getTemplate("firstpage"),
-      factory.options.templates.title,
-      factory.options.templates.versionString,
-      factory.options.templates.copyright
-    );
-
-    footer();
-  }
-  
-  /**
-   * A hack for figuring out the stylesheet file name.
-   */
-  override void generateCustomPage(char[] name, char[][] args ...) {
-    super.generateCustomPage(name, args);
-
-    if (name == "stylesheet") {
-      styleSheetFile = (new FilePath(
-        (cast(Object)outputs[0].conduit).toString())).file();
-    }
-  }
-
-  /**
-   * Overrides the default template fetcher in order to
-   * provide a consistent layout for all pages.
-   */
-  override char[] getTemplate(char[] name) {
-    auto content = super.getTemplate(name);
-
-    foreach(pageName; [
-      "firstpage"[], "toc"[], "classes"[], "modules"[], "listing"[],
-      "listings"[], "dependencies"[], "lastpage"[] ]) {
-      if (name == pageName) {
-        auto sprint = new Sprint!(char)(5120);
-        char[] title = factory.options.templates.title ~ " ";
-        switch(name) {
-          case "firstpage": title ~= "Documentation"; break;
-          case "toc": title ~= "TOC"; break;
-          case "classes": title ~= "Class index"; break;
-          case "modules": title ~= "Module index"; break;
-          case "listing": title ~= "File contents"; break;
-          case "listings": title ~= "File index"; break;
-          case "dependencies": title ~="Dependencies"; break;
-        }
-        return
-          sprint.format(super.getTemplate("pagetemplate"), styleSheetFile, title) ~
-          content;
-      }
-    }
-
-    return content;
-  }
-
-  void addList(char[][] contents, bool ordered) {
-    foreach(item; contents) {
-      switch(item) {
-        case "(": print(ordered ? "<ol>" : "<ul>"); continue;
-        case ")": print(ordered ? "</ol>" : "</ul>"); continue;
-        default: print("<li>")(item)("</li>");
-      }
-    }
-  }
-
-  override void addListing(char[] moduleName, char[] contents, bool inline) {
-    print.format(getTemplate("listing"), moduleName, contents);
-
-    footer();
-  }
-
-  protected:
-
-  /**
-   * Writes the page footer.
-   */
-  void footer() {
-    print.format(getTemplate("pagetemplate2"), docgen_version);
-  }
-}
--- a/trunk/src/docgen/page/latexwriter.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.page.latexwriter;
-
-import docgen.page.writer;
-import tango.io.FileConduit : FileConduit;
-
-/**
- * Writes a LaTeX document skeleton.
- */
-class LaTeXWriter : AbstractPageWriter!("latex", 1) {
-  this(PageWriterFactory factory, OutputStream[] outputs) {
-    super(factory, outputs);
-  }
-
-  void generateFirstPage() {
-    print.format(
-      getTemplate("firstpage"),
-      factory.options.templates.paperSize,
-      factory.options.templates.title,
-      factory.options.templates.versionString,
-      docgen_version,
-      timeNow(),
-      factory.options.listing.literateStyle ? "" : "%"
-    );
-  }
-
-  void addList(char[][] contents, bool ordered) {
-    foreach(item; contents) {
-      switch(item) {
-        case "(": print(ordered ? "\\begin{enumerate}" : "\\begin{itemize}"); continue;
-        case ")": print(ordered ? "\\end{enumerate}" : "\\end{itemize}"); continue;
-        default: print("\\item")(item)(\n);
-      }
-    }
-  }
-}
--- a/trunk/src/docgen/page/plaintextwriter.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.page.plaintextwriter;
-
-import docgen.page.writer;
-import docgen.misc.textutils;
-import tango.io.FileConduit : FileConduit;
-
-/**
- * Writes a plain text document skeleton.
- */
-class PlainTextWriter : AbstractPageWriter!("plaintext") {
-  this(PageWriterFactory factory, OutputStream[] outputs) {
-    super(factory);
-  }
-
-  override void generateTOC(Module[] modules) {
-    print.format(getTemplate("toc"));
-  }
-
-  override void generateModuleSection(Module[] modules) {
-    print.format(getTemplate("modules"));
-  }
-
-  override void generateListingSection(Module[] modules) {
-    print.format(getTemplate("listings"));
-  }
-
-  void generateDepGraphSection() {
-    print.format(getTemplate("dependencies"));
-  }
-
-  void generateFirstPage() {
-    print.format(getTemplate("firstpage"),
-      plainTextHeading(factory.options.templates.title ~ " Reference Manual"),
-      factory.options.templates.versionString,
-      docgen_version,
-      timeNow()
-    );
-  }
-
-  void addList(char[][] contents, bool ordered) {
-    uint[] counters;
-    foreach(item; contents) {
-      switch(item) {
-        case "(": counters ~= 1; continue;
-        case ")": counters.length = counters.length - 1; continue;
-        default:
-        if (counters.length>0)
-          for (int i=0; i <= counters.length; i++)
-            print(" ");
-        if (ordered)
-          print(++counters[$-1])(". ")(item)(\n);
-        else
-          print("* ")(item)(\n);
-      }
-    }
-  }
-}
--- a/trunk/src/docgen/page/writer.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,231 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.page.writer;
-
-public import docgen.misc.misc;
-public import docgen.misc.options;
-public import docgen.misc.parser;
-import tango.io.model.IConduit : OutputStream;
-import tango.time.chrono.Gregorian;
-import tango.text.locale.Core;
-import tango.time.WallClock;
-import tango.text.convert.Sprint;
-import tango.io.stream.FileStream;
-import tango.io.Stdout;
-import tango.io.Print: Print;
-import tango.text.convert.Layout : Layout;
-import tango.io.FilePath;
-import tango.io.FileScan;
-
-const templateDir = "docgen/templates/";
-
-const formatDirs = [ "latex"[], "xml"[], "html"[], "plaintext"[] ];
-
-/**
- * Writes the logical subcomponents of a document,
- * e.g. sections, embedded graphics, lists
- */
-interface PageWriter {
-  /**
-   * Updates the outputstreams.
-   */
-  void setOutput(OutputStream[] outputs);
-
-  /**
-   * Generates the first page(s).
-   */
-  void generateFirstPage();
-
-  /**
-   * Generates table of contents.
-   */
-  void generateTOC(Module[] modules);
-
-  /**
-   * Generates class documentation section.
-   */
-  void generateClassSection();
-
-  /**
-   * Generates module documentation section.
-   */
-  void generateModuleSection(Module[] modules);
-
-  /**
-   * Generates source code listing section.
-   */
-  void generateListingSection(Module[] modules);
-
-  /**
-   * Generates dependency graph section.
-   */
-  void generateDepGraphSection();
-
-  /**
-   * Generates an index section.
-   */
-  void generateIndexSection();
-
-  /**
-   * Generates the last page(s).
-   */
-  void generateLastPage();
-
-  /**
-   * Generates a page using a custom template file.
-   *
-   * Some examples: style sheet, DTD files, makefiles.
-   */
-  void generateCustomPage(char[] name, char[][] args ...);
-  
-  // --- page components
-  //
-  /*
-   * Adds an external graphics file. 
-   */
-  void addGraphics(char[] imageFile);
-  
-  /**
-   * Adds a source code listing.
-   */
-  void addListing(char[] moduleName, char[] contents, bool inline = true);
-
-  /**
-   * Adds a list of items.
-   */
-  void addList(char[][] contents, bool ordered);
-}
-
-interface PageWriterFactory : WriterFactory {
-  PageWriter createPageWriter(OutputStream[] outputs, DocFormat outputFormat);
-}
-
-template AbstractPageWriter(char[] format, int n = 0) {
-  abstract class AbstractPageWriter : AbstractWriter!(PageWriterFactory, n), PageWriter {
-    protected:
-
-    char[][char[]] m_templates;
-    Print!(char) print;
-
-    public:
-         
-    this(PageWriterFactory factory, OutputStream[] outputs) {
-      this(factory);
-      setOutput(outputs);
-    }
-
-    void setOutput(OutputStream[] outputs) {
-      this.outputs = outputs;
-      static if (n > 0)
-        assert(outputs.length == n, "Incorrect number of outputs");
-
-      print = new Print!(char)(new Layout!(char), outputs[0]);
-    }
-
-    void generateTOC(Module[] modules) {
-      print.format(getTemplate("toc"));
-    }
-
-    void generateClassSection() {
-      print.format(getTemplate("classes"));
-    }
-
-    void generateModuleSection(Module[] modules) {
-      print.format(getTemplate("modules"));
-    }
-
-    void generateListingSection(Module[] modules) {
-      print.format(getTemplate("listings"));
-    }
-
-    void generateDepGraphSection() {
-      print.format(getTemplate("dependencies"));
-    }
-
-    void generateIndexSection() {
-      print.format(getTemplate("index"));
-    }
-
-    void generateLastPage() {
-      print.format(getTemplate("lastpage"));
-    }
-
-    void generateCustomPage(char[] name, char[][] args ...) {
-      switch(args.length) {
-        case 0: print.format(getTemplate(name)); break;
-        case 1: print.format(getTemplate(name), args[0]); break;
-        case 2: print.format(getTemplate(name), args[0], args[1]); break;
-        case 3: print.format(getTemplate(name), args[0], args[1], args[2]); break;
-        default: throw new Exception("Too many arguments");
-      }
-    }
-
-    //---
-
-    void addGraphics(char[] imageFile) {
-      print.format(getTemplate("graphics"), imageFile);
-    }
-    
-    void addListing(char[] moduleName, char[] contents, bool inline) {
-      print.format(getTemplate("listing"), moduleName, contents);
-    }
-
-    protected:
-
-    this(PageWriterFactory factory) {
-      super(factory);
-    
-      auto scan = new FileScan();
-      scan(templateDir~factory.options.templates.templateStyle~"/"~format~"/", ".tpl");
-
-      debug Stdout(scan.files.length)(" template files loaded.\n");
-
-      foreach(tpl; scan.files) {
-        m_templates[tpl.name] = loadTemplate(tpl.toString());
-      }
-    }
-
-    char[] getTemplate(char[] name) {
-      auto tpl = name in m_templates;
-      assert(tpl, "Error: template ["~format~"/"~name~"] not found!");
-      return *tpl;
-    }
-
-    char[] loadTemplate(char[] fn) {
-      scope(failure) {
-        Stderr("Warning: error opening template "~fn~".");
-        return null;
-      }
-
-      auto file = new FileInput(fn);
-      auto content = new char[file.length];
-      auto bytesRead = file.read(content);
-      
-      assert(bytesRead == file.length, "Error reading template");
-      
-      file.close();
-      
-      return content;
-    }
-    
-    char[] timeNow() {
-      auto n = WallClock.now;
-      auto c = Gregorian.generic;
-      auto d = c.toDate(n);
-      auto sprint = new Sprint!(char);
-
-      auto culture = new Culture("en-GB");
-      auto dateTimeFormat = culture.dateTimeFormat();
-
-      return sprint.format("{} {} {} {}",
-        dateTimeFormat.getAbbreviatedDayName(c.getDayOfWeek(n)),
-        1,//d.day(),
-        //dateTimeFormat.getAbbreviatedMonthName(d.month()),
-        2,//d.month(),
-        3//d.year()) //FIXME: something is broken here (Error: function expected before (), not *(&d + 8u) of type uint)
-        ).dup;
-    }
-  }
-}
--- a/trunk/src/docgen/page/writers.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.page.writers;
-
-public import docgen.page.writer;
-import docgen.page.htmlwriter;
-import docgen.page.xmlwriter;
-import docgen.page.plaintextwriter;
-import docgen.page.latexwriter;
-
-class DefaultPageWriterFactory : AbstractWriterFactory, PageWriterFactory {
-  this(DocGenerator generator) {
-    super(generator);
-  }
-
-  PageWriter createPageWriter(OutputStream[] outputs, DocFormat outputFormat) {
-    switch (outputFormat) {
-      case DocFormat.LaTeX:
-        return new LaTeXWriter(this, outputs);
-      case DocFormat.XML:
-        return new XMLWriter(this, outputs);
-      case DocFormat.HTML:
-        return new HTMLWriter(this, outputs);
-      case DocFormat.PlainText:
-        return new PlainTextWriter(this, outputs);
-      default:
-        throw new Exception("Document writer type does not exist!");
-    }
-  }
-}
--- a/trunk/src/docgen/page/xmlwriter.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.page.xmlwriter;
-
-import docgen.page.writer;
-import docgen.misc.textutils;
-import tango.io.FileConduit : FileConduit;
-
-//TODO: this is mostly broken now
-
-/**
- * TODO
- */
-class XMLWriter : AbstractPageWriter!("xml", 1) {
-  this(PageWriterFactory factory, OutputStream[] outputs) {
-    super(factory, outputs);
-  }
-
-  void generateTOC(Module[] modules) {
-    // TODO
-    print.format(getTemplate("toc"));
-  }
-
-  void generateModuleSection() {
-    // TODO
-    print.format(getTemplate("modules"));
-  }
-
-  void generateListingSection() {
-    // TODO
-    print.format(getTemplate("listings"));
-  }
-
-  void generateDepGraphSection() {
-    // TODO
-    print.format(getTemplate("dependencies"));
-  }
-
-  void generateIndexSection() { }
-
-  void generateLastPage() { }
-
-  void generateFirstPage() { }
-
-  void addList(char[][] contents, bool ordered) {
-    foreach(item; contents) {
-      switch(item) {
-        case "(": print(ordered ? "<ol>" : "<ul>"); continue;
-        case ")": print(ordered ? "</ol>" : "</ul>"); continue;
-        default: print("<li>")(xml_escape(item))("</li>");
-      }
-    }
-  }
-}
--- a/trunk/src/docgen/sourcelisting/htmlwriter.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.sourcelisting.htmlwriter;
-
-import docgen.sourcelisting.writer;
-import docgen.misc.textutils;
-//import dil.Parser;
-import tango.io.stream.FileStream;
-
-
-/**
- * TODO
- */
-class HTMLWriter : AbstractWriter!(ListingWriterFactory), ListingWriter {
-  PageWriter writer;
-  
-  this(ListingWriterFactory factory, PageWriter writer) {
-    super(factory);
-    this.writer = writer;
-  }
-  
-  //void generateListing(Parser parser) { /* TODO */ }
-  
-  void generateListing(InputStream input, OutputStream output, char[] moduleName) {
-    auto inputStream = cast(FileInput)input;
-    auto content = new char[inputStream.length];
-    auto bytesRead = inputStream.read (content);
-    
-    assert(bytesRead == inputStream.length, "Error reading source file");
-    assert(output == null);
-    
-    writer.addListing(
-      moduleName,
-      xml_escape(content)
-    );
-  }
-}
--- a/trunk/src/docgen/sourcelisting/latexwriter.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.sourcelisting.latexwriter;
-
-import docgen.sourcelisting.writer;
-//import dil.Parser;
-import tango.io.FilePath;
-
-/**
- * Adds a code listing section for the given file. 
- */
-class LaTeXWriter : AbstractWriter!(ListingWriterFactory), ListingWriter {
-  PageWriter writer;
-  
-  this(ListingWriterFactory factory, PageWriter writer) {
-    super(factory);
-    this.writer = writer;
-  }
-
-  //void generateListing(Parser parser) { /* TODO */ }
-  
-  void generateListing(InputStream input, OutputStream output, char[] moduleName) {
-    output.copy(input);
-    
-    writer.addListing(
-      moduleName,
-      FilePath((cast(Object)output.conduit).toString()).file
-    );
-  }
-}
--- a/trunk/src/docgen/sourcelisting/writer.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.sourcelisting.writer;
-
-import docgen.misc.misc;
-public import docgen.page.writer;
-//import dil.Parser;
-import tango.io.model.IConduit : OutputStream, InputStream;
-
-interface ListingWriter {
-  //void generateListing(Parser parser);
-  void generateListing(InputStream input, OutputStream output, char[] moduleName);
-}
-
-interface ListingWriterFactory : WriterFactory {
-  ListingWriter createListingWriter(PageWriter writer, DocFormat outputFormat);
-}
--- a/trunk/src/docgen/sourcelisting/writers.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.sourcelisting.writers;
-
-public import docgen.sourcelisting.writer;
-import docgen.sourcelisting.latexwriter;
-import docgen.sourcelisting.htmlwriter;
-import docgen.sourcelisting.xmlwriter;
-
-class DefaultListingWriterFactory : AbstractWriterFactory, ListingWriterFactory {
-  this(DocGenerator generator) {
-    super(generator);
-  }
-
-  ListingWriter createListingWriter(PageWriter writer, DocFormat outputFormat) {
-    switch (outputFormat) {
-      case DocFormat.LaTeX:
-        return new LaTeXWriter(this, writer);
-      case DocFormat.XML:
-        return new XMLWriter(this, writer);
-      case DocFormat.HTML:
-        return new HTMLWriter(this, writer);
-      default:
-        throw new Exception("Listing writer type does not exist!");
-    }
-  }
-}
--- a/trunk/src/docgen/sourcelisting/xmlwriter.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.sourcelisting.xmlwriter;
-
-import docgen.sourcelisting.writer;
-//import dil.Parser;
-
-/**
- * TODO
- */
-class XMLWriter : AbstractWriter!(ListingWriterFactory), ListingWriter {
-  PageWriter writer;
-  
-  this(ListingWriterFactory factory, PageWriter writer) {
-    super(factory);
-    this.writer = writer;
-  }
-
-  //void generateListing(Parser parser) { /* TODO */ }
-  void generateListing(InputStream input, OutputStream output, char[] moduleName) { /* TODO */ }
-}
--- a/trunk/src/docgen/templates/README	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-The docgen uses the following template file names by default
-
-firstpage
-toc
-classes
-modules
-listings
-dependencies
-index
-lastpage
-langdef
-makefile
-graphics
-listing
--- a/trunk/src/docgen/templates/default/html/classes.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-<h1>{0} Class List</h1>
--- a/trunk/src/docgen/templates/default/html/dependencies.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-<h1>{} Dependencies</h1>
--- a/trunk/src/docgen/templates/default/html/firstpage.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<h1>{0} Documentation</h1>
-<h2 id="version">{1}</h2>
-<h2>© {2}</h2>
--- a/trunk/src/docgen/templates/default/html/graphics.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-<p><img src="{}" /></p>
--- a/trunk/src/docgen/templates/default/html/listing.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-<h1>{0} Contents</h1>
-<pre style="dcode">{1}</pre>
--- a/trunk/src/docgen/templates/default/html/listings.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-<h1>{0} File List</h1>
--- a/trunk/src/docgen/templates/default/html/makefile.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-for i in *.dot; do
-  F=`echo $i|sed 's/dot/{0}/'`
-  dot $i -T{0} -o$F
-done
-
--- a/trunk/src/docgen/templates/default/html/modules.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-<h1>{0} Module List</h1>
--- a/trunk/src/docgen/templates/default/html/pagetemplate.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-  <title>{1}</title>
-  <meta name="author" content="TODO" />
-  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-  <link rel="stylesheet" href="{0}" media="all" title="default" />
-</head>
-<body>
-<div class="tabs">
-  <ul>
-    <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
-    <li><a href="classes.html"><span>Classes</span></a></li>
-    <li><a href="modules.html"><span>Modules</span></a></li>
-    <li><a href="files.html"><span>Files</span></a></li>
-    <li><a href="depgraph.html"><span>Dependencies</span></a></li>
-  </ul>
-</div>
--- a/trunk/src/docgen/templates/default/html/pagetemplate2.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<hr />
-<p id="generator">Generated by {0}</p>
-</body>
-</html>
Binary file trunk/src/docgen/templates/default/html/static/tab_b.gif has changed
Binary file trunk/src/docgen/templates/default/html/static/tab_l.gif has changed
Binary file trunk/src/docgen/templates/default/html/static/tab_r.gif has changed
--- a/trunk/src/docgen/templates/default/html/static/tabs.css	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-/* tabs styles, based on http://www.alistapart.com/articles/slidingdoors */
-
-DIV.tabs
-{
-   float            : left;
-   width            : 100%;
-   background       : url("tab_b.gif") repeat-x bottom;
-   margin-bottom    : 4px;
-}
-
-DIV.tabs UL
-{
-   margin           : 0px;
-   padding-left     : 10px;
-   list-style       : none;
-}
-
-DIV.tabs LI, DIV.tabs FORM
-{
-   display          : inline;
-   margin           : 0px;
-   padding          : 0px;
-}
-
-DIV.tabs FORM
-{
-   float            : right;
-}
-
-DIV.tabs A
-{
-   float            : left;
-   background       : url("tab_r.gif") no-repeat right top;
-   border-bottom    : 1px solid #84B0C7;
-   font-size        : x-small;
-   font-weight      : bold;
-   text-decoration  : none;
-}
-
-DIV.tabs A:hover
-{
-   background-position: 100% -150px;
-}
-
-DIV.tabs A:link, DIV.tabs A:visited,
-DIV.tabs A:active, DIV.tabs A:hover
-{
-       color: #1A419D;
-}
-
-DIV.tabs SPAN
-{
-   float            : left;
-   display          : block;
-   background       : url("tab_l.gif") no-repeat left top;
-   padding          : 5px 9px;
-   white-space      : nowrap;
-}
-
-DIV.tabs INPUT
-{
-   float            : right;
-   display          : inline;
-   font-size        : 1em;
-}
-
-DIV.tabs TD
-{
-   font-size        : x-small;
-   font-weight      : bold;
-   text-decoration  : none;
-}
-
-
-
-/* Commented Backslash Hack hides rule from IE5-Mac \*/
-DIV.tabs SPAN {float : none;}
-/* End IE5-Mac hack */
-
-DIV.tabs A:hover SPAN
-{
-   background-position: 0% -150px;
-}
-
-DIV.tabs LI.current A
-{
-   background-position: 100% -150px;
-   border-width     : 0px;
-}
-
-DIV.tabs LI.current SPAN
-{
-   background-position: 0% -150px;
-   padding-bottom   : 6px;
-}
-
-DIV.nav
-{
-   background       : none;
-   border           : none;
-   border-bottom    : 1px solid #84B0C7;
-}
--- a/trunk/src/docgen/templates/default/html/stylesheet.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-@import "tabs.css";
-
-body {{
-background: #fff;
-}
-
-h1, h2 {{
-text-align: center;
-}
-
-h1 {{
-font-size: 1.5em;
-}
-
-h2#version {{
-font-size: 0.8em;
-}
-
-h2 {{
-font-size: 1.1em;
-}
-
-hr {{
-height: 0;
-border: 0;
-border-bottom: 1px solid black;
-}
-
-#generator {{
-text-align: right;
-font-size: small;
-font-style: italic;
-}
--- a/trunk/src/docgen/templates/default/html/toc.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-  <title>{0} Reference Manual</title>
-  <meta name="author" content="{1}" />
-  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-  <link rel="stylesheet" href="style.css" media="all" title="default" />
-  <link rel="stylesheet" href="print.css" media="print" />
-</head>
-<body>
-<h2>Table of Contents</h2>
-<hr />
-{0}
-</body>
-</html>
--- a/trunk/src/docgen/templates/default/latex/classes.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-\chapter{{Class documentation}
-\input{{classes}
--- a/trunk/src/docgen/templates/default/latex/dependencies.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-\chapter{{Dependency diagram}
-\input{{dependencies}
--- a/trunk/src/docgen/templates/default/latex/firstpage.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-\documentclass[{0}]{{book}
-\usepackage{{a4wide}
-\usepackage{{makeidx}
-\usepackage{{fancyhdr}
-\usepackage{{graphicx}
-\usepackage{{hyperref}
-\usepackage{{multicol}
-\usepackage{{float}
-\usepackage{{textcomp}
-\usepackage{{alltt}
-\usepackage[utf8]{{inputenc}
-\usepackage{{listings}
-\lstnewenvironment{{dcode}
-{{ \lstset{{language=d} }
-{{}
-\lstset{{
-  {5} literate=
-  {5}          {{<=}{{{{$\leq$}}1
-  {5}          {{>=}{{{{$\geq$}}1
-  {5}          {{!=}{{{{$\neq$}}1
-  {5}          {{...}{{{{$\dots$}}1
-  {5}          {{~}{{{{$\sim$}}1,
-  stringstyle=\ttfamily,
-  inputencoding=utf8,
-  extendedchars=false,
-  columns=fixed,
-  basicstyle=\small
-}
-\hypersetup{{backref,colorlinks=true}
-\makeindex
-\setcounter{{tocdepth}{{1}
-\newcommand{{\clearemptydoublepage}{{\newpage{{\pagestyle{{empty}\cleardoublepage}}
-\def\thechapter{{\Roman{{chapter}}
-\def\thesection{{\arabic{{chapter}.\arabic{{section}}
-% \renewcommand{{\footrulewidth}{{0.4pt}
-
-\begin{{document}
-
-\begin{{titlepage}
-\vspace*{{7cm}
-\begin{{center}
-{{\Large {1} Reference Manual\\[1ex]\large {2} }\\
-\vspace*{{1cm}
-{{\large Generated by {3} }\\
-\vspace*{{0.5cm}
-{{\small {4} }\\
-\end{{center}
-\end{{titlepage}
-
-\clearemptydoublepage
--- a/trunk/src/docgen/templates/default/latex/graphics.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-\includegraphics[width=1\textwidth,height=1\textheight,keepaspectratio]{{{0}}
--- a/trunk/src/docgen/templates/default/latex/index.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-\printindex
--- a/trunk/src/docgen/templates/default/latex/lastpage.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-\end{{document}
--- a/trunk/src/docgen/templates/default/latex/listing.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-\section{{Module {0}}
-\lstinputlisting[language=d]{{{1}}
-\clearpage
\ No newline at end of file
--- a/trunk/src/docgen/templates/default/latex/listings.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-\chapter{{File listings}
-\input{{files}
--- a/trunk/src/docgen/templates/default/latex/makefile.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-#!/bin/sh
-
-for i in *.dot; do
-  F=`echo $i|sed 's/dot/{1}/'`
-  dot $i -T{1} -o$F
-done
-
-pdflatex {0}
-makeindex document
-pdflatex {0}
--- a/trunk/src/docgen/templates/default/latex/modules.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-\chapter{{Module documentation}
-\input{{modules}
--- a/trunk/src/docgen/templates/default/latex/static/lstlang0.sty	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-%%
-%% D definition (c) 2007 Jari-Matti Mäkelä
-%%
-\lst@definelanguage{D}%
-  {morekeywords={abstract,alias,align,asm,assert,auto,body,bool,break,%
-      byte,case,cast,catch,cdouble,cent,cfloat,char,class,const,continue,%
-      creal,dchar,debug,default,delegate,delete,deprecated,do,double,%
-      else,enum,export,extern,false,final,finally,float,for,foreach,%
-      foreach_reverse,function,goto,idouble,if,ifloat,import,in,inout,%
-      int,interface,invariant,ireal,is,lazy,long,macro,mixin,module,new,%
-      null,out,override,package,pragma,private,protected,public,real,ref,%
-      return,scope,short,static,struct,super,switch,synchronized,template,%
-      this,throw,true,try,typedef,typeid,typeof,ubyte,ucent,uint,ulong,%
-      union,unittest,ushort,version,void,volatile,wchar,while,with},%
-   sensitive,%
-
-   morecomment=[s]{/*}{*/},%
-   morecomment=[n]{/+}{+/},%
-   morecomment=[l]//,%
-   morestring=[b]",%
-   morestring=[b]`%
-  }[keywords,comments,strings]%
--- a/trunk/src/docgen/templates/default/latex/toc.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-\tableofcontents
-\thispagestyle{{empty}
-
-\clearemptydoublepage
-
-\setcounter{{page}{{1}
--- a/trunk/src/docgen/templates/default/plaintext/classes.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-Class List
-----------
-
--- a/trunk/src/docgen/templates/default/plaintext/dependencies.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-Module Dependencies
--------------------
-
--- a/trunk/src/docgen/templates/default/plaintext/firstpage.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-{0}
-
-Version {1}
-
-Generated by {2}
-
-{3}
--- a/trunk/src/docgen/templates/default/plaintext/graphics.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-See {}.
\ No newline at end of file
--- a/trunk/src/docgen/templates/default/plaintext/listing.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-Module {0}
-See {1}.
-
--- a/trunk/src/docgen/templates/default/plaintext/listings.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-File listings
--------------
-
--- a/trunk/src/docgen/templates/default/plaintext/makefile.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-for i in *.dot; do
-  F=`echo $i|sed 's/dot/{0}/'`
-  dot $i -T{0} -o$F
-done
-
--- a/trunk/src/docgen/templates/default/plaintext/modules.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-Module List
------------
-
--- a/trunk/src/docgen/templates/default/plaintext/toc.tpl	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-Table of Contents
------------------
-
-1. Class documentation
-
-2. Module documentation
-
-3. File listings
-
-4. Dependency diagram
--- a/trunk/src/docgen/tests/common.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.tests.common;
-
-import docgen.misc.misc;
-import docgen.misc.options;
-import docgen.config.configurator;
-
-class TestDocGenerator : DocGenerator {
-  Configurator config;
-
-  this() {
-    config = new DefaultConfigurator();
-  }
-
-  public void generate() {
-
-  }
-  
-  public DocGeneratorOptions *options() {
-    return config.getConfiguration();
-  }
-}
--- a/trunk/src/docgen/tests/doctemplate.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.tests.doctemplate;
-
-import docgen.tests.common;
-import docgen.page.writers;
-import tango.io.FileConduit;
-
-// doc template
-//@unittest
-void doctemplate1() {
-  auto gen = new TestDocGenerator;
-  auto fname = "doctemplate.tex";
-  
-  auto gwf = new DefaultPageWriterFactory(gen);
-  auto file = new FileConduit("docgen/teststuff/" ~ fname, FileConduit.WriteCreate);
-  auto writer = gwf.createPageWriter( [ file ], DocFormat.LaTeX );
-  
-  writer.generateFirstPage();
-  writer.generateTOC(null);
-  writer.generateModuleSection(null);
-  writer.generateListingSection(null);
-  writer.generateDepGraphSection();
-  writer.generateIndexSection();
-  writer.generateLastPage();
-  
-  file.close();
-}
--- a/trunk/src/docgen/tests/graphs.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.tests.graphs;
-
-import docgen.tests.common;
-import docgen.misc.parser;
-import docgen.graphutils.writers;
-import docgen.page.writers;
-import tango.io.FileConduit;
-import dil.semantic.Module;
-
-alias DepGraph.Edge Edge;
-alias DepGraph.Vertex Vertex;
-
-void saveDefaultGraph(DepGraph depGraph, char[] fname) {
-  auto gen = new TestDocGenerator;
-  gen.options.graph.highlightCyclicVertices = true;
-  gen.options.graph.imageFormat = ImageFormat.SVG;
-  //gen.options.graph.graphFormat = GraphFormat.ModuleNames;
-  //gen.options.graph.graphFormat = GraphFormat.ModulePaths;
-  gen.options.graph.depth = 5;
-  auto ddf = new DefaultPageWriterFactory(gen);
-  auto gwf = new DefaultGraphWriterFactory(gen);
-  auto file = new FileConduit("docgen/teststuff/" ~ fname, FileConduit.WriteCreate);
-  auto file2 = new FileConduit("docgen/teststuff/" ~ fname ~ "-2", FileConduit.WriteCreate);
-
-  auto writer = gwf.createGraphWriter(
-    ddf.createPageWriter( [ file2 ], DocFormat.LaTeX),
-    GraphFormat.Dot
-  );
-  
-  writer.generateDepGraph(depGraph, file);
-  
-  file.close();
-  file2.close();
-}
-
-// no edges
-//@unittest
-void graph1() {
-  auto g = new DepGraph;
-  g.add(new Vertex("mod_a", "path.to.mod_a", 1));
-  g.add(new Vertex("mod_b", "path.to.mod_b", 2));
-  g.add(new Vertex("mod_c", "path.to.mod_c", 3));
-  
-  saveDefaultGraph(g, "graph1.dot");
-}
-
-
-// simple tree structure
-//@unittest
-void graph2() {
-  auto g = new DepGraph;
-  g.add(new Vertex("mod_a", "path.to.mod_a", 1));
-  g.add(new Vertex("mod_b", "path.to.mod_b", 2));
-  g.add(new Vertex("mod_c", "path.to.mod_c", 3));
-  g.add(new Vertex("mod_d", "path.to.mod_d", 4));
-
-  g.connect(1, 0);
-  g.connect(2, 0);
-  g.connect(3, 2);
-  
-  saveDefaultGraph(g, "graph2.dot");
-}
-
-// circular imports
-//@unittest
-void graph3() {
-  auto g = new DepGraph;
-  g.add(new Vertex("mod_a", "path.to.mod_a", 1));
-  g.add(new Vertex("mod_b", "path.to.mod_b", 2));
-  g.add(new Vertex("mod_c", "path.to.mod_c", 3));
-  g.add(new Vertex("mod_d", "path.to.mod_d", 4));
-
-  g.connect(1, 0);
-  g.connect(2, 1);
-  g.connect(0, 2);
-  
-  saveDefaultGraph(g, "graph3.dot");
-}
-
-// more complex graph
-//@unittest
-void graph4() {
-  auto g = new DepGraph;
-  g.add(new Vertex("mod_a", "path.to.mod_a", 1));
-  g.add(new Vertex("mod_b", "path.to.mod_b", 2));
-  g.add(new Vertex("mod_c", "path.to.mod_c", 3));
-  g.add(new Vertex("mod_d", "path.to.mod_d", 4));
-  g.add(new Vertex("mod_e", "path.to.mod_e", 5));
-  g.add(new Vertex("mod_f", "path.to.mod_f", 6));
-  g.add(new Vertex("mod_g", "path.to.mod_g", 7));
-
-  g.connect(1, 0);
-  g.connect(2, 1);
-  g.connect(0, 2); 
-  g.connect(0, 3);
-  g.connect(0, 4);
-  g.connect(3, 1);
-  g.connect(4, 1);
-  g.connect(0, 6);
-  g.connect(5, 1);
-  g.connect(5, 6);
-  g.connect(6, 0);
-
-  saveDefaultGraph(g, "graph4.dot");
-}
-
-
-// parses the test modules and creates a dep graph
-//@unittest
-void graph5() {
-  auto gen = new TestDocGenerator;
-  gen.options.graph.highlightCyclicVertices = true;
-  gen.options.graph.imageFormat = ImageFormat.PDF;
-  gen.options.outputFormats = [ DocFormat.LaTeX ];
-  auto fname = "dependencies.tex";
-  auto imgFname = "depgraph.dot";
-  
-  auto ddf = new DefaultPageWriterFactory(gen);
-  auto gwf = new DefaultGraphWriterFactory(gen);
-  auto file = new FileConduit("docgen/teststuff/" ~ fname, FileConduit.WriteCreate);
-  auto imgFile = new FileConduit("docgen/teststuff/" ~ imgFname, FileConduit.WriteCreate);
-  
-  Module[] modules;
-  Edge[] edges;
-  Vertex[char[]] vertices;
-  int id = 1;
-  
-  Parser.loadModules(
-    [ "c" ], [ "docgen/teststuff/" ],
-    null, true, -1,
-    (char[] fqn, char[] path, Module m) {
-      vertices[m.moduleFQN] = new DepGraph.Vertex(m.moduleFQN, m.filePath, id++);
-    },
-    (Module imported, Module importer, bool isPublic, bool isStatic) {
-      auto edge = vertices[imported.moduleFQN].addChild(vertices[importer.moduleFQN]);
-      edge.isPublic = isPublic;
-      edge.isStatic = isStatic;
-      edges ~= edge;
-    },
-    modules
-  );
-
-  auto writer = gwf.createGraphWriter(
-    ddf.createPageWriter( [ file ], DocFormat.LaTeX ),
-    GraphFormat.Dot
-  );
-  
-  auto graph = new DepGraph;
-  graph.edges = edges;
-  graph.vertices = vertices.values;
-
-  writer.generateDepGraph(graph, imgFile);
-  
-  file.close();
-  imgFile.close();
-}
--- a/trunk/src/docgen/tests/listing.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.tests.listing;
-
-import docgen.misc.parser;
-import docgen.tests.common;
-import docgen.sourcelisting.writers;
-import docgen.page.writers;
-import tango.io.FileConduit;
-import tango.text.Util;
-
-// doc template
-//@unittest
-void listing1() {
-  auto gen = new TestDocGenerator;
-  gen.options.outputFormats = [ DocFormat.LaTeX ];
-  auto fname = "files.tex";
-  
-  auto ddf = new DefaultPageWriterFactory(gen);
-  auto dlwf = new DefaultListingWriterFactory(gen);
-  auto file = new FileConduit("docgen/teststuff/" ~ fname, FileConduit.WriteCreate);
-  
-
-  Module[] modules;
-
-  Parser.loadModules(
-    [ "c" ], [ "docgen/teststuff/" ],
-    null, true, -1,
-    (char[] fqn, char[] path, Module m) {},
-    (Module imported, Module importer, bool isPublic, bool isStatic) {},
-    modules
-  );
-  
-  foreach(mod; modules) {
-    auto dstFname = replace(mod.moduleFQN.dup, '.', '_');
-    
-    auto srcFile = new FileConduit(mod.filePath);
-    auto dstFile = new FileConduit("docgen/teststuff/_" ~ dstFname ~ ".d", FileConduit.WriteCreate);
-    auto writer = dlwf.createListingWriter( ddf.createPageWriter( [ file ],
-          DocFormat.LaTeX ), DocFormat.LaTeX );
-    
-    writer.generateListing(srcFile, dstFile, mod.moduleFQN);
-
-    srcFile.close();
-    dstFile.close();
-  }
-  
-  file.close();
-}
--- a/trunk/src/docgen/tests/parse.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.tests.parse;
-
-import docgen.misc.parser;
-import tango.io.FileConduit;
-import tango.io.Print: Print;
-import tango.text.convert.Layout : Layout;
-
-void saveToFile(char[] fname, void delegate(Print!(char) file) foo) {
-  auto file = new FileConduit("docgen/teststuff/" ~ fname, FileConduit.WriteCreate);
-  auto output = new Print!(char)(new Layout!(char), file);
-  
-  foo(output);
-  
-  file.close();
-}
-
-// load some test files
-//@unittest
-void parse1() {
-  saveToFile("parse1.txt", (Print!(char) file){
-    Module[] modules;
-  
-    Parser.loadModules(
-      [ "c" ], [ "docgen/teststuff/" ],
-      null, true, -1,
-      (char[] fqn, char[] path, Module m) {
-        file.format("{0} = {1}\n", fqn, path);
-      },
-      (Module imported, Module importer, bool isPublic, bool isStatic) {
-        file.format("{0} <- {1}\n",
-          imported ? imported.moduleFQN : "null"[],
-          importer ? importer.moduleFQN : "null"[]
-        );
-      },
-      modules
-    );
-  });
-}
-
-// load the imports of dil
-//@unittest
-void parse2() {
-  saveToFile("parse2.txt", (Print!(char) file){
-    Module[] modules;
-    
-    Parser.loadModules(
-      [ "docgen/testsuite" ], [".", "/home/jm/d/tango/"],
-      null, true, -1,
-      (char[] fqn, char[] path, Module m) {
-        file.format("{0} = {1}\n", fqn, path);
-      },
-      (Module imported, Module importer, bool isPublic, bool isStatic) {
-        file.format("{0} <- {1}\n",
-          imported ? imported.moduleFQN : "null"[],
-          importer ? importer.moduleFQN : "null"[]
-        );
-      },
-      modules
-    );
-  });
-}
--- a/trunk/src/docgen/teststuff/a.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-module a;
-
-void foo() {}
-void bar() {}
--- a/trunk/src/docgen/teststuff/b.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-module b;
-
-import a;
-
--- a/trunk/src/docgen/teststuff/c.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-module c;
-
-import a;
-import b;
--- a/trunk/src/docgen/teststuff/clean.sh	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-rm _*
-rm dep*
-rm doc*
-rm *.tex
-rm graph*
-rm parse*
-touch modules.tex
--- a/trunk/src/docgen/teststuff/lstlang0.sty	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-%%
-%% D definition (c) 2007 Jari-Matti Mäkelä
-%%
-\lst@definelanguage{D}%
-  {morekeywords={abstract,alias,align,asm,assert,auto,body,bool,break,%
-      byte,case,cast,catch,cdouble,cent,cfloat,char,class,const,continue,%
-      creal,dchar,debug,default,delegate,delete,deprecated,do,double,%
-      else,enum,export,extern,false,final,finally,float,for,foreach,%
-      foreach_reverse,function,goto,idouble,if,ifloat,import,in,inout,%
-      int,interface,invariant,ireal,is,lazy,long,macro,mixin,module,new,%
-      null,out,override,package,pragma,private,protected,public,real,ref,%
-      return,scope,short,static,struct,super,switch,synchronized,template,%
-      this,throw,true,try,typedef,typeid,typeof,ubyte,ucent,uint,ulong,%
-      union,unittest,ushort,version,void,volatile,wchar,while,with},%
-   sensitive,%
-   morecomment=[s]{/*}{*/},%
-   morecomment=[n]{/+}{+/},%
-   morecomment=[l]//,%
-   morestring=[b]",%
-   morestring=[b]`%
-  }[keywords,comments,strings]%
\ No newline at end of file
--- a/trunk/src/docgen/testsuite.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/**
- * Author: Jari-Matti Mäkelä
- * License: GPL3
- */
-module docgen.testsuite;
-
-import docgen.tests.graphs;
-import docgen.tests.parse;
-import docgen.tests.doctemplate;
-import docgen.tests.listing;
-//import docgen.tests.sexp;
-import tango.io.Stdout;
-
-/**
- * A temporary test program for the docgen package.
- * I'll replace this with proper unittests in the future.
- *
- */
-void main() {
-  Stdout("Running..\n")();
-
-  Stdout(" Test1\n")();
-  graph1();
-  Stdout(" Test2\n")();
-  graph2();
-  Stdout(" Test3\n")();
-  graph3();
-  Stdout(" Test4\n")();
-  graph4();
-  Stdout(" Test5\n")();
-  graph5();
-  Stdout(" Test6\n")();
-  parse1();
-  Stdout(" Test7\n")();
-  parse2();
-  Stdout(" Test8\n")();
-  doctemplate1();
-  Stdout(" Test9\n")();
-  listing1();
-//  loadConfig();
-  Stdout("done.\n")();
-}
--- a/trunk/src/html.css	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-@charset "utf-8";
-.compilerinfo, .sourcecode, .linescolumn {
-  white-space: pre;
-  font-family: Monospace;
-  font-size: 0.8em;
-  margin:0;
-  padding:0;
-}
-.compilerinfo {
-  white-space: normal;
-  border: 1px solid #A22;
-  padding: 0.5em;
-  margin: 1em;
-}
-.compilerinfo .error { display: block; }
-.linescolumn {
-  text-align: right;
-  padding-right: 0.3em;
-  border-right: 1px dotted gray;
-}
-.linescolumn a {
-  display: block;
-  color: #44B;
-  text-decoration: none;
-}
-/* Number */
-.n { color: teal; }
-/* Keyword */
-.k { color: darkblue; font-weight: bold; }
-/* Line, block and nested comments */
-.lc, .bc, .nc { color: green; }
-/* Identifier */
-.i { color: black; }
-/* String literal */
-.sl { color: red; }
-/* Character literal */
-.cl { color: purple; }
-/* All bracket types */
-.br { color: orange; }
-/* Special tokens */
-.st { color: green; font-weight: bold; }
-/* #line, hash line */
-.hl { color: green; }
-/* filespec (e.g. #line number [filespec]) */
-.fs { color: purple;}
-/* When the first line starts with #! it's a "shebang" */
-.shebang { color: gray; }
-/* Operator */
-/*.op { color: royalblue; }*/
-/* Particular operators */
-/*.opaa { content: "and"; }*/ /*&& ∧*/
-/*.opoo { content: "or"; }*/ /*|| ∨*/
-/*.opn { content: "¬"; }*/ /*!*/
-/*.opne { content: "≠"; }*/ /*!=*/
-/*.ople { content: "≤"; }*/ /*<=*/
-/*.opge { content: "≥"; }*/ /*>=*/
-/*.oplg { content: "≶"; }*/ /*<>*/
-/*
-d = Declaration
-s = Statement
-e = Expression
-t = Type
-o = Other
-*/
-/* .d { background-color: #FFDDDD; } */
-/* .e { background-color: #DDDDFF; } */
-.d.Module .i, .d.Import .i { color: blue; }
- /*.t .i,*/ .t.Identifier .i, .TemplateTypeParameter .i { color: #911; } 
-.t .br, .t .op { color: #911; }
-.t .k { color: #911; font-weight: normal; }
--- a/trunk/src/html_map.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-/// A map of document elements and D tokens to format strings.
-string[string] map = [
-  "DocHead" : `<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">`\n
-              `<html>`\n
-              `<head>`\n
-              `  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">`\n
-              `  <link href="html.css" rel="stylesheet" type="text/css">`\n
-              `</head>`\n
-              `<body>`\n
-              `<table><tr>`\n,
-  "CompBegin"   : `<td><div class="compilerinfo">`\n,
-  "CompEnd"     : "</div>\n</td></tr><tr>",
-  "LexerError"  : `<p class="error L">{0}({1},{2})L: {3}</p>`\n,
-  "ParserError" : `<p class="error P">{0}({1},{2})P: {3}</p>`\n,
-
-  "LineNumberBegin" : `<td class="linescolumn">`,
-  "LineNumberEnd"   : "</td>\n<td>",
-  "LineNumber"      : `<a id="L{0}" href="#L{0}">{0}</a>`,
-
-  "SourceBegin" : `<td><pre class="sourcecode">`\n,
-  "SourceEnd"   : "\n</pre></td>",
-
-  "DocEnd"  : "\n</tr></table>"
-              "\n</body>"
-              "\n</html>",
-
-  // Node categories:
-  "Declaration" : "d",
-  "Statement"   : "s",
-  "Expression"  : "e",
-  "Type"        : "t",
-  "Other"       : "o",
-
-  // {0} = node category.
-  // {1} = node class name: "Call", "If", "Class" etc.
-  // E.g.: <span class="d Struct">...</d>
-  "NodeBegin" : `<span class="{0} {1}">`,
-  "NodeEnd"   : `</span>`,
-
-  "Identifier" : `<span class="i">{0}</span>`,
-  "String"     : `<span class="sl">{0}</span>`,
-  "Char"       : `<span class="cl">{0}</span>`,
-  "Number"     : `<span class="n">{0}</span>`,
-  "Keyword"    : `<span class="k">{0}</span>`,
-
-  "LineC"   : `<span class="lc">{0}</span>`,
-  "BlockC"  : `<span class="bc">{0}</span>`,
-  "NestedC" : `<span class="nc">{0}</span>`,
-
-  "Shebang"  : `<span class="shebang">{0}</span>`,
-  "HLine"    : `<span class="hl">{0}</span>`, // #line
-  "Filespec" : `<span class="fs">{0}</span>`, // #line N "filespec"
-  "Newline"  : "{0}", // \n | \r | \r\n | LS | PS
-  "Illegal"  : `<span class="ill">{0}</span>`, // A character not recognized by the lexer.
-
-  "SpecialToken" : `<span class="st">{0}</span>`, // __FILE__, __LINE__ etc.
-
-  "("    : "(",
-  ")"    : ")",
-  "["    : "[",
-  "]"    : "]",
-  "{"    : "{",
-  "}"    : "}",
-  "."    : ".",
-  ".."   : "..",
-  "..."  : "...",
-  "!<>=" : "!&lt;&gt;=", // Unordered
-  "!<>"  : "!&lt;&gt;",  // UorE
-  "!<="  : "!&lt;=",     // UorG
-  "!<"   : "!&lt;",      // UorGorE
-  "!>="  : "!&gt;=",     // UorL
-  "!>"   : "!&gt;",      // UorLorE
-  "<>="  : "&lt;&gt;=",  // LorEorG
-  "<>"   : "&lt;&gt;",   // LorG
-  "="    : "=",
-  "=="   : "==",
-  "!"    : "!",
-  "!="   : "!=",
-  "<="   : "&lt;=",
-  "<"    : "&lt;",
-  ">="   : "&gt;=",
-  ">"    : "&gt;",
-  "<<="  : "&lt;&lt;=",
-  "<<"   : "&lt;&lt;",
-  ">>="  : "&gt;&gt;=",
-  ">>"   : "&gt;&gt;",
-  ">>>=" : "&gt;&gt;&gt;=",
-  ">>>"  : "&gt;&gt;&gt;",
-  "|"    : "|",
-  "||"   : "||",
-  "|="   : "|=",
-  "&"    : "&amp;",
-  "&&"   : "&amp;&amp;",
-  "&="   : "&amp;=",
-  "+"    : "+",
-  "++"   : "++",
-  "+="   : "+=",
-  "-"    : "-",
-  "--"   : "--",
-  "-="   : "-=",
-  "/"    : "/",
-  "/="   : "/=",
-  "*"    : "*",
-  "*="   : "*=",
-  "%"    : "%",
-  "%="   : "%=",
-  "^"    : "^",
-  "^="   : "^=",
-  "~"    : "~",
-  "~="   : "~=",
-  ":"    : ":",
-  ";"    : ";",
-  "?"    : "?",
-  ","    : ",",
-  "$"    : "$",
-  "EOF"  : ""
-];
--- a/trunk/src/lang_de.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-
-string lang_code = "de";
-
-string[] messages = [
-  // Lexer messages:
-  "illegales Zeichen gefunden: '{0}'",
-//   "ungültiges Unicodezeichen.",
-  "ungültige UTF-8-Sequenz: '{0}'",
-  // ''
-  "unterminiertes Zeichenliteral.",
-  "leeres Zeichenliteral.",
-  // #line
-  "erwartete 'line' nach '#'.",
-  "Ganzzahl nach #line erwartet.",
-//   `erwartete Dateispezifikation (z.B. "pfad\zur\datei".)`,
-  "unterminierte Dateispezifikation (filespec.)",
-  "ein Special Token muss mit einem Zeilenumbruch abgeschlossen werden.",
-  // ""
-  "unterminiertes Zeichenkettenliteral.",
-  // x""
-  "Nicht-Hexzeichen '{0}' in Hexzeichenkette gefunden.",
-  "ungerade Anzahl von Hexziffern in Hexzeichenkette.",
-  "unterminierte Hexzeichenkette.",
-  // /* */ /+ +/
-  "unterminierter Blockkommentar (/* */).",
-  "unterminierter verschachtelter Kommentar (/+ +/).",
-  // `` r""
-  "unterminierte rohe Zeichenkette.",
-  "unterminierte Backquote-Zeichenkette.",
-  // \x \u \U
-  "undefinierte Escapesequenz '{0}' gefunden.",
-  "ungültige Unicode-Escapesequenz '{0}' gefunden.",
-  "unzureichende Anzahl von Hexziffern in Escapesequenz: '{0}'",
-  // \&[a-zA-Z][a-zA-Z0-9]+;
-  "undefinierte HTML-Entität '{0}'",
-  "unterminierte HTML-Entität '{0}'.",
-  "HTML-Entitäten müssen mit einem Buchstaben beginnen.",
-  // integer overflows
-  "Dezimalzahl überläuft im Vorzeichenbit.",
-  "Überlauf in Dezimalzahl.",
-  "Überlauf in Hexadezimalzahl.",
-  "Überlauf in Binärzahl.",
-  "Überlauf in Oktalzahl.",
-  "Überlauf in Fließkommazahl.",
-  "die Ziffern 8 und 9 sind in Oktalzahlen unzulässig.",
-  "ungültige Hexzahl; mindestens eine Hexziffer erforderlich.",
-  "ungültige Binärzahl; mindestens eine Binärziffer erforderlich.",
-  "der Exponent einer hexadezimalen Fließkommazahl ist erforderlich.",
-  "Hexadezimal-Exponenten müssen mit einer Dezimalziffer anfangen.",
-  "Exponenten müssen mit einer Dezimalziffer anfangen.",
-
-  // Parser messages:
-  "erwartete '{0}', fand aber '{1}'.",
-  "'{0}' ist redundant.",
-  "Template-Tupel-Parameter dürfen nur am Ende auftreten.",
-  "der 'in'-Vertrag der Funktion wurde bereits geparsed.",
-  "der 'out'-Vertrag der Funktion wurde bereits geparsed.",
-  "es wurde kein Verbindungstyp angegeben.",
-  "unbekannter Verbindungstyp '{0}'; gültig sind C, C++, D, Windows, Pascal und System.",
-  "erwartete eine oder mehrere Basisklassen, nicht '{0}'.",
-  "Basisklassen sind in Vorwärtsdeklarationen nicht erlaubt.",
-
-  // Help messages:
-  `dil v{0}
-Copyright (c) 2007-2008, Aziz Köksal. Lizensiert unter der GPL3.
-
-Befehle:
-{1}
-Geben Sie 'dil help <Befehl>' ein, um mehr Hilfe zu einem bestimmten Befehl zu
-erhalten.
-
-Kompiliert mit {2} v{3} am {4}.`,
-
-  `Generiere ein XML- oder HTML-Dokument aus einer D-Quelltextdatei.
-Verwendung:
-  dil gen datei.d [Optionen]
-
-Optionen:
-  --syntax         : generiere Elemente für den Syntaxbaum
-  --xml            : verwende XML-Format (voreingestellt)
-  --html           : verwende HTML-Format
-
-Beispiel:
-  dil gen Parser.d --html --syntax > Parser.html`,
-
-  ``,
-];
--- a/trunk/src/lang_en.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-
-string lang_code = "en";
-
-string[] messages = [
-  // Lexer messages:
-  "illegal character found: '{0}'",
-//   "invalid Unicode character.",
-  "invalid UTF-8 sequence: '{0}'",
-  // ''
-  "unterminated character literal.",
-  "empty character literal.",
-  // #line
-  "expected 'line' after '#'.",
-  "integer expected after #line",
-//   `expected filespec string (e.g. "path\to\file".)`,
-  "unterminated filespec string.",
-  "expected a terminating newline after special token.",
-  // ""
-  "unterminated string literal.",
-  // x""
-  "non-hex character '{0}' found in hex string.",
-  "odd number of hex digits in hex string.",
-  "unterminated hex string.",
-  // /* */ /+ +/
-  "unterminated block comment (/* */).",
-  "unterminated nested comment (/+ +/).",
-  // `` r""
-  "unterminated raw string.",
-  "unterminated back quote string.",
-  // \x \u \U
-  "found undefined escape sequence '{0}'.",
-  "found invalid Unicode escape sequence '{0}'.",
-  "insufficient number of hex digits in escape sequence: '{0}'",
-  // \&[a-zA-Z][a-zA-Z0-9]+;
-  "undefined HTML entity '{0}'",
-  "unterminated HTML entity '{0}'.",
-  "HTML entities must begin with a letter.",
-  // integer overflows
-  "decimal number overflows sign bit.",
-  "overflow in decimal number.",
-  "overflow in hexadecimal number.",
-  "overflow in binary number.",
-  "overflow in octal number.",
-  "overflow in float number.",
-  "digits 8 and 9 are not allowed in octal numbers.",
-  "invalid hex number; at least one hex digit expected.",
-  "invalid binary number; at least one binary digit expected.",
-  "the exponent of a hexadecimal float number is required.",
-  "hexadecimal float exponents must start with a digit.",
-  "exponents must start with a digit.",
-
-  // Parser messages
-  "expected '{0}', but found '{1}'.",
-  "'{0}' is redundant.",
-  "template tuple parameters can only be last.",
-  "the functions 'in' contract was already parsed.",
-  "the functions 'out' contract was already parsed.",
-  "no linkage type was specified.",
-  "unrecognized linkage type '{0}'; valid types are C, C++, D, Windows, Pascal und System.",
-  "expected one or more base classes, not '{0}'.",
-  "base classes are not allowed in forward declarations.",
-
-  // Help messages:
-  `dil v{0}
-Copyright (c) 2007-2008 by Aziz Köksal. Licensed under the GPL3.
-
-Subcommands:
-{1}
-Type 'dil help <subcommand>' for more help on a particular subcommand.
-
-Compiled with {2} v{3} on {4}.`,
-
-  `Generate an XML or HTML document from a D source file.
-Usage:
-  dil gen file.d [Options]
-
-Options:
-  --syntax         : generate tags for the syntax tree
-  --xml            : use XML format (default)
-  --html           : use HTML format
-
-Example:
-  dil gen Parser.d --html --syntax > Parser.html`,
-
-  `Parse a module and extract information from the resulting module dependency graph.
-Usage:
-  dil igraph file.d Format [Options]
-
-  The directory of file.d is implicitly added to the list of import paths.
-
-Format:
-  --dot            : generate a dot document
-  Further options for --dot:
-  -gbp             : Group modules by package names
-  -gbf             : Group modules by full package name
-  -hle             : highlight cyclic edges in the graph
-  -hlv             : highlight modules in cyclic relationship
-
-  --paths          : print a list of paths to the modules imported by file.d
-  --list           : print a list of the module names imported by file.d
-  Options common to --paths and --list:
-  -lN              : print N levels.
-  -m               : mark modules in cyclic relationships with a star.
-
-Options:
-  -Ipath           : add 'path' to the list of import paths where modules are
-                     looked for
-  -rREGEXP         : exclude modules whose names match the regular expression
-                     REGEXP
-  -i               : include unlocatable modules
-
-Example:
-  dil igraph src/main.d`,
-];
--- a/trunk/src/lang_fi.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/++
-  Author: Jari-Matti Mäkelä <jmjm@iki.fi>
-  License: GPL3
-+/
-
-string lang_code = "fi";
-
-string[] messages = [
-  // Lexer messages:
-  "virheellinen merkki: '{0}'",
-//   "virheellinen Unicode-merkki.",
-  "virheellinen UTF-8-merkkijono: '{0}'",
-  // ''
-  "päättämätön merkkiliteraali.",
-  "tyhjä merkkiliteraali.",
-  // #line
-  "odotettiin rivinumeroa '#':n jälkeen.",
-  "odotettiin kokonaislukua #line:n jälkeen",
-//   `odotettiin tiedostomäärittelyn merkkijonoa (esim. "polku\tiedostoon")`,
-  "päättämätön tiedostomäärittely.",
-  "odotettiin päättävää rivinvaihtoa erikoismerkin jälkeen.",
-  // ""
-  "päättämätön merkkijonoliteraali.",
-  // x""
-  "ei-heksamerkki '{0}' heksajonossa.",
-  "pariton määrä heksanumeroita heksajonossa.",
-  "päättämätön heksajono.",
-  // /* */ /+ +/
-  "päättämätön lohkokommentti (/* */).",
-  "päättämätön sisäkkäinen kommentti (/+ +/).",
-  // `` r""
-  "päättämätön raakamerkkijono.",
-  "päättämätön gravisaksenttimerkkijono.",
-  // \x \u \U
-  "määrittelemätön escape-sekvenssi {0}.",
-  "virheellinen Unicode escape-merkki '{0}'.",
-  "riittämätön määrä heksanumeroita escape-sekvenssissä: '{0}'",
-  // \&[a-zA-Z][a-zA-Z0-9]+;
-  "määrittelemätön HTML-entiteetti '{0}'",
-  "päättämätön HTML-entiteetti {0}.",
-  "HTML-entiteettien tulee alkaa kirjaimella.",
-  // integer overflows
-  "desimaaliluku ylivuotaa etumerkin.",
-  "desimaaliluvun ylivuoto.",
-  "heksadesimaaliluvun ylivuoto.",
-  "binääriluvun ylivuoto.",
-  "oktaaliluvun ylivuoto.",
-  "liukuluvun ylivuoto.",
-  "numerot 8 ja 9 eivät ole sallittuja oktaaliluvuissa.",
-  "virheellinen heksaluku; odotettiin vähintään yhtä heksanumeroa.",
-  "virheellinen binääriluku; odotettiin vähintään yhtä binäärinumeroa.",
-  "heksadesimaalisen liukuluvun eksponentti vaaditaan.",
-  "heksadesimaalisen liukuluvun eksponentin tulee alkaa numerolla.",
-  "eksponenttien tulee alkaa numerolla.",
-
-  // Parser messages
-  "odotettiin '{0}':a, mutta luettiin '{1}'.",
-  "'{0}' on redundantti.",
-  "tupla voi esiintyä ainoastaan mallin viimeisenä parametrina.",
-  "funktion alkuehto jäsennettiin jo.",
-  "funktion loppuehto jäsennettiin jo.",
-  "linkitystyyppiä ei määritelty.",
-  "tunnistamaton linkitystyyppi '{0}'; sallittuja tyyppejä ovat C, C++, D, Windows, Pascal ja System.",
-  "odotettiin yhtä tai useampaa luokkaa, ei '{0}':ta.",
-  "kantaluokat eivät ole sallittuja etukäteismäärittelyissä.",
-
-  // Help messages:
-  `dil v{0}
-Copyright (c) 2007-2008, Aziz Köksal. GPL3-lisensöity.
-
-Alikomennot:
-{1}
-Lisäohjeita tietystä alitoiminnosta saa kirjoittamalla 'dil help <toiminto>'.
-
-Käännetty {2}:n versiolla {3} {4}.`,
-
-  `Luo XML- tai HTML-dokumentti D-lähdekoodista.
-
-Käyttö:
-  dil gen tiedosto.d [Valinnat]
-
-Valinnat:
-  --syntax         : luo elementtejä syntaksipuun mukaisesti
-  --xml            : käytä XML-muotoa (oletus)
-  --html           : käytä HTML-muotoa
-
-Esimerkki:
-  dil gen Parser.d --html --syntax > Parser.html`,
-
-  ``,
-];
--- a/trunk/src/lang_tr.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-
-string lang_code = "tr";
-
-string[] messages = [
-  // Lexer messages:
-  "illegal karakter bulundu: '{0}'",
-//   "geçersiz Unikod karakteri.",
-  "geçersiz UTF-8 serisi: '{0}'",
-  // ''
-  "kapanmamış karakter sabiti.",
-  "boş karakter sabiti.",
-  // #line
-  "'#' karakter'den sonra 'line' beklendi.",
-  "'#line''den sonra rakam beklendi.",
-//   `filespec dizgisi beklendi (e.g. "yol\dosya".)`,
-  "kapanmamış filespec dizgisi.",
-  "özel belirtici'den (special token) sonra yeni bir satır beklendi.",
-  // ""
-  "kapanmamış çift tırnak dizgisi.",
-  // x""
-  "heks sayı olmayan karakter '{0}' heks dizgisi içinde bulundu.",
-  "heks dizginin içindeki sayılar çifter çifter olmalıdır.",
-  "kapanmamış heks dizgisi.",
-  // /* */ /+ +/
-  "kapanmamış blok açıklaması (/* */).",
-  "kapanmamış iç içe koyulabilen açıklaması (/+ +/).",
-  // `` r""
-  "kapanmamış çiğ dizgisi.",
-  "kapanmamış ters tırnak dizgisi.",
-  // \x \u \U
-  "tanımlanmamış çıkış serisi '{0}' bulundu.",
-  "geçersiz Unikod çıkış serisi '{0}' bulundu.",
-  "heksadesimal çıkış serisi sayıları yeterli değil: '{0}'",
-  // \&[a-zA-Z][a-zA-Z0-9]+;
-  "tanımlanmamış HTML varlık '{0}'",
-  "kapanmamış HTML varlık '{0}'.",
-  "HTML varlık bir harf ile başlamalı.",
-  // integer overflows
-  "desimal rakamın bit işareti taşdı.",
-  "desimal rakam taşması.",
-  "heksadesimal rakam taşması.",
-  "binari rakam taşması.",
-  "oktal rakam taşması.",
-  "float rakam taşması.",
-  "8 ve 9 sayılar oktal rakamlar'da geçersizdir.",
-  "geçersiz heks rakam; minimum bir heks sayı gereklidir.",
-  "geçersiz binari rakam; minimum bir binari sayı gereklidir.",
-  "bir heksadesimal float rakamın üsü gereklidir.",
-  "heksadesimal float üsler desimal sayı ile başlamalı.",
-  "üsler desimal sayı ile başlamalı.",
-
-  // Parser messages
-  "'{0}' beklendi, ama '{1}' bulundu.",
-  "'{0}' lüzumsuz.",
-  "şablon tuple parametre son sırada olmalı.",
-  "fonksiyonun 'in' kontratı daha önceden ayrıştırılmış.",
-  "fonksiyonun 'out' kontratı daha önceden ayrıştırılmış.",
-  "bağlantı tüp (linkage type) belirtilmedi.",
-  "bilinmeyen bağlantı tüpü (linkage type) '{0}'; geçerli olanlar C, C++, D, Windows, Pascal ve System.",
-  "expected one or more base classes, not '{0}'.", // TODO: translate
-  "base classes are not allowed in forward declarations.", // TODO: translate
-
-  // Help messages:
-  `dil v{0}
-Copyright (c) 2007-2008, Aziz Köksal. Lisans GPL3.
-
-Komutlar:
-{1}
-Belirli komut'a yardım edinmek için 'dil help <komut>' yazınız.
-
-Bu yazılım {2} v{3} ile {4} tarihinde derletilmiş.`,
-
-  `Bir D kaynak kodundan XML veya HTML dosyası oluştur.
-Kullanım:
-  dil gen dosya.d [Seçenekler]
-
-Seçenekler:
-  --syntax         : söz dizimi için etiketler yazdır
-  --xml            : XML biçimi kullan (varsayılır)
-  --html           : HTML biçimi kullan
-
-Örnek:
-  dil gen Parser.d --html --syntax > Parser.html`,
-
-  ``,
-];
--- a/trunk/src/macros_dil.ddoc	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-DDOC = <html>
-<head>
-  <META http-equiv="content-type" content="text/html; charset=utf-8">
-  <title>$(TITLE)</title>
-</head>
-<body>
-<h1><a href="$(SRCFILE)">$(TITLE)</a></h1>
-$(BODY)
-<hr>
-<p class="footer">$(COPYRIGHT) Page generated by $(LINK2 http://code.google.com/p/dil, dil) on $(DATETIME).</p>
-</body>
-</html>
-
-MODFQN = $(TITLE)
-SRCFILE = ./htmlsrc/$(MODFQN).html
-COPYRIGHT = Copyright © 2007-$(YEAR), Aziz Köksal. All rights reserved.
-SYMBOL_ = <a href="http://hg.sharesource.org/dil/file/tip/trunk/src/$(MODPATH)#L$2">$1</a>
-SYMBOL = <a href="$(SRCFILE)#L$2">$1</a>
-
-PRE = <pre>$0</pre>
-DDD = ---
-DMDBUG = $(LINK2 http://d.puremagic.com/issues/show_bug.cgi?id=$1, $2)
--- a/trunk/src/main.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,576 +0,0 @@
-/++
-  Author: Aziz Köksal
-  License: GPL3
-+/
-module main;
-
-import dil.parser.Parser;
-import dil.lexer.Lexer,
-       dil.lexer.Token;
-import dil.ast.Declarations,
-       dil.ast.Expressions,
-       dil.ast.Node,
-       dil.ast.Visitor;
-import dil.semantic.Module;
-import dil.semantic.Symbols;
-import dil.semantic.Pass1,
-       dil.semantic.Pass2,
-       dil.semantic.Interpreter;
-import dil.translator.German;
-import dil.doc.Doc;
-import dil.Messages;
-import dil.CompilerInfo;
-import dil.Information;
-import dil.SourceText;
-import dil.Compilation;
-
-import cmd.Generate;
-import cmd.Statistics;
-import cmd.ImportGraph;
-import cmd.DDoc;
-
-import Settings;
-import SettingsLoader;
-// import TypeRules;
-import common;
-
-import Integer = tango.text.convert.Integer;
-import tango.stdc.stdio;
-import tango.io.File;
-import tango.text.Util;
-import tango.time.StopWatch;
-import tango.text.Ascii : icompare;
-
-/// Entry function of dil.
-void main(char[][] args)
-{
-  auto infoMan = new InfoManager();
-  SettingsLoader.SettingsLoader(infoMan).load();
-  if (infoMan.hasInfo)
-    return printErrors(infoMan);
-
-  if (args.length <= 1)
-    return Stdout(helpMain()).newline;
-
-  string command = args[1];
-  switch (command)
-  {
-  case "c", "compile":
-    if (args.length < 2)
-      return printHelp("compile");
-
-    string[] filePaths;
-    auto context = newCompilationContext();
-    foreach (arg; args[2..$])
-    {
-      if (parseDebugOrVersion(arg, context))
-      {}
-      else
-        filePaths ~= arg;
-    }
-    infoMan = new InfoManager();
-    foreach (filePath; filePaths)
-    {
-      auto mod = new Module(filePath, infoMan);
-      // Parse the file.
-      mod.parse();
-      if (mod.hasErrors)
-        continue;
-
-      // Start semantic analysis.
-      auto pass1 = new SemanticPass1(mod, context);
-      pass1.start();
-
-      void printSymbolTable(ScopeSymbol scopeSym, char[] indent)
-      {
-        foreach (member; scopeSym.members)
-        {
-          auto tokens = getDocTokens(member.node);
-          char[] docText;
-          foreach (token; tokens)
-            docText ~= token.srcText;
-          Stdout(indent).formatln("Id:{}, Symbol:{}, DocText:{}", member.name.str, member.classinfo.name, docText);
-          if (auto s = cast(ScopeSymbol)member)
-            printSymbolTable(s, indent ~ "→ ");
-        }
-      }
-
-      printSymbolTable(mod, "");
-    }
-
-    infoMan.hasInfo && printErrors(infoMan);
-    break;
-  case "ddoc", "d":
-    if (args.length < 4)
-      return printHelp("ddoc");
-
-    auto destination = args[2];
-    auto macroPaths = GlobalSettings.ddocFilePaths;
-    char[][] filePaths;
-    bool incUndoc;
-    bool writeXML;
-    bool verbose;
-    // Parse arguments.
-    auto context = newCompilationContext();
-    foreach (arg; args[3..$])
-    {
-      if (parseDebugOrVersion(arg, context))
-      {}
-      else if (arg == "--xml")
-        writeXML = true;
-      else if (arg == "-i")
-        incUndoc = true;
-      else if (arg == "-v")
-        verbose = true;
-      else if (arg.length > 5 && icompare(arg[$-4..$], "ddoc") == 0)
-        macroPaths ~= arg;
-      else
-        filePaths ~= arg;
-    }
-
-    infoMan = new InfoManager();
-    // Execute command.
-    cmd.DDoc.execute(filePaths, destination, macroPaths, writeXML,
-                     incUndoc, verbose, context, infoMan);
-    infoMan.hasInfo && printErrors(infoMan);
-    break;
-  case "gen", "generate":
-    char[] fileName;
-    GenOption options = GenOption.Tokens;
-    foreach (arg; args[2..$])
-    {
-      switch (arg)
-      {
-      case "--syntax":
-        options |= GenOption.Syntax; break;
-      case "--xml":
-        options |= GenOption.XML; break;
-      case "--html":
-        options |= GenOption.HTML; break;
-      case "--lines":
-        options |= GenOption.PrintLines; break;
-      default:
-        fileName = arg;
-      }
-    }
-    if (!(options & (GenOption.XML | GenOption.HTML)))
-      options |= GenOption.XML; // Default to XML.
-    cmd.Generate.execute(fileName, options, infoMan);
-    infoMan.hasInfo && printErrors(infoMan);
-    break;
-  case "importgraph", "igraph":
-    string filePath;
-    string[] regexps;
-    string siStyle = "dashed"; // static import style
-    string piStyle = "bold";   // public import style
-    uint levels;
-    IGraphOption options;
-    auto context = newCompilationContext();
-    foreach (arg; args[2..$])
-    {
-      if (parseDebugOrVersion(arg, context))
-      {}
-      else if (strbeg(arg, "-I"))
-        context.importPaths ~= arg[2..$];
-      else if(strbeg(arg, "-r"))
-        regexps ~= arg[2..$];
-      else if(strbeg(arg, "-l"))
-        levels = Integer.toInt(arg[2..$]);
-      else if(strbeg(arg, "-si"))
-        siStyle = arg[3..$];
-      else if(strbeg(arg, "-pi"))
-        piStyle = arg[3..$];
-      else
-        switch (arg)
-        {
-        case "--dot":
-          options |= IGraphOption.PrintDot; break;
-        case "--paths":
-          options |= IGraphOption.PrintPaths; break;
-        case "--list":
-          options |= IGraphOption.PrintList; break;
-        case "-i":
-          options |= IGraphOption.IncludeUnlocatableModules; break;
-        case "-hle":
-          options |= IGraphOption.HighlightCyclicEdges; break;
-        case "-hlv":
-          options |= IGraphOption.HighlightCyclicVertices; break;
-        case "-gbp":
-          options |= IGraphOption.GroupByPackageNames; break;
-        case "-gbf":
-          options |= IGraphOption.GroupByFullPackageName; break;
-        case "-m":
-          options |= IGraphOption.MarkCyclicModules; break;
-        default:
-          filePath = arg;
-        }
-    }
-    cmd.ImportGraph.execute(filePath, context, regexps, levels, siStyle, piStyle, options);
-    break;
-  case "stats", "statistics":
-    char[][] filePaths;
-    bool printTokensTable;
-    bool printNodesTable;
-    foreach (arg; args[2..$])
-      if (arg == "--toktable")
-        printTokensTable = true;
-      else if (arg == "--asttable")
-        printNodesTable = true;
-      else
-        filePaths ~= arg;
-    cmd.Statistics.execute(filePaths, printTokensTable, printNodesTable);
-    break;
-  case "tok", "tokenize":
-    SourceText sourceText;
-    char[] filePath;
-    char[] separator;
-    bool ignoreWSToks;
-    bool printWS;
-
-    foreach (arg; args[2..$])
-    {
-      if (strbeg(arg, "-s"))
-        separator = arg[2..$];
-      else if (arg == "-")
-        sourceText = new SourceText("stdin", readStdin());
-      else if (arg == "-i")
-        ignoreWSToks = true;
-      else if (arg == "-ws")
-        printWS = true;
-      else
-        filePath = arg;
-    }
-
-    separator || (separator = "\n");
-    if (!sourceText)
-      sourceText = new SourceText(filePath, true);
-
-    infoMan = new InfoManager();
-    auto lx = new Lexer(sourceText, infoMan);
-    lx.scanAll();
-    auto token = lx.firstToken();
-
-    for (; token.kind != TOK.EOF; token = token.next)
-    {
-      if (token.kind == TOK.Newline || ignoreWSToks && token.isWhitespace)
-        continue;
-      if (printWS && token.ws)
-        Stdout(token.wsChars);
-      Stdout(token.srcText)(separator);
-    }
-
-    infoMan.hasInfo && printErrors(infoMan);
-    break;
-  case "trans", "translate":
-    if (args.length < 3)
-      return printHelp("trans");
-
-    if (args[2] != "German")
-      return Stdout.formatln("Error: unrecognized target language \"{}\"", args[2]);
-
-    infoMan = new InfoManager();
-    auto filePath = args[3];
-    auto mod = new Module(filePath, infoMan);
-    // Parse the file.
-    mod.parse();
-    if (!mod.hasErrors)
-    { // Translate
-      auto german = new GermanTranslator(Stdout, "  ");
-      german.translate(mod.root);
-    }
-    printErrors(infoMan);
-    break;
-  case "profile":
-    if (args.length < 3)
-      break;
-    char[][] filePaths;
-    if (args[2] == "dstress")
-    {
-      auto text = cast(char[])(new File("dstress_files")).read();
-      filePaths = split(text, "\0");
-    }
-    else
-      filePaths = args[2..$];
-
-    StopWatch swatch;
-    swatch.start;
-
-    foreach (filePath; filePaths)
-      (new Lexer(new SourceText(filePath, true))).scanAll();
-
-    Stdout.formatln("Scanned in {:f10}s.", swatch.stop);
-    break;
-  // case "parse":
-  //   if (args.length == 3)
-  //     parse(args[2]);
-  //   break;
-  case "?", "help":
-    printHelp(args.length >= 3 ? args[2] : "");
-    break;
-  // case "typerules":
-  //   genHTMLTypeRulesTables();
-  //   break;
-  default:
-  }
-}
-
-char[] readStdin()
-{
-  char[] text;
-  while (1)
-  {
-    auto c = getc(stdin);
-    if (c == EOF)
-      break;
-    text ~= c;
-  }
-  return text;
-}
-
-/// Available commands.
-const char[] COMMANDS =
-  "  compile (c)\n"
-  "  ddoc (d)\n"
-  "  generate (gen)\n"
-  "  help (?)\n"
-  "  importgraph (igraph)\n"
-  "  statistics (stats)\n"
-  "  tokenize (tok)\n"
-  "  translate (trans)\n";
-
-bool strbeg(char[] str, char[] begin)
-{
-  if (str.length >= begin.length)
-  {
-    if (str[0 .. begin.length] == begin)
-      return true;
-  }
-  return false;
-}
-
-/// Creates the global compilation context.
-CompilationContext newCompilationContext()
-{
-  auto cc = new CompilationContext;
-  cc.importPaths = GlobalSettings.importPaths;
-  cc.addVersionId("dil");
-  cc.addVersionId("all");
-version(D2)
-  cc.addVersionId("D_Version2");
-  foreach (versionId; GlobalSettings.versionIds)
-    if (!Lexer.isReservedIdentifier(versionId))
-      cc.versionIds[versionId] = true;
-  return cc;
-}
-
-bool parseDebugOrVersion(string arg, CompilationContext context)
-{
-  if (strbeg(arg, "-debug"))
-  {
-    if (arg.length > 7)
-    {
-      auto val = arg[7..$];
-      if (isdigit(val[0]))
-        context.debugLevel = Integer.toInt(val);
-      else if (!Lexer.isReservedIdentifier(val))
-        context.addDebugId(val);
-    }
-    else
-      context.debugLevel = 1;
-  }
-  else if (arg.length > 9 && strbeg(arg, "-version="))
-  {
-    auto val = arg[9..$];
-    if (isdigit(val[0]))
-      context.versionLevel = Integer.toInt(val);
-    else if (!Lexer.isReservedIdentifier(val))
-      context.addVersionId(val);
-  }
-  else
-    return false;
-  return true;
-}
-
-/// Prints the errors collected in infoMan.
-void printErrors(InfoManager infoMan)
-{
-  foreach (info; infoMan.info)
-  {
-    char[] errorFormat;
-    if (info.classinfo is LexerError.classinfo)
-      errorFormat = GlobalSettings.lexerErrorFormat;
-    else if (info.classinfo is ParserError.classinfo)
-      errorFormat = GlobalSettings.parserErrorFormat;
-    else if (info.classinfo is SemanticError.classinfo)
-      errorFormat = GlobalSettings.semanticErrorFormat;
-    else if (info.classinfo is Warning.classinfo)
-      errorFormat = "{0}: Warning: {3}";
-    else
-      continue;
-    auto err = cast(Problem)info;
-    Stderr.formatln(errorFormat, err.filePath, err.loc, err.col, err.getMsg);
-  }
-}
-
-/// Prints the compiler's main help message.
-char[] helpMain()
-{
-  auto COMPILED_WITH = __VENDOR__;
-  auto COMPILED_VERSION = Format("{}.{,:d3}", __VERSION__/1000, __VERSION__%1000);
-  auto COMPILED_DATE = __TIMESTAMP__;
-  return FormatMsg(MID.HelpMain, VERSION, COMMANDS, COMPILED_WITH,
-                   COMPILED_VERSION, COMPILED_DATE);
-}
-
-/// Prints a help message for command.
-void printHelp(char[] command)
-{
-  char[] msg;
-  switch (command)
-  {
-  case "c", "compile":
-    msg = `Compile D source files.
-Usage:
-  dil compile file.d [file2.d, ...] [Options]
-
-  This command only parses the source files and does little semantic analysis.
-  Errors are printed to standard error output.
-
-Options:
-  -debug           : include debug code
-  -debug=level     : include debug(l) code where l <= level
-  -debug=ident     : include debug(ident) code
-  -version=level   : include version(l) code where l >= level
-  -version=ident   : include version(ident) code
-
-Example:
-  dil c src/main.d`;
-    break;
-  case "ddoc", "d":
-    msg = `Generate documentation from DDoc comments in D source files.
-Usage:
-  dil ddoc Destination file.d [file2.d, ...] [Options]
-
-  Destination is the folder where the documentation files are written to.
-  Files with the extension .ddoc are recognized as macro definition files.
-
-Options:
-  --xml            : write XML instead of HTML documents
-  -i               : include undocumented symbols
-  -v               : verbose output
-
-Example:
-  dil d doc/ src/main.d src/macros_dil.ddoc -i`;
-    break;
-  case "gen", "generate":
-//     msg = GetMsg(MID.HelpGenerate);
-    msg = `Generate an XML or HTML document from a D source file.
-Usage:
-  dil gen file.d [Options]
-
-Options:
-  --syntax         : generate tags for the syntax tree
-  --xml            : use XML format (default)
-  --html           : use HTML format
-  --lines          : print line numbers
-
-Example:
-  dil gen Parser.d --html --syntax > Parser.html`;
-    break;
-  case "importgraph", "igraph":
-//     msg = GetMsg(MID.HelpImportGraph);
-    msg = `Parse a module and build a module dependency graph based on its imports.
-Usage:
-  dil igraph file.d Format [Options]
-
-  The directory of file.d is implicitly added to the list of import paths.
-
-Format:
-  --dot            : generate a dot document (default)
-  Options related to --dot:
-  -gbp             : Group modules by package names
-  -gbf             : Group modules by full package name
-  -hle             : highlight cyclic edges in the graph
-  -hlv             : highlight modules in cyclic relationships
-  -siSTYLE         : the edge style to use for static imports
-  -piSTYLE         : the edge style to use for public imports
-  STYLE can be: "dashed", "dotted", "solid", "invis" or "bold"
-
-  --paths          : print the file paths of the modules in the graph
-
-  --list           : print the names of the module in the graph
-  Options common to --paths and --list:
-  -lN              : print N levels.
-  -m               : use '*' to mark modules in cyclic relationships
-
-Options:
-  -Ipath           : add 'path' to the list of import paths where modules are
-                     looked for
-  -rREGEXP         : exclude modules whose names match the regular expression
-                     REGEXP
-  -i               : include unlocatable modules
-
-Example:
-  dil igraph src/main.d --list
-  dil igraph src/main.d | dot -Tpng > main.png`;
-    break;
-  case "tok", "tokenize":
-    msg = `Print the tokens of a D source file.
-Usage:
-  dil tok file.d [Options]
-
-Options:
-  -               : reads text from the standard input.
-  -sSEPARATOR     : print SEPARATOR instead of newline between tokens.
-  -i              : ignore whitespace tokens (e.g. comments, shebang etc.)
-  -ws             : print a token's preceding whitespace characters.
-
-Example:
-  echo "module foo; void func(){}" | dil tok -
-  dil tok main.d | grep ^[0-9]`;
-    break;
-  case "stats", "statistics":
-    msg = "Gather statistics about D source files.
-Usage:
-  dil stat file.d [file2.d, ...] [Options]
-
-Options:
-  --toktable      : print the count of all kinds of tokens in a table.
-  --asttable      : print the count of all kinds of nodes in a table.
-
-Example:
-  dil stat src/dil/Parser.d src/dil/Lexer.d";
-    break;
-  case "trans", "translate":
-    msg = `Translate a D source file to another language.
-Usage:
-  dil translate Language file.d
-
-  Languages that are supported:
-    *) German
-
-Example:
-  dil trans German src/main.d`;
-    break;
-  default:
-    msg = helpMain();
-  }
-  Stdout(msg).newline;
-}
-
-/+void parse(string fileName)
-{
-  auto mod = new Module(fileName);
-  mod.parse();
-
-  void print(Node[] decls, char[] indent)
-  {
-    foreach(decl; decls)
-    {
-      assert(decl !is null);
-      Stdout.formatln("{}{}: begin={} end={}", indent, decl.classinfo.name, decl.begin ? decl.begin.srcText : "\33[31mnull\33[0m", decl.end ? decl.end.srcText : "\33[31mnull\33[0m");
-      print(decl.children, indent ~ "  ");
-    }
-  }
-  print(mod.root.children, "");
-}+/
--- a/trunk/src/predefined.ddoc	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-DDOC = <html>
-<head>
-  <META http-equiv="content-type" content="text/html; charset=utf-8">
-  <title>$(TITLE)</title>
-</head>
-<body>
-<h1>$(TITLE)</h1>
-$(BODY)
-<hr>
-<p class="footer">$(COPYRIGHT) | Page generated by $(LINK2 http://code.google.com/p/dil, dil) on $(DATETIME).</p>
-</body>
-</html>
-
-B = <b>$0</b>
-I = <i>$0</i>
-U = <u>$0</u>
-P = <p>$0</p>
-DL = <dl>$0</dl>
-DT = <dt>$0</dt>
-DD = <dd>$0</dd>
-TABLE = <table>$0</table>
-TR = <tr>$0</tr>
-TH = <th>$0</th>
-TD = <td>$0</td>
-OL = <ol>$0</ol>
-UL = <ul>$0</ul>
-LI = <li>$0</li>
-BIG = <big>$0</big>
-SMALL = <small>$0</small>
-BR = <br>
-LINK = <a href="$0">$0</a>
-LINK2 = <a href="$1">$+</a>
-
-RED = <font color="red">$0</font>
-BLUE = <font color="blue">$0</font>
-GREEN = <font color="green">$0</font>
-YELLOW = <font color="yellow">$0</font>
-BLACK = <font color="black">$0</font>
-WHITE = <font color="white">$0</font>
-
-D_CODE    = <pre class="d_code">$0</pre>
-D_COMMENT = $(GREEN $0)
-D_STRING  = $(RED $0)
-D_KEYWORD = $(BLUE $0)
-D_PSYMBOL = $(U $0)
-D_PARAM   = $(I $0)
-
-DDOC_COMMENT   = <!-- $0 -->
-DDOC_DECL      = $(DT $(BIG $0))
-DDOC_DECL_DD   = $(DD $0)
-DDOC_DITTO     = $(BR)$0
-
-DDOC_SECTIONS  = $0
-DDOC_SUMMARY   = $0$(BR)$(BR)
-DDOC_DESCRIPTION = $0$(BR)$(BR)
-DDOC_AUTHORS   = $(B Authors:)$(BR)
-$0$(BR)$(BR)
-DDOC_BUGS      = $(RED BUGS:)$(BR)
-$0$(BR)$(BR)
-DDOC_COPYRIGHT = $(B Copyright:)$(BR)
-$0$(BR)$(BR)
-DDOC_DATE      = $(B Date:)$(BR)
-$0$(BR)$(BR)
-DDOC_DEPRECATED = $(RED Deprecated:)$(BR)
-$0$(BR)$(BR)
-DDOC_EXAMPLES  = $(B Examples:)$(BR)
-$0$(BR)$(BR)
-DDOC_HISTORY   = $(B History:)$(BR)
-$0$(BR)$(BR)
-DDOC_LICENSE   = $(B License:)$(BR)
-$0$(BR)$(BR)
-DDOC_RETURNS   = $(B Returns:)$(BR)
-$0$(BR)$(BR)
-DDOC_SEE_ALSO  = $(B See Also:)$(BR)
-$0$(BR)$(BR)
-DDOC_STANDARDS = $(B Standards:)$(BR)
-$0$(BR)$(BR)
-DDOC_THROWS    = $(B Throws:)$(BR)
-$0$(BR)$(BR)
-DDOC_VERSION   = $(B Version:)$(BR)
-$0$(BR)$(BR)
-DDOC_SECTION_H = $(B $0)$(BR)
-DDOC_SECTION   = $0$(BR)$(BR)
-
-DDOC_MEMBERS   = $(DL $0)
-DDOC_MODULE_MEMBERS    = $(DDOC_MEMBERS $0)
-DDOC_CLASS_MEMBERS     = $(DDOC_MEMBERS $0)
-DDOC_INTERFACE_MEMBERS = $(DDOC_MEMBERS $0)
-DDOC_STRUCT_MEMBERS    = $(DDOC_MEMBERS $0)
-DDOC_UNION_MEMBERS     = $(DDOC_MEMBERS $0)
-DDOC_TEMPLATE_MEMBERS  = $(DDOC_MEMBERS $0)
-DDOC_ENUM_MEMBERS      = $(DDOC_MEMBERS $0)
-
-DDOC_PARAMS = $(B Params:)$(BR)
-$(TABLE $0)$(BR)
-DDOC_PARAM_ROW = $(TR $0)
-DDOC_PARAM_ID = $(TD $0)
-DDOC_PARAM_DESC = $(TD $0)
-DDOC_BLANKLINE = $(BR)$(BR)
-
-DDOC_PSYMBOL = $(U $0)
-DDOC_KEYWORD = $(B $0)
-DDOC_PARAM = $(I $0)
-
-ATTRIBUTES = [$0]
-PROT = $0
-STC = $0
-LINKAGE = $0
-SYMBOL = $1
--- a/trunk/src/predefined_xml.ddoc	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-DDOC = <root>
-<module>$(TITLE)</module>
-$(BODY)
-<copyright>$(COPYRIGHT)</copyright>
-<generator>dil $(DDOC_VERSION) $(LINK http://code.google.com/p/dil)
-  <date>$(DATETIME)</date>
-</generator>
-</root>
-
-B = <b>$0</b>
-I = <i>$0</i>
-U = <u>$0</u>
-P = <p>$0</p>
-DL = <dl>$0</dl>
-DT = <dt>$0</dt>
-DD = <dd>$0</dd>
-TABLE = <table>$0</table>
-TR = <tr>$0</tr>
-TH = <th>$0</th>
-TD = <td>$0</td>
-OL = <ol>$0</ol>
-UL = <ul>$0</ul>
-LI = <li>$0</li>
-BIG = <big>$0</big>
-SMALL = <small>$0</small>
-BR = <br />
-LINK = <link href="$0">$0</link>
-LINK2 = <link href="$1">$+</link>
-
-RED = <font color="red">$0</font>
-BLUE = <font color="blue">$0</font>
-GREEN = <font color="green">$0</font>
-YELLOW = <font color="yellow">$0</font>
-BLACK = <font color="black">$0</font>
-WHITE = <font color="white">$0</font>
-
-D_CODE    = <dcode>$0</dcode>
-D_COMMENT = <dcomment>$0</dcomment>
-D_STRING  = <dstring>$0</dstring>
-D_COMMENT = <dkeyword>$0</dkeyword>
-D_PSYMBOL = <dpsymbol>$0</dpsymbol>
-D_PARAM   = <dparam>$0</dparam>
-
-DDOC_COMMENT   = <!-- $0 -->
-DDOC_DECL      = <declaration type="$1">$2</declaration>
-DDOC_DECL_DD   = $0
-DDOC_DITTO     = $0
-
-DDOC_SECTIONS    = <description>$0</description>
-DDOC_SECTION_T   = <section name="$1">$2</section>
-DDOC_SUMMARY     = $(DDOC_SECTION_T summary, $0)
-DDOC_DESCRIPTION = $(DDOC_SECTION_T description, $0)
-DDOC_AUTHORS     = $(DDOC_SECTION_T authors, $0)
-DDOC_BUGS        = $(DDOC_SECTION_T bugs, $0)
-DDOC_COPYRIGHT   = $(DDOC_SECTION_T copyright, $0)
-DDOC_DATE        = $(DDOC_SECTION_T date, $0)
-DDOC_DEPRECATED  = $(DDOC_SECTION_T deprecated, $0)
-DDOC_EXAMPLES    = $(DDOC_SECTION_T examples, $0)
-DDOC_HISTORY     = $(DDOC_SECTION_T history, $0)
-DDOC_LICENSE     = $(DDOC_SECTION_T license, $0)
-DDOC_RETURNS     = $(DDOC_SECTION_T returns, $0)
-DDOC_SEE_ALSO    = $(DDOC_SECTION_T seealso, $0)
-DDOC_STANDARDS   = $(DDOC_SECTION_T standards, $0)
-DDOC_THROWS      = $(DDOC_SECTION_T throws, $0)
-DDOC_VERSION     = $(DDOC_SECTION_T version, $0)
-DDOC_SECTION_H   = $(B $0)$(BR)
-DDOC_SECTION     = $0
-
-DDOC_MEMBERS           = <members>$0</members>
-DDOC_MODULE_MEMBERS    = $(DDOC_MEMBERS $0)
-DDOC_CLASS_MEMBERS     = $(DDOC_MEMBERS $0)
-DDOC_INTERFACE_MEMBERS = $(DDOC_MEMBERS $0)
-DDOC_STRUCT_MEMBERS    = $(DDOC_MEMBERS $0)
-DDOC_UNION_MEMBERS     = $(DDOC_MEMBERS $0)
-DDOC_TEMPLATE_MEMBERS  = $(DDOC_MEMBERS $0)
-DDOC_ENUM_MEMBERS      = $(DDOC_MEMBERS $0)
-
-DDOC_PARAMS     = <params>$0</params>
-DDOC_PARAM_ROW  = <param>$0</param>
-DDOC_PARAM_ID   = <name>$0</name>
-DDOC_PARAM_DESC = <description>$0</description>
-DDOC_BLANKLINE  = <newline />
-
-DDOC_PSYMBOL = $(U $0)
-DDOC_KEYWORD = $(B $0)
-DDOC_PARAM   = $0
-
-ATTRIBUTES      = <attributes>$0</attributes>
-ATTRIBUTE       = <attribute type="$1">$2</attribute>
-PROT            = $(ATTRIBUTE protection, $0)
-STC             = $(ATTRIBUTE storage, $0)
-LINKAGE         = $(ATTRIBUTE linkage, $0)
-SYMBOL          = $1
-PARENTS         = <parents>$0</parents>
-TYPE            = <type>$0</type>
-PARAMS          = <params>$0</params>
-RETURNS         = <returns>$0</returns>
-TEMPLATE_PARAMS = <templateparams>$0</templateparams>
--- a/trunk/src/tests/forward01.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-/++
-  Author: Jari-Matti Mäkelä
-+/
-
-// Impossible circular composition.
-struct A { B b; }
-struct B { A a; }
--- a/trunk/src/tests/forward02.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-/++
-  Author: Jari-Matti Mäkelä
-+/
-
-// Valid circular composition because of pointer.
-struct A { B* b; }
-struct B { A a; }
-// Equivalent to:
-struct A { A* a; }
-
-// Valid circular composition because classes are reference types.
-class C { D d; }
-class D { C c; }
--- a/trunk/src/tests/forward03.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-/++
-  Author: Aziz Köksal
-+/
-
-// Impossible static circular reference.
-const x = y;
-const y = x;
-
-// Impossible static circular reference.
-struct A
-{ const int a = B.b; }
-struct B
-{ const int b = A.a; }
-
-struct C
-{
-  const x = C.x;
-}
\ No newline at end of file
--- a/trunk/src/tests/forward04.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-/++
-  Author: Aziz Köksal
-+/
-
-class A { auto x = pi; }
-mixin("const pi = 3.14;");
--- a/trunk/src/tests/forward05.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-/++
-  Author: Aziz Köksal
-+/
-
-struct A
-{ int a = B.x; }
-
-struct B
-{ const int x = 1; }
--- a/trunk/src/translator/about.ui	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-<ui version="4.0" >
- <class>AboutDialog</class>
- <widget class="QDialog" name="AboutDialog" >
-  <property name="windowModality" >
-   <enum>Qt::WindowModal</enum>
-  </property>
-  <property name="geometry" >
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>414</width>
-    <height>157</height>
-   </rect>
-  </property>
-  <property name="windowTitle" >
-   <string>About</string>
-  </property>
-  <layout class="QVBoxLayout" >
-   <item>
-    <widget class="QLabel" name="label1" >
-     <property name="text" >
-      <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
-p, li { white-space: pre-wrap; }
-&lt;/style>&lt;/head>&lt;body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
-&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">A tool for managing message catalogues in different languages.&lt;/p>
-&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">These catalogues can be used to make an application multilingual.&lt;/p>
-&lt;p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">&lt;/p>
-&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007 by Aziz Köksal &amp;lt;aziz.koeksal@gmail.com&amp;gt;&lt;/p>
-&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Licensed under the GPL2.&lt;/p>&lt;/body>&lt;/html></string>
-     </property>
-     <property name="textFormat" >
-      <enum>Qt::RichText</enum>
-     </property>
-     <property name="alignment" >
-      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
-     </property>
-     <property name="wordWrap" >
-      <bool>true</bool>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <widget class="QDialogButtonBox" name="buttonBox" >
-     <property name="standardButtons" >
-      <set>QDialogButtonBox::Ok</set>
-     </property>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <resources/>
- <connections>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>accepted()</signal>
-   <receiver>AboutDialog</receiver>
-   <slot>close()</slot>
-   <hints>
-    <hint type="sourcelabel" >
-     <x>346</x>
-     <y>274</y>
-    </hint>
-    <hint type="destinationlabel" >
-     <x>317</x>
-     <y>256</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
-</ui>
--- a/trunk/src/translator/closing_project.ui	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-<ui version="4.0" >
- <class>ClosingProjectDialog</class>
- <widget class="QDialog" name="ClosingProjectDialog" >
-  <property name="geometry" >
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>400</width>
-    <height>300</height>
-   </rect>
-  </property>
-  <property name="windowTitle" >
-   <string>Closing Project</string>
-  </property>
-  <layout class="QVBoxLayout" >
-   <item>
-    <widget class="QLabel" name="label" >
-     <property name="text" >
-      <string>The following documents have been modified:</string>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <widget class="QTreeWidget" name="treeWidget" >
-     <column>
-      <property name="text" >
-       <string>Title</string>
-      </property>
-     </column>
-     <column>
-      <property name="text" >
-       <string>Full Path</string>
-      </property>
-     </column>
-    </widget>
-   </item>
-   <item>
-    <spacer>
-     <property name="orientation" >
-      <enum>Qt::Vertical</enum>
-     </property>
-     <property name="sizeHint" >
-      <size>
-       <width>382</width>
-       <height>33</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" >
-     <item>
-      <spacer>
-       <property name="orientation" >
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeHint" >
-        <size>
-         <width>40</width>
-         <height>20</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-     <item>
-      <widget class="QPushButton" name="button_Save_Selected" >
-       <property name="text" >
-        <string>&amp;Save Selected</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QPushButton" name="button_Discard_All" >
-       <property name="text" >
-        <string>&amp;Discard All Changes</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QPushButton" name="button_Cancel" >
-       <property name="text" >
-        <string>&amp;Cancel</string>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-  </layout>
- </widget>
- <resources/>
- <connections>
-  <connection>
-   <sender>button_Save_Selected</sender>
-   <signal>clicked()</signal>
-   <receiver>ClosingProjectDialog</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel" >
-     <x>144</x>
-     <y>269</y>
-    </hint>
-    <hint type="destinationlabel" >
-     <x>179</x>
-     <y>238</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>button_Cancel</sender>
-   <signal>clicked()</signal>
-   <receiver>ClosingProjectDialog</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel" >
-     <x>337</x>
-     <y>268</y>
-    </hint>
-    <hint type="destinationlabel" >
-     <x>328</x>
-     <y>248</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
-</ui>
--- a/trunk/src/translator/errors.py	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-# Author: Aziz Köksal
-# License: GPL2
-import exceptions
-
-class LoadingError(exceptions.Exception):
-  def __init__(self, msg):
-    self.msg = msg
-    return
-  def __str__(self):
-    return self.msg
--- a/trunk/src/translator/langfile.py	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-# -*- coding: utf-8 -*-
-# Author: Aziz Köksal
-# License: GPL2
-import yaml
-from errors import LoadingError
-
-# Avoid that all unicode strings are tagged with "!!python/unicode".
-def unicode_representer(dumper, data):
-  return dumper.represent_scalar(u'tag:yaml.org,2002:str', data)
-yaml.add_representer(unicode, unicode_representer)
-
-def newLangFile(langCode, authors, license):
-  return {
-    "LangCode":langCode,
-    "Authors":authors,
-    "License":license,
-    "Messages":[]
-  }
-
-class LangFile:
-  def __init__(self, filePath):
-    from os import path
-    self.filePath = path.abspath(filePath)
-    self.isSource = False
-    self.source = None
-    # Load language file and check data integrity.
-    try:
-      self.doc = yaml.load(open(filePath, "r"))
-    except yaml.YAMLError, e:
-      raise LoadingError(str(e))
-    self.verify()
-
-  def verify(self):
-    doc = self.doc
-    self.checkType(doc, dict)
-    try:
-      self.langCode = str(doc["LangCode"])
-      self.authors = list(doc["Authors"])
-      self.license = unicode(doc["License"])
-      self.messages = list(doc["Messages"])
-    except KeyError, e:
-      raise LoadingError("Missing member '%s' in '%s'" % (e.message, filePath))
-
-    authors = []
-    for author in self.authors:
-      self.checkType(author, dict, "LangFile: author must be of type dict.")
-      try:
-        author["Name"] = unicode(author["Name"])
-        author["EMail"] = str(author["EMail"])
-        authors += [author]
-      except KeyError, e:
-        raise LoadingError("Author is missing '%s' in '%s'" % (e.message, filePath))
-    self.authors = authors
-
-    self.msgDict = {} # {ID : msg, ...}
-    for msg in self.messages:
-      self.checkType(msg, dict, "LangFile: messages must be of type dict.")
-      try:
-        msg["ID"] = int(msg["ID"])
-        msg["Text"] = unicode(msg["Text"])
-        msg["Annot"] = unicode(msg["Annot"])
-        msg["LastEd"] = int(msg["LastEd"])
-      except KeyError, e:
-        raise LoadingError("LangFile: a message is missing the '%s' key." % str(e))
-      self.msgDict[msg["ID"]] = msg
-
-  def checkType(self, var, type_, msg=""):
-    if not isinstance(var, type_):
-      raise LoadingError(msg)
-
-  def setSource(self, sourceLangFile):
-    self.source = sourceLangFile
-
-  def getMsg(self, ID):
-    for msg in self.messages:
-      if msg["ID"] == ID:
-        return msg
-    return None
-
-  def createMissingMessages(self, IDs):
-    for ID in IDs:
-      if not self.msgDict.has_key(ID):
-        msg = self.createEmptyMsg(ID)
-        self.msgDict[ID] = msg
-        self.messages += [msg]
-
-  def createEmptyMsg(self, ID):
-    return {"ID":ID,"Text":"","Annot":"","LastEd":""}
-
-  def save(self):
-    self.doc["LangCode"] = self.langCode
-    self.doc["License"] = self.license
-    self.doc["Authors"] = self.authors
-    langFile = open(self.filePath, "w")
-    yaml.dump(self.doc, stream=langFile, allow_unicode=True)
-    langFile.close()
-
-  def setLangCode(self, langCode):
-    self.langCode = langCode
-
-  def setLicense(self, license):
-    self.license = license
-
-  def setAuthors(self, authors):
-    self.authors = authors
-
-  def getFileName(self):
-    from os import path
-    return path.basename(self.filePath)
-
-  def getFilePath(self):
-    return self.filePath
--- a/trunk/src/translator/langfile_properties.ui	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-<ui version="4.0" >
- <class>LangFilePropertiesDialog</class>
- <widget class="QDialog" name="LangFilePropertiesDialog" >
-  <property name="geometry" >
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>400</width>
-    <height>228</height>
-   </rect>
-  </property>
-  <property name="windowTitle" >
-   <string>Language File Properties</string>
-  </property>
-  <layout class="QVBoxLayout" >
-   <item>
-    <layout class="QGridLayout" >
-     <item row="1" column="0" >
-      <widget class="QLabel" name="label_2" >
-       <property name="text" >
-        <string>Language code:</string>
-       </property>
-       <property name="alignment" >
-        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-       </property>
-       <property name="buddy" >
-        <cstring>langCodeField</cstring>
-       </property>
-      </widget>
-     </item>
-     <item row="1" column="1" >
-      <widget class="QLineEdit" name="langCodeField" />
-     </item>
-     <item row="2" column="0" >
-      <widget class="QLabel" name="label" >
-       <property name="text" >
-        <string>Creation date:</string>
-       </property>
-       <property name="alignment" >
-        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-       </property>
-       <property name="buddy" >
-        <cstring>creationDateField</cstring>
-       </property>
-      </widget>
-     </item>
-     <item row="2" column="1" >
-      <widget class="QLineEdit" name="creationDateField" />
-     </item>
-     <item row="0" column="1" >
-      <widget class="QTextEdit" name="authorsField" />
-     </item>
-     <item row="0" column="0" >
-      <widget class="QLabel" name="label_3" >
-       <property name="text" >
-        <string>Author(s):</string>
-       </property>
-       <property name="alignment" >
-        <set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <spacer>
-     <property name="orientation" >
-      <enum>Qt::Vertical</enum>
-     </property>
-     <property name="sizeType" >
-      <enum>QSizePolicy::Fixed</enum>
-     </property>
-     <property name="sizeHint" >
-      <size>
-       <width>20</width>
-       <height>10</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
-   <item>
-    <widget class="QDialogButtonBox" name="buttonBox" >
-     <property name="orientation" >
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="standardButtons" >
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
-     </property>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <resources/>
- <connections>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>accepted()</signal>
-   <receiver>LangFilePropertiesDialog</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel" >
-     <x>227</x>
-     <y>278</y>
-    </hint>
-    <hint type="destinationlabel" >
-     <x>157</x>
-     <y>274</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>rejected()</signal>
-   <receiver>LangFilePropertiesDialog</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel" >
-     <x>295</x>
-     <y>284</y>
-    </hint>
-    <hint type="destinationlabel" >
-     <x>286</x>
-     <y>274</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
-</ui>
--- a/trunk/src/translator/make_ui.sh	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-#!/bin/bash
-
-ui_file=$1
-echo $ui_file \> ui_`basename $ui_file .ui`.py
-pyuic4 $ui_file > ui_`basename $ui_file .ui`.py
--- a/trunk/src/translator/make_uis.sh	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-#!/bin/bash
-
-for ui_file in *.ui; do
-  ./make_ui.sh $ui_file
-done
\ No newline at end of file
--- a/trunk/src/translator/msg_form.ui	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-<ui version="4.0" >
- <class>MsgForm</class>
- <widget class="QWidget" name="MsgForm" >
-  <property name="geometry" >
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>456</width>
-    <height>512</height>
-   </rect>
-  </property>
-  <property name="windowTitle" >
-   <string>Form</string>
-  </property>
-  <layout class="QVBoxLayout" >
-   <item>
-    <widget class="QSplitter" name="splitter" >
-     <property name="orientation" >
-      <enum>Qt::Vertical</enum>
-     </property>
-     <widget class="QWidget" name="layoutWidget" >
-      <layout class="QVBoxLayout" >
-       <item>
-        <widget class="QLabel" name="label" >
-         <property name="text" >
-          <string>Messages:</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QTreeWidget" name="treeWidget" >
-         <column>
-          <property name="text" >
-           <string>1</string>
-          </property>
-         </column>
-        </widget>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="layoutWidget" >
-      <layout class="QGridLayout" >
-       <item row="0" column="0" >
-        <layout class="QVBoxLayout" >
-         <item>
-          <widget class="QLabel" name="label_2" >
-           <property name="text" >
-            <string>Source string:</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QTextEdit" name="sourceEdit" />
-         </item>
-        </layout>
-       </item>
-       <item row="0" column="1" >
-        <layout class="QVBoxLayout" >
-         <item>
-          <widget class="QLabel" name="label_3" >
-           <property name="text" >
-            <string>Source annotation:</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QTextEdit" name="sourceAnnotEdit" />
-         </item>
-        </layout>
-       </item>
-       <item row="1" column="0" >
-        <layout class="QVBoxLayout" >
-         <item>
-          <widget class="QLabel" name="label_4" >
-           <property name="text" >
-            <string>Translation:</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QTextEdit" name="translEdit" />
-         </item>
-        </layout>
-       </item>
-       <item row="1" column="1" >
-        <layout class="QVBoxLayout" >
-         <item>
-          <widget class="QLabel" name="label_5" >
-           <property name="text" >
-            <string>Translator's annotation:</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QTextEdit" name="translAnnotEdit" />
-         </item>
-        </layout>
-       </item>
-      </layout>
-     </widget>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
--- a/trunk/src/translator/new_project.ui	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-<ui version="4.0" >
- <class>NewProjectDialog</class>
- <widget class="QDialog" name="NewProjectDialog" >
-  <property name="geometry" >
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>401</width>
-    <height>131</height>
-   </rect>
-  </property>
-  <property name="windowTitle" >
-   <string>Create New Project</string>
-  </property>
-  <layout class="QVBoxLayout" >
-   <item>
-    <layout class="QGridLayout" >
-     <item row="0" column="0" >
-      <layout class="QGridLayout" >
-       <item row="0" column="0" >
-        <widget class="QLabel" name="label" >
-         <property name="text" >
-          <string>Project name:</string>
-         </property>
-         <property name="alignment" >
-          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-         </property>
-         <property name="buddy" >
-          <cstring>projectName</cstring>
-         </property>
-        </widget>
-       </item>
-       <item row="0" column="1" >
-        <widget class="QLineEdit" name="projectName" />
-       </item>
-       <item row="1" column="0" >
-        <widget class="QLabel" name="label_2" >
-         <property name="text" >
-          <string>Project file:</string>
-         </property>
-         <property name="alignment" >
-          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-         </property>
-         <property name="buddy" >
-          <cstring>projectFilePath</cstring>
-         </property>
-        </widget>
-       </item>
-       <item row="1" column="1" >
-        <layout class="QHBoxLayout" >
-         <item>
-          <widget class="QLineEdit" name="projectFilePath" />
-         </item>
-         <item>
-          <widget class="QToolButton" name="pickFileButton" >
-           <property name="text" >
-            <string>...</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-      </layout>
-     </item>
-     <item row="1" column="0" >
-      <spacer>
-       <property name="orientation" >
-        <enum>Qt::Vertical</enum>
-       </property>
-       <property name="sizeHint" >
-        <size>
-         <width>20</width>
-         <height>40</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-     <item row="2" column="0" >
-      <widget class="QDialogButtonBox" name="buttonBox" >
-       <property name="orientation" >
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="standardButtons" >
-        <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-  </layout>
- </widget>
- <resources/>
- <connections>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>accepted()</signal>
-   <receiver>NewProjectDialog</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel" >
-     <x>228</x>
-     <y>108</y>
-    </hint>
-    <hint type="destinationlabel" >
-     <x>157</x>
-     <y>130</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>rejected()</signal>
-   <receiver>NewProjectDialog</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel" >
-     <x>296</x>
-     <y>114</y>
-    </hint>
-    <hint type="destinationlabel" >
-     <x>286</x>
-     <y>130</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
-</ui>
--- a/trunk/src/translator/project.py	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-# -*- coding: utf-8 -*-
-# Author: Aziz Köksal
-# License: GPL2
-import os
-from errors import LoadingError
-import langfile
-import datetime
-import yaml
-
-def newProjectData(projectName):
-  return {
-    "Name":projectName,
-    "LangFiles":[],
-    "SourceLangFile":'',
-    "MsgIDs":[],
-    "CreationDate":str(datetime.datetime.utcnow()),
-    "BuildScript":''
-  }
-
-class Project:
-  # Members:
-  # name
-  # source
-  # langFilePaths
-  # langFile
-  # msgids
-  # creationDate
-  def __init__(self, projectPath):
-    self.projectPath = projectPath
-    # Load project file and check data integrity.
-    try:
-      self.doc = yaml.load(open(projectPath, "r"))
-    except yaml.YAMLError, e:
-      raise LoadingError(str(e))
-    self.verify()
-
-  def verify(self):
-    doc = self.doc
-    self.checkType(doc, dict)
-    try:
-      self.name = unicode(doc["Name"])
-      self.srcLangFilePath = str(doc["SourceLangFile"])
-      self.langFilePaths = list(doc["LangFiles"])
-      self.msgIDs = list(doc["MsgIDs"])
-      self.creationDate = str(doc["CreationDate"])
-      self.buildScript = str(doc["BuildScript"])
-    except KeyError, e:
-      raise LoadingError("Missing member '%s' in '%s'" % (e.message, projectPath))
-
-    for path in self.langFilePaths:
-      self.checkType(path, str)
-
-    msgIDs = []
-    for msg in self.msgIDs:
-      self.checkType(msg, dict)
-      try:
-         msg["ID"]  = int(msg["ID"])
-         msg["Name"] = unicode(msg["Name"])
-         msg["Order"] = int(msg["Order"])
-      except KeyError, e:
-        raise LoadingError("Project: a message is missing the '%s' key." % str(e))
-      msgIDs += [msg]
-    self.msgIDs = msgIDs
-
-    # Load language files.
-    self.langFiles = []
-    IDList = [msg["ID"] for msgID in self.msgIDs]
-    for filePath in self.langFilePaths:
-      langFile = self.loadLangFile(filePath)
-      langFile.createMissingMessages(IDList)
-      self.langFiles += [langFile]
-    self.srcLangFile = self.loadLangFile(self.srcLangFilePath)
-    self.srcLangFile.createMissingMessages(IDList)
-    self.srcLangFile.isSource = True
-    self.langFiles += [self.srcLangFile]
-
-    for langFile in self.langFiles:
-      langFile.setSource(self.srcLangFile)
-
-  def checkType(self, var, type_):
-    if not isinstance(var, type_):
-      raise LoadingException("%s is not of type %s" % (str(var), str(type_)))
-
-  def loadLangFile(self, filePath):
-    if not os.path.exists(filePath):
-      # Look in project directory.
-      projectDir = os.path.dirname(self.projectPath)
-      filePath2 = os.path.join(projectDir, filePath)
-      if not os.path.exists(filePath2):
-        raise LoadingError("Project: Language file '%s' doesn't exist"%filePath)
-      filePath = filePath2
-    return langfile.LangFile(filePath)
-
-  def setName(self, name):
-    self.name = name
-
-  def setBuildScript(self, filePath):
-    self.buildScript = filePath
-
-  def setCreationDate(self, date):
-    self.creationDate = date
-
-  def save(self):
-    self.doc["Name"] = self.name
-    self.doc["BuildScript"] = self.buildScript
-    self.doc["CreationDate"] = self.creationDate
-    file_ = open(self.projectPath, "w")
-    yaml.dump(self.doc, stream=file_, allow_unicode=True)
-    file_.close()
--- a/trunk/src/translator/project_properties.ui	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,136 +0,0 @@
-<ui version="4.0" >
- <class>ProjectPropertiesDialog</class>
- <widget class="QDialog" name="ProjectPropertiesDialog" >
-  <property name="geometry" >
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>400</width>
-    <height>152</height>
-   </rect>
-  </property>
-  <property name="windowTitle" >
-   <string>Project Properties</string>
-  </property>
-  <layout class="QVBoxLayout" >
-   <item>
-    <layout class="QGridLayout" >
-     <item row="0" column="0" >
-      <widget class="QLabel" name="label_2" >
-       <property name="text" >
-        <string>Project name:</string>
-       </property>
-       <property name="alignment" >
-        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-       </property>
-       <property name="buddy" >
-        <cstring>projectNameField</cstring>
-       </property>
-      </widget>
-     </item>
-     <item row="0" column="1" >
-      <widget class="QLineEdit" name="projectNameField" />
-     </item>
-     <item row="1" column="0" >
-      <widget class="QLabel" name="label" >
-       <property name="text" >
-        <string>Build script:</string>
-       </property>
-       <property name="alignment" >
-        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-       </property>
-       <property name="buddy" >
-        <cstring>buildScriptField</cstring>
-       </property>
-      </widget>
-     </item>
-     <item row="1" column="1" >
-      <layout class="QHBoxLayout" >
-       <item>
-        <widget class="QLineEdit" name="buildScriptField" />
-       </item>
-       <item>
-        <widget class="QToolButton" name="pickFileButton" >
-         <property name="text" >
-          <string>...</string>
-         </property>
-        </widget>
-       </item>
-      </layout>
-     </item>
-     <item row="2" column="1" >
-      <widget class="QLineEdit" name="creationDateField" />
-     </item>
-     <item row="2" column="0" >
-      <widget class="QLabel" name="label_3" >
-       <property name="text" >
-        <string>Creation date:</string>
-       </property>
-       <property name="alignment" >
-        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <spacer>
-     <property name="orientation" >
-      <enum>Qt::Vertical</enum>
-     </property>
-     <property name="sizeHint" >
-      <size>
-       <width>20</width>
-       <height>40</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
-   <item>
-    <widget class="QDialogButtonBox" name="buttonBox" >
-     <property name="orientation" >
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="standardButtons" >
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
-     </property>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <resources/>
- <connections>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>accepted()</signal>
-   <receiver>ProjectPropertiesDialog</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel" >
-     <x>227</x>
-     <y>278</y>
-    </hint>
-    <hint type="destinationlabel" >
-     <x>157</x>
-     <y>274</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>rejected()</signal>
-   <receiver>ProjectPropertiesDialog</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel" >
-     <x>295</x>
-     <y>284</y>
-    </hint>
-    <hint type="destinationlabel" >
-     <x>286</x>
-     <y>274</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
-</ui>
--- a/trunk/src/translator/translator.py	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,685 +0,0 @@
-#! /usr/bin/python
-# -*- coding: utf-8 -*-
-# Author: Aziz Köksal
-# License: GPL2
-import sys, os
-import yaml
-
-from PyQt4 import QtCore, QtGui
-# User interface modules
-from ui_translator import Ui_MainWindow
-from ui_about import Ui_AboutDialog
-from ui_new_project import Ui_NewProjectDialog
-from ui_project_properties import Ui_ProjectPropertiesDialog
-from ui_msg_form import Ui_MsgForm
-from ui_closing_project import Ui_ClosingProjectDialog
-
-from project import Project, newProjectData
-
-g_scriptDir = sys.path[0]
-g_CWD = os.getcwd()
-g_projectExt = ".tproj"
-g_catExt = ".cat"
-g_settingsFile = os.path.join(g_scriptDir, "settings.yaml")
-g_settings = {}
-
-Qt = QtCore.Qt
-Qt.connect = QtCore.QObject.connect
-Qt.disconnect = QtCore.QObject.disconnect
-Qt.SIGNAL = QtCore.SIGNAL
-Qt.SLOT = QtCore.SLOT
-
-def QTabWidgetCloseAll(self):
- for i in range(self.count()-1,-1,-1):
-   widget = self.widget(i)
-   self.removeTab(i)
-   widget.close()
-QtGui.QTabWidget.closeAll = QTabWidgetCloseAll
-
-class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
-  def __init__(self):
-    QtGui.QMainWindow.__init__(self)
-    self.setupUi(self)
-
-    self.project = None
-    # Modifications
-    self.pages = QtGui.QTabWidget()
-    self.setCentralWidget(self.pages)
-    self.disableMenuItems()
-    self.projectDock = QtGui.QDockWidget("Project", self)
-    self.projectTree = ProjectTree(self.projectDock, self)
-    self.projectDock.setWidget(self.projectTree)
-    self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.projectDock)
-    # Custom connections
-    triggered = Qt.SIGNAL("triggered()")
-    Qt.connect(self.action_About, triggered, self.showAboutDialog)
-    Qt.connect(self.action_New_Project, triggered, self.createNewProject)
-    Qt.connect(self.action_Open_Project, triggered, self.openProjectAction)
-    Qt.connect(self.action_Close_Project, triggered, self.closeProjectAction)
-    Qt.connect(self.action_Save, triggered, self.saveForm)
-    Qt.connect(self.action_Save_All, triggered, self.saveAllForms)
-    Qt.connect(self.action_Close, triggered, self.closeForm)
-    Qt.connect(self.action_Close_All, triggered, self.closeAllForms)
-    Qt.connect(self.action_Properties, triggered, self.showProjectProperties)
-    Qt.connect(self.action_Add_Catalogue, triggered, self.addCatalogue)
-    Qt.connect(self.action_Add_New_Catalogue, triggered, self.addNewCatalogue)
-    Qt.connect(self.projectTree, Qt.SIGNAL("itemDoubleClicked(QTreeWidgetItem*,int)"), self.projectTreeItemDblClicked)
-    Qt.connect(self.projectTree, Qt.SIGNAL("onKeyEnter"), self.projectTreeItemActivated)
-    Qt.connect(self.projectTree, Qt.SIGNAL("onKeyDelete"), self.projectTreeItemDeleted)
-
-    shortcut = QtGui.QShortcut(QtGui.QKeySequence(Qt.CTRL+Qt.Key_Tab), self)
-    Qt.connect(shortcut, Qt.SIGNAL("activated()"), self.nextDocument)
-    shortcut = QtGui.QShortcut(QtGui.QKeySequence(Qt.CTRL+Qt.SHIFT+Qt.Key_Tab), self)
-    Qt.connect(shortcut, Qt.SIGNAL("activated()"), self.prevDocument)
-
-    self.readSettings()
-
-  def nextDocument(self):
-    count = self.pages.count()
-    if count < 1: return
-    index = self.pages.currentIndex()+1
-    if index == count: index = 0
-    self.pages.setCurrentIndex(index)
-
-  def prevDocument(self):
-    count = self.pages.count()
-    if count < 1: return
-    index = self.pages.currentIndex()-1
-    if index == -1: index = count-1
-    self.pages.setCurrentIndex(index)
-
-  def showAboutDialog(self):
-    about = QtGui.QDialog()
-    Ui_AboutDialog().setupUi(about)
-    about.exec_()
-
-  def showProjectProperties(self):
-    dialog = ProjectPropertiesDialog(self.project)
-    dialog.exec_()
-    self.projectTree.updateProjectName()
-
-  def createNewProject(self):
-    if self.rejectClosingProject():
-      return
-    dialog = NewProjectDialog()
-    code = dialog.exec_()
-    if code == QtGui.QDialog.Accepted:
-      self.closeProject()
-      self.openProject(str(dialog.projectFilePath.text()))
-
-  def openProjectAction(self):
-    if self.rejectClosingProject():
-      return
-    filePath = QtGui.QFileDialog.getOpenFileName(self, "Select Project File", g_CWD, "Translator Project (*%s)" % g_projectExt);
-    filePath = str(filePath)
-    if filePath:
-      self.closeProject()
-      self.openProject(filePath)
-
-  def openProject(self, filePath):
-    from errors import LoadingError
-    try:
-      self.project = Project(filePath)
-    except LoadingError, e:
-      QtGui.QMessageBox.critical(self, "Error", u"Couldn't load project file:\n\n"+str(e))
-      return
-    self.enableMenuItems()
-    self.projectTree.setProject(self.project)
-
-  def closeProjectAction(self):
-    if not self.rejectClosingProject():
-      self.closeProject()
-
-  def addCatalogue(self):
-    filePath = QtGui.QFileDialog.getOpenFileName(self, "Select Project File", g_CWD, "Catalogue (*%s)" % g_catExt);
-    filePath = str(filePath)
-    # TODO:
-    #self.project.addLangFile(filePath)
-
-  def addNewCatalogue(self):
-    pass
-
-  def rejectClosingProject(self):
-    if self.project == None:
-      return False
-
-    modifiedDocs = []
-    # Check if any open document is modified.
-    for i in range(0, self.pages.count()):
-      if self.pages.widget(i).isModified:
-        modifiedDocs += [self.pages.widget(i)]
-    # Display dialog if so.
-    if len(modifiedDocs):
-      dialog = ClosingProjectDialog(modifiedDocs)
-      code = dialog.exec_()
-      if code == dialog.Accepted:
-        for doc in dialog.getSelectedDocs():
-          self.saveDocument(doc)
-      elif code == dialog.Rejected:
-        return True
-      elif code == dialog.DiscardAll:
-        pass
-
-    return False
-
-  def closeProject(self):
-    if self.project == None:
-      return
-    self.project.save()
-    del self.project
-    self.project = None
-    self.disableMenuItems()
-    self.projectTree.clear()
-    self.pages.closeAll()
-
-  def enableMenuItems(self):
-    #self.action_Close_Project.setEnabled(True)
-    for action in [ self.action_Save,
-                    self.action_Save_All,
-                    self.action_Close,
-                    self.action_Close_All ]:
-      action.setEnabled(True)
-    self.menubar.insertMenu(self.menu_Help.menuAction(), self.menu_Project)
-
-  def disableMenuItems(self):
-    #self.action_Close_Project.setEnabled(False)
-    for action in [ self.action_Save,
-                    self.action_Save_All,
-                    self.action_Close,
-                    self.action_Close_All ]:
-      action.setEnabled(False)
-    self.menubar.removeAction(self.menu_Project.menuAction())
-
-  def projectTreeItemDblClicked(self, item, int):
-    self.projectTreeItemActivated(item)
-
-  def projectTreeItemActivated(self, item):
-    if item == None:
-      return
-
-    if isinstance(item, LangFileItem):
-      msgForm = None
-      if not item.isDocOpen():
-        msgForm = item.openDoc()
-        msgForm.setModifiedCallback(self.formModified)
-      else:
-        msgForm = item.openDoc()
-      index = self.pages.indexOf(msgForm)
-      if index == -1:
-        index = self.pages.addTab(msgForm, msgForm.getDocumentTitle())
-      self.pages.setCurrentIndex(index)
-      msgForm.updateData()
-
-  def projectTreeItemDeleted(self, item):
-    pass
-
-  def formModified(self, form):
-    # Append an asterisk to the tab label
-    index = self.pages.indexOf(form)
-    text = form.getDocumentTitle() + "*"
-    self.pages.setTabText(index, text)
-
-  def saveForm(self):
-    self.saveDocument(self.pages.currentWidget())
-
-  def saveAllForms(self):
-    for i in range(0, self.pages.count()):
-      self.saveDocument(self.pages.widget(i))
-
-  def saveDocument(self, form):
-    if form.isModified:
-      # Reset tab text.
-      index = self.pages.indexOf(form)
-      text = form.getDocumentTitle()
-      self.pages.setTabText(index, text)
-
-      form.save()
-
-  def closeForm(self):
-    if self.pages.currentWidget():
-      self.closeDocument(self.pages.currentWidget())
-
-  def closeAllForms(self):
-    for i in range(self.pages.count()-1, -1, -1):
-      self.closeDocument(self.pages.widget(i))
-
-  def closeDocument(self, form):
-    if form.isModified:
-      MB = QtGui.QMessageBox
-      button = MB.question(self, "Closing Document", "The document '%s' has been modified.\nDo you want to save the changes?" % form.getDocumentFullPath(), MB.Save | MB.Discard | MB.Cancel, MB.Cancel)
-      if button == MB.Cancel:
-        return False
-      if button == MB.Save:
-        self.saveDocument(form)
-    index = self.pages.indexOf(form)
-    self.pages.removeTab(index)
-    form.close()
-    return True
-
-  def closeEvent(self, event):
-    if self.rejectClosingProject():
-      event.ignore()
-      return
-    self.closeProject()
-    self.writeSettings()
-    # Closing application
-
-  def moveToCenterOfDesktop(self):
-    rect = QtGui.QApplication.desktop().geometry()
-    self.move(rect.center() - self.rect().center())
-
-  def readSettings(self):
-    # Set default size
-    self.resize(QtCore.QSize(500, 400))
-    doc = {}
-    try:
-      doc = yaml.load(open(g_settingsFile, "r"))
-    except:
-      self.moveToCenterOfDesktop()
-      return
-
-    g_settings = doc
-    if not isinstance(doc, dict):
-      g_settings = {}
-
-    try:
-      coord = doc["Window"]
-      size = QtCore.QSize(coord["Size"][0], coord["Size"][1])
-      point = QtCore.QPoint(coord["Pos"][0], coord["Pos"][1])
-      self.resize(size)
-      self.move(point)
-    except:
-      self.moveToCenterOfDesktop()
-
-  def writeSettings(self):
-    # Save window coordinates
-    g_settings["Window"] = {
-      "Pos" : [self.pos().x(), self.pos().y()],
-      "Size" : [self.size().width(), self.size().height()]
-    }
-    yaml.dump(g_settings, open(g_settingsFile, "w")) #default_flow_style=False
-
-
-class Document(QtGui.QWidget):
-  def __init__(self):
-    QtGui.QWidget.__init__(self)
-    self.isModified = False
-    self.modifiedCallback = None
-    self.documentTitle = ""
-    self.documentFullPath = ""
-
-  def modified(self):
-    if not self.isModified:
-      self.isModified = True
-      self.modifiedCallback(self)
-
-  def setModifiedCallback(self, func):
-    self.modifiedCallback = func
-
-  def save(self):
-    self.isModified = False
-
-  def close(self):
-    self.emit(Qt.SIGNAL("closed()"))
-    QtGui.QWidget.close(self)
-
-  def getDocumentTitle(self):
-    return self.documentTitle
-
-  def getDocumentFullPath(self):
-    return self.documentFullPath
-
-
-class MessageItem(QtGui.QTreeWidgetItem):
-  def __init__(self, msg):
-    QtGui.QTreeWidgetItem.__init__(self, [str(msg["ID"]), msg["Text"], "Done"])
-    self.msg = msg
-
-  def getID(self):
-    return self.msg["ID"]
-
-  def setMsgText(self, text):
-    self.msg["Text"] = text
-
-  def setMsgAnnot(self, text):
-    self.msg["Annot"] = text
-
-
-class MsgForm(Document, Ui_MsgForm):
-  def __init__(self, langFile):
-    Document.__init__(self)
-    self.documentTitle = langFile.getFileName()
-    self.documentFullPath = langFile.getFilePath()
-    self.setupUi(self)
-    self.vboxlayout.setMargin(0)
-
-    self.langFile = langFile
-    self.currentItem = None
-    self.colID = 0
-    self.colText = 1
-    #self.colStat = 2
-    #self.treeWidget.setColumnCount(3)
-    self.treeWidget.setColumnCount(2)
-    self.treeWidget.setHeaderLabels(["ID", "Text"]) #, "Status"
-    self.msgItemDict = {} # Maps msg IDs to msg items.
-    for msg in self.langFile.messages:
-      item = MessageItem(msg)
-      self.msgItemDict[msg["ID"]] = item
-      self.treeWidget.addTopLevelItem(item)
-
-    Qt.connect(self.treeWidget, Qt.SIGNAL("currentItemChanged (QTreeWidgetItem *,QTreeWidgetItem *)"), self.treeItemChanged)
-    Qt.connect(self.translEdit, Qt.SIGNAL("textChanged()"), self.translEditTextChanged)
-    Qt.connect(self.translAnnotEdit, Qt.SIGNAL("textChanged()"), self.translAnnotEditTextChanged)
-
-    #self.translEdit.focusOutEvent = self.translEditFocusOut
-
-  def sourceMsgChanged(self, msg):
-    # TODO:
-    pass
-
-  def treeItemChanged(self, current, previous):
-    if current == None:
-      self.setTranslMsg("")
-      self.setSourceMsg("")
-      return
-    ID = current.getID()
-    # Set the text controls.
-    # The slots receiving text changed signals do nothing if self.currentItem is None.
-    self.currentItem = None
-    self.setTranslMsg(self.langFile.getMsg(ID))
-    self.setSourceMsg(self.langFile.source.getMsg(ID))
-    self.currentItem = current
-
-  def setTranslMsg(self, msg):
-    self.translEdit.setText(msg["Text"])
-    self.translAnnotEdit.setText(msg["Annot"])
-
-  def setSourceMsg(self, msg):
-    self.sourceEdit.setText(msg["Text"])
-    self.sourceAnnotEdit.setText(msg["Annot"])
-
-  #def translEditFocusOut(self, event):
-    #if self.currentItem:
-      #print self.currentItem.text(self.colText)
-      #if self.translEdit.document().isModified():
-        #self.translEdit.document().setModified(False)
-        #print "translEdit was modified"
-    #QtGui.QTextEdit.focusOutEvent(self.translEdit, event)
-
-  def translEditTextChanged(self):
-    if self.currentItem:
-      text = unicode(self.translEdit.toPlainText())
-      self.currentItem.setText(self.colText, text)
-      self.currentItem.setMsgText(text)
-      self.modified()
-
-  def translAnnotEditTextChanged(self):
-    if self.currentItem:
-      text = unicode(self.translAnnotEdit.toPlainText())
-      self.currentItem.setMsgAnnot(text)
-      self.modified()
-
-  def updateData(self):
-    if self.currentItem == None:
-      return
-    ID = self.currentItem.getID()
-    msg = self.langFile.source.getMsg(ID)
-    text = self.sourceEdit.toPlainText()
-    if text != msg["Text"]:
-      self.sourceEdit.setText(msg["Text"])
-    text = self.sourceAnnotEdit.toPlainText()
-    if text != msg["Annot"]:
-      self.sourceAnnotEdit.setText(msg["Annot"])
-
-  def save(self):
-    Document.save(self)
-    self.langFile.save()
-
-
-class MsgFormSource(MsgForm):
-  def __init__(self, langFile):
-    MsgForm.__init__(self, langFile)
-
-    for x in [self.translEdit,
-              self.translAnnotEdit,
-              self.label_4,
-              self.label_5]:
-      x.close()
-
-    Qt.connect(self.sourceEdit, Qt.SIGNAL("textChanged()"), self.sourceEditTextChanged)
-    Qt.connect(self.sourceAnnotEdit, Qt.SIGNAL("textChanged()"), self.sourceAnnotEditTextChanged)
-
-  def treeItemChanged(self, current, previous):
-    if current == None:
-      self.setSourceMsg("")
-      return
-    ID = current.getID()
-    self.currentItem = None
-    self.setSourceMsg(self.langFile.getMsg(ID))
-    self.currentItem = current
-
-  def sourceEditTextChanged(self):
-    if self.currentItem:
-      text = unicode(self.sourceEdit.toPlainText())
-      self.currentItem.setText(self.colText, text)
-      self.currentItem.setMsgText(text)
-      self.modified()
-
-  def sourceAnnotEditTextChanged(self):
-    if self.currentItem:
-      text = unicode(self.sourceAnnotEdit.toPlainText())
-      #self.currentItem.setText(self.colAnnot, text)
-      self.currentItem.setMsgAnnot(text)
-      self.modified()
-
-
-class MsgIDItem(QtGui.QTreeWidgetItem):
-  def __init__(self, parent, text):
-    QtGui.QTreeWidgetItem.__init__(self, parent, [text])
-    self.setFlags(self.flags()|Qt.ItemIsEditable);
-
-class LangFileItem(QtGui.QTreeWidgetItem):
-  def __init__(self, parent, langFile):
-    QtGui.QTreeWidgetItem.__init__(self, parent, [langFile.langCode])
-    self.langFile = langFile
-    self.msgForm = None
-
-  def isDocOpen(self):
-    return self.msgForm != None
-
-  def openDoc(self):
-    if self.msgForm == None:
-      if self.langFile.isSource:
-        self.msgForm = MsgFormSource(self.langFile)
-      else:
-        self.msgForm = MsgForm(self.langFile)
-      Qt.connect(self.msgForm, Qt.SIGNAL("closed()"), self.docClosed)
-    return self.msgForm
-
-  def docClosed(self):
-    self.msgForm = None
-
-class ProjectItem(QtGui.QTreeWidgetItem):
-  def __init__(self, text):
-    QtGui.QTreeWidgetItem.__init__(self, [text])
-    self.setFlags(self.flags()|Qt.ItemIsEditable);
-
-class ProjectTree(QtGui.QTreeWidget):
-  def __init__(self, parent, mainWindow):
-    QtGui.QTreeWidget.__init__(self, parent)
-    self.mainWindow = mainWindow
-    self.project = None
-    self.topItem = None
-    self.msgIDsItem = None
-    self.headerItem().setHidden(True)
-    self.ignoreItemChanged = False
-
-  def itemChanged(self, item, column):
-    if self.ignoreItemChanged:
-      return
-    text = unicode(item.text(0))
-    #if hasattr(item, "textChanged"):
-      #item.textChanged(text)
-    if isinstance(item, ProjectItem):
-      self.project.setName(text)
-      print text
-
-  def keyReleaseEvent(self, event):
-    Qt = QtCore.Qt
-    key = event.key()
-    if key in [Qt.Key_Enter, Qt.Key_Return]:
-      self.emit(Qt.SIGNAL("onKeyEnter"), self.currentItem())
-    elif key == Qt.Key_Delete:
-      self.emit(Qt.SIGNAL("onKeyDelete"), self.currentItem())
-
-  def setProject(self, project):
-    self.project = project
-
-    self.topItem = ProjectItem(self.project.name)
-    self.addTopLevelItem(self.topItem)
-
-    for langFile in self.project.langFiles:
-      langFileItem = LangFileItem(self.topItem, langFile)
-
-    self.msgIDsItem = QtGui.QTreeWidgetItem(self.topItem, ["Message IDs"])
-    for msgID in self.project.msgIDs:
-      MsgIDItem(self.msgIDsItem, msgID["Name"])
-
-    for x in [self.topItem, self.msgIDsItem]:
-      x.setExpanded(True)
-
-    Qt.connect(self, Qt.SIGNAL("itemChanged(QTreeWidgetItem*,int)"), self.itemChanged)
-
-  def contextMenuEvent(self, event):
-    item = self.itemAt(event.pos())
-    func_map = {
-      None : lambda item: None,
-      QtGui.QTreeWidgetItem : lambda item: None,
-      ProjectItem : self.showMenuProjectItem,
-      LangFileItem : self.showMenuLangFileItem,
-      MsgIDItem : self.showMenuMsgIDItem
-    }
-    func_map[type(item)](item)
-
-  def showMenuProjectItem(self, item):
-    mousePos = QtGui.QCursor.pos()
-    menu = QtGui.QMenu()
-    actions = {}
-    actions[menu.addAction("Build")] = lambda: None
-    actions[menu.addAction("Properties")] = lambda: self.mainWindow.showProjectProperties()
-    actions[menu.exec_(mousePos)]()
-
-  def showMenuLangFileItem(self, item):
-    print "LangFileItem"
-
-  def showMenuMsgIDItem(self, item):
-    print "MsgIDItem"
-
-  def updateProjectName(self):
-    self.ignoreItemChanged = True
-    self.topItem.setText(0, self.project.name)
-    self.ignoreItemChanged = False
-
-  def clear(self):
-    self.project = None
-    self.topItem = None
-    self.msgIDsItem = None
-    Qt.disconnect(self, Qt.SIGNAL("itemChanged(QTreeWidgetItem*,int)"), self.itemChanged)
-    QtGui.QTreeWidget.clear(self)
-
-
-class ClosingProjectDialog(QtGui.QDialog, Ui_ClosingProjectDialog):
-  DiscardAll = 2
-  def __init__(self, docs):
-    QtGui.QDialog.__init__(self)
-    self.setupUi(self)
-    Qt.connect(self.button_Discard_All, Qt.SIGNAL("clicked()"),   self.discardAll)
-
-    self.items = []
-    for doc in docs:
-      title = doc.getDocumentTitle()
-      path = doc.getDocumentFullPath()
-      item = QtGui.QTreeWidgetItem([title, path])
-      item.doc = doc
-      item.setFlags(item.flags()|Qt.ItemIsUserCheckable);
-      item.setCheckState(0, Qt.Checked)
-      self.items += [item]
-    self.treeWidget.addTopLevelItems(self.items)
-
-    self.button_Cancel.setFocus()
-
-  def getSelectedDocs(self):
-    return [item.doc for item in self.items if item.checkState(0)]
-
-  def discardAll(self):
-    self.done(self.DiscardAll)
-
-
-class ProjectPropertiesDialog(QtGui.QDialog, Ui_ProjectPropertiesDialog):
-  def __init__(self, project):
-    QtGui.QDialog.__init__(self)
-    self.setupUi(self)
-    Qt.connect(self.pickFileButton, Qt.SIGNAL("clicked()"), self.pickFilePath)
-
-    self.project = project
-    self.projectNameField.setText(self.project.name)
-    self.buildScriptField.setText(self.project.buildScript)
-    self.creationDateField.setText(self.project.creationDate)
-
-  def pickFilePath(self):
-    filePath = QtGui.QFileDialog.getOpenFileName(self, "Select Build Script File", g_CWD, "Python Script (*.py)");
-    if filePath:
-      self.buildScriptField.setText(str(filePath))
-
-  def accept(self):
-    self.project.setName(unicode(self.projectNameField.text()))
-    self.project.setBuildScript(unicode(self.buildScriptField.text()))
-    self.project.setCreationDate(str(self.creationDateField.text()))
-    QtGui.QDialog.accept(self)
-
-
-class NewProjectDialog(QtGui.QDialog, Ui_NewProjectDialog):
-  def __init__(self):
-    QtGui.QDialog.__init__(self)
-    self.setupUi(self)
-    Qt.connect(self.pickFileButton, Qt.SIGNAL("clicked()"), self.pickFilePath)
-
-  def pickFilePath(self):
-    filePath = QtGui.QFileDialog.getSaveFileName(self, "New Project File", g_CWD, "Translator Project (*%s)" % g_projectExt);
-    if filePath:
-      filePath = str(filePath) # Convert QString
-      if os.path.splitext(filePath)[1] != g_projectExt:
-        filePath += g_projectExt
-      self.projectFilePath.setText(filePath)
-
-  def accept(self):
-    projectName = str(self.projectName.text())
-    filePath = str(self.projectFilePath.text())
-
-    MB = QtGui.QMessageBox
-    if projectName == "":
-      MB.warning(self, "Warning", "Please, enter a name for the project.")
-      return
-    if filePath == "":
-      MB.warning(self, "Warning", "Please, choose or enter a path for the project file.")
-      return
-
-    projectData = newProjectData(projectName)
-
-    if os.path.splitext(filePath)[1] != g_projectExt:
-      filePath += g_projectExt
-
-    try:
-      yaml.dump(projectData, open(filePath, "w"), default_flow_style=False)
-    except Exception, e:
-      MB.critical(self, "Error", str(e))
-      return
-
-    # Accept and close dialog.
-    QtGui.QDialog.accept(self)
-
-if __name__ == "__main__":
-  app = QtGui.QApplication(sys.argv)
-  main = MainWindow()
-  main.show()
-  sys.exit(app.exec_())
--- a/trunk/src/translator/translator.ui	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +0,0 @@
-<ui version="4.0" >
- <class>MainWindow</class>
- <widget class="QMainWindow" name="MainWindow" >
-  <property name="geometry" >
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>608</width>
-    <height>464</height>
-   </rect>
-  </property>
-  <property name="windowTitle" >
-   <string>Translator</string>
-  </property>
-  <widget class="QWidget" name="centralwidget" >
-   <layout class="QVBoxLayout" />
-  </widget>
-  <widget class="QMenuBar" name="menubar" >
-   <property name="geometry" >
-    <rect>
-     <x>0</x>
-     <y>0</y>
-     <width>608</width>
-     <height>29</height>
-    </rect>
-   </property>
-   <widget class="QMenu" name="menu_File" >
-    <property name="title" >
-     <string>&amp;File</string>
-    </property>
-    <addaction name="action_Open_Project" />
-    <addaction name="action_New_Project" />
-    <addaction name="separator" />
-    <addaction name="action_Save" />
-    <addaction name="action_Save_All" />
-    <addaction name="separator" />
-    <addaction name="action_Close" />
-    <addaction name="action_Close_All" />
-    <addaction name="separator" />
-    <addaction name="action_Quit" />
-   </widget>
-   <widget class="QMenu" name="menu_Help" >
-    <property name="title" >
-     <string>&amp;Help</string>
-    </property>
-    <addaction name="action_About" />
-   </widget>
-   <widget class="QMenu" name="menu_Project" >
-    <property name="title" >
-     <string>&amp;Project</string>
-    </property>
-    <addaction name="action_Add_Catalogue" />
-    <addaction name="action_Add_New_Catalogue" />
-    <addaction name="action_Build_Project" />
-    <addaction name="separator" />
-    <addaction name="action_Properties" />
-    <addaction name="separator" />
-    <addaction name="action_Close_Project" />
-   </widget>
-   <addaction name="menu_File" />
-   <addaction name="menu_Project" />
-   <addaction name="menu_Help" />
-  </widget>
-  <widget class="QStatusBar" name="statusbar" />
-  <action name="action_Quit" >
-   <property name="text" >
-    <string>&amp;Quit</string>
-   </property>
-   <property name="shortcut" >
-    <string>Ctrl+Q</string>
-   </property>
-  </action>
-  <action name="action_About" >
-   <property name="text" >
-    <string>&amp;About</string>
-   </property>
-  </action>
-  <action name="action_New_Project" >
-   <property name="text" >
-    <string>&amp;New Project...</string>
-   </property>
-   <property name="shortcut" >
-    <string>Ctrl+N</string>
-   </property>
-  </action>
-  <action name="action_Add_Catalogue" >
-   <property name="text" >
-    <string>&amp;Add catalogue...</string>
-   </property>
-  </action>
-  <action name="action_Properties" >
-   <property name="text" >
-    <string>&amp;Properties</string>
-   </property>
-  </action>
-  <action name="action_Build_Project" >
-   <property name="text" >
-    <string>&amp;Build Project</string>
-   </property>
-  </action>
-  <action name="action_Open_Project" >
-   <property name="text" >
-    <string>&amp;Open Project...</string>
-   </property>
-   <property name="shortcut" >
-    <string>Ctrl+O</string>
-   </property>
-  </action>
-  <action name="action_Close" >
-   <property name="text" >
-    <string>&amp;Close</string>
-   </property>
-   <property name="shortcut" >
-    <string>Ctrl+W</string>
-   </property>
-  </action>
-  <action name="action_Add_New_Catalogue" >
-   <property name="text" >
-    <string>Add new catalogue...</string>
-   </property>
-  </action>
-  <action name="action_Close_Project" >
-   <property name="text" >
-    <string>&amp;Close Project</string>
-   </property>
-   <property name="shortcut" >
-    <string>Ctrl+F4</string>
-   </property>
-  </action>
-  <action name="action_Save" >
-   <property name="text" >
-    <string>&amp;Save</string>
-   </property>
-   <property name="shortcut" >
-    <string>Ctrl+S</string>
-   </property>
-  </action>
-  <action name="action_Save_All" >
-   <property name="text" >
-    <string>Save &amp;All</string>
-   </property>
-   <property name="shortcut" >
-    <string>Ctrl+Shift+S</string>
-   </property>
-  </action>
-  <action name="action_Close_All" >
-   <property name="text" >
-    <string>Clos&amp;e All</string>
-   </property>
-   <property name="shortcut" >
-    <string>Ctrl+Shift+W</string>
-   </property>
-  </action>
- </widget>
- <resources/>
- <connections>
-  <connection>
-   <sender>action_Quit</sender>
-   <signal>triggered()</signal>
-   <receiver>MainWindow</receiver>
-   <slot>close()</slot>
-   <hints>
-    <hint type="sourcelabel" >
-     <x>-1</x>
-     <y>-1</y>
-    </hint>
-    <hint type="destinationlabel" >
-     <x>303</x>
-     <y>231</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
-</ui>
--- a/trunk/src/translator/ui_about.py	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'about.ui'
-#
-# Created: Sun Oct 21 17:33:29 2007
-#      by: PyQt4 UI code generator 4.1
-#
-# WARNING! All changes made in this file will be lost!
-
-import sys
-from PyQt4 import QtCore, QtGui
-
-class Ui_AboutDialog(object):
-    def setupUi(self, AboutDialog):
-        AboutDialog.setObjectName("AboutDialog")
-        AboutDialog.setWindowModality(QtCore.Qt.WindowModal)
-        AboutDialog.resize(QtCore.QSize(QtCore.QRect(0,0,414,157).size()).expandedTo(AboutDialog.minimumSizeHint()))
-
-        self.vboxlayout = QtGui.QVBoxLayout(AboutDialog)
-        self.vboxlayout.setObjectName("vboxlayout")
-
-        self.label1 = QtGui.QLabel(AboutDialog)
-        self.label1.setTextFormat(QtCore.Qt.RichText)
-        self.label1.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
-        self.label1.setWordWrap(True)
-        self.label1.setObjectName("label1")
-        self.vboxlayout.addWidget(self.label1)
-
-        self.buttonBox = QtGui.QDialogButtonBox(AboutDialog)
-        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok)
-        self.buttonBox.setObjectName("buttonBox")
-        self.vboxlayout.addWidget(self.buttonBox)
-
-        self.retranslateUi(AboutDialog)
-        QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("accepted()"),AboutDialog.close)
-        QtCore.QMetaObject.connectSlotsByName(AboutDialog)
-
-    def retranslateUi(self, AboutDialog):
-        AboutDialog.setWindowTitle(QtGui.QApplication.translate("AboutDialog", "About", None, QtGui.QApplication.UnicodeUTF8))
-        self.label1.setText(QtGui.QApplication.translate("AboutDialog", "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
-        "p, li { white-space: pre-wrap; }\n"
-        "</style></head><body style=\" font-family:\'Sans Serif\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
-        "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">A tool for managing message catalogues in different languages.</p>\n"
-        "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">These catalogues can be used to make an application multilingual.</p>\n"
-        "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
-        "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Copyright © 2007 by Aziz Köksal &lt;aziz.koeksal@gmail.com&gt;</p>\n"
-        "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Licensed under the GPL2.</p></body></html>", None, QtGui.QApplication.UnicodeUTF8))
-
--- a/trunk/src/translator/ui_closing_project.py	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'closing_project.ui'
-#
-# Created: Sun Nov 11 23:01:28 2007
-#      by: PyQt4 UI code generator 4.1
-#
-# WARNING! All changes made in this file will be lost!
-
-import sys
-from PyQt4 import QtCore, QtGui
-
-class Ui_ClosingProjectDialog(object):
-    def setupUi(self, ClosingProjectDialog):
-        ClosingProjectDialog.setObjectName("ClosingProjectDialog")
-        ClosingProjectDialog.resize(QtCore.QSize(QtCore.QRect(0,0,400,300).size()).expandedTo(ClosingProjectDialog.minimumSizeHint()))
-
-        self.vboxlayout = QtGui.QVBoxLayout(ClosingProjectDialog)
-        self.vboxlayout.setObjectName("vboxlayout")
-
-        self.label = QtGui.QLabel(ClosingProjectDialog)
-        self.label.setObjectName("label")
-        self.vboxlayout.addWidget(self.label)
-
-        self.treeWidget = QtGui.QTreeWidget(ClosingProjectDialog)
-        self.treeWidget.setObjectName("treeWidget")
-        self.vboxlayout.addWidget(self.treeWidget)
-
-        spacerItem = QtGui.QSpacerItem(382,33,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Expanding)
-        self.vboxlayout.addItem(spacerItem)
-
-        self.hboxlayout = QtGui.QHBoxLayout()
-        self.hboxlayout.setObjectName("hboxlayout")
-
-        spacerItem1 = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum)
-        self.hboxlayout.addItem(spacerItem1)
-
-        self.button_Save_Selected = QtGui.QPushButton(ClosingProjectDialog)
-        self.button_Save_Selected.setObjectName("button_Save_Selected")
-        self.hboxlayout.addWidget(self.button_Save_Selected)
-
-        self.button_Discard_All = QtGui.QPushButton(ClosingProjectDialog)
-        self.button_Discard_All.setObjectName("button_Discard_All")
-        self.hboxlayout.addWidget(self.button_Discard_All)
-
-        self.button_Cancel = QtGui.QPushButton(ClosingProjectDialog)
-        self.button_Cancel.setDefault(True)
-        self.button_Cancel.setObjectName("button_Cancel")
-        self.hboxlayout.addWidget(self.button_Cancel)
-        self.vboxlayout.addLayout(self.hboxlayout)
-
-        self.retranslateUi(ClosingProjectDialog)
-        QtCore.QObject.connect(self.button_Save_Selected,QtCore.SIGNAL("clicked()"),ClosingProjectDialog.accept)
-        QtCore.QObject.connect(self.button_Cancel,QtCore.SIGNAL("clicked()"),ClosingProjectDialog.reject)
-        QtCore.QMetaObject.connectSlotsByName(ClosingProjectDialog)
-
-    def retranslateUi(self, ClosingProjectDialog):
-        ClosingProjectDialog.setWindowTitle(QtGui.QApplication.translate("ClosingProjectDialog", "Closing Project", None, QtGui.QApplication.UnicodeUTF8))
-        self.label.setText(QtGui.QApplication.translate("ClosingProjectDialog", "The following documents have been modified:", None, QtGui.QApplication.UnicodeUTF8))
-        self.treeWidget.headerItem().setText(0,QtGui.QApplication.translate("ClosingProjectDialog", "Title", None, QtGui.QApplication.UnicodeUTF8))
-        self.treeWidget.headerItem().setText(1,QtGui.QApplication.translate("ClosingProjectDialog", "Full Path", None, QtGui.QApplication.UnicodeUTF8))
-        self.button_Save_Selected.setText(QtGui.QApplication.translate("ClosingProjectDialog", "&Save Selected", None, QtGui.QApplication.UnicodeUTF8))
-        self.button_Discard_All.setText(QtGui.QApplication.translate("ClosingProjectDialog", "&Discard All Changes", None, QtGui.QApplication.UnicodeUTF8))
-        self.button_Cancel.setText(QtGui.QApplication.translate("ClosingProjectDialog", "&Cancel", None, QtGui.QApplication.UnicodeUTF8))
-
--- a/trunk/src/translator/ui_langfile_properties.py	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'langfile_properties.ui'
-#
-# Created: Sat Nov 17 23:14:57 2007
-#      by: PyQt4 UI code generator 4.1
-#
-# WARNING! All changes made in this file will be lost!
-
-import sys
-from PyQt4 import QtCore, QtGui
-
-class Ui_LangFilePropertiesDialog(object):
-    def setupUi(self, LangFilePropertiesDialog):
-        LangFilePropertiesDialog.setObjectName("LangFilePropertiesDialog")
-        LangFilePropertiesDialog.resize(QtCore.QSize(QtCore.QRect(0,0,400,228).size()).expandedTo(LangFilePropertiesDialog.minimumSizeHint()))
-
-        self.vboxlayout = QtGui.QVBoxLayout(LangFilePropertiesDialog)
-        self.vboxlayout.setObjectName("vboxlayout")
-
-        self.gridlayout = QtGui.QGridLayout()
-        self.gridlayout.setObjectName("gridlayout")
-
-        self.label_2 = QtGui.QLabel(LangFilePropertiesDialog)
-        self.label_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
-        self.label_2.setObjectName("label_2")
-        self.gridlayout.addWidget(self.label_2,1,0,1,1)
-
-        self.langCodeField = QtGui.QLineEdit(LangFilePropertiesDialog)
-        self.langCodeField.setObjectName("langCodeField")
-        self.gridlayout.addWidget(self.langCodeField,1,1,1,1)
-
-        self.label = QtGui.QLabel(LangFilePropertiesDialog)
-        self.label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
-        self.label.setObjectName("label")
-        self.gridlayout.addWidget(self.label,2,0,1,1)
-
-        self.creationDateField = QtGui.QLineEdit(LangFilePropertiesDialog)
-        self.creationDateField.setObjectName("creationDateField")
-        self.gridlayout.addWidget(self.creationDateField,2,1,1,1)
-
-        self.authorsField = QtGui.QTextEdit(LangFilePropertiesDialog)
-        self.authorsField.setObjectName("authorsField")
-        self.gridlayout.addWidget(self.authorsField,0,1,1,1)
-
-        self.label_3 = QtGui.QLabel(LangFilePropertiesDialog)
-        self.label_3.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTop|QtCore.Qt.AlignTrailing)
-        self.label_3.setObjectName("label_3")
-        self.gridlayout.addWidget(self.label_3,0,0,1,1)
-        self.vboxlayout.addLayout(self.gridlayout)
-
-        spacerItem = QtGui.QSpacerItem(20,10,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Fixed)
-        self.vboxlayout.addItem(spacerItem)
-
-        self.buttonBox = QtGui.QDialogButtonBox(LangFilePropertiesDialog)
-        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
-        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Ok)
-        self.buttonBox.setObjectName("buttonBox")
-        self.vboxlayout.addWidget(self.buttonBox)
-        self.label_2.setBuddy(self.langCodeField)
-        self.label.setBuddy(self.creationDateField)
-
-        self.retranslateUi(LangFilePropertiesDialog)
-        QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("accepted()"),LangFilePropertiesDialog.accept)
-        QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("rejected()"),LangFilePropertiesDialog.reject)
-        QtCore.QMetaObject.connectSlotsByName(LangFilePropertiesDialog)
-
-    def retranslateUi(self, LangFilePropertiesDialog):
-        LangFilePropertiesDialog.setWindowTitle(QtGui.QApplication.translate("LangFilePropertiesDialog", "Language File Properties", None, QtGui.QApplication.UnicodeUTF8))
-        self.label_2.setText(QtGui.QApplication.translate("LangFilePropertiesDialog", "Language code:", None, QtGui.QApplication.UnicodeUTF8))
-        self.label.setText(QtGui.QApplication.translate("LangFilePropertiesDialog", "Creation date:", None, QtGui.QApplication.UnicodeUTF8))
-        self.label_3.setText(QtGui.QApplication.translate("LangFilePropertiesDialog", "Author(s):", None, QtGui.QApplication.UnicodeUTF8))
-
--- a/trunk/src/translator/ui_msg_form.py	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'msg_form.ui'
-#
-# Created: Fri Nov  9 15:38:32 2007
-#      by: PyQt4 UI code generator 4.1
-#
-# WARNING! All changes made in this file will be lost!
-
-import sys
-from PyQt4 import QtCore, QtGui
-
-class Ui_MsgForm(object):
-    def setupUi(self, MsgForm):
-        MsgForm.setObjectName("MsgForm")
-        MsgForm.resize(QtCore.QSize(QtCore.QRect(0,0,456,512).size()).expandedTo(MsgForm.minimumSizeHint()))
-
-        self.vboxlayout = QtGui.QVBoxLayout(MsgForm)
-        self.vboxlayout.setObjectName("vboxlayout")
-
-        self.splitter = QtGui.QSplitter(MsgForm)
-        self.splitter.setOrientation(QtCore.Qt.Vertical)
-        self.splitter.setObjectName("splitter")
-
-        self.layoutWidget = QtGui.QWidget(self.splitter)
-        self.layoutWidget.setObjectName("layoutWidget")
-
-        self.vboxlayout1 = QtGui.QVBoxLayout(self.layoutWidget)
-        self.vboxlayout1.setObjectName("vboxlayout1")
-
-        self.label = QtGui.QLabel(self.layoutWidget)
-        self.label.setObjectName("label")
-        self.vboxlayout1.addWidget(self.label)
-
-        self.treeWidget = QtGui.QTreeWidget(self.layoutWidget)
-        self.treeWidget.setObjectName("treeWidget")
-        self.vboxlayout1.addWidget(self.treeWidget)
-
-        self.layoutWidget1 = QtGui.QWidget(self.splitter)
-        self.layoutWidget1.setObjectName("layoutWidget1")
-
-        self.gridlayout = QtGui.QGridLayout(self.layoutWidget1)
-        self.gridlayout.setObjectName("gridlayout")
-
-        self.vboxlayout2 = QtGui.QVBoxLayout()
-        self.vboxlayout2.setObjectName("vboxlayout2")
-
-        self.label_2 = QtGui.QLabel(self.layoutWidget1)
-        self.label_2.setObjectName("label_2")
-        self.vboxlayout2.addWidget(self.label_2)
-
-        self.sourceEdit = QtGui.QTextEdit(self.layoutWidget1)
-        self.sourceEdit.setObjectName("sourceEdit")
-        self.vboxlayout2.addWidget(self.sourceEdit)
-        self.gridlayout.addLayout(self.vboxlayout2,0,0,1,1)
-
-        self.vboxlayout3 = QtGui.QVBoxLayout()
-        self.vboxlayout3.setObjectName("vboxlayout3")
-
-        self.label_3 = QtGui.QLabel(self.layoutWidget1)
-        self.label_3.setObjectName("label_3")
-        self.vboxlayout3.addWidget(self.label_3)
-
-        self.sourceAnnotEdit = QtGui.QTextEdit(self.layoutWidget1)
-        self.sourceAnnotEdit.setObjectName("sourceAnnotEdit")
-        self.vboxlayout3.addWidget(self.sourceAnnotEdit)
-        self.gridlayout.addLayout(self.vboxlayout3,0,1,1,1)
-
-        self.vboxlayout4 = QtGui.QVBoxLayout()
-        self.vboxlayout4.setObjectName("vboxlayout4")
-
-        self.label_4 = QtGui.QLabel(self.layoutWidget1)
-        self.label_4.setObjectName("label_4")
-        self.vboxlayout4.addWidget(self.label_4)
-
-        self.translEdit = QtGui.QTextEdit(self.layoutWidget1)
-        self.translEdit.setObjectName("translEdit")
-        self.vboxlayout4.addWidget(self.translEdit)
-        self.gridlayout.addLayout(self.vboxlayout4,1,0,1,1)
-
-        self.vboxlayout5 = QtGui.QVBoxLayout()
-        self.vboxlayout5.setObjectName("vboxlayout5")
-
-        self.label_5 = QtGui.QLabel(self.layoutWidget1)
-        self.label_5.setObjectName("label_5")
-        self.vboxlayout5.addWidget(self.label_5)
-
-        self.translAnnotEdit = QtGui.QTextEdit(self.layoutWidget1)
-        self.translAnnotEdit.setObjectName("translAnnotEdit")
-        self.vboxlayout5.addWidget(self.translAnnotEdit)
-        self.gridlayout.addLayout(self.vboxlayout5,1,1,1,1)
-        self.vboxlayout.addWidget(self.splitter)
-
-        self.retranslateUi(MsgForm)
-        QtCore.QMetaObject.connectSlotsByName(MsgForm)
-
-    def retranslateUi(self, MsgForm):
-        MsgForm.setWindowTitle(QtGui.QApplication.translate("MsgForm", "Form", None, QtGui.QApplication.UnicodeUTF8))
-        self.label.setText(QtGui.QApplication.translate("MsgForm", "Messages:", None, QtGui.QApplication.UnicodeUTF8))
-        self.treeWidget.headerItem().setText(0,QtGui.QApplication.translate("MsgForm", "1", None, QtGui.QApplication.UnicodeUTF8))
-        self.label_2.setText(QtGui.QApplication.translate("MsgForm", "Source string:", None, QtGui.QApplication.UnicodeUTF8))
-        self.label_3.setText(QtGui.QApplication.translate("MsgForm", "Source annotation:", None, QtGui.QApplication.UnicodeUTF8))
-        self.label_4.setText(QtGui.QApplication.translate("MsgForm", "Translation:", None, QtGui.QApplication.UnicodeUTF8))
-        self.label_5.setText(QtGui.QApplication.translate("MsgForm", "Translator\'s annotation:", None, QtGui.QApplication.UnicodeUTF8))
-
--- a/trunk/src/translator/ui_new_project.py	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'new_project.ui'
-#
-# Created: Sun Oct 21 17:33:29 2007
-#      by: PyQt4 UI code generator 4.1
-#
-# WARNING! All changes made in this file will be lost!
-
-import sys
-from PyQt4 import QtCore, QtGui
-
-class Ui_NewProjectDialog(object):
-    def setupUi(self, NewProjectDialog):
-        NewProjectDialog.setObjectName("NewProjectDialog")
-        NewProjectDialog.resize(QtCore.QSize(QtCore.QRect(0,0,401,131).size()).expandedTo(NewProjectDialog.minimumSizeHint()))
-
-        self.vboxlayout = QtGui.QVBoxLayout(NewProjectDialog)
-        self.vboxlayout.setObjectName("vboxlayout")
-
-        self.gridlayout = QtGui.QGridLayout()
-        self.gridlayout.setObjectName("gridlayout")
-
-        self.gridlayout1 = QtGui.QGridLayout()
-        self.gridlayout1.setObjectName("gridlayout1")
-
-        self.label = QtGui.QLabel(NewProjectDialog)
-        self.label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
-        self.label.setObjectName("label")
-        self.gridlayout1.addWidget(self.label,0,0,1,1)
-
-        self.projectName = QtGui.QLineEdit(NewProjectDialog)
-        self.projectName.setObjectName("projectName")
-        self.gridlayout1.addWidget(self.projectName,0,1,1,1)
-
-        self.label_2 = QtGui.QLabel(NewProjectDialog)
-        self.label_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
-        self.label_2.setObjectName("label_2")
-        self.gridlayout1.addWidget(self.label_2,1,0,1,1)
-
-        self.hboxlayout = QtGui.QHBoxLayout()
-        self.hboxlayout.setObjectName("hboxlayout")
-
-        self.projectFilePath = QtGui.QLineEdit(NewProjectDialog)
-        self.projectFilePath.setObjectName("projectFilePath")
-        self.hboxlayout.addWidget(self.projectFilePath)
-
-        self.pickFileButton = QtGui.QToolButton(NewProjectDialog)
-        self.pickFileButton.setObjectName("pickFileButton")
-        self.hboxlayout.addWidget(self.pickFileButton)
-        self.gridlayout1.addLayout(self.hboxlayout,1,1,1,1)
-        self.gridlayout.addLayout(self.gridlayout1,0,0,1,1)
-
-        spacerItem = QtGui.QSpacerItem(20,40,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Expanding)
-        self.gridlayout.addItem(spacerItem,1,0,1,1)
-
-        self.buttonBox = QtGui.QDialogButtonBox(NewProjectDialog)
-        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
-        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Ok)
-        self.buttonBox.setObjectName("buttonBox")
-        self.gridlayout.addWidget(self.buttonBox,2,0,1,1)
-        self.vboxlayout.addLayout(self.gridlayout)
-        self.label.setBuddy(self.projectName)
-        self.label_2.setBuddy(self.projectFilePath)
-
-        self.retranslateUi(NewProjectDialog)
-        QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("accepted()"),NewProjectDialog.accept)
-        QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("rejected()"),NewProjectDialog.reject)
-        QtCore.QMetaObject.connectSlotsByName(NewProjectDialog)
-
-    def retranslateUi(self, NewProjectDialog):
-        NewProjectDialog.setWindowTitle(QtGui.QApplication.translate("NewProjectDialog", "Create New Project", None, QtGui.QApplication.UnicodeUTF8))
-        self.label.setText(QtGui.QApplication.translate("NewProjectDialog", "Project name:", None, QtGui.QApplication.UnicodeUTF8))
-        self.label_2.setText(QtGui.QApplication.translate("NewProjectDialog", "Project file:", None, QtGui.QApplication.UnicodeUTF8))
-        self.pickFileButton.setText(QtGui.QApplication.translate("NewProjectDialog", "...", None, QtGui.QApplication.UnicodeUTF8))
-
--- a/trunk/src/translator/ui_project_properties.py	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'project_properties.ui'
-#
-# Created: Sat Nov 17 23:14:55 2007
-#      by: PyQt4 UI code generator 4.1
-#
-# WARNING! All changes made in this file will be lost!
-
-import sys
-from PyQt4 import QtCore, QtGui
-
-class Ui_ProjectPropertiesDialog(object):
-    def setupUi(self, ProjectPropertiesDialog):
-        ProjectPropertiesDialog.setObjectName("ProjectPropertiesDialog")
-        ProjectPropertiesDialog.resize(QtCore.QSize(QtCore.QRect(0,0,400,152).size()).expandedTo(ProjectPropertiesDialog.minimumSizeHint()))
-
-        self.vboxlayout = QtGui.QVBoxLayout(ProjectPropertiesDialog)
-        self.vboxlayout.setObjectName("vboxlayout")
-
-        self.gridlayout = QtGui.QGridLayout()
-        self.gridlayout.setObjectName("gridlayout")
-
-        self.label_2 = QtGui.QLabel(ProjectPropertiesDialog)
-        self.label_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
-        self.label_2.setObjectName("label_2")
-        self.gridlayout.addWidget(self.label_2,0,0,1,1)
-
-        self.projectNameField = QtGui.QLineEdit(ProjectPropertiesDialog)
-        self.projectNameField.setObjectName("projectNameField")
-        self.gridlayout.addWidget(self.projectNameField,0,1,1,1)
-
-        self.label = QtGui.QLabel(ProjectPropertiesDialog)
-        self.label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
-        self.label.setObjectName("label")
-        self.gridlayout.addWidget(self.label,1,0,1,1)
-
-        self.hboxlayout = QtGui.QHBoxLayout()
-        self.hboxlayout.setObjectName("hboxlayout")
-
-        self.buildScriptField = QtGui.QLineEdit(ProjectPropertiesDialog)
-        self.buildScriptField.setObjectName("buildScriptField")
-        self.hboxlayout.addWidget(self.buildScriptField)
-
-        self.pickFileButton = QtGui.QToolButton(ProjectPropertiesDialog)
-        self.pickFileButton.setObjectName("pickFileButton")
-        self.hboxlayout.addWidget(self.pickFileButton)
-        self.gridlayout.addLayout(self.hboxlayout,1,1,1,1)
-
-        self.creationDateField = QtGui.QLineEdit(ProjectPropertiesDialog)
-        self.creationDateField.setObjectName("creationDateField")
-        self.gridlayout.addWidget(self.creationDateField,2,1,1,1)
-
-        self.label_3 = QtGui.QLabel(ProjectPropertiesDialog)
-        self.label_3.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
-        self.label_3.setObjectName("label_3")
-        self.gridlayout.addWidget(self.label_3,2,0,1,1)
-        self.vboxlayout.addLayout(self.gridlayout)
-
-        spacerItem = QtGui.QSpacerItem(20,40,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Expanding)
-        self.vboxlayout.addItem(spacerItem)
-
-        self.buttonBox = QtGui.QDialogButtonBox(ProjectPropertiesDialog)
-        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
-        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Ok)
-        self.buttonBox.setObjectName("buttonBox")
-        self.vboxlayout.addWidget(self.buttonBox)
-        self.label_2.setBuddy(self.projectNameField)
-        self.label.setBuddy(self.buildScriptField)
-
-        self.retranslateUi(ProjectPropertiesDialog)
-        QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("accepted()"),ProjectPropertiesDialog.accept)
-        QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("rejected()"),ProjectPropertiesDialog.reject)
-        QtCore.QMetaObject.connectSlotsByName(ProjectPropertiesDialog)
-
-    def retranslateUi(self, ProjectPropertiesDialog):
-        ProjectPropertiesDialog.setWindowTitle(QtGui.QApplication.translate("ProjectPropertiesDialog", "Project Properties", None, QtGui.QApplication.UnicodeUTF8))
-        self.label_2.setText(QtGui.QApplication.translate("ProjectPropertiesDialog", "Project name:", None, QtGui.QApplication.UnicodeUTF8))
-        self.label.setText(QtGui.QApplication.translate("ProjectPropertiesDialog", "Build script:", None, QtGui.QApplication.UnicodeUTF8))
-        self.pickFileButton.setText(QtGui.QApplication.translate("ProjectPropertiesDialog", "...", None, QtGui.QApplication.UnicodeUTF8))
-        self.label_3.setText(QtGui.QApplication.translate("ProjectPropertiesDialog", "Creation date:", None, QtGui.QApplication.UnicodeUTF8))
-
--- a/trunk/src/translator/ui_translator.py	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'translator.ui'
-#
-# Created: Fri Nov  9 20:02:57 2007
-#      by: PyQt4 UI code generator 4.1
-#
-# WARNING! All changes made in this file will be lost!
-
-import sys
-from PyQt4 import QtCore, QtGui
-
-class Ui_MainWindow(object):
-    def setupUi(self, MainWindow):
-        MainWindow.setObjectName("MainWindow")
-        MainWindow.resize(QtCore.QSize(QtCore.QRect(0,0,608,464).size()).expandedTo(MainWindow.minimumSizeHint()))
-
-        self.centralwidget = QtGui.QWidget(MainWindow)
-        self.centralwidget.setObjectName("centralwidget")
-
-        self.vboxlayout = QtGui.QVBoxLayout(self.centralwidget)
-        self.vboxlayout.setObjectName("vboxlayout")
-        MainWindow.setCentralWidget(self.centralwidget)
-
-        self.menubar = QtGui.QMenuBar(MainWindow)
-        self.menubar.setGeometry(QtCore.QRect(0,0,608,29))
-        self.menubar.setObjectName("menubar")
-
-        self.menu_File = QtGui.QMenu(self.menubar)
-        self.menu_File.setObjectName("menu_File")
-
-        self.menu_Help = QtGui.QMenu(self.menubar)
-        self.menu_Help.setObjectName("menu_Help")
-
-        self.menu_Project = QtGui.QMenu(self.menubar)
-        self.menu_Project.setObjectName("menu_Project")
-        MainWindow.setMenuBar(self.menubar)
-
-        self.statusbar = QtGui.QStatusBar(MainWindow)
-        self.statusbar.setObjectName("statusbar")
-        MainWindow.setStatusBar(self.statusbar)
-
-        self.action_Quit = QtGui.QAction(MainWindow)
-        self.action_Quit.setObjectName("action_Quit")
-
-        self.action_About = QtGui.QAction(MainWindow)
-        self.action_About.setObjectName("action_About")
-
-        self.action_New_Project = QtGui.QAction(MainWindow)
-        self.action_New_Project.setObjectName("action_New_Project")
-
-        self.action_Add_Catalogue = QtGui.QAction(MainWindow)
-        self.action_Add_Catalogue.setObjectName("action_Add_Catalogue")
-
-        self.action_Properties = QtGui.QAction(MainWindow)
-        self.action_Properties.setObjectName("action_Properties")
-
-        self.action_Build_Project = QtGui.QAction(MainWindow)
-        self.action_Build_Project.setObjectName("action_Build_Project")
-
-        self.action_Open_Project = QtGui.QAction(MainWindow)
-        self.action_Open_Project.setObjectName("action_Open_Project")
-
-        self.action_Close = QtGui.QAction(MainWindow)
-        self.action_Close.setObjectName("action_Close")
-
-        self.action_Add_New_Catalogue = QtGui.QAction(MainWindow)
-        self.action_Add_New_Catalogue.setObjectName("action_Add_New_Catalogue")
-
-        self.action_Close_Project = QtGui.QAction(MainWindow)
-        self.action_Close_Project.setObjectName("action_Close_Project")
-
-        self.action_Save = QtGui.QAction(MainWindow)
-        self.action_Save.setObjectName("action_Save")
-
-        self.action_Save_All = QtGui.QAction(MainWindow)
-        self.action_Save_All.setObjectName("action_Save_All")
-
-        self.action_Close_All = QtGui.QAction(MainWindow)
-        self.action_Close_All.setObjectName("action_Close_All")
-        self.menu_File.addAction(self.action_Open_Project)
-        self.menu_File.addAction(self.action_New_Project)
-        self.menu_File.addSeparator()
-        self.menu_File.addAction(self.action_Save)
-        self.menu_File.addAction(self.action_Save_All)
-        self.menu_File.addSeparator()
-        self.menu_File.addAction(self.action_Close)
-        self.menu_File.addAction(self.action_Close_All)
-        self.menu_File.addSeparator()
-        self.menu_File.addAction(self.action_Quit)
-        self.menu_Help.addAction(self.action_About)
-        self.menu_Project.addAction(self.action_Add_Catalogue)
-        self.menu_Project.addAction(self.action_Add_New_Catalogue)
-        self.menu_Project.addAction(self.action_Build_Project)
-        self.menu_Project.addSeparator()
-        self.menu_Project.addAction(self.action_Properties)
-        self.menu_Project.addSeparator()
-        self.menu_Project.addAction(self.action_Close_Project)
-        self.menubar.addAction(self.menu_File.menuAction())
-        self.menubar.addAction(self.menu_Project.menuAction())
-        self.menubar.addAction(self.menu_Help.menuAction())
-
-        self.retranslateUi(MainWindow)
-        QtCore.QObject.connect(self.action_Quit,QtCore.SIGNAL("triggered()"),MainWindow.close)
-        QtCore.QMetaObject.connectSlotsByName(MainWindow)
-
-    def retranslateUi(self, MainWindow):
-        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "Translator", None, QtGui.QApplication.UnicodeUTF8))
-        self.menu_File.setTitle(QtGui.QApplication.translate("MainWindow", "&File", None, QtGui.QApplication.UnicodeUTF8))
-        self.menu_Help.setTitle(QtGui.QApplication.translate("MainWindow", "&Help", None, QtGui.QApplication.UnicodeUTF8))
-        self.menu_Project.setTitle(QtGui.QApplication.translate("MainWindow", "&Project", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_Quit.setText(QtGui.QApplication.translate("MainWindow", "&Quit", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_Quit.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+Q", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_About.setText(QtGui.QApplication.translate("MainWindow", "&About", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_New_Project.setText(QtGui.QApplication.translate("MainWindow", "&New Project...", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_New_Project.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+N", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_Add_Catalogue.setText(QtGui.QApplication.translate("MainWindow", "&Add catalogue...", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_Properties.setText(QtGui.QApplication.translate("MainWindow", "&Properties", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_Build_Project.setText(QtGui.QApplication.translate("MainWindow", "&Build Project", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_Open_Project.setText(QtGui.QApplication.translate("MainWindow", "&Open Project...", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_Open_Project.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+O", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_Close.setText(QtGui.QApplication.translate("MainWindow", "&Close", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_Close.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+W", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_Add_New_Catalogue.setText(QtGui.QApplication.translate("MainWindow", "Add new catalogue...", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_Close_Project.setText(QtGui.QApplication.translate("MainWindow", "&Close Project", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_Close_Project.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+F4", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_Save.setText(QtGui.QApplication.translate("MainWindow", "&Save", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_Save.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+S", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_Save_All.setText(QtGui.QApplication.translate("MainWindow", "Save &All", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_Save_All.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+Shift+S", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_Close_All.setText(QtGui.QApplication.translate("MainWindow", "Clos&e All", None, QtGui.QApplication.UnicodeUTF8))
-        self.action_Close_All.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+Shift+W", None, QtGui.QApplication.UnicodeUTF8))
-
--- a/trunk/src/util/uni.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,632 +0,0 @@
-
-// Written in the D programming language.
-
-/*
- * Placed into the Public Domain.
- * Digital Mars, www.digitalmars.com
- * Written by Walter Bright
- */
-
-/**
- * Simple Unicode character classification functions.
- * For ASCII classification, see $(LINK2 std_ctype.html, std.ctype).
- * Macros:
- *	WIKI=Phobos/StdUni
- * References:
- *	$(LINK2 http://www.digitalmars.com/d/ascii-table.html, ASCII Table),
- *	$(LINK2 http://en.wikipedia.org/wiki/Unicode, Wikipedia),
- *	$(LINK2 http://www.unicode.org, The Unicode Consortium)
- * Trademarks:
- *	Unicode(tm) is a trademark of Unicode, Inc.
- * Copyright:
- *	Public Domain.
- */
-
-
-module util.uni;
-
-/**
- * Returns !=0 if c is a Unicode lower case character.
- */
-int isUniLower(dchar c)
-{
-    if (c <= 0x7F)
-	return (c >= 'a' && c <= 'z');
-
-    return isUniAlpha(c) && c == toUniLower(c);
-}
-
-/**
- * Returns !=0 if c is a Unicode upper case character.
- */
-int isUniUpper(dchar c)
-{
-    if (c <= 0x7F)
-	return (c >= 'A' && c <= 'Z');
-
-    return isUniAlpha(c) && c == toUniUpper(c);
-}
-
-/**
- * If c is a Unicode upper case character, return the lower case
- * equivalent, otherwise return c.
- */
-dchar toUniLower(dchar c)
-{
-    if (c >= 'A' && c <= 'Z')
-    {
-        c += 32;
-    }
-    else if (c >= 0x00C0)
-    {
-	if ((c >= 0x00C0 && c <= 0x00D6) || (c >= 0x00D8 && c<=0x00DE))
-	{
-	    c += 32;
-	}
-	else if ((c >= 0x0100 && c < 0x0138) || (c > 0x0149 && c < 0x0178))
-	{
-	    if (c == 0x0130)
-		c = 0x0069;
-	    else if ((c & 1) == 0)
-		c += 1;
-	}
-	else if (c == 0x0178)
-	{
-	    c = 0x00FF;
-	}
-	else if ((c >= 0x0139 && c < 0x0149) || (c > 0x0178 && c < 0x017F))
-	{
-	    if (c & 1)
-		c += 1;
-	}
-	else if (c >= 0x0200 && c <= 0x0217)
-	{
-	    if ((c & 1) == 0)
-		c += 1;
-	}
-	else if ((c >= 0x0401 && c <= 0x040C) || (c>= 0x040E && c <= 0x040F))
-	{
-	    c += 80;
-	}
-	else if (c >= 0x0410  && c <= 0x042F)
-	{
-	    c += 32;
-	}
-	else if (c >= 0x0460 && c <= 0x047F)
-	{
-	    if ((c & 1) == 0)
-		c += 1;
-	}
-	else if (c >= 0x0531 && c <= 0x0556)
-	{
-	    c += 48;
-	}
-	else if (c >= 0x10A0 && c <= 0x10C5)
-	{
-	    c += 48;
-	}
-	else if (c >= 0xFF21 && c <= 0xFF3A)
-	{
-	    c += 32;
-	}
-    }
-    return c;
-}
-
-/**
- * If c is a Unicode lower case character, return the upper case
- * equivalent, otherwise return c.
- */
-dchar toUniUpper(dchar c)
-{
-    if (c >= 'a' && c <= 'z')
-    {
-	c -= 32;
-    }
-    else if (c >= 0x00E0)
-    {
-	if ((c >= 0x00E0 && c <= 0x00F6) || (c >= 0x00F8 && c <= 0x00FE))
-	{
-	    c -= 32;
-	}
-	else if (c == 0x00FF)
-	{
-	    c = 0x0178;
-	}
-	else if ((c >= 0x0100 && c < 0x0138) || (c > 0x0149 && c < 0x0178))
-	{
-	    if (c == 0x0131)
-		c = 0x0049;
-	    else if (c & 1)
-		c -= 1;
-	}
-	else if ((c >= 0x0139 && c < 0x0149) || (c > 0x0178 && c < 0x017F))
-	{
-	    if ((c & 1) == 0)
-		c = c-1;
-	}
-	else if (c == 0x017F)
-	{
-	    c = 0x0053;
-	}
-	else if (c >= 0x0200 && c <= 0x0217)
-	{
-	    if (c & 1)
-		c = c-1;
-	}
-	else if (c >= 0x0430 && c<= 0x044F)
-	{
-	    c -= 32;
-	}
-	else if ((c >= 0x0451 && c <= 0x045C) || (c >=0x045E && c<= 0x045F))
-	{
-	    c -= 80;
-	}
-	else if (c >= 0x0460 && c <= 0x047F)
-	{
-	    if (c & 1)
-		c -= 1;
-	}
-	else if (c >= 0x0561 && c < 0x0587)
-	{
-	    c -= 48;
-	}
-	else if (c >= 0xFF41 && c <= 0xFF5A)
-	{
-	    c -= 32;
-	}
-    }
-    return c;
-}
-
-
-/*******************************
- * Return !=0 if u is a Unicode alpha character.
- * (general Unicode category: Lu, Ll, Lt, Lm and Lo)
- *
- * Standards: Unicode 5.0.0
- */
-
-int isUniAlpha(dchar u)
-{
-    static dchar table[][2] =
-    [
-	[ 'A', 'Z' ],
-	[ 'a', 'z' ],
-	[ 0x00AA, 0x00AA ],
-	[ 0x00B5, 0x00B5 ],
-	[ 0x00BA, 0x00BA ],
-	[ 0x00C0, 0x00D6 ],
-	[ 0x00D8, 0x00F6 ],
-	[ 0x00F8, 0x02C1 ],
-	[ 0x02C6, 0x02D1 ],
-	[ 0x02E0, 0x02E4 ],
-	[ 0x02EE, 0x02EE ],
-	[ 0x037A, 0x037D ],
-	[ 0x0386, 0x0386 ],
-	[ 0x0388, 0x038A ],
-	[ 0x038C, 0x038C ],
-	[ 0x038E, 0x03A1 ],
-	[ 0x03A3, 0x03CE ],
-	[ 0x03D0, 0x03F5 ],
-	[ 0x03F7, 0x0481 ],
-	[ 0x048A, 0x0513 ],
-	[ 0x0531, 0x0556 ],
-	[ 0x0559, 0x0559 ],
-	[ 0x0561, 0x0587 ],
-	[ 0x05D0, 0x05EA ],
-	[ 0x05F0, 0x05F2 ],
-	[ 0x0621, 0x063A ],
-	[ 0x0640, 0x064A ],
-	[ 0x066E, 0x066F ],
-	[ 0x0671, 0x06D3 ],
-	[ 0x06D5, 0x06D5 ],
-	[ 0x06E5, 0x06E6 ],
-	[ 0x06EE, 0x06EF ],
-	[ 0x06FA, 0x06FC ],
-	[ 0x06FF, 0x06FF ],
-	[ 0x0710, 0x0710 ],
-	[ 0x0712, 0x072F ],
-	[ 0x074D, 0x076D ],
-	[ 0x0780, 0x07A5 ],
-	[ 0x07B1, 0x07B1 ],
-	[ 0x07CA, 0x07EA ],
-	[ 0x07F4, 0x07F5 ],
-	[ 0x07FA, 0x07FA ],
-	[ 0x0904, 0x0939 ],
-	[ 0x093D, 0x093D ],
-	[ 0x0950, 0x0950 ],
-	[ 0x0958, 0x0961 ],
-	[ 0x097B, 0x097F ],
-	[ 0x0985, 0x098C ],
-	[ 0x098F, 0x0990 ],
-	[ 0x0993, 0x09A8 ],
-	[ 0x09AA, 0x09B0 ],
-	[ 0x09B2, 0x09B2 ],
-	[ 0x09B6, 0x09B9 ],
-	[ 0x09BD, 0x09BD ],
-	[ 0x09CE, 0x09CE ],
-	[ 0x09DC, 0x09DD ],
-	[ 0x09DF, 0x09E1 ],
-	[ 0x09F0, 0x09F1 ],
-	[ 0x0A05, 0x0A0A ],
-	[ 0x0A0F, 0x0A10 ],
-	[ 0x0A13, 0x0A28 ],
-	[ 0x0A2A, 0x0A30 ],
-	[ 0x0A32, 0x0A33 ],
-	[ 0x0A35, 0x0A36 ],
-	[ 0x0A38, 0x0A39 ],
-	[ 0x0A59, 0x0A5C ],
-	[ 0x0A5E, 0x0A5E ],
-	[ 0x0A72, 0x0A74 ],
-	[ 0x0A85, 0x0A8D ],
-	[ 0x0A8F, 0x0A91 ],
-	[ 0x0A93, 0x0AA8 ],
-	[ 0x0AAA, 0x0AB0 ],
-	[ 0x0AB2, 0x0AB3 ],
-	[ 0x0AB5, 0x0AB9 ],
-	[ 0x0ABD, 0x0ABD ],
-	[ 0x0AD0, 0x0AD0 ],
-	[ 0x0AE0, 0x0AE1 ],
-	[ 0x0B05, 0x0B0C ],
-	[ 0x0B0F, 0x0B10 ],
-	[ 0x0B13, 0x0B28 ],
-	[ 0x0B2A, 0x0B30 ],
-	[ 0x0B32, 0x0B33 ],
-	[ 0x0B35, 0x0B39 ],
-	[ 0x0B3D, 0x0B3D ],
-	[ 0x0B5C, 0x0B5D ],
-	[ 0x0B5F, 0x0B61 ],
-	[ 0x0B71, 0x0B71 ],
-	[ 0x0B83, 0x0B83 ],
-	[ 0x0B85, 0x0B8A ],
-	[ 0x0B8E, 0x0B90 ],
-	[ 0x0B92, 0x0B95 ],
-	[ 0x0B99, 0x0B9A ],
-	[ 0x0B9C, 0x0B9C ],
-	[ 0x0B9E, 0x0B9F ],
-	[ 0x0BA3, 0x0BA4 ],
-	[ 0x0BA8, 0x0BAA ],
-	[ 0x0BAE, 0x0BB9 ],
-	[ 0x0C05, 0x0C0C ],
-	[ 0x0C0E, 0x0C10 ],
-	[ 0x0C12, 0x0C28 ],
-	[ 0x0C2A, 0x0C33 ],
-	[ 0x0C35, 0x0C39 ],
-	[ 0x0C60, 0x0C61 ],
-	[ 0x0C85, 0x0C8C ],
-	[ 0x0C8E, 0x0C90 ],
-	[ 0x0C92, 0x0CA8 ],
-	[ 0x0CAA, 0x0CB3 ],
-	[ 0x0CB5, 0x0CB9 ],
-	[ 0x0CBD, 0x0CBD ],
-	[ 0x0CDE, 0x0CDE ],
-	[ 0x0CE0, 0x0CE1 ],
-	[ 0x0D05, 0x0D0C ],
-	[ 0x0D0E, 0x0D10 ],
-	[ 0x0D12, 0x0D28 ],
-	[ 0x0D2A, 0x0D39 ],
-	[ 0x0D60, 0x0D61 ],
-	[ 0x0D85, 0x0D96 ],
-	[ 0x0D9A, 0x0DB1 ],
-	[ 0x0DB3, 0x0DBB ],
-	[ 0x0DBD, 0x0DBD ],
-	[ 0x0DC0, 0x0DC6 ],
-	[ 0x0E01, 0x0E30 ],
-	[ 0x0E32, 0x0E33 ],
-	[ 0x0E40, 0x0E46 ],
-	[ 0x0E81, 0x0E82 ],
-	[ 0x0E84, 0x0E84 ],
-	[ 0x0E87, 0x0E88 ],
-	[ 0x0E8A, 0x0E8A ],
-	[ 0x0E8D, 0x0E8D ],
-	[ 0x0E94, 0x0E97 ],
-	[ 0x0E99, 0x0E9F ],
-	[ 0x0EA1, 0x0EA3 ],
-	[ 0x0EA5, 0x0EA5 ],
-	[ 0x0EA7, 0x0EA7 ],
-	[ 0x0EAA, 0x0EAB ],
-	[ 0x0EAD, 0x0EB0 ],
-	[ 0x0EB2, 0x0EB3 ],
-	[ 0x0EBD, 0x0EBD ],
-	[ 0x0EC0, 0x0EC4 ],
-	[ 0x0EC6, 0x0EC6 ],
-	[ 0x0EDC, 0x0EDD ],
-	[ 0x0F00, 0x0F00 ],
-	[ 0x0F40, 0x0F47 ],
-	[ 0x0F49, 0x0F6A ],
-	[ 0x0F88, 0x0F8B ],
-	[ 0x1000, 0x1021 ],
-	[ 0x1023, 0x1027 ],
-	[ 0x1029, 0x102A ],
-	[ 0x1050, 0x1055 ],
-	[ 0x10A0, 0x10C5 ],
-	[ 0x10D0, 0x10FA ],
-	[ 0x10FC, 0x10FC ],
-	[ 0x1100, 0x1159 ],
-	[ 0x115F, 0x11A2 ],
-	[ 0x11A8, 0x11F9 ],
-	[ 0x1200, 0x1248 ],
-	[ 0x124A, 0x124D ],
-	[ 0x1250, 0x1256 ],
-	[ 0x1258, 0x1258 ],
-	[ 0x125A, 0x125D ],
-	[ 0x1260, 0x1288 ],
-	[ 0x128A, 0x128D ],
-	[ 0x1290, 0x12B0 ],
-	[ 0x12B2, 0x12B5 ],
-	[ 0x12B8, 0x12BE ],
-	[ 0x12C0, 0x12C0 ],
-	[ 0x12C2, 0x12C5 ],
-	[ 0x12C8, 0x12D6 ],
-	[ 0x12D8, 0x1310 ],
-	[ 0x1312, 0x1315 ],
-	[ 0x1318, 0x135A ],
-	[ 0x1380, 0x138F ],
-	[ 0x13A0, 0x13F4 ],
-	[ 0x1401, 0x166C ],
-	[ 0x166F, 0x1676 ],
-	[ 0x1681, 0x169A ],
-	[ 0x16A0, 0x16EA ],
-	[ 0x1700, 0x170C ],
-	[ 0x170E, 0x1711 ],
-	[ 0x1720, 0x1731 ],
-	[ 0x1740, 0x1751 ],
-	[ 0x1760, 0x176C ],
-	[ 0x176E, 0x1770 ],
-	[ 0x1780, 0x17B3 ],
-	[ 0x17D7, 0x17D7 ],
-	[ 0x17DC, 0x17DC ],
-	[ 0x1820, 0x1877 ],
-	[ 0x1880, 0x18A8 ],
-	[ 0x1900, 0x191C ],
-	[ 0x1950, 0x196D ],
-	[ 0x1970, 0x1974 ],
-	[ 0x1980, 0x19A9 ],
-	[ 0x19C1, 0x19C7 ],
-	[ 0x1A00, 0x1A16 ],
-	[ 0x1B05, 0x1B33 ],
-	[ 0x1B45, 0x1B4B ],
-	[ 0x1D00, 0x1DBF ],
-	[ 0x1E00, 0x1E9B ],
-	[ 0x1EA0, 0x1EF9 ],
-	[ 0x1F00, 0x1F15 ],
-	[ 0x1F18, 0x1F1D ],
-	[ 0x1F20, 0x1F45 ],
-	[ 0x1F48, 0x1F4D ],
-	[ 0x1F50, 0x1F57 ],
-	[ 0x1F59, 0x1F59 ],
-	[ 0x1F5B, 0x1F5B ],
-	[ 0x1F5D, 0x1F5D ],
-	[ 0x1F5F, 0x1F7D ],
-	[ 0x1F80, 0x1FB4 ],
-	[ 0x1FB6, 0x1FBC ],
-	[ 0x1FBE, 0x1FBE ],
-	[ 0x1FC2, 0x1FC4 ],
-	[ 0x1FC6, 0x1FCC ],
-	[ 0x1FD0, 0x1FD3 ],
-	[ 0x1FD6, 0x1FDB ],
-	[ 0x1FE0, 0x1FEC ],
-	[ 0x1FF2, 0x1FF4 ],
-	[ 0x1FF6, 0x1FFC ],
-	[ 0x2071, 0x2071 ],
-	[ 0x207F, 0x207F ],
-	[ 0x2090, 0x2094 ],
-	[ 0x2102, 0x2102 ],
-	[ 0x2107, 0x2107 ],
-	[ 0x210A, 0x2113 ],
-	[ 0x2115, 0x2115 ],
-	[ 0x2119, 0x211D ],
-	[ 0x2124, 0x2124 ],
-	[ 0x2126, 0x2126 ],
-	[ 0x2128, 0x2128 ],
-	[ 0x212A, 0x212D ],
-	[ 0x212F, 0x2139 ],
-	[ 0x213C, 0x213F ],
-	[ 0x2145, 0x2149 ],
-	[ 0x214E, 0x214E ],
-	[ 0x2183, 0x2184 ],
-	[ 0x2C00, 0x2C2E ],
-	[ 0x2C30, 0x2C5E ],
-	[ 0x2C60, 0x2C6C ],
-	[ 0x2C74, 0x2C77 ],
-	[ 0x2C80, 0x2CE4 ],
-	[ 0x2D00, 0x2D25 ],
-	[ 0x2D30, 0x2D65 ],
-	[ 0x2D6F, 0x2D6F ],
-	[ 0x2D80, 0x2D96 ],
-	[ 0x2DA0, 0x2DA6 ],
-	[ 0x2DA8, 0x2DAE ],
-	[ 0x2DB0, 0x2DB6 ],
-	[ 0x2DB8, 0x2DBE ],
-	[ 0x2DC0, 0x2DC6 ],
-	[ 0x2DC8, 0x2DCE ],
-	[ 0x2DD0, 0x2DD6 ],
-	[ 0x2DD8, 0x2DDE ],
-	[ 0x3005, 0x3006 ],
-	[ 0x3031, 0x3035 ],
-	[ 0x303B, 0x303C ],
-	[ 0x3041, 0x3096 ],
-	[ 0x309D, 0x309F ],
-	[ 0x30A1, 0x30FA ],
-	[ 0x30FC, 0x30FF ],
-	[ 0x3105, 0x312C ],
-	[ 0x3131, 0x318E ],
-	[ 0x31A0, 0x31B7 ],
-	[ 0x31F0, 0x31FF ],
-	[ 0x3400, 0x4DB5 ],
-	[ 0x4E00, 0x9FBB ],
-	[ 0xA000, 0xA48C ],
-	[ 0xA717, 0xA71A ],
-	[ 0xA800, 0xA801 ],
-	[ 0xA803, 0xA805 ],
-	[ 0xA807, 0xA80A ],
-	[ 0xA80C, 0xA822 ],
-	[ 0xA840, 0xA873 ],
-	[ 0xAC00, 0xD7A3 ],
-	[ 0xF900, 0xFA2D ],
-	[ 0xFA30, 0xFA6A ],
-	[ 0xFA70, 0xFAD9 ],
-	[ 0xFB00, 0xFB06 ],
-	[ 0xFB13, 0xFB17 ],
-	[ 0xFB1D, 0xFB1D ],
-	[ 0xFB1F, 0xFB28 ],
-	[ 0xFB2A, 0xFB36 ],
-	[ 0xFB38, 0xFB3C ],
-	[ 0xFB3E, 0xFB3E ],
-	[ 0xFB40, 0xFB41 ],
-	[ 0xFB43, 0xFB44 ],
-	[ 0xFB46, 0xFBB1 ],
-	[ 0xFBD3, 0xFD3D ],
-	[ 0xFD50, 0xFD8F ],
-	[ 0xFD92, 0xFDC7 ],
-	[ 0xFDF0, 0xFDFB ],
-	[ 0xFE70, 0xFE74 ],
-	[ 0xFE76, 0xFEFC ],
-	[ 0xFF21, 0xFF3A ],
-	[ 0xFF41, 0xFF5A ],
-	[ 0xFF66, 0xFFBE ],
-	[ 0xFFC2, 0xFFC7 ],
-	[ 0xFFCA, 0xFFCF ],
-	[ 0xFFD2, 0xFFD7 ],
-	[ 0xFFDA, 0xFFDC ],
-	[ 0x10000, 0x1000B ],
-	[ 0x1000D, 0x10026 ],
-	[ 0x10028, 0x1003A ],
-	[ 0x1003C, 0x1003D ],
-	[ 0x1003F, 0x1004D ],
-	[ 0x10050, 0x1005D ],
-	[ 0x10080, 0x100FA ],
-	[ 0x10300, 0x1031E ],
-	[ 0x10330, 0x10340 ],
-	[ 0x10342, 0x10349 ],
-	[ 0x10380, 0x1039D ],
-	[ 0x103A0, 0x103C3 ],
-	[ 0x103C8, 0x103CF ],
-	[ 0x10400, 0x1049D ],
-	[ 0x10800, 0x10805 ],
-	[ 0x10808, 0x10808 ],
-	[ 0x1080A, 0x10835 ],
-	[ 0x10837, 0x10838 ],
-	[ 0x1083C, 0x1083C ],
-	[ 0x1083F, 0x1083F ],
-	[ 0x10900, 0x10915 ],
-	[ 0x10A00, 0x10A00 ],
-	[ 0x10A10, 0x10A13 ],
-	[ 0x10A15, 0x10A17 ],
-	[ 0x10A19, 0x10A33 ],
-	[ 0x12000, 0x1236E ],
-	[ 0x1D400, 0x1D454 ],
-	[ 0x1D456, 0x1D49C ],
-	[ 0x1D49E, 0x1D49F ],
-	[ 0x1D4A2, 0x1D4A2 ],
-	[ 0x1D4A5, 0x1D4A6 ],
-	[ 0x1D4A9, 0x1D4AC ],
-	[ 0x1D4AE, 0x1D4B9 ],
-	[ 0x1D4BB, 0x1D4BB ],
-	[ 0x1D4BD, 0x1D4C3 ],
-	[ 0x1D4C5, 0x1D505 ],
-	[ 0x1D507, 0x1D50A ],
-	[ 0x1D50D, 0x1D514 ],
-	[ 0x1D516, 0x1D51C ],
-	[ 0x1D51E, 0x1D539 ],
-	[ 0x1D53B, 0x1D53E ],
-	[ 0x1D540, 0x1D544 ],
-	[ 0x1D546, 0x1D546 ],
-	[ 0x1D54A, 0x1D550 ],
-	[ 0x1D552, 0x1D6A5 ],
-	[ 0x1D6A8, 0x1D6C0 ],
-	[ 0x1D6C2, 0x1D6DA ],
-	[ 0x1D6DC, 0x1D6FA ],
-	[ 0x1D6FC, 0x1D714 ],
-	[ 0x1D716, 0x1D734 ],
-	[ 0x1D736, 0x1D74E ],
-	[ 0x1D750, 0x1D76E ],
-	[ 0x1D770, 0x1D788 ],
-	[ 0x1D78A, 0x1D7A8 ],
-	[ 0x1D7AA, 0x1D7C2 ],
-	[ 0x1D7C4, 0x1D7CB ],
-	[ 0x20000, 0x2A6D6 ],
-	[ 0x2F800, 0x2FA1D ],
-    ];
-
-    debug
-    {
-	for (int i = 0; i < table.length; i++)
-	{
-	    assert(table[i][0] <= table[i][1]);
-	    if (i < table.length - 1)
-	    {
-//		if (table[i][1] >= table[i + 1][0])
-//		    printf("table[%d][1] = x%x, table[%d][0] = x%x\n", i, table[i][1], i + 1, table[i + 1][0]);
-		assert(table[i][1] < table[i + 1][0]);
-	    }
-	}
-    }
-
-    if (u < 0xAA)
-    {
-	if (u < 'A')
-	    goto Lisnot;
-	if (u <= 'Z')
-	    goto Lis;
-	if (u < 'a')
-	    goto Lisnot;
-	if (u <= 'z')
-	    goto Lis;
-	goto Lisnot;
-    }
-
-    // Binary search
-    uint mid;
-    uint low;
-    uint high;
-
-    low = 0;
-    high = table.length - 1;
-    while (cast(int)low <= cast(int)high)
-    {
-	mid = (low + high) >> 1;
-	if (u < table[mid][0])
-	    high = mid - 1;
-	else if (u > table[mid][1])
-	    low = mid + 1;
-	else
-	    goto Lis;
-    }
-
-Lisnot:
-    debug
-    {
-	for (int i = 0; i < table.length; i++)
-	{
-	    assert(u < table[i][0] || u > table[i][1]);
-	}
-    }
-    return 0;
-
-Lis:
-    debug
-    {
-	for (int i = 0; i < table.length; i++)
-	{
-	    if (u >= table[i][0] && u <= table[i][1])
-		return 1;
-	}
-	assert(0);		// should have been in table
-    }
-    return 1;
-}
-
-unittest
-{
-    for (uint i = 0; i < 0x80; i++)
-    {
-	if (i >= 'A' && i <= 'Z')
-	    assert(isUniAlpha(i));
-	else if (i >= 'a' && i <= 'z')
-	    assert(isUniAlpha(i));
-	else
-	    assert(!isUniAlpha(i));
-    }
-}
--- a/trunk/src/xml.css	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-@charset "utf-8";
-compilerinfo, sourcecode, linescolumn {
-  white-space: pre;
-  font-family: Monospace;
-  font-size: 0.8em;
-}
-compilerinfo, sourcecode {
-  display: block;
-}
-compilerinfo {
-  white-space: normal;
-  border: 1px solid #A22;
-  padding: 0.5em;
-  margin: 1em;
-}
-compilerinfo error { display: block; }
-linescolumn {
-  display: block;
-  float: left;
-  text-align: right;
-  margin-right: 0.2em;
-  border-right: 1px solid gray;
-}
-linescolumn a { display: block; color: #555; }
-/* Number */
-n { color: teal; }
-/* Keyword */
-k { color: darkblue; font-weight: bold; }
-/* Line, block and nested comments */
-lc, bc, nc { color: green; }
-/* Identifier */
-i { color: black; }
-/* String literal */
-sl { color: red; }
-/* Character literal */
-cl { color: purple; }
-/* All bracket types */
-br { color: orange; }
-/* Special tokens */
-st { color: green; font-weight: bold; }
-/* #line, hash line */
-hl { color: green; }
-/* filespec (e.g. #line number [filespec]) */
-fs { color: purple;}
-/* When the first line starts with #! it's a "shebang" */
-shebang { color: gray; }
-/* Deprecated styles. */
-/* Operator */
-/*op { color: royalblue; }*/
-/* Particular operators */
-/*op[t=aa] { content: "and"; }*/ /*&& ∧*/
-/*op[t=oo] { content: "or"; }*/ /*|| ∨*/
-/*op[t=n] { content: "¬"; }*/ /*!*/
-/*op[t=ne] { content: "≠"; }*/ /*!=*/
-/*op[t=le] { content: "≤"; }*/ /*<=*/
-/*op[t=ge] { content: "≥"; }*/ /*>=*/
-/*op[t=lg] { content: "≶"; }*/ /*<>*/
-/*
-d = Declaration
-s = Statement
-e = Expression
-t = Type
-o = Other
-*/
-/* d { background-color: #FFDDDD; } */
-/* e { background-color: #DDDDFF; } */
-d[t=Illegal], s[t=Illegal] { background-color: #DD4422; }
-d[t=Module] i, d[t=Import] i { color: blue; }
-t > i { color: #911; }
-t > br, t > op { color: #911; }
-t[t=Integral] k { color: #911; font-weight: normal; }
--- a/trunk/src/xml_map.d	Sat Mar 08 22:09:59 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/// A map of document elements and D tokens to format strings.
-string[string] map = [
-  "DocHead" : `<?xml version="1.0"?>`\n
-              `<?xml-stylesheet href="xml.css" type="text/css"?>`\n
-              "<root>\n",
-  "DocEnd"  : "\n</root>",
-  "SourceBegin" : "<sourcecode>",
-  "SourceEnd"   : "\n</sourcecode>",
-  "CompBegin"   : "<compiler>\n",
-  "CompEnd"     : "</compiler>\n",
-  "LexerError"  : `<error t="L">{0}({1},{2})L: {3}</error>`\n,
-  "ParserError" : `<error t="P">{0}({1},{2})P: {3}</error>`\n,
-  "LineNumberBegin" : `<linescolumn>`,
-  "LineNumberEnd"   : `</linescolumn>`,
-  "LineNumber"      : `<a xml:id="L{0}">{0}</a>`,
-
-  // Node categories:
-  "Declaration" : "d",
-  "Statement"   : "s",
-  "Expression"  : "e",
-  "Type"        : "t",
-  "Other"       : "o",
-
-  // {0} = node category.
-  // {1} = node class name: "Call", "If", "Class" etc.
-  // E.g.: <d t="Struct">...</d>
-  "NodeBegin" : `<{0} t="{1}">`,
-  "NodeEnd"   : `</{0}>`,
-
-  "Identifier" : "<i>{0}</i>",
-  "String"     : "<sl>{0}</sl>",
-  "Char"       : "<cl>{0}</cl>",
-  "Number"     : "<n>{0}</n>",
-  "Keyword"    : "<k>{0}</k>",
-
-  "LineC"   : "<lc>{0}</lc>",
-  "BlockC"  : "<bc>{0}</bc>",
-  "NestedC" : "<nc>{0}</nc>",
-
-  "Shebang"  : "<shebang>{0}</shebang>",
-  "HLine"    : "<hl>{0}</hl>", // #line
-  "Filespec" : "<fs>{0}</fs>", // #line N "filespec"
-  "Newline"  : "{0}", // \n | \r | \r\n | LS | PS
-  "Illegal"  : "<ill>{0}</ill>", // A character not recognized by the lexer.
-
-  "SpecialToken" : "<st>{0}</st>", // __FILE__, __LINE__ etc.
-
-  "("    : "<br>(</br>",
-  ")"    : "<br>)</br>",
-  "["    : "<br>[</br>",
-  "]"    : "<br>]</br>",
-  "{"    : "<br>{</br>",
-  "}"    : "<br>}</br>",
-  "."    : ".",
-  ".."   : "..",
-  "..."  : "...",
-  "!<>=" : "!&lt;&gt;=", // Unordered
-  "!<>"  : "!&lt;&gt;",  // UorE
-  "!<="  : "!&lt;=",     // UorG
-  "!<"   : "!&lt;",      // UorGorE
-  "!>="  : "!&gt;=",     // UorL
-  "!>"   : "!&gt;",      // UorLorE
-  "<>="  : "&lt;&gt;=",  // LorEorG
-  "<>"   : "&lt;&gt;",   // LorG
-  "="    : "=",
-  "=="   : "==",
-  "!"    : "!",
-  "!="   : "!=",
-  "<="   : "&lt;=",
-  "<"    : "&lt;",
-  ">="   : "&gt;=",
-  ">"    : "&gt;",
-  "<<="  : "&lt;&lt;=",
-  "<<"   : "&lt;&lt;",
-  ">>="  : "&gt;&gt;=",
-  ">>"   : "&gt;&gt;",
-  ">>>=" : "&gt;&gt;&gt;=",
-  ">>>"  : "&gt;&gt;&gt;",
-  "|"    : "|",
-  "||"   : "||",
-  "|="   : "|=",
-  "&"    : "&amp;",
-  "&&"   : "&amp;&amp;",
-  "&="   : "&amp;=",
-  "+"    : "+",
-  "++"   : "++",
-  "+="   : "+=",
-  "-"    : "-",
-  "--"   : "--",
-  "-="   : "-=",
-  "/"    : "/",
-  "/="   : "/=",
-  "*"    : "*",
-  "*="   : "*=",
-  "%"    : "%",
-  "%="   : "%=",
-  "^"    : "^",
-  "^="   : "^=",
-  "~"    : "~",
-  "~="   : "~=",
-  ":"    : ":",
-  ";"    : ";",
-  "?"    : "?",
-  ","    : ",",
-  "$"    : "$",
-  "EOF"  : ""
-];