diff --git a/COPYING b/COPYING
new file mode 100644
--- /dev/null
+++ b/COPYING
@@ -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>.
diff --git a/Gom.hs b/Gom.hs
new file mode 100644
--- /dev/null
+++ b/Gom.hs
@@ -0,0 +1,98 @@
+------------------------------------------------------------------
+-- |
+-- Module      : Main
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires GeneralizedNewtypeDeriving)
+--
+-- Entry point of hgom. 
+--------------------------------------------------------------------
+
+{-# LANGUAGE PatternGuards #-}
+
+module Main (main,entryPoint) where
+
+import Gom.Sig
+import Gom.Parser
+import Gom.Pretty ()
+import Gom.Checker
+import Gom.SymbolTable
+import Gom.CodeGen
+import Gom.OOMappingGen
+import Gom.Config
+import Gom.FileGen
+
+import System.Environment (getArgs)
+import Text.PrettyPrint.Leijen (pretty)
+
+#if TEST
+import qualified Gom.UnitTests as T
+import Test.Framework (defaultMainWithArgs)
+#endif
+
+hgomVersion :: String
+hgomVersion = "Version 0.5.1 - March 2009"
+
+-- | @main = getArgs >>= entryPoint@
+main ::  IO ()
+main = getArgs >>= entryPoint
+
+-- | entry poiny of hgom, separated from @main@ in order 
+-- to make it callable by other programs
+entryPoint :: [String] -> IO ()
+entryPoint args =
+  case gomOpts args of 
+    Left err    -> paramsError err
+    Right (c,n) -> go1 c n
+
+-- | before parsing: checks all \"... and exit\" functions 
+-- that don't require parsing
+go1 :: Config -> [String] -> IO ()
+go1 c n | help c              = putStrLn usage
+        | version c           = putStrLn hgomVersion
+#if TEST
+        | Just as <- utests c  = defaultMainWithArgs T.testSuite as
+#endif
+        | otherwise           = case n of
+            [f] -> go2 f c 
+            []  -> paramsError "No input file specified.\n"
+            _   -> paramsError "Too many input files specified.\n"
+
+-- | parsing: checks that all went well and calls @go3@
+go2 :: FilePath -> Config -> IO ()
+go2 f c = do em <- parseModule `fmap` readFile f
+             case em of Left err -> error ("parse error at " ++ show err)
+                        Right m  -> go3 f c m
+
+-- | after parsing:
+--
+--    * checks all "... and exit" functions that require parsing
+--
+--    * checks well-formedness
+--
+--    * runs compilation chain
+go3 :: FilePath -> Config -> Module -> IO ()
+go3 f c sig | prprint c = print $ pretty sig
+            | checker c = case checkEverything sig of
+                Nothing -> gomain
+                Just d  -> error (f ++ " contains errors:\n" ++ show d)
+            | otherwise = gomain
+  where gomain = (if oomapping c then ooChain else hgomChain) c sig
+
+-- | compilation chain for hgom
+hgomChain :: Config -> Module -> IO ()
+hgomChain conf = generateFileHierarchy (compact conf) . 
+                 flip st2java conf . 
+                 completeVariadics .  
+                 ast2st
+
+-- | compilation chain for oomapings
+ooChain :: Config -> Module -> IO ()
+ooChain conf = generateFileHierarchy (compact conf) . 
+               flip st2oomapping conf .
+               ast2st 
diff --git a/Gom/Checker.hs b/Gom/Checker.hs
new file mode 100644
--- /dev/null
+++ b/Gom/Checker.hs
@@ -0,0 +1,311 @@
+------------------------------------------------------------------
+-- |
+-- Module      : Gom.Checker
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--
+-- Checker to be run before the construction of a symbol table.
+--------------------------------------------------------------------
+
+module Gom.Checker (
+  NameConsistencyError(),
+  UndefSortError(),
+  MultipleCtorDecl(),
+  MultipleSortDecl(),
+  MultipleFieldsError(),
+  GeneratedConstructorsClash(),
+  -- * Individual features checking
+  checkJavaKeywordClash,
+  checkCtorModuleClash,
+  checkMultipleSortDecl,
+  checkMultipleCtorDecl,
+  checkDuplicateFields,
+  checkNameConsistency,
+  checkUndefSorts,
+  checkGenClashes,
+  -- * All-in-one check
+  checkEverything
+) where
+
+import Gom.Sig
+import Gom.Pretty()
+
+import qualified Data.Map as M
+import qualified Data.Set as S
+import qualified Data.List as L
+import Data.Maybe(mapMaybe)
+import Text.PrettyPrint.Leijen
+import Data.Char(toLower)
+
+newtype NameConsistencyError = NCE [(SortId,[(FieldId,[SortId])])]
+
+instance Pretty NameConsistencyError where
+  pretty (NCE e) = vsep $ map f e
+    where f (s,al) = hang 2 (text "In the definition of sort" <+> 
+                     text (show s) <> text ":" <$> vsep (map g al))
+          g (x,l)  = text "field" <+> text (show x) <+> 
+                     text "has many sorts:" <+>
+                     hsep (punctuate (text ",") (map pretty l))
+
+newtype UndefSortError = USE [(SortId,[(CtorId,[SortId])])]
+
+instance Pretty UndefSortError where
+  pretty (USE e) = vsep $ map f e
+    where f (s,l)  = nest 2 $ text "In the definition of sort" <+> 
+                              text (show s) <> text ":" </> vsep (map g l)
+          g (c,ss) = nest 2 $ text "in constructor" <+> text (show c) <> 
+                              text ":" </> 
+                              text "the following sorts are not defined:" <+>
+                              hsep (punctuate (text ",") (map pretty ss))
+
+newtype MultipleFieldsError = MFE [(SortId,[(CtorId,[(FieldId,Int)])])]
+
+instance Pretty MultipleFieldsError where
+  pretty (MFE e) = vsep $ map f e
+    where f (s,l)  = nest 2 $ text "In the definition of sort" <+> 
+                              text (show s) <> text ":" </> vsep (map g l)
+          g (c,fs) = nest 2 $ text "in constructor" <+> text (show c) <> 
+                              text ":" </> vsep (map h fs)
+          h (fi,n) = text "there are" <+> int n <+> 
+                     text "fields named" <+> text (show fi)
+
+newtype MultipleCtorDecl = MCD [(CtorId,Int)]
+
+instance Pretty MultipleCtorDecl where
+  pretty (MCD l) = vsep $ map f l
+    where f (c,n) = text "Constructor" <+> text (show c) 
+                    <+> text "is declared" <+> int n <+> text "times."
+
+newtype MultipleSortDecl = MSD [(SortId,Int)]
+
+instance Pretty MultipleSortDecl where
+  pretty (MSD l) = vsep $ map f l
+    where f (c,n) = text "Sort" <+> text (show c)
+                    <+> text "is declared" <+> int n <+> text "times."
+
+newtype GeneratedConstructorsClash = GCG [(CtorId,[CtorId])]
+
+instance Pretty GeneratedConstructorsClash where
+  pretty (GCG l) = vsep $ map f l
+    where f (c,cs) = text "Variadic constructor" <+> text (show c) <+>
+                     nest 2 (text "clashes with:" </>
+                            (hsep . punctuate (text ",")) (map pretty cs))
+
+data JavaKeywordClash = JKC [String] [SortId] [CtorId] [FieldId]
+
+instance Pretty JavaKeywordClash where
+  pretty (JKC m s c f) = vcat [p "Module name"       m,
+                               p "Sort name"         s, 
+                               p "Constructors name" c, 
+                               p "Field name"        f]
+    where p mes = vcat . map (er mes)
+          er mes x = text mes <+> dquotes (pretty x) <+> 
+                     text "clashes with java keywords."
+
+data CtorModuleClash = CMC [CtorId]
+
+instance Pretty CtorModuleClash where
+  pretty (CMC cs) = vcat (map f cs)
+    where f c = text "Constructor" <+> pretty c <+> 
+                text "clashes with module's name."
+
+-- | helper function to pack checkers results into Maybes
+pack :: ([t] -> a) -> [t] -> Maybe a
+pack _ [] = Nothing
+pack c l  = Just (c l)
+
+-- | Auxiliary function for 'checkNameConsistency'
+differentSortsForAName :: SortDef -> [(FieldId, [SortId])]
+differentSortsForAName = 
+  convert . M.filter f . populate M.empty . simpleFieldsOf
+  where populate m []         = m
+        populate m ((x,t):fs) = let ts = S.singleton t
+                                    m' = M.insertWith S.union x ts m
+                                in populate m' fs
+        f s = S.size s > 1
+        convert = M.toAscList . M.map S.toList
+
+-- | Checks that each field name in all the constructors of a sort 
+-- is assigned the same type everywhere.
+-- 
+-- As an example, for the following signature
+--
+-- > Expr = Lit(x:int) 
+-- >      | Str(x:String) 
+-- >      | ...
+--
+-- the function will report that @x@ is assigned both @int@ and
+-- @String@ sorts.
+checkNameConsistency :: Module -> Maybe NameConsistencyError
+checkNameConsistency = pack NCE . mapMaybe check . sortDefs 
+  where check def = case differentSortsForAName def of
+          [] -> Nothing
+          al -> Just (sortName def, al)
+
+-- | Checks that all sorts mentionned in the constructors are either 
+-- defined or imported.
+--
+-- As an example, in the following module
+--
+-- > module M
+-- > imports String
+-- > abstract syntax
+-- >
+-- > Expr = Lit(x:int) 
+-- >      | Str(y:String) 
+-- > 
+-- > List = nil() | (x:A,xs:List)
+--
+-- the function will report that @int@ and @A@ are not defined. 
+checkUndefSorts :: Module -> Maybe UndefSortError
+checkUndefSorts sig = pack USE $ mapMaybe f (sortDefs sig)
+  where def = exportedSorts sig
+        f (SortDef n _ ctrs) = 
+          case mapMaybe g ctrs of
+            [] -> Nothing
+            cs -> Just (n,cs)
+        g c = case h c of
+            [] -> Nothing
+            ss -> Just (ctorName c, ss)
+        h (Simple _ fis) = L.nub $ concatMap (i . snd) fis
+        h (Variadic _ s) = i s
+        i x | x `notElem` def = [x]
+            | otherwise       = []
+
+count :: (Ord a) => [a] -> [(a, Int)]
+count = mapMaybe multi . L.group . L.sort
+  where multi [_] = Nothing
+        multi cs  = Just (head cs, length cs)
+
+-- | Checks, for each constructor defined in the signature, 
+-- that all of its fields have different names.
+--
+-- As an example, for the following constructor
+--
+-- > Plus(e:Expr,e:Expr)
+--
+-- the function will report that @Plus@ contains two fields named @e@. 
+checkDuplicateFields :: Module -> Maybe MultipleFieldsError
+checkDuplicateFields sig = pack MFE $ mapMaybe f (sortDefs sig)
+  where f (SortDef n _ ctrs) = 
+          case mapMaybe g ctrs of
+            [] -> Nothing
+            cs -> Just (n,cs)
+        g c = case h c of
+            [] -> Nothing
+            ss -> Just (ctorName c, ss)
+        h (Simple _ fis) = count $ map fst fis 
+        h (Variadic _ _) = []
+
+-- | Checks that a constructor is not declared twice in the module
+--
+-- As an exemple, for the following signature
+--
+-- > IntList = nil() | cons(x:int,y:IntList)
+-- > StrList = nil() | cons(x:Str,y:StrList)
+--
+-- the function will report that both @nil@ and @cons@ are declared twice.
+checkMultipleCtorDecl :: Module -> Maybe MultipleCtorDecl
+checkMultipleCtorDecl = pack MCD . count . constructorNames
+
+-- | Checks that a sort is not defined twice in the module
+--
+-- As an exemple, for the following signature
+--
+-- > List = inil() | icons(x:int,y:IntList)
+-- > List = snil() | scons(x:Str,y:StrList)
+--
+-- the function will report that @List@ is defined twice.
+checkMultipleSortDecl :: Module -> Maybe MultipleSortDecl
+checkMultipleSortDecl = pack MSD . count . exportedSorts
+
+-- | Checks that constructor names that will be generated for
+-- every variadic constructor don't collide with user-declared
+-- constructors.
+--
+-- As an exemple, for the following signature
+--
+-- > List = list(int*)
+-- > T    = Emptylist(...) | Conslist(...)
+--
+-- the function will report that @list@ clashes with both @Emptylist@ and
+-- @Conslist@.
+checkGenClashes :: Module -> Maybe GeneratedConstructorsClash
+checkGenClashes m = pack GCG $ mapMaybe check vcs
+  where vcs = vconstructorNames m
+        cs  = constructorNames  m
+        check vc = 
+          let l = L.nub $ filter (`elem` [prependEmpty vc, prependCons vc]) cs
+          in if null l then Nothing else Just (vc,l)
+           
+
+checkers :: [Module -> Maybe Doc]
+checkers = [w checkJavaKeywordClash,
+            w checkCtorModuleClash,
+            w checkMultipleSortDecl,
+            w checkMultipleCtorDecl,
+            w checkDuplicateFields,
+            w checkNameConsistency,
+            w checkUndefSorts,
+            w checkGenClashes]
+  where w check x = pretty `fmap` check x
+
+javaKeywords :: S.Set String
+javaKeywords = S.fromList
+  ["abstract","continue","for","new","switch","assert","default","goto",
+   "package","synchronized","do","if","private","this","break",
+   "implements","protected","throw","else","import",
+   "public","throws","case","enum","instanceof","return","transient",
+   "catch","extends","try","final","interface",
+   "static","void","class","finally","strictfp","volatile","const",
+   "native","super","while",
+   "boolean","double","byte","int","short","long","float","char"]
+
+-- | Looks for module, sorts, ctors and fields names that would clash
+-- with java keywords.
+checkJavaKeywordClash :: Module -> Maybe JavaKeywordClash
+checkJavaKeywordClash m = pack4 (filter checkMod [moduleName m])
+                                (filter checkSort $ definedSorts m)
+                                (filter checkCtor $ constructorNames m)
+                                (filter checkFld $ simpleFieldsNames m)
+  where pack4 [] [] [] [] = Nothing
+        pack4 l1 l2 l3 l4 = Just $ JKC l1 l2 l3 l4
+        isJkw      = (`S.member` javaKeywords)
+        checkMod   = isJkw . map toLower
+        checkSort  = isJkw . map toLower . idStr
+        checkCtor  = isJkw . idStr 
+        checkFld   = isJkw . idStr
+
+-- | Looks for clashes between lowercase module name and constructor names
+checkCtorModuleClash :: Module -> Maybe CtorModuleClash
+checkCtorModuleClash m = pack CMC clashes
+  where lowmn   = map toLower (moduleName m)
+        clashes = filter ((== lowmn) . idStr) (constructorNames m)
+
+-- | Reports, in this order, the results of:
+--    - 'checkJavaKeywordClash'
+--
+--    - 'checkCtorModuleClash'
+--
+--    - 'checkMultipleSortDecl'
+--
+--    - 'checkMultipleCtorDecl'
+--
+--    - 'checkDuplicateFields'
+--
+--    - 'checkNameConsistency'
+--
+--    - 'checkUndefSorts'
+--
+--    - 'checkGenClashes'
+checkEverything :: Module -> Maybe Doc
+checkEverything m = ret $ mapMaybe ($ m) checkers  
+  where ret [] = Nothing
+        ret l  = Just $ foldr1 dbreak l
+        dbreak x y = x <> linebreak <> linebreak <> y
diff --git a/Gom/CodeGen.hs b/Gom/CodeGen.hs
new file mode 100644
--- /dev/null
+++ b/Gom/CodeGen.hs
@@ -0,0 +1,56 @@
+-------------------------------------------------------------------
+-- |
+-- Module      : Gom.CodeGen
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--
+-- Generation of a file hierarchy from a symbol table.
+-------------------------------------------------------------------- 
+
+module Gom.CodeGen (st2java) where
+
+import Data.Char(toLower)
+
+import Gom.SymbolTable
+import Gom.Config
+import Gom.FileGen
+import Gom.CodeGen.Common.Constants
+import Gom.CodeGen.Common.GenMonad
+import Gom.CodeGen.Abstract
+import Gom.CodeGen.Mappings
+import Gom.CodeGen.Strategies
+import Gom.CodeGen.Sorts
+
+-- | Compiles a symbol table into a Java hierarchy
+st2java :: SymbolTable -> Config -> FileHierarchy
+st2java =  runGen  compSt
+
+-- | Generates the whole file hierarchy of the \"global\" symbol table.
+compSt :: Gen FileHierarchy
+compSt = do mn <- map toLower `fmap` askSt modName
+            ds <- askSt definedSortsIds
+            hs <- mapM compSort ds
+            ac <- compAbstract
+            tfs <- compTomFiles
+            pr <- askConf package
+            cs <- mapM compStrategy ds
+            pc <- ifP $ Class "Parser" absParser
+            lc <- ifP $ Class "Lexer" absLexer
+            ps <- ifC $ Package "strategy" cs
+            let always = tfs ++ [ac,Package "types" (concat hs)] 
+            return . wrap pr $ Package mn (always ++ pc ++ lc ++ ps)
+  where -- wraps the package in the user-provided prefix hierarchy (-p option)
+        wrap Nothing  h = h
+        wrap (Just l) h = foldr w h l
+        w p h = Package p [h]
+        ifC x = do congrval <- askConf congr
+                   case congrval of
+                     NoCongr -> return []
+                     _ ->       return [x]
+        ifP x = ifConf parsers [x] []
diff --git a/Gom/CodeGen/Abstract.hs b/Gom/CodeGen/Abstract.hs
new file mode 100644
--- /dev/null
+++ b/Gom/CodeGen/Abstract.hs
@@ -0,0 +1,55 @@
+------------------------------------------------------------------
+-- |
+-- Module      : Gom.CodeGen.Abstract
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--------------------------------------------------------------------
+
+module Gom.CodeGen.Abstract (
+  compAbstract
+) where
+
+import Gom.CodeGen.Common
+import Gom.SymbolTable
+import Gom.Config
+import Gom.FileGen
+
+import Control.Applicative
+import Text.PrettyPrint.Leijen hiding ((<$>))
+
+-- | Generates the @ModAbstractType@ abstract java class for module @Mod@.
+compAbstract :: Gen FileHierarchy
+compAbstract = do at <- abstractType
+                  -- if haskell option is enabled, generate abstract toHaskell
+                  hs <- ifConf haskell hask []
+                  -- if sharing option is enabled, generate abstract methods
+                  ss <- ifConf sharing [abstractSharing] []
+                  -- if visit option is enabled, implement visitable 
+                  iv <- ifConf visit [jVisitable] []
+                  -- if sharing option is enabled, implement shared
+                  is <- ifConf sharing [jSharedId] []
+                  -- generate renderString and/or renderChar
+                  rs <- str <$> askSt importsString <*> askSt importsChar
+                  -- if random is enabled, generate builtin random generation
+                  ra <- ifConf random [randomBuiltins] []
+                  -- if depth is enabled, generate size abstract method
+                  de <- ifConf depth [abstractDepth] []
+                  -- if size is enabled, generate size abstract method
+                  si <- ifConf size [abstractSize] []
+                  -- build the class
+                  return $ Class at (cl at (hs++ss++rs++ra++de++si) (iv++is))
+
+  where cl at e i = rClass (public <+> abstract) (text at) Nothing i (body e)
+        body      = vcat . (always ++)
+        always    = [abstractSymbolName,toStringBody,abstractToStringBuilder]
+        hask      = [toHaskellBody,abstractToHaskellBuilder]
+
+        str True  _     = [renderStringMethod,renderCharMethod] 
+        str False True  = [renderCharMethod]
+        str False False = []
diff --git a/Gom/CodeGen/Common.hs b/Gom/CodeGen/Common.hs
new file mode 100644
--- /dev/null
+++ b/Gom/CodeGen/Common.hs
@@ -0,0 +1,27 @@
+------------------------------------------------------------------
+-- |
+-- Module      : Gom.CodeGen.Common
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--
+-- Exports common functions used by code generation modules.
+--------------------------------------------------------------------
+
+module Gom.CodeGen.Common (
+  module Gom.CodeGen.Common.GenMonad,
+  module Gom.CodeGen.Common.Helpers,
+  module Gom.CodeGen.Common.Constants,
+  module Gom.CodeGen.Common.Builtins
+) where
+
+import  Gom.CodeGen.Common.GenMonad
+import  Gom.CodeGen.Common.Helpers
+import  Gom.CodeGen.Common.Constants
+import  Gom.CodeGen.Common.Builtins
+
diff --git a/Gom/CodeGen/Common/Builtins.hs b/Gom/CodeGen/Common/Builtins.hs
new file mode 100644
--- /dev/null
+++ b/Gom/CodeGen/Common/Builtins.hs
@@ -0,0 +1,91 @@
+------------------------------------------------------------------
+-- |
+-- Module      : Gom.CodeGen.Common.Builtins
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--
+-- Builtins handling.
+--------------------------------------------------------------------
+
+module Gom.CodeGen.Common.Builtins (
+  isBuiltin,
+  isBoolean,
+  isInt,
+  isChar,
+  isDouble,
+  isFloat,
+  isLong,
+  isString,
+  qualifiedBuiltin,
+  builtinImport,
+  renderBuiltin
+) where
+
+import Data.Maybe(fromMaybe)
+import Text.PrettyPrint.Leijen
+
+import Gom.CodeGen.Common.Helpers
+import Gom.Sig
+
+-- | List of supported java builtins
+builtins :: [String]
+builtins = ["boolean","int","char","double","float","long","String"]
+
+-- | Check if some sort is a builtin.
+isBuiltin :: SortId -> Bool
+isBuiltin = (`elem` builtins) . idStr
+ 
+-- | Check if some sort is a java bool
+isBoolean :: SortId -> Bool
+-- | Check if some sort is a java int
+isInt :: SortId -> Bool
+-- | Check if some sort is a java char
+isChar :: SortId -> Bool
+-- | Check if some sort is a java double
+isDouble :: SortId -> Bool
+-- | Check if some sort is a java float
+isFloat :: SortId -> Bool
+-- | Check if some sort is a java long
+isLong :: SortId -> Bool
+-- | Check if some sort is a java String
+isString :: SortId -> Bool
+
+[isBoolean,isInt,isChar,isDouble,isFloat,isLong,isString] = 
+  map (\b x -> idStr x == b) builtins
+
+qbuiltins :: [(String,Doc)]
+qbuiltins = zip builtins (map text qts)
+  where qts = ["java.lang.Boolean",
+               "java.lang.Integer",
+               "java.lang.Character",
+               "java.lang.Double",
+               "java.lang.Float",
+               "java.lang.Long"] 
+
+-- | Returns the qualified java type for builtin boxing.
+qualifiedBuiltin :: SortId -> Doc
+qualifiedBuiltin s = fromMaybe (pretty s) (idStr s `lookup` qbuiltins)
+
+ibuiltins :: [(String,Doc)]
+ibuiltins = zip builtins (map text toms)
+  where toms = ["boolean.tom","int.tom","char.tom",
+                "double.tom","float.tom","long.tom","string.tom"] 
+
+-- | Returns the right .tom filename associated to a builtin.
+builtinImport :: SortId -> Doc
+builtinImport s = fromMaybe (pretty s) (idStr s `lookup` ibuiltins)
+
+-- | @renderBuiltin s f b@ generates what is necessary to put
+-- the representation of @f@ (field of sort @s@) in the buffer @b@.
+renderBuiltin :: SortId -> Doc -> Doc -> Doc
+renderBuiltin s f b 
+  | isString s = text "renderString" <> parens (b <> comma <> f)
+  | isChar   s = text "renderChar"   <> parens (b <> comma <> f)
+  | otherwise  = rMethodCall b (text "append") [f]
+
diff --git a/Gom/CodeGen/Common/Constants.hs b/Gom/CodeGen/Common/Constants.hs
new file mode 100644
--- /dev/null
+++ b/Gom/CodeGen/Common/Constants.hs
@@ -0,0 +1,937 @@
+------------------------------------------------------------------
+-- |
+-- Module      : Gom.CodeGen.Common.Constants
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--
+-- Big 'Doc' constants.
+--------------------------------------------------------------------
+
+module Gom.CodeGen.Common.Constants (
+  includeSl,
+  toStringBody,
+  abstractToStringBuilder,
+  toHaskellBody,
+  abstractToHaskellBuilder,
+  abstractSymbolName,
+  abstractSharing,
+  randomBuiltins,
+  abstractSize,
+  abstractDepth,
+  absParser,
+  absLexer,
+  hashCodeMethod,
+  renderStringMethod,
+  renderCharMethod,
+) where
+
+import Text.PrettyPrint.Leijen
+
+-- | @include { sl.tom }@ text constant 
+includeSl :: Doc
+includeSl = text "%include { sl.tom }"
+
+-- | Full text of the toString method of @moduleAbstractType@.
+toStringBody :: Doc
+toStringBody = vcat $ map text
+  ["public String toString() {",
+   "  java.lang.StringBuilder buf = new java.lang.StringBuilder();",
+   "  toStringBuilder(buf);",
+   "  return buf.toString();",
+   "}"]
+
+-- | Full prototype of the abstract method of @moduleAbstractType@.
+abstractToStringBuilder :: Doc
+abstractToStringBuilder = 
+  text "public abstract void toStringBuilder(java.lang.StringBuilder buf);"
+
+-- | Full text of the toHaskell method of @moduleAbstractType@.
+toHaskellBody :: Doc
+toHaskellBody = vcat $ map text
+  ["public String toHaskell() {",
+  "  java.lang.StringBuilder buf = new java.lang.StringBuilder();",
+  "  toHaskellBuilder(buf);",
+  "  return buf.toString();",
+  "}"]
+
+-- | Full prototype of the abstract method of @moduleAbstractType@.
+abstractToHaskellBuilder :: Doc
+abstractToHaskellBuilder = 
+  text "public abstract void toHaskellBuilder(java.lang.StringBuilder buf);"
+
+-- | Full prototype of the abstract methode of @moduleAbstractType@.
+abstractSymbolName :: Doc
+abstractSymbolName =
+  text "public abstract String symbolName();"
+
+-- | Code of the 
+-- @pubic void renderChar(StringBuilder buf, char c)@
+-- method
+renderCharMethod :: Doc
+renderCharMethod = vcat $ map text
+  ["public void renderChar(java.lang.StringBuilder buf, char c) {",
+   "  buf.append('\\'');",
+   "  switch (c) {",
+   "    case '\\n':",
+   "      buf.append('\\\\');",
+   "      buf.append('n');",
+   "      break;",
+   "    case '\\t':",
+   "      buf.append('\\\\');",
+   "      buf.append('t');",
+   "      break;",
+   "    case '\\b':",
+   "      buf.append('\\\\');",
+   "      buf.append('b');",
+   "      break;",
+   "    case '\\r':",
+   "      buf.append('\\\\');",
+   "      buf.append('r');",
+   "      break;",
+   "    case '\\f':",
+   "      buf.append('\\\\');",
+   "      buf.append('f');",
+   "      break;",
+   "    case '\\\\':",
+   "      buf.append('\\\\');",
+   "      buf.append('\\\\');",
+   "      break;",
+   "    case '\\'':",
+   "      buf.append('\\\\');",
+   "      buf.append('\\'');",
+   "      break;",
+   "      case '\\\"':",
+   "        buf.append('\\\\');",
+   "      buf.append('\\\"');",
+   "      break;",
+   "    case '!':",
+   "    case '@':",
+   "    case '#':",
+   "    case '$':",
+   "    case '%':",
+   "    case '^':",
+   "    case '&':",
+   "    case '*':",
+   "    case '(':",
+   "    case ')':",
+   "    case '-':",
+   "    case '_':",
+   "    case '+':",
+   "    case '=':",
+   "    case '|':",
+   "    case '~':",
+   "    case '{':",
+   "    case '}':",
+   "    case '[':",
+   "    case ']':",
+   "    case ';':",
+   "    case ':':",
+   "    case '<':",
+   "    case '>':",
+   "    case ',':",
+   "    case '.':",
+   "    case '?':",
+   "    case ' ':",
+   "    case '/':",
+   "      buf.append(c);",
+   "      break;",
+   "",
+   "    default:",
+   "      if (java.lang.Character.isLetterOrDigit(c)) {",
+   "        buf.append(c);",
+   "      } else {",
+   "        buf.append('\\\\');",
+   "        buf.append((char) ('0' + c / 64));",
+   "        c = (char) (c % 64);",
+   "        buf.append((char) ('0' + c / 8));",
+   "        c = (char) (c % 8);",
+   "        buf.append((char) ('0' + c));",
+   "      }",
+   "  }",
+   "  buf.append('\\'');",
+   "}"]
+
+-- | Code of the 
+-- @pubic void renderChar(StringBuilder buf, String s)@
+-- method
+renderStringMethod :: Doc
+renderStringMethod = vcat $ map text
+  ["public void renderString(java.lang.StringBuilder buf, String x) {",
+   "  buf.append('\"');",
+   "  for (int i = 0; i < x.length(); i++) {",
+   "    char c = x.charAt(i);",
+   "    switch (c) {",
+   "      case '\\n':",
+   "        buf.append('\\\\');",
+   "        buf.append('n');",
+   "        break;",
+   "      case '\\t':",
+   "        buf.append('\\\\');",
+   "        buf.append('t');",
+   "        break;",
+   "      case '\\b':",
+   "        buf.append('\\\\');",
+   "        buf.append('b');",
+   "        break;",
+   "      case '\\r':",
+   "        buf.append('\\\\');",
+   "        buf.append('r');",
+   "        break;",
+   "      case '\\f':",
+   "        buf.append('\\\\');",
+   "        buf.append('f');",
+   "        break;",
+   "      case '\\\\':",
+   "        buf.append('\\\\');",
+   "        buf.append('\\\\');",
+   "        break;",
+   "      case '\\'':",
+   "        buf.append('\\\\');",
+   "        buf.append('\\'');",
+   "        break;",
+   "      case '\\\"':",
+   "        buf.append('\\\\');",
+   "        buf.append('\\\"');",
+   "        break;",
+   "      case '!':",
+   "      case '@':",
+   "      case '#':",
+   "      case '$':",
+   "      case '%':",
+   "      case '^':",
+   "      case '&':",
+   "      case '*':",
+   "      case '(':",
+   "      case ')':",
+   "      case '-':",
+   "      case '_':",
+   "      case '+':",
+   "      case '=':",
+   "      case '|':",
+   "      case '~':",
+   "      case '{':",
+   "      case '}':",
+   "      case '[':",
+   "      case ']':",
+   "      case ';':",
+   "      case ':':",
+   "      case '<':",
+   "      case '>':",
+   "      case ',':",
+   "      case '.':",
+   "      case '?':",
+   "      case ' ':",
+   "      case '/':",
+   "        buf.append(c);",
+   "        break;",
+   "  ",
+   "      default:",
+   "        if (java.lang.Character.isLetterOrDigit(c)) {",
+   "          buf.append(c);",
+   "        } else {",
+   "          buf.append('\\\\');",
+   "          buf.append((char) ('0' + c / 64));",
+   "          c = (char) (c % 64);",
+   "          buf.append((char) ('0' + c / 8));",
+   "          c = (char) (c % 8);",
+   "          buf.append((char) ('0' + c));",
+   "        }",
+   "    }",
+   "  }",
+   "  buf.append('\"');",
+   "}"]
+
+-- | declaration of sharing related methods and fields for the
+-- modNameAbstractType class
+abstractSharing :: Doc
+abstractSharing = vcat $ map text
+  ["protected static final shared.SharedObjectFactory factory =",
+   "   shared.SingletonSharedObjectFactory.getInstance();",
+   "private int uniqueID;",
+   "public int getUniqueIdentifier() {",
+   "  return uniqueID;",
+   "}",
+   "public void setUniqueIdentifier(int uniqueID) {",
+   "  this.uniqueID = uniqueID;",
+   "}"]
+
+-- | declaration of random related methods for the
+-- modNameAbstractType class
+randomBuiltins :: Doc
+randomBuiltins = vcat $ map text
+  ["public final static long randomlong(java.util.Random rand) {",
+   "  return rand.nextLong();",
+   "}",
+   "public final static boolean randomboolean(java.util.Random rand) {",
+   "  return rand.nextBoolean();",
+   "}",
+   "public final static int randomint(java.util.Random rand) {",
+   "  return rand.nextInt();",
+   "}",
+   "public final static double randomdouble(java.util.Random rand) {",
+   "  return rand.nextDouble();",
+   "}",
+   "public final static float randomfloat(java.util.Random rand) {",
+   "  return rand.nextFloat();",
+   "}",
+   "public static char randomchar(java.util.Random rand) {",
+   "  return (char) rand.nextInt(256);",
+   "}",
+   "public static String randomString(java.util.Random rand) {",
+   "  int n = rand.nextInt(10);",
+   "  char buf[] = new char[n];",
+   "  for (int i=0; i<n; i++) {",
+   "    buf[i] = (char) rand.nextInt(256);",
+   "  }",
+   "  return new String(buf);",
+   "}"]
+
+-- | declaration of the @hashCode@ method which returns the private 
+-- @hashCode@ member of a constructor
+hashCodeMethod :: Doc
+hashCodeMethod = vcat $ map text 
+  ["public final int hashCode() {",
+   "  return hashCode;",
+   "}"]
+
+-- | declaration of the @depth@ abstract method
+abstractDepth :: Doc
+abstractDepth = text "public abstract int depth();"
+
+-- | declaration of the @size@ abstract method
+abstractSize :: Doc
+abstractSize = text "public abstract int size();"
+
+-- | The parser class generated in package @mod@.
+absParser :: Doc
+absParser = vcat $ map text 
+  ["public class Parser {",
+   "  private Lexer lex;",
+   "  private Lexer.Token cur;",
+   "  public Parser(String _s) {",
+   "    this.lex = new Lexer(new java.io.StringReader(_s));",
+   "    next();",
+   "  }",
+   "  public final boolean isRpar() {",
+   "    return cur.type == Lexer.TokenType.RPAR;",
+   "  }",
+   "  public final boolean isComma() {",
+   "    return cur.type == Lexer.TokenType.COMMA;",
+   "  }",
+   "  final void next() {",
+   "    try { cur = lex.yylex(); }",
+   "    catch (java.io.IOException e) {",
+   "     throw new RuntimeException();",
+   "    }",
+   "  }",
+   "  public final boolean parseboolean() {",
+   "    switch (cur.type) {",
+   "      case TRUE:",
+   "        next();",
+   "        return true;",
+   "      case FALSE:",
+   "        next();",
+   "        return false;",
+   "      default:",
+   "       throw new RuntimeException();",
+   "    }",
+   "  }",
+   "  public final String parseString() {",
+   "    if (cur.type == Lexer.TokenType.STRING) {",
+   "      String res = cur.string;",
+   "      next();",
+   "      return res;",
+   "    }",
+   "    else throw new RuntimeException();",
+   "  }",
+   "  public final int parseint() {",
+   "    if (cur.type == Lexer.TokenType.INTEGRAL) {",
+   "      int res = Integer.valueOf(cur.string);",
+   "      next();",
+   "      return res;",
+   "    }",
+   "    else throw new RuntimeException();",
+   "  }",
+   "  public final long parselong() {",
+   "    if (cur.type == Lexer.TokenType.INTEGRAL) {",
+   "      long res = Long.valueOf(cur.string);",
+   "      next();",
+   "      return res;",
+   "    }",
+   "    else throw new RuntimeException();",
+   "  }",
+   "  public final float parsefloat() {",
+   "    if (cur.type == Lexer.TokenType.DECIMAL) {",
+   "      float res = Float.valueOf(cur.string);",
+   "      next();",
+   "      return res;",
+   "    }",
+   "    else throw new RuntimeException();",
+   "  }",
+   "  public final double parsedouble() {",
+   "    if (cur.type == Lexer.TokenType.DECIMAL) {",
+   "      double res = Double.valueOf(cur.string);",
+   "      next();",
+   "      return res;",
+   "    }",
+   "    else throw new RuntimeException();",
+   "  }",
+   "  public final char parsechar() {",
+   "    if (cur.type == Lexer.TokenType.CHAR) {",
+   "      char res = cur.string.charAt(1);",
+   "      next();",
+   "      return res;",
+   "    }",
+   "    else throw new RuntimeException();",
+   "  }",
+   "  public final String parseId() {",
+   "    if (cur.type == Lexer.TokenType.IDENTIFIER) {",
+   "      String res = cur.string;",
+   "      next();",
+   "      return res;",
+   "    }",
+   "    else throw new RuntimeException();",
+   "  }",
+   "  public final void parseLpar() { ",
+   "    if (cur.type == Lexer.TokenType.LPAR) {",
+   "      next();",
+   "      return;",
+   "    }",
+   "    else throw new RuntimeException();",
+   "  }",
+   "  public final void parseRpar() {",
+   "    if (cur.type == Lexer.TokenType.RPAR) {",
+   "      next();",
+   "      return;",
+   "    }",
+   "    else throw new RuntimeException();",
+   "  }",
+   "  public final void parseComma() {",
+   "    if (cur.type == Lexer.TokenType.COMMA) {",
+   "      next();",
+   "      return;",
+   "    }",
+   "    else throw new RuntimeException();",
+   "  }",
+   "}"]
+
+-- | The lexer class generated in package @mod@.
+absLexer :: Doc
+absLexer = vcat $ map text 
+  ["/* generated by JFlex */",
+   "class Lexer {",
+   "  public static final int YYEOF = -1;",
+   "  private static final int ZZ_BUFFERSIZE = 16384;",
+   "  public static final int STRING = 2;",
+   "  public static final int YYINITIAL = 0;",
+   "  private static final int ZZ_LEXSTATE[] = { ",
+   "     0,  0,  1, 1",
+   "  };",
+   "  private static final String ZZ_CMAP_PACKED = ",
+   "    \"\\11\\15\\1\\3\\1\\2\\1\\0\\1\\3\\1\\1\\16\\15\\4\\0\\1\\3\\1\\0\"+",
+   "    \"\\1\\26\\1\\0\\1\\14\\2\\0\\1\\25\\1\\22\\1\\23\\2\\0\\1\\24\\1\\16\"+",
+   "    \"\\1\\20\\1\\0\\4\\30\\4\\31\\2\\17\\7\\0\\4\\14\\1\\21\\25\\14\\1\\0\"+",
+   "    \"\\1\\27\\2\\0\\1\\14\\1\\0\\1\\11\\1\\33\\2\\14\\1\\7\\1\\10\\5\\14\"+",
+   "    \"\\1\\12\\1\\14\\1\\32\\3\\14\\1\\5\\1\\13\\1\\4\\1\\6\\5\\14\\4\\0\"+",
+   "    \"\\41\\15\\2\\0\\4\\14\\4\\0\\1\\14\\2\\0\\1\\15\\7\\0\\1\\14\\4\\0\"+",
+   "    \"\\1\\14\\5\\0\\27\\14\\1\\0\\37\\14\\1\\0\\u013f\\14\\31\\0\\162\\14\\4\\0\"+",
+   "    \"\\14\\14\\16\\0\\5\\14\\11\\0\\1\\14\\21\\0\\130\\15\\5\\0\\23\\15\\12\\0\"+",
+   "    \"\\1\\14\\13\\0\\1\\14\\1\\0\\3\\14\\1\\0\\1\\14\\1\\0\\24\\14\\1\\0\"+",
+   "    \"\\54\\14\\1\\0\\46\\14\\1\\0\\5\\14\\4\\0\\202\\14\\1\\0\\4\\15\\3\\0\"+",
+   "    \"\\105\\14\\1\\0\\46\\14\\2\\0\\2\\14\\6\\0\\20\\14\\41\\0\\46\\14\\2\\0\"+",
+   "    \"\\1\\14\\7\\0\\47\\14\\11\\0\\21\\15\\1\\0\\27\\15\\1\\0\\3\\15\\1\\0\"+",
+   "    \"\\1\\15\\1\\0\\2\\15\\1\\0\\1\\15\\13\\0\\33\\14\\5\\0\\3\\14\\15\\0\"+",
+   "    \"\\4\\15\\14\\0\\6\\15\\13\\0\\32\\14\\5\\0\\13\\14\\16\\15\\7\\0\\12\\15\"+",
+   "    \"\\4\\0\\2\\14\\1\\15\\143\\14\\1\\0\\1\\14\\10\\15\\1\\0\\6\\15\\2\\14\"+",
+   "    \"\\2\\15\\1\\0\\4\\15\\2\\14\\12\\15\\3\\14\\2\\0\\1\\14\\17\\0\\1\\15\"+",
+   "    \"\\1\\14\\1\\15\\36\\14\\33\\15\\2\\0\\3\\14\\60\\0\\46\\14\\13\\15\\1\\14\"+",
+   "    \"\\u014f\\0\\3\\15\\66\\14\\2\\0\\1\\15\\1\\14\\20\\15\\2\\0\\1\\14\\4\\15\"+",
+   "    \"\\3\\0\\12\\14\\2\\15\\2\\0\\12\\15\\21\\0\\3\\15\\1\\0\\10\\14\\2\\0\"+",
+   "    \"\\2\\14\\2\\0\\26\\14\\1\\0\\7\\14\\1\\0\\1\\14\\3\\0\\4\\14\\2\\0\"+",
+   "    \"\\1\\15\\1\\14\\7\\15\\2\\0\\2\\15\\2\\0\\3\\15\\11\\0\\1\\15\\4\\0\"+",
+   "    \"\\2\\14\\1\\0\\3\\14\\2\\15\\2\\0\\12\\15\\4\\14\\15\\0\\3\\15\\1\\0\"+",
+   "    \"\\6\\14\\4\\0\\2\\14\\2\\0\\26\\14\\1\\0\\7\\14\\1\\0\\2\\14\\1\\0\"+",
+   "    \"\\2\\14\\1\\0\\2\\14\\2\\0\\1\\15\\1\\0\\5\\15\\4\\0\\2\\15\\2\\0\"+",
+   "    \"\\3\\15\\13\\0\\4\\14\\1\\0\\1\\14\\7\\0\\14\\15\\3\\14\\14\\0\\3\\15\"+",
+   "    \"\\1\\0\\11\\14\\1\\0\\3\\14\\1\\0\\26\\14\\1\\0\\7\\14\\1\\0\\2\\14\"+",
+   "    \"\\1\\0\\5\\14\\2\\0\\1\\15\\1\\14\\10\\15\\1\\0\\3\\15\\1\\0\\3\\15\"+",
+   "    \"\\2\\0\\1\\14\\17\\0\\2\\14\\2\\15\\2\\0\\12\\15\\1\\0\\1\\14\\17\\0\"+",
+   "    \"\\3\\15\\1\\0\\10\\14\\2\\0\\2\\14\\2\\0\\26\\14\\1\\0\\7\\14\\1\\0\"+",
+   "    \"\\2\\14\\1\\0\\5\\14\\2\\0\\1\\15\\1\\14\\6\\15\\3\\0\\2\\15\\2\\0\"+",
+   "    \"\\3\\15\\10\\0\\2\\15\\4\\0\\2\\14\\1\\0\\3\\14\\4\\0\\12\\15\\1\\0\"+",
+   "    \"\\1\\14\\20\\0\\1\\15\\1\\14\\1\\0\\6\\14\\3\\0\\3\\14\\1\\0\\4\\14\"+",
+   "    \"\\3\\0\\2\\14\\1\\0\\1\\14\\1\\0\\2\\14\\3\\0\\2\\14\\3\\0\\3\\14\"+",
+   "    \"\\3\\0\\10\\14\\1\\0\\3\\14\\4\\0\\5\\15\\3\\0\\3\\15\\1\\0\\4\\15\"+",
+   "    \"\\11\\0\\1\\15\\17\\0\\11\\15\\11\\0\\1\\14\\7\\0\\3\\15\\1\\0\\10\\14\"+",
+   "    \"\\1\\0\\3\\14\\1\\0\\27\\14\\1\\0\\12\\14\\1\\0\\5\\14\\4\\0\\7\\15\"+",
+   "    \"\\1\\0\\3\\15\\1\\0\\4\\15\\7\\0\\2\\15\\11\\0\\2\\14\\4\\0\\12\\15\"+",
+   "    \"\\22\\0\\2\\15\\1\\0\\10\\14\\1\\0\\3\\14\\1\\0\\27\\14\\1\\0\\12\\14\"+",
+   "    \"\\1\\0\\5\\14\\2\\0\\1\\15\\1\\14\\7\\15\\1\\0\\3\\15\\1\\0\\4\\15\"+",
+   "    \"\\7\\0\\2\\15\\7\\0\\1\\14\\1\\0\\2\\14\\4\\0\\12\\15\\22\\0\\2\\15\"+",
+   "    \"\\1\\0\\10\\14\\1\\0\\3\\14\\1\\0\\27\\14\\1\\0\\20\\14\\4\\0\\6\\15\"+",
+   "    \"\\2\\0\\3\\15\\1\\0\\4\\15\\11\\0\\1\\15\\10\\0\\2\\14\\4\\0\\12\\15\"+",
+   "    \"\\22\\0\\2\\15\\1\\0\\22\\14\\3\\0\\30\\14\\1\\0\\11\\14\\1\\0\\1\\14\"+",
+   "    \"\\2\\0\\7\\14\\3\\0\\1\\15\\4\\0\\6\\15\\1\\0\\1\\15\\1\\0\\10\\15\"+",
+   "    \"\\22\\0\\2\\15\\15\\0\\60\\14\\1\\15\\2\\14\\7\\15\\4\\0\\10\\14\\10\\15\"+",
+   "    \"\\1\\0\\12\\15\\47\\0\\2\\14\\1\\0\\1\\14\\2\\0\\2\\14\\1\\0\\1\\14\"+",
+   "    \"\\2\\0\\1\\14\\6\\0\\4\\14\\1\\0\\7\\14\\1\\0\\3\\14\\1\\0\\1\\14\"+",
+   "    \"\\1\\0\\1\\14\\2\\0\\2\\14\\1\\0\\4\\14\\1\\15\\2\\14\\6\\15\\1\\0\"+",
+   "    \"\\2\\15\\1\\14\\2\\0\\5\\14\\1\\0\\1\\14\\1\\0\\6\\15\\2\\0\\12\\15\"+",
+   "    \"\\2\\0\\2\\14\\42\\0\\1\\14\\27\\0\\2\\15\\6\\0\\12\\15\\13\\0\\1\\15\"+",
+   "    \"\\1\\0\\1\\15\\1\\0\\1\\15\\4\\0\\2\\15\\10\\14\\1\\0\\42\\14\\6\\0\"+",
+   "    \"\\24\\15\\1\\0\\2\\15\\4\\14\\4\\0\\10\\15\\1\\0\\44\\15\\11\\0\\1\\15\"+",
+   "    \"\\71\\0\\42\\14\\1\\0\\5\\14\\1\\0\\2\\14\\1\\0\\7\\15\\3\\0\\4\\15\"+",
+   "    \"\\6\\0\\12\\15\\6\\0\\6\\14\\4\\15\\106\\0\\46\\14\\12\\0\\51\\14\\7\\0\"+",
+   "    \"\\132\\14\\5\\0\\104\\14\\5\\0\\122\\14\\6\\0\\7\\14\\1\\0\\77\\14\\1\\0\"+",
+   "    \"\\1\\14\\1\\0\\4\\14\\2\\0\\7\\14\\1\\0\\1\\14\\1\\0\\4\\14\\2\\0\"+",
+   "    \"\\47\\14\\1\\0\\1\\14\\1\\0\\4\\14\\2\\0\\37\\14\\1\\0\\1\\14\\1\\0\"+",
+   "    \"\\4\\14\\2\\0\\7\\14\\1\\0\\1\\14\\1\\0\\4\\14\\2\\0\\7\\14\\1\\0\"+",
+   "    \"\\7\\14\\1\\0\\27\\14\\1\\0\\37\\14\\1\\0\\1\\14\\1\\0\\4\\14\\2\\0\"+",
+   "    \"\\7\\14\\1\\0\\47\\14\\1\\0\\23\\14\\16\\0\\11\\15\\56\\0\\125\\14\\14\\0\"+",
+   "    \"\\u026c\\14\\2\\0\\10\\14\\12\\0\\32\\14\\5\\0\\113\\14\\3\\0\\3\\14\\17\\0\"+",
+   "    \"\\15\\14\\1\\0\\4\\14\\3\\15\\13\\0\\22\\14\\3\\15\\13\\0\\22\\14\\2\\15\"+",
+   "    \"\\14\\0\\15\\14\\1\\0\\3\\14\\1\\0\\2\\15\\14\\0\\64\\14\\40\\15\\3\\0\"+",
+   "    \"\\1\\14\\3\\0\\2\\14\\1\\15\\2\\0\\12\\15\\41\\0\\3\\15\\2\\0\\12\\15\"+",
+   "    \"\\6\\0\\130\\14\\10\\0\\51\\14\\1\\15\\126\\0\\35\\14\\3\\0\\14\\15\\4\\0\"+",
+   "    \"\\14\\15\\12\\0\\12\\15\\36\\14\\2\\0\\5\\14\\u038b\\0\\154\\14\\224\\0\\234\\14\"+",
+   "    \"\\4\\0\\132\\14\\6\\0\\26\\14\\2\\0\\6\\14\\2\\0\\46\\14\\2\\0\\6\\14\"+",
+   "    \"\\2\\0\\10\\14\\1\\0\\1\\14\\1\\0\\1\\14\\1\\0\\1\\14\\1\\0\\37\\14\"+",
+   "    \"\\2\\0\\65\\14\\1\\0\\7\\14\\1\\0\\1\\14\\3\\0\\3\\14\\1\\0\\7\\14\"+",
+   "    \"\\3\\0\\4\\14\\2\\0\\6\\14\\4\\0\\15\\14\\5\\0\\3\\14\\1\\0\\7\\14\"+",
+   "    \"\\17\\0\\4\\15\\32\\0\\5\\15\\20\\0\\2\\14\\23\\0\\1\\14\\13\\0\\4\\15\"+",
+   "    \"\\6\\0\\6\\15\\1\\0\\1\\14\\15\\0\\1\\14\\40\\0\\22\\14\\36\\0\\15\\15\"+",
+   "    \"\\4\\0\\1\\15\\3\\0\\6\\15\\27\\0\\1\\14\\4\\0\\1\\14\\2\\0\\12\\14\"+",
+   "    \"\\1\\0\\1\\14\\3\\0\\5\\14\\6\\0\\1\\14\\1\\0\\1\\14\\1\\0\\1\\14\"+",
+   "    \"\\1\\0\\4\\14\\1\\0\\3\\14\\1\\0\\7\\14\\3\\0\\3\\14\\5\\0\\5\\14\"+",
+   "    \"\\26\\0\\44\\14\\u0e81\\0\\3\\14\\31\\0\\11\\14\\6\\15\\1\\0\\5\\14\\2\\0\"+",
+   "    \"\\5\\14\\4\\0\\126\\14\\2\\0\\2\\15\\2\\0\\3\\14\\1\\0\\137\\14\\5\\0\"+",
+   "    \"\\50\\14\\4\\0\\136\\14\\21\\0\\30\\14\\70\\0\\20\\14\\u0200\\0\\u19b6\\14\\112\\0\"+",
+   "    \"\\u51a6\\14\\132\\0\\u048d\\14\\u0773\\0\\u2ba4\\14\\u215c\\0\\u012e\\14\\2\\0\\73\\14\\225\\0\"+",
+   "    \"\\7\\14\\14\\0\\5\\14\\5\\0\\1\\14\\1\\15\\12\\14\\1\\0\\15\\14\\1\\0\"+",
+   "    \"\\5\\14\\1\\0\\1\\14\\1\\0\\2\\14\\1\\0\\2\\14\\1\\0\\154\\14\\41\\0\"+",
+   "    \"\\u016b\\14\\22\\0\\100\\14\\2\\0\\66\\14\\50\\0\\15\\14\\3\\0\\20\\15\\20\\0\"+",
+   "    \"\\4\\15\\17\\0\\2\\14\\30\\0\\3\\14\\31\\0\\1\\14\\6\\0\\5\\14\\1\\0\"+",
+   "    \"\\207\\14\\2\\0\\1\\15\\4\\0\\1\\14\\13\\0\\12\\15\\7\\0\\32\\14\\4\\0\"+",
+   "    \"\\1\\14\\1\\0\\32\\14\\12\\0\\132\\14\\3\\0\\6\\14\\2\\0\\6\\14\\2\\0\"+",
+   "    \"\\6\\14\\2\\0\\3\\14\\3\\0\\2\\14\\3\\0\\2\\14\\22\\0\\3\\15\\4\\0\";",
+   "  private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED);",
+   "  private static final int [] ZZ_ACTION = zzUnpackAction();",
+   "  private static final String ZZ_ACTION_PACKED_0 =",
+   "    \"\\2\\0\\1\\1\\2\\2\\3\\3\\1\\1\\1\\4\\1\\5\\1\\6\"+",
+   "    \"\\1\\7\\1\\1\\1\\10\\1\\11\\1\\12\\1\\1\\2\\3\\2\\0\"+",
+   "    \"\\1\\13\\1\\14\\1\\15\\1\\16\\1\\17\\1\\20\\2\\21\\1\\22\"+",
+   "    \"\\1\\23\\2\\3\\1\\24\\1\\25\\1\\26\\1\\27\\1\\3\\1\\0\"+",
+   "    \"\\1\\30\\1\\31\\1\\0\\1\\24\";",
+   "  private static int [] zzUnpackAction() {",
+   "    int [] result = new int[44];",
+   "    int offset = 0;",
+   "    offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);",
+   "    return result;",
+   "  }",
+   "  private static int zzUnpackAction(String packed, int offset, int [] result) {",
+   "    int i = 0;       ",
+   "    int j = offset;  ",
+   "    int l = packed.length();",
+   "    while (i < l) {",
+   "      int count = packed.charAt(i++);",
+   "      int value = packed.charAt(i++);",
+   "      do result[j++] = value; while (--count > 0);",
+   "    }",
+   "    return j;",
+   "  }",
+   "  private static final int [] ZZ_ROWMAP = zzUnpackRowMap();",
+   "  private static final String ZZ_ROWMAP_PACKED_0 =",
+   "    \"\\0\\0\\0\\34\\0\\70\\0\\124\\0\\70\\0\\160\\0\\214\\0\\250\"+",
+   "    \"\\0\\304\\0\\340\\0\\70\\0\\70\\0\\70\\0\\374\\0\\70\\0\\u0118\"+",
+   "    \"\\0\\70\\0\\u0134\\0\\u0150\\0\\u016c\\0\\u0188\\0\\u01a4\\0\\70\\0\\70\"+",
+   "    \"\\0\\70\\0\\70\\0\\70\\0\\70\\0\\u01c0\\0\\70\\0\\70\\0\\70\"+",
+   "    \"\\0\\u01dc\\0\\u01f8\\0\\u0214\\0\\70\\0\\u0230\\0\\214\\0\\u024c\\0\\u0268\"+",
+   "    \"\\0\\70\\0\\214\\0\\u0284\\0\\u0284\";",
+   "  private static int [] zzUnpackRowMap() {",
+   "    int [] result = new int[44];",
+   "    int offset = 0;",
+   "    offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);",
+   "    return result;",
+   "  }",
+   "  private static int zzUnpackRowMap(String packed, int offset, int [] result) {",
+   "    int i = 0;  ",
+   "    int j = offset;  ",
+   "    int l = packed.length();",
+   "    while (i < l) {",
+   "      int high = packed.charAt(i++) << 16;",
+   "      result[j++] = high | packed.charAt(i++);",
+   "    }",
+   "    return j;",
+   "  }",
+   "  private static final int [] ZZ_TRANS = zzUnpackTrans();",
+   "  private static final String ZZ_TRANS_PACKED_0 =",
+   "    \"\\1\\3\\1\\4\\2\\5\\1\\6\\3\\7\\1\\10\\4\\7\\1\\3\"+",
+   "    \"\\1\\11\\1\\12\\1\\3\\1\\7\\1\\13\\1\\14\\1\\15\\1\\16\"+",
+   "    \"\\1\\17\\1\\3\\2\\12\\2\\7\\1\\20\\1\\3\\1\\0\\23\\20\"+",
+   "    \"\\1\\21\\1\\22\\4\\20\\36\\0\\1\\5\\35\\0\\1\\7\\1\\23\"+",
+   "    \"\\10\\7\\1\\0\\1\\7\\1\\0\\1\\7\\6\\0\\4\\7\\4\\0\"+",
+   "    \"\\12\\7\\1\\0\\1\\7\\1\\0\\1\\7\\6\\0\\4\\7\\4\\0\"+",
+   "    \"\\5\\7\\1\\24\\4\\7\\1\\0\\1\\7\\1\\0\\1\\7\\6\\0\"+",
+   "    \"\\4\\7\\17\\0\\1\\12\\10\\0\\2\\12\\21\\0\\1\\12\\1\\25\"+",
+   "    \"\\7\\0\\2\\12\\6\\0\\12\\26\\1\\0\\1\\26\\1\\0\\1\\26\"+",
+   "    \"\\6\\0\\4\\26\\1\\20\\2\\0\\23\\20\\2\\0\\4\\20\\4\\0\"+",
+   "    \"\\1\\27\\1\\30\\2\\0\\1\\31\\14\\0\\1\\32\\1\\33\\1\\34\"+",
+   "    \"\\1\\35\\1\\36\\1\\37\\1\\40\\4\\0\\2\\7\\1\\41\\7\\7\"+",
+   "    \"\\1\\0\\1\\7\\1\\0\\1\\7\\6\\0\\4\\7\\4\\0\\6\\7\"+",
+   "    \"\\1\\42\\3\\7\\1\\0\\1\\7\\1\\0\\1\\7\\6\\0\\4\\7\"+",
+   "    \"\\17\\0\\1\\43\\10\\0\\2\\43\\27\\0\\1\\44\\36\\0\\2\\45\"+",
+   "    \"\\6\\0\\3\\7\\1\\46\\6\\7\\1\\0\\1\\7\\1\\0\\1\\7\"+",
+   "    \"\\6\\0\\4\\7\\4\\0\\7\\7\\1\\47\\2\\7\\1\\0\\1\\7\"+",
+   "    \"\\1\\0\\1\\7\\6\\0\\4\\7\\17\\0\\1\\43\\1\\0\\1\\50\"+",
+   "    \"\\6\\0\\2\\43\\32\\0\\2\\51\\6\\0\\3\\7\\1\\52\\6\\7\"+",
+   "    \"\\1\\0\\1\\7\\1\\0\\1\\7\\6\\0\\4\\7\\16\\0\\1\\53\"+",
+   "    \"\\1\\54\\10\\0\\2\\54\\21\\0\\1\\54\\10\\0\\2\\54\\2\\0\";",
+   "  private static int [] zzUnpackTrans() {",
+   "    int [] result = new int[672];",
+   "    int offset = 0;",
+   "    offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);",
+   "    return result;",
+   "  }",
+   "  private static int zzUnpackTrans(String packed, int offset, int [] result) {",
+   "    int i = 0;       ",
+   "    int j = offset;  ",
+   "    int l = packed.length();",
+   "    while (i < l) {",
+   "      int count = packed.charAt(i++);",
+   "      int value = packed.charAt(i++);",
+   "      value--;",
+   "      do result[j++] = value; while (--count > 0);",
+   "    }",
+   "    return j;",
+   "  }",
+   "  private static final int ZZ_UNKNOWN_ERROR = 0;",
+   "  private static final int ZZ_NO_MATCH = 1;",
+   "  private static final int ZZ_PUSHBACK_2BIG = 2;",
+   "  private static final String ZZ_ERROR_MSG[] = {",
+   "    \"Unkown internal scanner error\",",
+   "    \"Error: could not match input\",",
+   "    \"Error: pushback value was too large\"",
+   "  };",
+   "  private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();",
+   "  private static final String ZZ_ATTRIBUTE_PACKED_0 =",
+   "    \"\\2\\0\\1\\11\\1\\1\\1\\11\\5\\1\\3\\11\\1\\1\\1\\11\"+",
+   "    \"\\1\\1\\1\\11\\3\\1\\2\\0\\6\\11\\1\\1\\3\\11\\3\\1\"+",
+   "    \"\\1\\11\\3\\1\\1\\0\\1\\11\\1\\1\\1\\0\\1\\1\";",
+   "  private static int [] zzUnpackAttribute() {",
+   "    int [] result = new int[44];",
+   "    int offset = 0;",
+   "    offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);",
+   "    return result;",
+   "  }",
+   "  private static int zzUnpackAttribute(String packed, int offset, int [] result) {",
+   "    int i = 0;       ",
+   "    int j = offset;  ",
+   "    int l = packed.length();",
+   "    while (i < l) {",
+   "      int count = packed.charAt(i++);",
+   "      int value = packed.charAt(i++);",
+   "      do result[j++] = value; while (--count > 0);",
+   "    }",
+   "    return j;",
+   "  }",
+   "  private java.io.Reader zzReader;",
+   "  private int zzState;",
+   "  private int zzLexicalState = YYINITIAL;",
+   "  private char zzBuffer[] = new char[ZZ_BUFFERSIZE];",
+   "  private int zzMarkedPos;",
+   "  private int zzCurrentPos;",
+   "  private int zzStartRead;",
+   "  private int zzEndRead;",
+   "  private int yyline;",
+   "  private int yychar;",
+   "  private int yycolumn;",
+   "  private boolean zzAtBOL = true;",
+   "  private boolean zzAtEOF;",
+   "  StringBuffer string = new StringBuffer();",
+   "  enum TokenType { IDENTIFIER, INTEGRAL, STRING, LPAR, RPAR, COMMA, CHAR, DECIMAL, TRUE, FALSE } ;",
+   "  public class Token { ",
+   "    public Token(TokenType t, String s) { type = t; string = s; }",
+   "    TokenType type; ",
+   "    String string; ",
+   "  } ",
+   "  Lexer(java.io.Reader in) {",
+   "    this.zzReader = in;",
+   "  }",
+   "  Lexer(java.io.InputStream in) {",
+   "    this(new java.io.InputStreamReader(in));",
+   "  }",
+   "  private static char [] zzUnpackCMap(String packed) {",
+   "    char [] map = new char[0x10000];",
+   "    int i = 0;  ",
+   "    int j = 0;  ",
+   "    while (i < 1720) {",
+   "      int  count = packed.charAt(i++);",
+   "      char value = packed.charAt(i++);",
+   "      do map[j++] = value; while (--count > 0);",
+   "    }",
+   "    return map;",
+   "  }",
+   "  private boolean zzRefill() throws java.io.IOException {",
+   "    if (zzStartRead > 0) {",
+   "      System.arraycopy(zzBuffer, zzStartRead,",
+   "                       zzBuffer, 0,",
+   "                       zzEndRead-zzStartRead);",
+   "      zzEndRead-= zzStartRead;",
+   "      zzCurrentPos-= zzStartRead;",
+   "      zzMarkedPos-= zzStartRead;",
+   "      zzStartRead = 0;",
+   "    }",
+   "    if (zzCurrentPos >= zzBuffer.length) {",
+   "      char newBuffer[] = new char[zzCurrentPos*2];",
+   "      System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length);",
+   "      zzBuffer = newBuffer;",
+   "    }",
+   "    int numRead = zzReader.read(zzBuffer, zzEndRead,",
+   "                                            zzBuffer.length-zzEndRead);",
+   "    if (numRead > 0) {",
+   "      zzEndRead+= numRead;",
+   "      return false;",
+   "    }",
+   "    // unlikely but not impossible: read 0 characters, but not at end of stream    ",
+   "    if (numRead == 0) {",
+   "      int c = zzReader.read();",
+   "      if (c == -1) {",
+   "        return true;",
+   "      } else {",
+   "        zzBuffer[zzEndRead++] = (char) c;",
+   "        return false;",
+   "      }     ",
+   "    }",
+   "\t// numRead < 0",
+   "    return true;",
+   "  }",
+   "  public final void yyclose() throws java.io.IOException {",
+   "    zzAtEOF = true;            ",
+   "    zzEndRead = zzStartRead;  ",
+   "    if (zzReader != null)",
+   "      zzReader.close();",
+   "  }",
+   "  public final void yyreset(java.io.Reader reader) {",
+   "    zzReader = reader;",
+   "    zzAtBOL  = true;",
+   "    zzAtEOF  = false;",
+   "    zzEndRead = zzStartRead = 0;",
+   "    zzCurrentPos = zzMarkedPos = 0;",
+   "    yyline = yychar = yycolumn = 0;",
+   "    zzLexicalState = YYINITIAL;",
+   "  }",
+   "  public final int yystate() {",
+   "    return zzLexicalState;",
+   "  }",
+   "  public final void yybegin(int newState) {",
+   "    zzLexicalState = newState;",
+   "  }",
+   "  public final String yytext() {",
+   "    return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead );",
+   "  }",
+   "  public final char yycharat(int pos) {",
+   "    return zzBuffer[zzStartRead+pos];",
+   "  }",
+   "  public final int yylength() {",
+   "    return zzMarkedPos-zzStartRead;",
+   "  }",
+   "  private void zzScanError(int errorCode) {",
+   "    String message;",
+   "    try {",
+   "      message = ZZ_ERROR_MSG[errorCode];",
+   "    }",
+   "    catch (ArrayIndexOutOfBoundsException e) {",
+   "      message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR];",
+   "    }",
+   "    throw new Error(message);",
+   "  } ",
+   "  public void yypushback(int number)  {",
+   "    if ( number > yylength() )",
+   "      zzScanError(ZZ_PUSHBACK_2BIG);",
+   "    zzMarkedPos -= number;",
+   "  }",
+   "  public Token yylex() throws java.io.IOException {",
+   "    int zzInput;",
+   "    int zzAction;",
+   "    // cached fields:",
+   "    int zzCurrentPosL;",
+   "    int zzMarkedPosL;",
+   "    int zzEndReadL = zzEndRead;",
+   "    char [] zzBufferL = zzBuffer;",
+   "    char [] zzCMapL = ZZ_CMAP;",
+   "    int [] zzTransL = ZZ_TRANS;",
+   "    int [] zzRowMapL = ZZ_ROWMAP;",
+   "    int [] zzAttrL = ZZ_ATTRIBUTE;",
+   "    while (true) {",
+   "      zzMarkedPosL = zzMarkedPos;",
+   "      zzAction = -1;",
+   "      zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL;",
+   "      zzState = ZZ_LEXSTATE[zzLexicalState];",
+   "      zzForAction: {",
+   "        while (true) {",
+   "          if (zzCurrentPosL < zzEndReadL)",
+   "            zzInput = zzBufferL[zzCurrentPosL++];",
+   "          else if (zzAtEOF) {",
+   "            zzInput = YYEOF;",
+   "            break zzForAction;",
+   "          }",
+   "          else {",
+   "            // store back cached positions",
+   "            zzCurrentPos  = zzCurrentPosL;",
+   "            zzMarkedPos   = zzMarkedPosL;",
+   "            boolean eof = zzRefill();",
+   "            // get translated positions and possibly new buffer",
+   "            zzCurrentPosL  = zzCurrentPos;",
+   "            zzMarkedPosL   = zzMarkedPos;",
+   "            zzBufferL      = zzBuffer;",
+   "            zzEndReadL     = zzEndRead;",
+   "            if (eof) {",
+   "              zzInput = YYEOF;",
+   "              break zzForAction;",
+   "            }",
+   "            else {",
+   "              zzInput = zzBufferL[zzCurrentPosL++];",
+   "            }",
+   "          }",
+   "          int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ];",
+   "          if (zzNext == -1) break zzForAction;",
+   "          zzState = zzNext;",
+   "          int zzAttributes = zzAttrL[zzState];",
+   "          if ( (zzAttributes & 1) == 1 ) {",
+   "            zzAction = zzState;",
+   "            zzMarkedPosL = zzCurrentPosL;",
+   "            if ( (zzAttributes & 8) == 8 ) break zzForAction;",
+   "          }",
+   "        }",
+   "      }",
+   "      // store back cached position",
+   "      zzMarkedPos = zzMarkedPosL;",
+   "      switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {",
+   "        case 18: ",
+   "          { string.append('\\n');",
+   "          }",
+   "        case 26: break;",
+   "        case 5: ",
+   "          { return new Token(TokenType.LPAR,\"(\");",
+   "          }",
+   "        case 27: break;",
+   "        case 9: ",
+   "          { string.append( yytext() );",
+   "          }",
+   "        case 28: break;",
+   "        case 6: ",
+   "          { return new Token(TokenType.RPAR,\")\");",
+   "          }",
+   "        case 29: break;",
+   "        case 24: ",
+   "          { String text = yytext();",
+   "                                   int x2 = Character.digit(text.charAt(1),4);",
+   "                                   int x1 = Character.digit(text.charAt(2),8);",
+   "                                   int x0 = Character.digit(text.charAt(3),8);",
+   "                                   string.append( (char) (x0 + 8 * x1 + 64 * x2) );",
+   "          }",
+   "        case 30: break;",
+   "        case 17: ",
+   "          { String text = yytext();",
+   "                                   int x0 = Character.digit(text.charAt(3),8);",
+   "                                   string.append( (char) x0 );",
+   "          }",
+   "        case 31: break;",
+   "        case 19: ",
+   "          { string.append('\\b');",
+   "          }",
+   "        case 32: break;",
+   "        case 21: ",
+   "          { return new Token(TokenType.CHAR,yytext());",
+   "          }",
+   "        case 33: break;",
+   "        case 16: ",
+   "          { string.append('\\\\');",
+   "          }",
+   "        case 34: break;",
+   "        case 22: ",
+   "          { String text = yytext();",
+   "                                   int x1 = Character.digit(text.charAt(2),4);",
+   "                                   int x0 = Character.digit(text.charAt(3),8);",
+   "                                   string.append( (char) (x0 + 8 * x1) );",
+   "          }",
+   "        case 35: break;",
+   "        case 3: ",
+   "          { return new Token(TokenType.IDENTIFIER,yytext());",
+   "          }",
+   "        case 36: break;",
+   "        case 7: ",
+   "          { return new Token(TokenType.COMMA,\",\");",
+   "          }",
+   "        case 37: break;",
+   "        case 8: ",
+   "          { string.setLength(0); yybegin(STRING);",
+   "          }",
+   "        case 38: break;",
+   "        case 14: ",
+   "          { string.append('\\'');",
+   "          }",
+   "        case 39: break;",
+   "        case 25: ",
+   "          { return new Token(TokenType.FALSE,\"false\");",
+   "          }",
+   "        case 40: break;",
+   "        case 23: ",
+   "          { return new Token(TokenType.TRUE,\"true\");",
+   "          }",
+   "        case 41: break;",
+   "        case 4: ",
+   "          { return new Token(TokenType.INTEGRAL,yytext());",
+   "          }",
+   "        case 42: break;",
+   "        case 12: ",
+   "          { string.append('\\r');",
+   "          }",
+   "        case 43: break;",
+   "        case 10: ",
+   "          { yybegin(YYINITIAL); ",
+   "                                   return new Token(TokenType.STRING,string.toString());",
+   "          }",
+   "        case 44: break;",
+   "        case 15: ",
+   "          { string.append('\\\"');",
+   "          }",
+   "        case 45: break;",
+   "        case 20: ",
+   "          { return new Token(TokenType.DECIMAL,yytext());",
+   "          }",
+   "        case 46: break;",
+   "        case 13: ",
+   "          { string.append('\\f');",
+   "          }",
+   "        case 47: break;",
+   "        case 1: ",
+   "          { throw new Error(\"Illegal character <\"+ yytext()+\">\");",
+   "          }",
+   "        case 48: break;",
+   "        case 2: ",
+   "          { ",
+   "          }",
+   "        case 49: break;",
+   "        case 11: ",
+   "          { string.append('\\t');",
+   "          }",
+   "        case 50: break;",
+   "        default: ",
+   "          if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {",
+   "            zzAtEOF = true;",
+   "            return null;",
+   "          } ",
+   "          else {",
+   "            zzScanError(ZZ_NO_MATCH);",
+   "          }",
+   "      }",
+   "    }",
+   "  }",
+   "}"]
diff --git a/Gom/CodeGen/Common/GenMonad.hs b/Gom/CodeGen/Common/GenMonad.hs
new file mode 100644
--- /dev/null
+++ b/Gom/CodeGen/Common/GenMonad.hs
@@ -0,0 +1,159 @@
+------------------------------------------------------------------
+-- |
+-- Module      : Gom.CodeGen.Common.GenMonad
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--
+-- Defines the 'Gen' monad, a context containing a read-only symbol table.
+--------------------------------------------------------------------
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+module Gom.CodeGen.Common.GenMonad (
+  -- * Definition
+  Gen(),
+  runGen,
+  -- * Basic access
+  askSt,
+  askConf,
+  ifConf,
+  ifConfM,
+  iterOverFields,
+  iterOverSortFields,
+  -- * High-Level access
+  packagePrefix,
+  qualifiedSort,
+  qualifiedCtor,
+  abstractType,
+  qualifiedAbstractType,
+  qualifiedStratPrefix
+) where
+
+import Gom.Sig
+import Gom.SymbolTable
+import Gom.CodeGen.Common.Builtins
+import Gom.Config
+
+import Text.PrettyPrint.Leijen
+import Control.Monad.Reader
+import Control.Applicative
+import Data.Char(toLower)
+import Data.List(nub, intersperse)
+
+-- | A computation inside a context containing a read-only symbol table.
+newtype Gen a = Gen (Reader (SymbolTable,Config) a)
+  deriving (Functor, Monad, MonadReader (SymbolTable,Config))
+
+instance Applicative Gen where
+  (<*>) = ap
+  pure  = return
+
+-- | Run the Gen monad
+runGen ::  Gen a -> SymbolTable -> Config -> a
+runGen (Gen comp) st c = runReader comp (st,c)
+
+-- | Query symbol table.
+askSt :: (SymbolTable -> a) -> Gen a
+askSt f = asks (f . fst)
+
+-- | Query configuration.
+askConf :: (Config -> a) -> Gen a
+askConf f = asks (f . snd)
+
+-- | @ifConf f e d@ is @return e@ if @f config@ holds, else @return d@ .
+--
+-- Example usage: 
+--
+-- > do hs <- ifConf haskell [rMethod ...] []
+-- >    return rClass ... (vcat $ defaultMethods ++ hs)
+ifConf :: (Config -> Bool) -> a -> a -> Gen a
+ifConf f e d = ifConfM f (return e) (return d) 
+
+-- | @ifConfM f e d@ is @e@ if @f config@ holds, else @d@ .
+--
+-- Example usage: 
+--
+-- > do hs <- ifConfM haskell compSomeMethods (return [])
+-- >    return rClass ... (vcat $ defaultMethods ++ hs)
+ifConfM :: (Config -> Bool) -> Gen a -> Gen a -> Gen a
+ifConfM f e d = do cond <- askConf f
+                   if cond then e else d
+
+-- | Helper fonction that iters over the fields of
+-- a constructor and combines them.
+iterOverFields 
+  :: (FieldId -> SortId -> Gen a) -- ^ the function to iter
+  -> ([a] -> b)                   -- ^ the combinator
+  -> CtorId                       -- ^ the constructor
+  -> Gen b
+iterOverFields f g c = do fis  <- askSt (fieldsOf c)
+                          fis' <- mapM (uncurry f) fis
+                          return $ g fis'
+
+-- | Helper fonction for 'compEmptyGettersOfSort' and 
+-- 'compEmptySettersOfSort'. Iters the first argument on the fields of the
+-- subject sort and combines them with the second one. Duplicate fields are
+-- merged.
+iterOverSortFields 
+  :: (SortId -> FieldId -> SortId -> Gen a) 
+     -- ^ gets codomain, field name and field sort
+  -> ([a] -> b) -- ^ combinator of results
+  -> SortId     -- ^ subject sort
+  -> Gen b
+iterOverSortFields f g s = do cs <- askSt (sCtorsOf s)
+                              fs <- (nub . concat) `fmap` mapM combine cs
+                              ms <- mapM (\(co,(fi,ty)) -> f co fi ty) fs
+                              return $ g ms
+   where combine c = do fis <- askSt (fieldsOf c)
+                        co  <- askSt (codomainOf c)
+                        return $ map ((,) co) fis
+
+
+-- | Returns the package prefix ended by a dot.
+--
+-- As an example, returns @aa.bb.cc.foo@ for the module @Foo@,
+-- provided the user toggled @-p aa.bb.cc@.
+packagePrefix :: Gen Doc
+packagePrefix = do m <- map toLower `fmap` askSt modName
+                   go (pretty m) `fmap` askConf package
+  where go dm Nothing  = dm
+        go dm (Just l) = hcat . intersperse dot $ map text l ++ [dm]
+
+-- | Given a sort @S@, returns @module.types.S@
+qualifiedSort :: SortId -> Gen Doc
+qualifiedSort s 
+  | isBuiltin s = return $ pretty s
+  | otherwise   = do p <- packagePrefix
+                     return $ p <> dot <> text "types" <> dot <> pretty s
+
+-- | Given a constructor @C@ of codomain @S@, returns
+-- @module.types.s.C@
+qualifiedCtor :: CtorId -> Gen Doc
+qualifiedCtor c = 
+  do p <- packagePrefix
+     lows <- lowerId `fmap` askSt (codomainOf c)
+     return $ p <> dot <> text "types" <> dot <> 
+              pretty lows <> dot <> pretty c
+
+-- | Generates @mAbstractType@ for the current module @m@.
+abstractType :: Gen String
+abstractType = do mn <- askSt modName
+                  return $ mn ++ "AbstractType"
+
+-- | Generates @m.mAbstractType@ for the current module @m@.
+qualifiedAbstractType :: Gen Doc
+qualifiedAbstractType = do at <- abstractType
+                           pr <- packagePrefix 
+                           return $ pr <> dot <> text at
+
+-- | Given a sort @S@ in the module @m@, generates @m.strategy.s@
+qualifiedStratPrefix :: SortId -> Gen Doc
+qualifiedStratPrefix s = do
+  m <- packagePrefix
+  return $ m <> dot <> text "strategy" <> dot <> pretty (lowerId s)
diff --git a/Gom/CodeGen/Common/Helpers.hs b/Gom/CodeGen/Common/Helpers.hs
new file mode 100644
--- /dev/null
+++ b/Gom/CodeGen/Common/Helpers.hs
@@ -0,0 +1,310 @@
+-------------------------------------------------------------------
+-- |
+-- Module      : Gom.CodeGen.Common.Helpers
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--
+-- Some utility functions for generating
+-- java and tom pieces of type 'Doc'.
+--------------------------------------------------------------------
+
+module Gom.CodeGen.Common.Helpers (
+  -- * Java pretty-printing
+  -- ** Generic
+  ibraces, sbraces, encloseCommas, 
+  encloseCommasNB, rBody, _u,
+  -- ** Java keywords
+  abstract, public, protected, private, this,
+  jreturn, throw, new, void, instanceof, jif,
+  while, jelse, true, false, final, static,
+  -- ** Java Types
+  jint, jStringBuilder, jboolean,
+  jObject, jVisitable, jShared, jSharedId,
+  jSCombinator, jStrategy,
+  jVisitableArray, jStrategyArray,
+  -- ** Classes
+  rClass,
+  -- ** Classes
+  rInterface,
+  -- ** Methods
+  rMethodDef, rMethodCall, rWrapBuiltin, rConstructorCall,
+  -- ** Control structures
+  rIfThen, rIfThenElse, rWhile, rSwitch,
+  -- * Tom pretty-printing
+  -- ** Mappings
+  rOp, rOpList, rTypeterm,
+  rIsFsym, rMake, rGetSlot,
+  -- ** Other
+  inline
+) where
+
+import Text.PrettyPrint.Leijen
+
+-- | Adds an underscore in front of an id
+_u :: Doc -> Doc
+_u = (text "_" <>)
+
+-- | Encloses a document into { } and indents the body.
+ibraces :: Doc -> Doc
+ibraces d = group $ nest 2 (lbrace <$> d) <$> rbrace
+
+-- | Encloses a document into { }
+sbraces :: Doc -> Doc
+sbraces d = lbrace <+> d <+> rbrace
+
+abstract,public,protected,private :: Doc
+this,jreturn,throw,new,void,final,static :: Doc
+instanceof,jif,while,jelse,true,false :: Doc
+
+abstract   = text "abstract"
+public     = text "public"
+protected  = text "protected"
+private    = text "private"
+this       = text "this"
+jreturn    = text "return"
+throw      = text "throw"
+new        = text "new"
+void       = text "void"
+instanceof = text "instanceof"
+jif        = text "if"
+while      = text "while"
+jelse      = text "else"
+true       = text "true"
+false      = text "false"
+final      = text "final"
+static     = text "static"
+
+jint,jStringBuilder,jboolean,jObject :: Doc
+jSCombinator,jStrategy, jVisitable :: Doc
+jShared,jSharedId,jVisitableArray,jStrategyArray :: Doc
+jint            = text "int"
+jboolean        = text "boolean"
+jStringBuilder  = text "java.lang.StringBuilder"
+jObject         = text "Object"
+jVisitable      = text "tom.library.sl.Visitable"
+jStrategy       = text "tom.library.sl.Strategy"
+jSCombinator    = text "tom.library.sl.AbstractStrategyCombinator"
+jShared         = text "shared.SharedObject"
+jSharedId       = text "shared.SharedObjectWithID"
+jVisitableArray = jVisitable <> text "[]"
+jStrategyArray  = jStrategy <> text "[]"
+
+-- | Renders the list enclosed in parenthesis and
+-- separated by commas. Breaks lines if the list is too long.
+encloseCommas :: [Doc] -> Doc
+encloseCommas [] = text "()"
+encloseCommas l = parens $ nest 2 (softbreak <> fillSep (punctuate comma l))
+
+-- | Renders the list enclosed in parenthesis and
+-- separated by commas. Doesn't break lines (NB is for No Break).
+encloseCommasNB :: [Doc] -> Doc
+encloseCommasNB [] = text "()"
+encloseCommasNB l = parens . hcat . punctuate comma $ l
+
+-- | Renders the list punctuated by semicolons
+rBody :: [Doc] -> Doc
+rBody [] = empty
+rBody l = align $ sep (punctuate semi l) <> semi
+
+-- | Renders @modifier class name { body }@.
+rClass
+ :: Doc   -- ^ modifier (public, private..)
+ -> Doc   -- ^ class name
+ -> Maybe Doc   -- ^ extends
+ -> [Doc] -- ^ implements
+ -> Doc   -- ^ body
+ -> Doc
+rClass md cn ex im body = 
+  md <+> text "class" <+> cn <+> r1 ex <+> r2 im <+> ibraces body
+  where r1 Nothing  = empty
+        r1 (Just d) = text "extends" <+> d
+        r2 [] = empty
+        r2 l  = text "implements" <+> hsep (punctuate comma l)
+
+
+-- | Renders @modifier interface name { body }@.
+rInterface
+ :: Doc   -- ^ modifier (public, private..)
+ -> Doc   -- ^ interface name
+ -> Doc   -- ^ body
+ -> Doc
+
+rInterface md cn body = 
+  md <+> text "interface" <+> cn <+> ibraces body
+
+-- | Renders @modifier type name(arg_1,...,arg_n) { body }@.
+rMethodDef
+ :: Doc   -- ^ modifier
+ -> Doc   -- ^ return type
+ -> Doc   -- ^ method name
+ -> [Doc] -- ^ arguments
+ -> Doc   -- ^ body
+ -> Doc
+rMethodDef md ty mn args body = 
+  md <+> ty <+> mn <> encloseCommas args <+> ibraces body
+
+-- | Renders @object.method(arg_1,...,arg_n)@.
+rMethodCall
+ :: Doc   -- ^ object
+ -> Doc   -- ^ method name
+ -> [Doc] -- ^ arguments
+ -> Doc
+rMethodCall o f args = 
+  o <> dot <> f <> encloseCommas args
+
+-- | Renders @new className(arg_1,...,arg_n)@.
+rConstructorCall
+ :: Doc   -- ^ class name
+ -> [Doc] -- ^ arguments
+ -> Doc
+rConstructorCall c args = 
+  new <+> c <> encloseCommas args
+
+-- | @rWrapBuiltin qt@ renders
+--
+-- > tom.library.sl.VisitableBuiltin<qt>
+rWrapBuiltin
+  :: Doc -- ^ qualified type
+  -> Doc
+rWrapBuiltin qt =
+  text "tom.library.sl.VisitableBuiltin" <> angles qt
+
+-- | Renders @if(cond) { then body }@.
+rIfThen 
+  :: Doc -- ^ condition
+  -> Doc -- ^ then body
+  -> Doc
+rIfThen c b = 
+  group $ jif <+> parens c <+> ibraces b
+
+-- | Renders @if(cond) { then body } else { else body }@.
+rIfThenElse 
+  :: Doc -- ^ condition
+  -> Doc -- ^ then body
+  -> Doc -- ^ else body
+  -> Doc
+rIfThenElse c b1 b2 = 
+  group $ jif <+> parens c <+> ibraces b1 <+> jelse <+> ibraces b2
+
+-- | Renders @while(cond) { body }@
+rWhile
+  :: Doc -- ^ cond
+  -> Doc -- ^ body
+  -> Doc
+rWhile c b = group $ while <+> parens c <+> ibraces b
+
+-- | @rSwitch s [(l1,r1),..,(ln,rn)] d@ renders
+--
+-- > switch (s) {
+-- >   l1: r1
+-- >   ...
+-- >   l2: r2
+-- >   default: d
+-- > }
+rSwitch
+ :: Doc -- ^ subject
+ -> [(Doc,Doc)] -- ^ lhs, rhs
+ -> Maybe Doc -- ^ default case
+ -> Doc
+rSwitch s l d = text "switch" <+> parens s <+> ibraces body
+  where body    = vcat (map f l) <$> 
+                  maybe empty ((text "default:" <+>) . align) d
+        f (x,y) = text "case" <+> x <> colon <+> align y
+
+-- | @rTypeterm s qs shr@ renders
+--
+-- > %typeterm s {
+-- >   implement { qs }
+-- >   is_sort(t) { ($t instanceof qs) }
+-- >   equals(t1,t2) { eq }
+-- > }
+--
+-- where @eq = $t1 == $t2@ if @shr@,
+-- @$t1.equals($t2)@ otherwise.
+rTypeterm
+  :: Doc -- ^ sort
+  -> Doc -- ^ qualified sort
+  -> Bool -- ^ sharing ?
+  -> Doc
+rTypeterm s qs deep =
+  text "%typeterm" <+> s <+> ibraces (vcat
+    [text "implement" <+> sbraces qs,
+     text "is_sort(t) { ($t instanceof" <+> qs <> text ") }",
+     text "equals(t1,t2) { (" <> eq <> text ") }"])
+  where eq = text $ if deep then "$t1 == $t2"
+                            else "$t1.equals($t2)"
+
+-- | Renders @is_fsym(t) { ($t instanceof sort) }@.
+rIsFsym
+  :: Doc -- ^ sort 
+  -> Doc
+rIsFsym s = 
+  text "is_fsym(t) { ($t instanceof" <+> s <> text ") }"
+
+-- | Renders @make(arg1,..,argn) { (m.types.co.make($arg1,..,$argn)) }@.
+rMake
+ :: Doc   -- ^ qualified constructor
+ -> [Doc] -- ^ arguments
+ -> Doc
+rMake qc as =
+  text "make" <> args <+> (sbraces . parens) (qc <> text ".make" <> iargs)
+  where gen   = parens . hcat . punctuate comma
+        args  = gen as
+        iargs = gen (map inline as)
+
+
+-- | Renders @get_slot(slot,t) { $t.getslot() }@.
+rGetSlot
+ :: Doc -- ^ slot
+ -> Doc
+rGetSlot x =
+  text "get_slot(" <> x <> text ",t) { $t.get" <> x <> text "() }"
+
+-- | Renders @%op sort c(field1,..,field2) { body }@.
+rOp :: Doc   -- ^ sort
+    -> Doc   -- ^ constructor
+    -> [(Doc,Doc)] -- ^ fields
+    -> Doc   -- ^ body
+    -> Doc
+rOp s c fs b = 
+   text "%op" <+> s <+> c <> 
+   (parens . hsep . punctuate comma $ map f fs) <+> ibraces b
+  where f (x,t) = x <> colon <> t
+
+-- | @rOpList c co dom cons empty@ renders
+--
+-- > %oplist co VC(dom*) {
+-- >   is_fsym(t) { (($t instanceof cons) || ($t instanceof empty)) }
+-- >   make_empty() { empty.make() }
+-- >   make_insert(e,l) { cons.make($e,$l) }
+-- >   get_head(l) { $l.getHeadc() }
+-- >   get_tail(l) { $l.getTailc() }
+-- >   is_empty(l) { $l.isEmptyc() }
+-- > }
+rOpList 
+  :: Doc -- ^ the constructor
+  -> Doc -- ^ codomain of the constructor
+  -> Doc -- ^ domain of the constructor
+  -> Doc -- ^ qualified Cons
+  -> Doc -- ^ qualified Empty
+  -> Doc
+rOpList c co dom consc emptyc =
+  text "%oplist" <+> co <+> c <> parens (dom <> text "*") <+> 
+   ibraces (vcat
+     [text "is_fsym(t) { (($t instanceof" <+> consc <> 
+        text ") || ($t instanceof" <+> emptyc <> text ")) }",
+      text "make_empty() {" <+> emptyc <> text ".make() }",
+      text "make_insert(e,l) {" <+> consc <> text ".make($e,$l) }",
+      text "get_head(l) { $l.getHead" <> c <> text "() }",
+      text "get_tail(l) { $l.getTail" <> c <> text "() }",
+      text "is_empty(l) { $l.isEmpty" <> c <> text "() }"])
+
+-- | @inline d@ renders @$d@.
+inline :: Doc -> Doc
+inline = (text "$" <>)
diff --git a/Gom/CodeGen/Constructors.hs b/Gom/CodeGen/Constructors.hs
new file mode 100644
--- /dev/null
+++ b/Gom/CodeGen/Constructors.hs
@@ -0,0 +1,894 @@
+------------------------------------------------------------------
+-- |
+-- Module      : Gom.CodeGen.Constructors
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--------------------------------------------------------------------
+
+module Gom.CodeGen.Constructors (
+  compConstructor,
+  compAbstractVariadic
+) where
+
+import Gom.Sig
+import Gom.Config
+import Gom.FileGen
+import Gom.SymbolTable
+import Gom.CodeGen.Common
+
+import Text.PrettyPrint.Leijen
+import Control.Monad.Reader
+import Data.List(intersperse)
+
+-- | Given a variadic constructor @VC@, generates an abstract class @VC.java@.
+compAbstractVariadic :: CtorId -> Gen FileHierarchy
+compAbstractVariadic vc = do cl <- body
+                             return $ Class (show vc) cl
+  where ifP = flip (ifConfM parsers) (return empty)
+        body = do co  <- askSt (codomainOf vc)
+                  qto <- qualifiedSort co
+                  tsb <- compToStringBuilderVariadic vc
+                  pa  <- ifP $ compParseVariadic vc
+                  pat <- ifP $ compParseVariadicTail vc
+                  return $ rClass (public <+> abstract) (pretty vc)
+                                  (Just qto) [] (vcat [tsb,pa,pat])
+ 
+-- | Given a variadic constructor @List(T*)@, generates
+--
+-- >  public void toStringBuilder(java.lang.StringBuilder buf) {
+-- >   buffer.append("List(");
+-- >   if(this instanceof mod.types.codom.ConsList) {
+-- >     mod.types.List cur = this;
+-- >     while(cur instanceof mod.types.codom.ConsList) {
+-- >       mod.types.T elem = cur.getHeadList();
+-- >       cur = cur.getTailList();
+-- >       elem.toStringBuilder(buf);
+-- >       if(cur instanceof mod.types.codom.ConsList) {
+-- >         buf.append(",");
+-- >       }
+-- >     }
+-- >     if(!(cur instanceof mod.types.codom.EmptyList)) {
+-- >       buf.append(",");
+-- >       cur.toStringBuilder(buf);
+-- >     }
+-- >   }
+-- >   buf.append(")");
+-- > }
+compToStringBuilderVariadic :: CtorId -> Gen Doc
+compToStringBuilderVariadic vc = do
+  qcons <- qualifiedCtor cons
+  qnil  <- qualifiedCtor nil
+  co    <- askSt (codomainOf vc)
+  dom   <- askSt (fieldOf vc) 
+  qco   <- pretty `fmap` qualifiedSort co
+  qdom  <- pretty `fmap` qualifiedSort dom
+  let mid = middle qco qcons qnil qdom (isBuiltin dom)
+  return $ rMethodDef public void toSB
+                      [jStringBuilder <+> buf]
+                      (rBody [pre,mid,post])
+  where bapp arg = rMethodCall buf (text "append") [arg]
+        cons = prependCons vc
+        nil  = prependEmpty vc
+        pre  = bapp $ dquotes (pretty vc <> lparen)
+        post = bapp $ dquotes rparen 
+        comm = bapp $ dquotes comma
+        cur  = text "__cur"
+        elm  = text "__elem"
+        getH = text "getHead" <> pretty vc
+        getT = text "getTail" <> pretty vc
+        toSB = text "toStringBuilder"
+        buf  = text "__buf"
+        jneg = (text "!" <>) . parens
+        middle qco qc qn dom btin = 
+          rIfThen (this <+> instanceof <+> qc) $ rBody
+            [qco <+> cur <+> equals <+> this,
+             rWhile (cur <+> instanceof <+> qc) $ rBody
+               [dom <+> elm <+> equals <+> rMethodCall cur getH [],
+                cur <+> equals <+> rMethodCall cur getT [],
+                if btin then bapp elm else rMethodCall elm toSB [buf],
+                rIfThen (cur <+> instanceof <+> qc) (rBody [comm])],
+             rIfThen (jneg $ cur <+> instanceof <+> qn) $ rBody 
+               [comm, rMethodCall cur toSB [buf]]]
+
+-- | Given a sort @s@, @parseRecCall arg s@ generates
+--
+--  * @arg.parses()@ if @s@ is a builtin, 
+--
+--  * @mod.types.s.parse(arg)@ otherwise
+parseRecCall :: Doc -> SortId -> Gen Doc
+parseRecCall arg s = do
+  qs <- qualifiedSort s
+  return $ if isBuiltin s 
+    then rMethodCall arg (text "parse" <> pretty s) []
+    else rMethodCall qs (text "parse") [arg]
+
+-- | Given a constructor @C(x1:T1,...,xn:Tn)@, 
+-- of codomain @Co@, generates
+--
+-- > final static mod.types.Co parseArgs(mod.Parser par) {
+-- >   par.parseLpar();
+-- >   mod.types.T1 x1 = mod.types.T1.parse(par);
+-- >   par.parseComma();
+-- >   ...
+-- >   par.parseComma();
+-- >   mod.types.Tn xn = mod.types.Tn.parse(par);
+-- >   par.parseRpar();
+-- >   return mod.types.Co.C.make(x1,...,xn);
+-- > }
+compParseConstructor :: CtorId -> Gen Doc
+compParseConstructor c = do
+  pr   <- packagePrefix
+  co   <- askSt (codomainOf c)
+  qco  <- qualifiedSort co
+  recs <- iterOverFields call (intersperse pcomm) c
+  post <- postM
+  return $ rMethodDef (final <+> static <+> public)
+                      qco (text "parseArgs")
+                      [pars pr <+> arg] (rBody (pre:recs++post))
+  where pars pr  = pr <> dot <> text "Parser"
+        arg      = text "__par"
+        pcomm    = rMethodCall arg (text "parseComma") []
+        call f s = do 
+          qs  <- qualifiedSort s
+          rec <- parseRecCall arg s
+          return $ qs <+> _u (pretty f) <+> equals <+> rec
+        pre      = rMethodCall arg (text "parseLpar") []
+        postM    = do qc <- qualifiedCtor c
+                      fis <- map (_u . pretty . fst) `fmap` askSt (fieldsOf c)
+                      return [rMethodCall arg (text "parseRpar") [], 
+                              jreturn <+> rMethodCall qc (text "make") fis]
+
+-- | Given a variadic constructor @VC(T*)@, 
+-- of codomain @Co@, generates
+--
+-- > static public mod.types.Co parseArgs(mod.Parser par) {
+-- >   par.parseLpar();
+-- >   if (par.isRpar()) {
+-- >     par.parseRpar();
+-- >     return mod.types.vc.EmptyVC.make();
+-- >   } else {
+-- >     mod.types.T  head =  mod.types.T.parse(par)
+-- >     mod.types.Co tail = mod.types.vc.VC.parseTail(par);
+-- >     par.parseRpar();
+-- >     return mod.types.vc.ConsVC.make(head,tail);
+-- >   }
+-- > }
+compParseVariadic :: CtorId -> Gen Doc
+compParseVariadic vc = do
+  pr    <- packagePrefix
+  co    <- askSt (codomainOf vc)
+  qco   <- qualifiedSort co
+  qvc   <- qualifiedCtor vc
+  qcons <- qualifiedCtor (prependCons vc)
+  qnil  <- qualifiedCtor (prependEmpty vc)
+  phead <- parseHead
+  return $ rMethodDef 
+    (static <+> public) qco (text "parseArgs") [pars pr <+> arg]
+    (vcat [text "__par.parseLpar();",
+           rIfThenElse (text "__par.isRpar()")
+             (rBody [text "__par.parseRpar()", makeNil qnil])
+             (rBody [phead, parseTail qco qvc,
+                     text "__par.parseRpar()", makeCons qcons])])
+  where pars pr      = pr <> dot <> text "Parser"
+        arg          = text "__par"
+        parseHead    = do dom  <- askSt (fieldOf vc)
+                          qdom <- qualifiedSort dom
+                          rec  <- parseRecCall arg dom
+                          return $ qdom <+> text "__head" <+> equals <+> rec
+        retMake q as = jreturn <+> rMethodCall q (text "make") as
+        makeCons qc  = retMake qc [text "__head", text "__tail"]
+        makeNil  qn  = retMake qn []
+        parseTail qco qvc = qco <+> text "__tail" <+> equals <+> 
+                            rMethodCall qvc (text "parseTail") [arg]
+
+-- | Given a variadic constructor @VC(T*)@, 
+-- of codomain @Co@, generates
+--
+-- > static public mod.types.Co parseTail(mod.Parser par) {
+-- >   if (par.isComma()) {
+-- >     par.parseComma();
+-- >     mod.types.T  head = mod.types.T.parse(par)
+-- >     mod.types.Co tail = mod.types.vc.VC.parseTail(par);
+-- >     return mod.types.vc.ConsVC.make(head,tail);
+-- >   } else {
+-- >     return mod.types.vc.EmptyVC.make();
+-- >   }
+-- > }
+compParseVariadicTail :: CtorId -> Gen Doc
+compParseVariadicTail vc = do
+  pr    <- packagePrefix
+  co    <- askSt (codomainOf vc)
+  qco   <- qualifiedSort co
+  qvc   <- qualifiedCtor vc
+  qcons <- qualifiedCtor (prependCons vc)
+  qnil  <- qualifiedCtor (prependEmpty vc)
+  phead <- parseHead
+  return $ rMethodDef 
+    (static <+> public) qco (text "parseTail") [pars pr <+> arg]
+    (rIfThenElse (text "__par.isComma()")
+       (rBody [text "__par.parseComma()", phead,
+               parseTail qco qvc ,makeCons qcons])
+       (makeNil qnil <> semi))
+  where pars pr      = pr <> dot <> text "Parser"
+        arg          = text "__par"
+        parseHead    = do dom  <- askSt (fieldOf vc)
+                          qdom <- qualifiedSort dom
+                          rec  <- parseRecCall arg dom
+                          return $ qdom <+> text "__head" <+> equals <+> rec
+        retMake q as = jreturn <+> rMethodCall q (text "make") as
+        makeCons qc  = retMake qc [text "__head", text "__tail"]
+        makeNil  qn  = retMake qn []
+        parseTail qco qvc = qco <+> text "__tail" <+> equals <+> 
+                            rMethodCall qvc (text "parseTail") [arg]
+
+-- | Given a non-variadic constructor @C@, generates a concrete class @C.java@.
+compConstructor :: CtorId -> Gen FileHierarchy
+compConstructor c = do mem  <- compMembersOfConstructor c
+                       smem <- ifSh $ compSharingMembers c
+                       ctor <- compCtorOfConstructor c
+                       mak  <- compMakeOfConstructor c
+                       get  <- compGettersOfConstructor c
+                       set  <- compSettersOfConstructor c
+                       tos  <- ifNG $ compToStringBuilder c
+                       toh  <- ifConfM haskell (compToHaskellBuilder c) rempty
+                       eqs  <- ifConfM sharing (compEquiv c) (compEquals c)
+                       hac  <- ifConf sharing hashCodeMethod empty
+                       dup  <- ifSh $ compDuplicate c
+                       ini  <- ifSh $ compInit c
+                       inh  <- ifSh $ compInitHash c
+                       haf  <- ifSh $ compHashFun c
+                       gcc  <- ifV  $ compGetChildCount c
+                       gca  <- ifV  $ compGetChildAt c
+                       gcs  <- ifV  $ compGetChildren c
+                       sca  <- ifV  $ compSetChildAt c
+                       scs  <- ifV  $ compSetChildren c
+                       par  <- ifP  $ compParseConstructor c
+                       ran  <- ifR  $ compMakeRandomConstructor c
+                       dep  <- ifD  $ compDepthConstructor c 
+                       siz  <- ifSi $ compSizeConstructor c 
+                       let isc = compIsX c
+                       let syn = compSymbolName c
+                       let body = vcat [mem,smem,ctor,mak,syn,
+                                        get,set,tos,toh,eqs,hac,
+                                        dup,ini,inh,haf,isc,gcc,gca,
+                                        gcs,sca,scs,par,ran,dep,siz]
+                       cls  <- wrap body
+                       return $ Class (show c) cls
+
+  where rempty = return empty
+        ifV  = flip (ifConfM visit  ) rempty
+        ifSh = flip (ifConfM sharing) rempty
+        ifP  = flip (ifConfM parsers) rempty
+        ifR  = flip (ifConfM random ) rempty
+        ifD  = flip (ifConfM depth  ) rempty
+        ifSi = flip (ifConfM size   ) rempty
+        -- ifNG == if not generated
+        ifNG a = askSt (isGenerated c) >>= maybe a (const rempty)
+        wrap b = do
+          gen <- askSt (isGenerated c)                                     
+          let rcls d = rClass public (pretty c) (Just d) [] b            
+          case gen of Nothing -> do co  <- askSt (codomainOf c)
+                                    qco <- qualifiedSort co
+                                    return $ rcls qco
+                      Just bc -> do qbc <- qualifiedCtor bc
+                                    return $ rcls qbc
+
+-- | Given a non-variadic constructor @C(x1:T1,..,xn:Tn)@,
+-- generates @m.types.T1 x1; ...; m.types.Tn xn;@
+compMembersOfConstructor :: CtorId -> Gen Doc
+compMembersOfConstructor c = iterOverFields rdr rBody c
+  where rdr f s = do qs <- qualifiedSort s
+                     return $ private <+> qs <+> _u (pretty f)
+
+-- | Given a non-variadic constructor @C(x1:T1,..,xn:Tn)@,
+-- generates:
+--
+-- > private int hashCode;
+-- > private static C proto = new C();
+-- > private static int nameHash = 
+-- >   shared.HashFunctions.stringHashFunction(mod.types.s.c,n);
+compSharingMembers :: CtorId -> Gen Doc
+compSharingMembers c = do
+  qc  <- qualifiedCtor c
+  len <- length `fmap` askSt (fieldsOf c) 
+  return $ rBody [text "private static int nameHash" <+> equals <+>
+                  rMethodCall (text "shared.HashFunctions")
+                              (text "stringHashFunction") 
+                              [dquotes qc, int len],
+                  text "private int hashCode",
+                  text "private static" <+> pretty c <+> 
+                  text "__proto = new" <+> pretty c <> text "()"]
+
+-- | Given a non-variadic constructor @C(x1:T1,..,xn:Tn)@,
+-- generates the constructor:
+--
+-- > private C(m.types.T1 x1, ..., m.types.Tn xn) {
+-- >   this.x1 = x1;
+-- >   ...
+-- >   this.xn = xn;
+-- > }
+compCtorOfConstructor :: CtorId -> Gen Doc
+compCtorOfConstructor c = ifConfM sharing ctorShr ctorNoShr
+  where ctorShr   = return $ rMethodDef private empty (pretty c) [] empty
+        ctorNoShr = do fis <- askSt (fieldsOf c)
+                       a <- mapM rdr1 fis
+                       let b = rBody $ map rdr2 fis
+                       return $ rMethodDef private empty (pretty c) a b
+          where rdr1 (f,s) = do qs <- qualifiedSort s
+                                return $ qs <+> _u (pretty f)
+                rdr2 (f,_) = this <> dot <> _u (pretty f) <+>
+                             equals <+> _u (pretty f)
+
+-- | Given a non-variadic constructor @C(x1:T1,..,xn:Tn)@,
+-- generates the make method:
+--
+-- > public static C make(m.types.T1 x1, ..., m.types.Tn xn) {
+-- >  proto.initHashCode(x1,..,xn);
+-- >  return (C) factory.build(proto);
+-- > }
+--
+-- or the following if @--noSharing@ has been toggled:
+--
+-- > public static C make(m.types.T1 x1, ..., m.types.Tn xn) {
+-- >   return new C(x1, ..., xn);
+-- > } 
+compMakeOfConstructor :: CtorId -> Gen Doc
+compMakeOfConstructor c = ifConfM sharing cmakes cmake
+  where -- the sharing case
+        cmakes = do cfs <- cfields 
+                    let call = rMethodCall proto inith (map (pretty.fst) cfs)
+                    let ret  = jreturn <+> parens (pretty c) <+> build
+                    makeDef $ rBody [call,ret]
+          where proto = text "__proto"
+                inith = text "initHashCode"
+                build = text "factory.build(__proto)"
+        -- the no sharing case
+        cmake  = do cfs <- cfields
+                    let b = newC (map (pretty . fst) cfs) <> semi
+                    makeDef b
+          where newC fs = jreturn <+> rConstructorCall (pretty c) fs
+        -- takes a body bd and returns public static C make(...) { bd }
+        makeDef bd = do cfs <- cfields 
+                        a <- mapM rdr cfs
+                        return $ rMethodDef (public <+> static) 
+                                 (pretty c) (text "make") a bd
+          where rdr (f,s) = do qs <- qualifiedSort s
+                               return $ qs <+> (text .show) f
+        -- the fields of c
+        cfields = askSt (fieldsOf c)
+
+-- | Given a non-variadic constructor @C(x1:T1,..,xn:Tn)@,
+-- generates the methods: 
+--
+-- > public m.types.T1 getx1() { return x1; }
+-- > ...
+-- > public m.types.Tn getxn() { return xn; }
+compGettersOfConstructor :: CtorId -> Gen Doc
+compGettersOfConstructor = iterOverFields getter vcat
+  where getter f s = do qs <- qualifiedSort s
+                        let fun = text "get" <> pretty f
+                        let b = rBody [jreturn <+> _u (pretty f)]
+                        return $ rMethodDef public qs fun [] b 
+
+-- | Given a non-variadic constructor @C(x1:T1,..,xn:Tn)@,
+-- generates the methods: 
+--
+-- > public void setx1(m.types.T1 x1) 
+-- >   { this.x1 = x1; }
+-- > ...
+-- > public void setxn(m.types.Tn xn) 
+-- >   { this.xn = xn; }
+compSettersOfConstructor :: CtorId -> Gen Doc
+compSettersOfConstructor = iterOverFields setter vcat
+  where setter f s = do qs <- qualifiedSort s
+                        let fun = text "set" <> pretty f
+                        let a = [pretty qs <+> _u (pretty f)]
+                        let b = rBody [this <> dot <> _u (pretty f) 
+                                       <+> equals <+> _u (pretty f)]
+                        return $ rMethodDef public void fun a b 
+
+-- | Given a non-variadic constructor @C(x1:T1,..,xn:Tn)@,
+-- generates 
+--
+-- > public String toStringBuilder(java.lang.StringBuilder buf) {
+-- >   buffer.append("C(");
+-- >   x1.toStringBuilder(buf);
+-- >   buffer.append(",");
+-- >   ...
+-- >   buffer.append(",");
+-- >   xn.toStringBuilder(buf);
+-- >   buffer.append(")");
+-- > }
+compToStringBuilder :: CtorId -> Gen Doc
+compToStringBuilder c = do rcalls <- iterOverFields rcall id c
+                           return $ rMethodDef 
+                             public void (text "toStringBuilder")
+                             [jStringBuilder <+> text "__buf"]
+                             (complete rcalls)
+  where complete b = rBody $ open : intersperse apcomma b ++ [close]
+        bapp arg   = text "__buf.append" <> parens arg
+        apcomma    = bapp $ dquotes comma
+        open       = bapp $ dquotes (pretty c <> lparen)
+        close      = bapp $ dquotes rparen
+        rcall x s  = return $
+          if isBuiltin s then renderBuiltin s (_u $ pretty x) (text "__buf")
+                         else rMethodCall (this <> dot <> _u (pretty x))
+                                          (text "toStringBuilder") 
+                                          [text "__buf"]
+
+-- | Given a non-variadic constructor @C(x1:T1,..,xn:Tn)@,
+-- generates 
+--
+-- > public String toHaskellBuilder(java.lang.StringBuilder buf) {
+-- >   buffer.append("(C");
+-- >   buffer.append(" ");
+-- >   x1.toStringBuilder(buf);
+-- >   buffer.append(" ");
+-- >   ...
+-- >   buffer.append(" ");
+-- >   xn.toStringBuilder(buf);
+-- >   buffer.append(")");
+-- > }
+compToHaskellBuilder :: CtorId -> Gen Doc
+compToHaskellBuilder c = do rcalls <- iterOverFields rcall id c
+                            return $ rMethodDef 
+                              public void (text "toHaskellBuilder")
+                              [jStringBuilder <+> text "__buf"]
+                              (complete rcalls)
+  where complete b = rBody $ open : addspaces b ++ [close]
+        bapp arg   = text "__buf.append" <> parens arg
+        apspace    = bapp $ dquotes space
+        addspaces  = foldr (\x r -> apspace:x:r) []
+        open       = bapp $ dquotes (lparen <> pretty c)
+        close      = bapp $ dquotes rparen
+        rcall x s  = return $
+          if isBuiltin s then renderBuiltin s (_u $ pretty x) (text "__buf")
+                         else rMethodCall (this <> dot <> _u (pretty x))
+                                          (text "toHaskellBuilder") 
+                                          [text "__buf"]
+
+-- | Given a non-variadic constructor @C(x1:T1,..,xn:Tn)@,
+-- @compEquiv C@ generates 
+--
+-- > public boolean equivalent(shared.SharedObject o) {
+-- >   if (o instanceof C) {
+-- >     C typed_o = (C) o;
+-- >     return true &&
+-- >            this.x1 == o.x1 &&
+-- >            ...
+-- >            this.xn == o.xn;
+-- >   } else {
+-- >     return false;
+-- >   }
+-- > }
+compEquiv :: CtorId -> Gen Doc
+compEquiv = compEqAux meth comb jShared
+  where meth = text "equivalent"
+        comb lhs rhs = lhs <+> text "==" <+> rhs
+
+-- | Given a non-variadic constructor @C(x1:T1,..,xn:Tn)@,
+-- @compEquals C@ generates 
+--
+-- > public boolean equals(java.lang.Object o) {
+-- >   if (o instanceof C) {
+-- >     C typed_o = (C) o;
+-- >     return true &&
+-- >            this.x1.equals(o.x1) &&
+-- >            ...
+-- >            this.xn.equals(o.xn);
+-- >   } else {
+-- >     return false;
+-- >   }
+-- > }
+compEquals :: CtorId -> Gen Doc
+compEquals = compEqAux meth comb jObject
+  where meth = text "equals"
+        comb lhs rhs = rMethodCall lhs meth [rhs]
+
+-- | Given a constructor @C(x1:T1,..,xn:Tn)@, generates
+--
+-- > public shared.SharedObject duplicate() {
+-- >   C clone = new C();
+-- >   clone.init(this.x1,..,this.xn,hashCode);
+-- >   return clone;
+-- > }
+compDuplicate :: CtorId -> Gen Doc
+compDuplicate c = rdr `fmap` askSt (fieldsOf c)
+  where pc  = pretty c
+        cl  = text "__clone"
+        th  = (text "this." <>) . _u . pretty . fst
+        rdr = rMethodDef public jShared (text "duplicate") [] . body
+        body fis = rBody 
+          [pc <+> cl <+> equals <+> rConstructorCall pc [],
+           rMethodCall cl (text "init") (map th fis ++ [text "hashCode"]),
+           jreturn <+> cl]
+
+-- | Given a constructor @C(x1:T1,..,xn:Tn)@, generates
+--
+-- > private void init(T1 x1, ..., Tn xn, int hashCode) {
+-- >   this.x1 = x1;
+-- >   ...
+-- >   this.xn = xn;
+-- >   this.hashCode = hashCode;
+-- > }
+compInit :: CtorId -> Gen Doc 
+compInit c = do cfs <- askSt $ fieldsOf c
+                tfs <- mapM rdr cfs
+                let args = tfs ++ [text "int __hashCode"]
+                let body = rBody $ map ass cfs ++ [lastLine]
+                return $ rMethodDef private void (text "init") args body
+  where rdr (f,s) = do qs <- qualifiedSort s
+                       return $ qs <+> _u (pretty f)
+        ass (f,s) = let pf = _u (pretty f)
+                    in this <> dot <> pf <+> equals <+> 
+                       if isString s then pf <> text ".intern()" else pf
+        lastLine  = text "this.hashCode = __hashCode"
+
+-- | Given a constructor @C(x1:T1,..,xn:Tn)@, generates
+--
+-- > private void initHashCode(T1 x1, ..., Tn xn) {
+-- >   this.x1 = x1;
+-- >   ...
+-- >   this.xn = xn;
+-- >   this.hashCode = hashFunction();
+-- > }
+compInitHash :: CtorId -> Gen Doc 
+compInitHash c = do cfs <- askSt $ fieldsOf c
+                    args <- mapM rdr cfs
+                    let body = rBody $ map ass cfs ++ [lastLine]
+                    return $ rMethodDef private void 
+                             (text "initHashCode") args body
+  where rdr (f,s) = do qs <- qualifiedSort s
+                       return $ qs <+> _u (pretty f)
+        ass (f,s) = let pf = _u (pretty f)
+                    in this <> dot <> pf <+> equals <+> 
+                       if isString s then pf <> text ".intern()" else pf
+        lastLine  = text "this.hashCode = hashFunction()"
+
+-- | Auxiliary function for @'compHashFun'@, generates the fields-related part
+-- of the @hashFunction@ method.
+hashArgs :: [(FieldId,SortId)] -> Int -> [Doc]
+hashArgs fis len = zipWith (\i (f,s) -> hashArg i f s) (desc (len -1)) fis
+  where desc n = n:desc (n-1)
+
+-- | Auxiliary function for @'hashArgs'@, generates the recursive call
+-- to the @hashFunction@ method for a non-builin field, ad-hoc magic
+-- otherwise.
+hashArg :: Int -> FieldId -> SortId -> Doc
+hashArg idx fid sid = let res d = char accum <+> text "+=" <+> parens d in
+                      if shift == 0 then res go
+                                    else res $ go <+> text "<<" <+> int shift
+  where go | isILC     sid = pfid
+           | isBoolean sid = pfid <> text "?1:0"
+           | isFloat   sid = text "(int)" <> toInt pfid <> text "^" <>
+                             parens (toInt pfid) <> text ">>>16"
+           | isDouble  sid = text "(int)" <> toLong pfid <> text "^" <>
+                             parens (toLong pfid) <> text ">>>32"
+           | otherwise     = rMethodCall pfid (text "hashCode") []
+        shift = (idx `mod` 4) * 8
+        accum = "aaaabbbbcccc" !! (idx `mod` 12)
+        isILC s = any ($ s) [isInt,isLong,isChar]
+        toInt x = text "java.lang.Float.floatToIntBits" <> parens x
+        toLong x = text "java.lang.Double.doubleToLongBits" <> parens x
+        pfid = this <> dot <> _u (pretty fid)
+
+-- | Given a constructor @C(x1:T1,..,xn:Tn)@, generates
+--
+-- > protected int hashFunction() {
+-- > int a, b, c;
+-- >   a = 0x9e3779b9;
+-- >   b = nameHash << 8;
+-- >   c = n;
+-- >   hashArgs [(x1,T1),..,(xn,Tn)] n
+-- >   a -= b; a -= c; a ^= (c >> 13);
+-- >   b -= c; b -= a; b ^= (a << 8);
+-- >   c -= a; c -= b; c ^= (b >> 13);
+-- >   a -= b; a -= c; a ^= (c >> 12);
+-- >   b -= c; b -= a; b ^= (a << 16);
+-- >   c -= a; c -= b; c ^= (b >> 5);
+-- >   a -= b; a -= c; a ^= (c >> 3);
+-- >   b -= c; b -= a; b ^= (a << 10); 
+-- >   c -= a; c -= b; c ^= (b >> 15);
+-- >   return c;
+-- > }
+compHashFun :: CtorId -> Gen Doc
+compHashFun c = do 
+  fis <- askSt (fieldsOf c)
+  let len = length fis
+  let modif = protected <+> if len == 0 then static else empty 
+  return $ rMethodDef modif jint (text "hashFunction") [] (body fis len)
+  where body f l = rBody (prologue ++ mid f l ++ epilogue)
+        prologue = map text ["int a, b, c",
+                             "a = 0x9e3779b9",
+                             "b = nameHash << 8"]
+        mid f l  = (text "c =" <+> int l) : hashArgs f l
+        epilogue = map text ["a -= b; a -= c; a ^= (c >> 13)",
+                             "b -= c; b -= a; b ^= (a << 8)" ,
+                             "c -= a; c -= b; c ^= (b >> 13)",
+                             "a -= b; a -= c; a ^= (c >> 12)",
+                             "b -= c; b -= a; b ^= (a << 16)",
+                             "c -= a; c -= b; c ^= (b >> 5)" ,
+                             "a -= b; a -= c; a ^= (c >> 3)" ,
+                             "b -= c; b -= a; b ^= (a << 10)",
+                             "c -= a; c -= b; c ^= (b >> 15)",
+                             "return c"]
+
+-- | Given a constructor @c@ of arity @n@, generates
+--
+-- > public int getChildCount() {
+-- >   return n;
+-- > }
+compGetChildCount ::  CtorId -> Gen Doc
+compGetChildCount c = do ar <- length `fmap` askSt (fieldsOf c)
+                         return $ wrap ar
+  where wrap n = rMethodDef public jint (text "getChildCount") 
+                            [] (jreturn <+> int n <> semi)
+
+-- | Given a constructor @c@ of fields @x1,..,xn@ generates
+--
+-- > public tom.library.sl.Visitable getChildAt(int n) {
+-- >   switch(n) {
+-- >     case 0: return this.x1;
+-- >     ...
+-- >     case n-1: return this.xn;
+-- >     default: throw new IndexOutOfBoundsException();
+-- >   }
+-- > }
+--
+-- Common.Builtins are boxed in @tom.library.sl.VisitableBuiltin@.
+compGetChildAt :: CtorId -> Gen Doc
+compGetChildAt c = do fis <- askSt (fieldsOf c)
+                      let cs  = zip (map int [0..]) (map cook fis)
+                      let arg = text "n"
+                      return $ rMethodDef 
+                                 public jVisitable (text "getChildAt")
+                                 [jint <+> arg] (body arg cs)
+  where cook (f,s) = jreturn <+> wrap (this <> dot <> _u (pretty f)) s <> semi 
+        body n cs  = rSwitch n cs (Just outOfBounds)
+        outOfBounds = text "throw new IndexOutOfBoundsException();"
+        wrap f s | isBuiltin s = rConstructorCall (rWrapBuiltin qs) [f]
+                 | otherwise   = f
+          where qs = qualifiedBuiltin s
+
+-- | Given a constructor @c@ of fields @x1,..,xn@ generates
+--
+-- > public tom.library.sl.Visitable[] getChildren() {
+-- >   return new tom.library.sl.Visitable[] {
+-- >     this.x1, ..., this.xn
+-- >   };
+-- > }
+--
+-- Common.Builtins are boxed in @tom.library.sl.VisitableBuiltin@.
+compGetChildren :: CtorId -> Gen Doc
+compGetChildren c = do fis <- askSt (fieldsOf c)
+                       return $ rMethodDef public jVisitableArray
+                                           (text "getChildren")
+                                           [] (body fis)
+  where body fs = let cs = align . sep . punctuate comma $ map child fs
+                  in jreturn <+> new <+> jVisitableArray <+> ibraces cs <> semi
+        child (f,s) =
+          if isBuiltin s then rConstructorCall (rWrapBuiltin qs) [df] else df
+            where qs = qualifiedBuiltin s
+                  df = this <> dot <> _u (pretty f)
+
+-- | Given a constructor @c@ of fields @x1,..,xn@ generates
+--
+-- > public tom.library.sl.Visitable setChildAt(tom.library.sl.Visitable v) {
+-- >   switch(n) {
+-- >     case 0: return c.make((m.foo.T1) x1,this.x2,..,this.xn);
+-- >     ...
+-- >     case n-1: return c.make(this.x1,...,(m.foo.Tn) this.xn);
+-- >     default: throw new IndexOutOfBoundsException();
+-- >   }
+-- > }
+--
+-- Common.Builtins are unboxed from @tom.library.sl.VisitableBuiltin@.
+compSetChildAt :: CtorId -> Gen Doc
+compSetChildAt c = do fis  <- askSt (fieldsOf c)
+                      fis' <- mapM set (parts fis)
+                      let cs  = zip (map int [0..]) fis'
+                      return $ rMethodDef 
+                        public jVisitable (text "setChildAt")
+                        [jint <+> text "__n", jVisitable <+> text "__v"]
+                        (body cs)
+  where body cs     = rSwitch (text "__n") cs (Just outOfBounds)
+        outOfBounds = text "throw new IndexOutOfBoundsException();"
+        set (xs1,(_,t),xs2) = 
+          let f (x,_) = this <> dot <> _u (pretty x)
+              dxs1    = map f xs1
+              dxs2    = map f xs2
+          in do dx <- cast t
+                let args = dxs1++[dx]++dxs2
+                let call = rMethodCall (pretty c) (text "make") args
+                return $ jreturn <+> call <> semi
+        parts l = go [] l where go _  []     = []
+                                go xs [x]    = [(xs,x,[])]
+                                go xs (x:ys) = (xs,x,ys) : go (xs++[x]) ys
+        cast t = if isBuiltin t 
+                   then let qbt = rWrapBuiltin (qualifiedBuiltin t)
+                            cas = parens (parens qbt <+> text "__v")
+                        in return $ rMethodCall cas (text "getBuiltin") []
+                   else do qt <- qualifiedSort t
+                           return $ parens qt <+> text "__v"
+
+-- | Given a constructor @c@ of fields @x1,..,xn@ generates
+--
+-- > public tom.library.sl.Visitable 
+-- >   setChildren(tom.library.sl.Visitable[] cs) {
+-- >   if (cs.length == n-1 && 
+-- >       cs[0] instanceof T0 &&
+-- >       ..
+-- >       cs[n] instanceof Tn) {
+-- >        return c.make(cs[0],..,cs[n])
+-- >   } else {
+-- >     throw new IndexOutOfBoundsException();
+-- >   }
+-- > }
+--
+-- Common.Builtins are unboxed from @tom.library.sl.VisitableBuiltin@.
+compSetChildren :: CtorId -> Gen Doc 
+compSetChildren c = do cs  <- askSt (fieldsOf c)
+                       csn <- zipWithM cook [0..] cs
+                       let cd  = cond csn
+                       let bd  = body csn
+                       let ite = rIfThenElse cd bd er
+                       return $ rMethodDef 
+                                  public jVisitable (text "setChildren")
+                                  [jVisitableArray <+> text "__cs"] ite
+  where cond csn = let cl = checkLen (length csn)
+                       ci = map checkInstance csn
+                   in align . fillSep $ intersperse (text "&&") (cl:ci)
+        checkLen n = text "__cs.length ==" <+> int n
+        checkInstance (n,t,qt) = nth n <+> instanceof <+> td
+          where td = if isBuiltin t 
+                       then text "tom.library.sl.VisitableBuiltin"
+                       else pretty qt
+        body csn = let call = rMethodCall (pretty c) (text "make") (map r csn)
+                   in jreturn <+> call <> semi
+          where r (n,t,qt) | isBuiltin t = rMethodCall cas 
+                                           (text "getBuiltin") []
+                           | otherwise   = parens (pretty qt) <+> nth n 
+                  where wqt = rWrapBuiltin (qualifiedBuiltin t)
+                        cas = parens (parens wqt <+> nth n)
+        er = text "throw new IndexOutOfBoundsException();"
+        nth n = text "__cs" <> brackets (int n)
+        cook n (_,t) = do qt <- qualifiedSort t
+                          return (n,t,qt)
+
+-- | Given a constructor C, generates
+--
+-- > public boolean isC() { return true; }
+compIsX :: CtorId -> Doc
+compIsX c = let fun = text "is" <> pretty c
+                b   = rBody [jreturn <+> true]
+            in rMethodDef public jboolean fun [] b 
+
+-- | @compSymbolName c@ renders 
+--
+-- > public String symbolName() {
+-- >   return "c";
+-- > }
+compSymbolName 
+  :: CtorId -- ^ constructor name
+  -> Doc
+compSymbolName c =
+  text "public String symbolName()" <+> 
+  ibraces (rBody [jreturn <+> dquotes (pretty c)])
+
+-- | Auxiliary function for 'compEquals' and 'compEquiv'. 
+-- Given a non-variadic constructor @C(x1:T1,..,xn:Tn)@,
+-- a method name @method@, a type name @ty@ and a combinator @comb@, 
+-- @compEqAux method comb ty C@ generates 
+--
+-- > public boolean method(ty o) {
+-- >   if (o instanceof C) {
+-- >     C typed_o = (C) o;
+-- >     return true &&
+-- >            this.x1 `comb` o.x1 &&
+-- >            ...
+-- >            this.xn `comb` o.xn;
+-- >   } else {
+-- >     return false;
+-- >   }
+-- > }
+compEqAux :: Doc -> (Doc -> Doc -> Doc) -> Doc -> CtorId -> Gen Doc
+compEqAux meth comb ty c = do rcalls <- iterOverFields rcall id c
+                              return $ rMethodDef 
+                                (public <+> final) jboolean meth
+                                [ty <+> text "__o"] (complete rcalls)
+  where pc = pretty c
+        complete b = rIfThenElse cond (branch1 b) (jreturn <+> false <> semi) 
+        cond       = text "__o" <+> instanceof <+> pc 
+        branch1 b  = rBody [l1,l2 (true:b)]
+        l1 = pc <+> text "__typed_o" <+> equals <+> parens pc <+> text "__o"
+        l2 b = jreturn <+> (align . fillSep $ intersperse (text "&&") b)
+        rcall x s = let lhs = this <> dot <> _u (pretty x)
+                        rhs = text "__typed_o." <> _u (pretty x)
+                    in return $ if isBuiltin s
+                                  then lhs <+> text "==" <+> rhs
+                                  else lhs `comb` rhs
+
+
+-- | Given a sort @s@, @randomRecCall s@ generates
+--
+--  * @mod.modAbstractType.randoms(rand)@ if @s@ is a builtin, 
+--
+--  * @mod.types.s.makeRandom(rand,depth)@ otherwise
+randomRecCall :: SortId -> Gen Doc
+randomRecCall s = do
+  qs <- qualifiedSort s
+  at <- qualifiedAbstractType
+  return $ if isBuiltin s 
+    then rMethodCall at (text "random" <> pretty s) [text "__rand"]
+    else rMethodCall qs (text "makeRandom") [text "__rand", text "__depth"]
+
+
+-- | Given a constructor @C(x1:T1,...,xn:Tn)@, 
+-- of codomain @Co@, generates
+--
+-- > final static public
+-- > mod.types.Co makeRandom(java.util.Random rand, int depth) {
+-- >   return
+-- >   mod.types.co.C.make(mod.types.T1.makeRandom(rand,depth),
+-- >                       ...,
+-- >                       mod.types.Tn.makeRandom(rand,depth));
+-- > }
+compMakeRandomConstructor :: CtorId -> Gen Doc
+compMakeRandomConstructor c = do
+  qc  <- qualifiedCtor c
+  co  <- askSt (codomainOf c)
+  qco <- qualifiedSort co
+  tys <- map snd `fmap` askSt (fieldsOf c)
+  rcalls <- mapM randomRecCall tys
+  return $ rMethodDef (final <+> static <+> public)
+                      qco (text "makeRandom")
+                      [text "java.util.Random __rand", text "int __depth"]
+                      (body qc rcalls)
+  where body qc rc = jreturn <+> rMethodCall qc (text "make") rc <> semi
+
+-- | Given a constructor @C(x1:T1,...,xn:Tn)@, generates
+--
+-- > final public static int depth() {
+-- >   int max = 0;
+-- >   int cd = 0;
+-- >   cd = x1.depth();
+-- >   if (cd > max) max = cd;
+-- >   ...
+-- >   cd = xn.depth();
+-- >   if (cd > max) max = cd;
+-- >   return max + 1;
+-- > }
+compDepthConstructor :: CtorId -> Gen Doc
+compDepthConstructor c = do
+  fis <- askSt (fieldsOf c)
+  return .wrap $ if null fis then text "return 0;" else pack fis
+  where call (f,s) 
+          | isBuiltin s = []
+          | otherwise = [this <> dot <> _u (pretty f) <> text ".depth();",
+                         text "if (__cd > __max) __max = __cd;"]
+        pack l = vcat ([pre] ++ mid ++ [post]) 
+           where pre  = text "int __max = 0; int __cd = 0;"
+                 mid  = concatMap call l
+                 post = text "return __max + 1;"
+        wrap d = text "final public int depth()" <+> ibraces d
+
+-- > final public static int size() {
+-- >   return x1.size() + ... + xn.size();
+-- > }
+compSizeConstructor :: CtorId -> Gen Doc
+compSizeConstructor c = do
+  fis <- askSt (fieldsOf c)
+  return . pack $ if null fis then one else add (map call fis)
+  where add = align . fillSep . intersperse (text "+")
+        one = text "1"
+        call (f,s) | isBuiltin s = one
+                   | otherwise   = this <> dot <> _u (pretty f)
+                                   <> text ".size()"
+        pack d = text "final public int size()" 
+                 <+> ibraces (jreturn <+> d <> semi)
diff --git a/Gom/CodeGen/Mappings.hs b/Gom/CodeGen/Mappings.hs
new file mode 100644
--- /dev/null
+++ b/Gom/CodeGen/Mappings.hs
@@ -0,0 +1,139 @@
+------------------------------------------------------------------
+-- |
+-- Module      : Gom.CodeGen.Mappings
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--------------------------------------------------------------------
+
+module Gom.CodeGen.Mappings (
+  compTomFiles
+) where
+
+import Gom.Sig
+import Gom.Config
+import Gom.FileGen
+import Gom.SymbolTable
+import Gom.CodeGen.Common
+
+import Text.PrettyPrint.Leijen
+import Control.Arrow((***))
+
+-- | Generates the @Mod.tom@ and @_Mod.tom@ tom mappings files for
+-- module @Mod@
+compTomFiles :: Gen [FileHierarchy]
+compTomFiles = do mn    <- askSt modName
+                  srts  <- askSt definedSortsIds
+                  ctrs  <- askSt simpleConstructorsIds
+                  vctrs <- askSt variadicConstructorsIds
+                  incls <- compIncludes
+                  tyts  <- mapM compTypeTerm srts
+                  ops   <- mapM compOp ctrs
+                  opls  <- mapM compOpList vctrs
+                  sops <-  mapM compSOp ctrs
+                  vcongr <- askConf congr
+                  let mappings = incls:(tyts++ops++opls)
+                  return $ case vcongr of 
+                     NoCongr  -> [Tom mn (vsep mappings)]
+                     SameFile -> [Tom mn (vsep $ includeSl:mappings++sops)]
+                     SeparateFile -> [Tom mn $ vsep mappings, 
+                                      Tom ('_':mn) (vsep $ includeSl:sops)]
+
+-- | Generates @%include { x.tom }@ for every imported sort @x@
+compIncludes :: Gen Doc
+compIncludes = do is <- askSt importedSorts
+                  return $ vcat (map rdr is)
+  where rdr s = text "%include" <+> 
+                sbraces (builtinImport s)
+
+-- | Given a sort @S@, generates
+--
+-- > %typeterm S {
+-- >   implement { m.types.S }
+-- >   is_sort(t) { ($t instanceof m.types.S) }
+-- >   equals(t1,t2) { ($t1 == $t2) }
+-- > }
+--
+-- generats @$t1.equals($t2)@ if @--noSharing@ has been
+-- toggled
+compTypeTerm :: SortId -> Gen Doc
+compTypeTerm s = do qs <- qualifiedSort s
+                    sh <- askConf sharing 
+                    return $ rTypeterm (pretty s) qs sh
+
+-- | Given a non-variadic constructor @C(x1:T1,..,xn:Tn)@
+-- of codomain @Co@, generates
+--
+-- > %op Co C(x1:T1,..,xn:Tn) {
+-- >   is_fsym(t) { ($t instanceof m.types.C) }
+-- >   get_slot(x1,t) { $t.getx1() }
+-- >   ...
+-- >   get_slot(xn,t) { $t.getxn() }
+-- >   make (t1,..,tn) { (m.types.co.c.make($t1,..,$tn)) }
+-- > }
+compOp :: CtorId -> Gen Doc
+compOp c = do isfsym <- compIsFsym
+              slots  <- iterOverFields compSlot vcat c
+              s      <- askSt (codomainOf c)
+              fis    <- askSt (fieldsOf c)
+              let pfis = map (pretty *** pretty) fis
+              make   <- compMake (map fst pfis)
+              return $ rOp (pretty s) (pretty c) pfis
+                           (vcat [isfsym,slots,make])
+  where compIsFsym   = do qc <- qualifiedCtor c
+                          return $ rIsFsym qc
+        compSlot x _ = return $ rGetSlot (pretty x)
+        compMake xs  = do qc <- qualifiedCtor c
+                          return $ rMake qc xs 
+
+-- | Given a variadic constructor @VC(T*)@
+-- of codomain @Co@, generates
+--
+-- > %oplist Co VC(T*) {
+-- >   is_fsym(t) { (    ($t instanceof foo.types.co.ConsVC) 
+-- >                  || ($t instanceof foo.types.co.EmptyVC)) }
+-- >   make_empty() { foo.types.co.EmptyVC.make() }
+-- >   make_insert(e,l) { foo.types.co.ConsVC.make($e,$l) }
+-- >   get_head(l) { $l.getHeadVC() }
+-- >   get_tail(l) { $l.getTailVC() }
+-- >   is_empty(l) { $l.isEmptyVC() }
+-- > }
+compOpList :: CtorId -> Gen Doc
+compOpList c = do co     <- askSt (codomainOf c)
+                  dom    <- askSt (fieldOf c)
+                  consc  <- qualifiedCtor (prependCons c)
+                  emptyc <- qualifiedCtor (prependEmpty c)
+                  return $ rOpList (pretty c) (pretty co) 
+                                   (pretty dom) consc emptyc
+
+-- | Given a non-variadic constructor @C(x1:T1,..,xn:Tn)@
+-- of codomain @Co@, generates
+--
+-- > %op Strategy _C(s1:Strategy,..,sn:Strategy) {
+-- >   is_fsym(t) { $t m.strategy.co._C }
+-- >   get_slot(s1,t) { (tom.library.sl.Strategy) $t.getChildAt(0) }
+-- >   ...
+-- >   get_slot(sn,t) { (tom.library.sl.Strategy) $t.getChildAt(n-1) }
+-- >   make (t1,..,tn) { new m.strategy.co._C($t1,..,$tn) }
+-- > }
+compSOp :: CtorId -> Gen Doc
+compSOp c = do sc <- compStratClass
+               n  <- length `fmap` askSt (fieldsOf c)
+               return $ rOp (text "Strategy") (_u $ pretty c) (mkTypedArgs n)
+                            (vcat [rIsFsym sc, slots n, mkMake n sc])
+  where compStratClass = do co <- askSt (codomainOf c)
+                            pr <- qualifiedStratPrefix co
+                            return $ pr <> dot <> _u (pretty c)
+        mkSlot i = text "get_slot(s" <> int i <> 
+                   text ",t) { (tom.library.sl.Strategy) $t.getChildAt(" <> 
+                   int (i-1) <> text ") }"
+        mkMake n sc = text "make" <> args n "s" <> text "{ new " <> 
+                      sc <> args n "$s" <> text " }"
+          where args ar s = encloseCommasNB [text s <> int i | i <- [1..ar]]
+        mkTypedArgs n = [(text "s" <> int i, text "Strategy") | i <- [1..n]]
+        slots n = vcat $ map mkSlot [1..n]
diff --git a/Gom/CodeGen/Sorts.hs b/Gom/CodeGen/Sorts.hs
new file mode 100644
--- /dev/null
+++ b/Gom/CodeGen/Sorts.hs
@@ -0,0 +1,219 @@
+------------------------------------------------------------------
+-- |
+-- Module      : Gom.CodeGen.Sorts
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--------------------------------------------------------------------
+
+module Gom.CodeGen.Sorts (
+  compSort
+) where
+
+import Gom.Sig
+import Gom.Config
+import Gom.FileGen
+import Gom.SymbolTable
+import Gom.CodeGen.Common
+import Gom.CodeGen.Constructors
+
+import Text.PrettyPrint.Leijen
+import Control.Monad(foldM)
+
+-- | Given a sort @Sort@, generates 
+--  an abstract class @Sort.java@
+--  and a package @sort@ containing:
+--
+--     - an abstract  class @VC.java@ for every variadic constructor @VC@ of
+--     @Sort@
+--
+--     - a concrete class @C.java@ for every non-variadic constructor @C@ of
+--     @Sort@
+compSort :: SortId -> Gen [FileHierarchy]
+compSort s = do ac    <- compAbstractSort s
+                vctrs <- askSt (vCtorsOf s)
+                ctrs  <- askSt (sCtorsOf s)
+                avs   <- mapM compAbstractVariadic vctrs
+                ccs   <- mapM compConstructor ctrs
+                return [ac, Package (show $ lowerId s) (avs ++ ccs)] 
+
+-- | Given a sort @S@, generates an abstract class @S.java@.
+compAbstractSort :: SortId -> Gen FileHierarchy
+compAbstractSort s = do eg <- compEmptyGettersOfSort s
+                        es <- compEmptySettersOfSort s
+                        ei <- compEmptyIsX s
+                        fs <- ifP $ compFromStringSort s
+                        pa <- ifP $ compParseSort s
+                        ri <- ifR $ compMakeRandomSortInit s
+                        ra <- ifR $ compMakeRandomSort s
+                        cl <- wrap $ vcat [eg,es,ei,pa,fs,ri,ra]
+                        return $ Class (show s) cl
+  where ifP = flip (ifConfM parsers) (return empty)
+        ifR = flip (ifConfM random) (return empty)
+        wrap body = do qat <- qualifiedAbstractType
+                       return $ rClass (public <+> abstract) 
+                                       (pretty s) (Just qat)  
+                                       [] body
+
+-- | @hasNotError s f@ renders 
+-- @throw new UnsupportedOperationException(\"this s has no f.\")@
+hasNotError :: SortId -> FieldId -> Doc
+hasNotError s f = throw <+> new <+> text "UnsupportedOperationException" <>
+                  parens (dquotes $ text "This" <+> pretty s <+> 
+                                    text "has no" <+> pretty f <> dot)
+
+-- | Given a sort S, generates the methods: 
+--
+-- > public m.types.T getx() {
+-- >   throw new UnsupportedOperationException("This S has no x");
+-- > }
+--
+-- for each of its fields @x:T@
+compEmptyGettersOfSort :: SortId -> Gen Doc
+compEmptyGettersOfSort = iterOverSortFields getter vcat
+  where getter co f t = do qt <- qualifiedSort t
+                           let fun = text "get" <> pretty f
+                           let b = rBody [hasNotError co f]
+                           return $ rMethodDef public qt fun [] b 
+
+-- | Given a sort S, generates the methods: 
+--
+-- > public void setx(m.types.T x) {
+-- >   throw new UnsupportedOperationException("This S has no x");
+-- > }
+--
+-- for each of its fields @x:T@
+compEmptySettersOfSort :: SortId -> Gen Doc
+compEmptySettersOfSort = iterOverSortFields setter vcat
+  where setter co f t = do qt <- qualifiedSort t
+                           let fun = text "set" <> pretty f
+                           let a = [pretty qt <+> pretty f]
+                           let b = rBody [hasNotError co f]
+                           return $ rMethodDef public void fun a b 
+
+-- | Given a sort S, generates the methods: 
+--
+-- > public void isx() {
+-- >   return false;
+-- > }
+--
+-- for each of its fields @x@
+compEmptyIsX :: SortId -> Gen Doc
+compEmptyIsX s = do cs  <- askSt (sCtorsOf s) 
+                    return . vcat $ map isx cs
+  where isx f = let fun = text "is" <> pretty f
+                    b   = rBody [jreturn <+> false]
+                in rMethodDef public jboolean fun [] b 
+
+-- | Given a sort @T = f1(...) | ... | fn(...)@, generates
+--
+-- > static public sig.types.T parse(mod.Parser par) {
+-- >   String id = par.parseId();
+-- >   if (id.equals("f1")) return mod.types.t.f1.parse(par);
+-- >   else ....
+-- >   else if(id.equals("fn")) return mod.types.t.fn.parse(par);
+-- >   else throw new RuntimeException();
+-- > }
+compParseSort :: SortId -> Gen Doc
+compParseSort s = do
+  qs  <- qualifiedSort s
+  scs <- askSt (sCtorsOf s)
+  vcs <- askSt (vCtorsOf s)
+  let cs = scs ++ vcs
+  qcs <- mapM qualifiedCtor cs
+  pr  <- packagePrefix
+  let calls = foldr ifsym post (zip cs qcs)
+  return $ rMethodDef (static <+> public) qs (text "parse")
+           [pars pr <+> arg] (vcat [pre,calls])
+  where pars pr  = pr <> dot <> text "Parser"
+        arg = text "__par"
+        pre = text "String __id = par.parseId();"
+        post = text "throw new RuntimeException();"
+        cond c = rMethodCall (text "__id") (text "equals") [dquotes $ pretty c]
+        rcall qc = rMethodCall (pretty qc) (text "parseArgs") [arg]
+        ifsym (c,qc) = rIfThenElse (cond c) (jreturn <+> rcall qc <> semi)
+
+-- | Given a sort @S@, generates
+--
+-- > public static mod.types.S fromString(String __s) {
+-- >   return mod.types.S.parse(new mod.Parser(__s));
+-- > }
+compFromStringSort :: SortId -> Gen Doc
+compFromStringSort s = do
+  qs <- qualifiedSort s
+  pr <- packagePrefix
+  let pa = pr <> dot <> text "Parser"
+  return $ vcat
+    [text "public static" <+> qs <+> text "fromString(String __s) {",
+     text "  return" <+> qs <> text ".parse(new" <+> pa <> text "(__s));",
+     text "}"]
+
+-- | Given a sort @T = f1(...) | ... | fn(...)@, generates
+--
+-- > static public sig.types.T 
+-- > makeRandom(java.util.Random rand, int depth) {
+-- >   if (depth <= 0) {
+-- >     switch(rand.nextInt(m)) {
+-- >       case 0: return sig.types.t.g1.make();
+-- >       ...
+-- >       case m-1: return sig.types.t.gn.make();
+-- >     }
+-- >   } else {
+-- >     switch(rand.nextInt(n)) {
+-- >       case 0: return sig.types.t.f1.makeRandom(rand,maxdepth);
+-- >       ...
+-- >       case n-1: return sig.types.t.fn.makeRandom(rand,maxdepth);
+-- >       default: throw new RuntimeException("never happens");
+-- >     }
+-- >   }
+-- > }
+--
+-- Where @g1 ... gm@ are the constructors with arity 0 among @f1 ... fn@.
+compMakeRandomSort :: SortId -> Gen Doc
+compMakeRandomSort s = do
+  qs         <- qualifiedSort s
+  cs         <- askSt (sCtorsOf s)
+  (zcs,nzcs) <- partitionM isConst cs
+  qzcs       <- mapM qualifiedCtor zcs
+  qnzcs      <- mapM qualifiedCtor nzcs
+  let rcalls1 = map rcall1 qzcs 
+  let rcalls2 = map rcall2 qnzcs
+  return $ rMethodDef (static <+> public) qs (text "makeRandom")
+                      [text "java.util.Random __rand", text "int __depth"]
+                      (pack rcalls1 (rcalls1 ++ rcalls2))
+  where isConst c  = null `fmap` askSt (fieldsOf c) 
+        rcall1 qc  = jreturn <+> pretty qc <> text ".make();"
+        rcall2 qc  = jreturn <+> pretty qc <> 
+                     text ".makeRandom(__rand,__depth-1);"
+        ints       = map int [0..]
+        dflt       = text "throw new RuntimeException();"
+        nextint n  = rMethodCall (text "__rand") 
+                     (text "nextInt") [int (max n 1)]
+        pack c1 c2 = rIfThen (text "__depth <= 0") 
+                       (rSwitch (nextint $ length c1) (zip ints c1) Nothing)
+                     <$> 
+                     rSwitch (nextint $ length c2) (zip ints c2) (Just dflt)
+
+-- | generates
+--
+-- > static public sig.types.T makeRandom(int depth) {
+-- >   sig.types.T.makeRandom(new java.util.Random(), depth);
+-- > }
+compMakeRandomSortInit :: SortId -> Gen Doc
+compMakeRandomSortInit s = do
+  qs <- qualifiedSort s
+  return $ rMethodDef (static <+> public) qs (text "makeRandom") 
+                      [text "int __depth"] (body qs)
+  where body qs = jreturn <+> qs <> 
+                  text ".makeRandom(new java.util.Random(), __depth);"
+
+-- | Monadic version of Data.List.partition
+partitionM :: (Monad m) => (a -> m Bool) -> [a] -> m ([a], [a])
+partitionM p xs = foldM f ([],[]) xs
+  where f (a,b) x = do test <- p x
+                       return $ if test then (x:a,b) else (a,x:b)
diff --git a/Gom/CodeGen/Strategies.hs b/Gom/CodeGen/Strategies.hs
new file mode 100644
--- /dev/null
+++ b/Gom/CodeGen/Strategies.hs
@@ -0,0 +1,129 @@
+------------------------------------------------------------------
+-- |
+-- Module      : Gom.CodeGen.Strategies
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--------------------------------------------------------------------
+
+module Gom.CodeGen.Strategies (
+  compStrategy
+) where
+
+import Gom.Sig
+import Gom.FileGen
+import Gom.SymbolTable
+import Gom.CodeGen.Common
+
+import Text.PrettyPrint.Leijen
+
+-- | Given a sort @S@ of constructors @Ci@, 
+-- generates the package @s@ containing the
+-- @_Ci@ congruence classes.
+compStrategy :: SortId -> Gen FileHierarchy
+compStrategy s = do ctrs  <- askSt (sCtorsOf s)
+                    cs <- mapM compCongruence ctrs
+                    return $ Package (show $ lowerId s) cs 
+
+-- | Given a non-variadic constructor @C@, 
+-- generates a congruence strategy class @_C.java@.
+compCongruence :: CtorId -> Gen FileHierarchy
+compCongruence c = 
+  do body <- vcat `fmap` sequence [compCongruenceConstructor c,
+                                   compVisit c, compVisitLight c]
+     return $ Class classname (wrap body)
+  where wrap = rClass public (text classname) (Just jSCombinator) []
+        classname = '_':show c
+
+-- | Given a non-variadic constructor @C@, generates
+-- the method @public int visit(Introspector introspector) { ... }@
+-- for class @_C@.
+compVisit :: CtorId -> Gen Doc
+compVisit c = body `fmap` qualifiedCtor c
+  where body qc = vcat $ map text 
+          ["public int visit(tom.library.sl.Introspector introspector) {",
+           "  environment.setIntrospector(introspector);",
+           "  Object any = environment.getSubject();",
+           "  if (any instanceof " ++ show qc ++ ") {",
+           "    int childCount = introspector.getChildCount(any);",
+           "    Object[] childs = null;",
+           "    for(int i = 0; i < childCount; i++) {",
+           "      Object oldChild = introspector.getChildAt(any,i);",
+           "      environment.down(i+1);",
+           "      int status = arguments[i].visit(introspector);",
+           "      if(status != tom.library.sl.Environment.SUCCESS) {",
+           "        environment.upLocal();",
+           "        return status;",
+           "      }",
+           "      Object newChild = environment.getSubject();",
+           "      if(childs != null) {",
+           "        childs[i] = newChild;",
+           "      } else if(newChild != oldChild) {",
+           "        // allocate the array, and fill it",
+           "        childs = introspector.getChildren(any);",
+           "        childs[i] = newChild;",
+           "      } ",
+           "      environment.upLocal();",
+           "    }",
+           "    if(childs!=null) {",
+           "      environment.setSubject",
+           "        (introspector.setChildren(any,childs));",
+           "    }",
+           "    return tom.library.sl.Environment.SUCCESS;",
+           "  } else {",
+           "    return tom.library.sl.Environment.FAILURE;",
+           "  }",
+           "}"]
+
+-- | Given a non-variadic constructor @C@, generates
+-- the method @public int visitLight(Introspector introspector) { ... }@
+-- for class @_C@.
+compVisitLight :: CtorId -> Gen Doc
+compVisitLight c = do n <- length `fmap` askSt (fieldsOf c)
+                      qc <- qualifiedCtor c
+                      return $ body qc n
+  where body qc n = vcat $ map text 
+          ["public <T> T visitLight(T any,",
+           "  tom.library.sl.Introspector introspector)", 
+           "  throws tom.library.sl.VisitFailure {",
+           "  if(any instanceof " ++ show qc ++ ") {",
+           "    T result = any;",
+           "    Object[] childs = null;",
+           "    for (int i = 0, nbi = 0; i <" ++ show n ++"; i++) {",
+           "        Object oldChild = introspector.getChildAt(any,nbi);",
+           "        Object newChild =",
+           "           arguments[i].visitLight(oldChild,introspector);",
+           "        if(childs != null) {",
+           "          childs[nbi] = newChild;",
+           "        } else if(newChild != oldChild) {",
+           "          // allocate the array, and fill it",
+           "          childs = introspector.getChildren(any);",
+           "          childs[nbi] = newChild;",
+           "        }",
+           "        nbi++;",
+           "    }",
+           "    if(childs!=null) {",
+           "      result = introspector.setChildren(any,childs);",
+           "    }",
+           "    return result;",
+           "  } else {",
+           "    throw new tom.library.sl.VisitFailure();",
+           "  }",
+           "}"]
+        
+-- | Given a non-variadic constructor @C@, generates
+-- the constructor of @_C@.
+compCongruenceConstructor :: CtorId -> Gen Doc
+compCongruenceConstructor c = do
+  fs <- map convert `fmap` askSt (fieldsOf c)
+  return $ rMethodDef public empty (text "_" <> pretty c) 
+                      (map (jStrategy <+>) fs) (rBody [body fs])
+  where convert = (text "s" <>) . pretty . fst
+        body fs = rMethodCall this (text "initSubterm") [array]
+          where array   = new <+> jStrategyArray <+> sbraces content 
+                content = align $ sep (punctuate comma fs)
diff --git a/Gom/Config.hs b/Gom/Config.hs
new file mode 100644
--- /dev/null
+++ b/Gom/Config.hs
@@ -0,0 +1,170 @@
+-------------------------------------------------------------------
+-- |
+-- Module      : Gom.Config
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--
+-- Handle user args.
+--------------------------------------------------------------------
+
+module Gom.Config (
+  Config(..),
+  CongrOpt(..),
+  gomOpts,
+  usage,
+  paramsError
+) where
+
+
+import Control.Monad.Error
+import Data.Foldable(foldlM)
+import System.Console.GetOpt
+
+-- | Datatype representing the parameters passed to hgom by the user.
+data Config =
+  Config {
+    help    :: Bool, -- ^ display help message ?
+    version :: Bool, -- ^ display version information ?
+    package :: Maybe [String], -- ^ optional package prefix
+    prprint :: Bool,  -- ^ pretty-print module and exit ?
+#if TEST
+    utests  :: Maybe [String], -- ^ run unit tests ? 
+#endif
+    haskell :: Bool, -- ^ generate @toHaskell@ methods ?
+    visit   :: Bool, -- ^ implement @Visitable@ ? 
+    checker :: Bool, -- ^ perform checks ?
+    congr   :: CongrOpt, -- ^ generate congruence strategies ?
+    oomapping :: Bool, -- ^ generate oo mappings?
+    sharing :: Bool, -- ^ maximally share terms ?
+    compact :: Bool, -- ^ generate compact code ?
+    parsers :: Bool, -- ^ generate @from*@ methods ? 
+    random  :: Bool, -- ^ generate @makeRandom@ methods ?
+    depth   :: Bool, -- ^ generate @depth@ methods ?
+    size    :: Bool  -- ^ generate @size@ methods ?
+  } 
+
+-- | Default configuration.
+defaultConfig :: Config
+defaultConfig = 
+  Config {
+    help    = False,
+    version = False,
+    package = Nothing,
+    prprint = False,
+#if TEST
+    utests  = Nothing,
+#endif
+    haskell = False,
+    visit   = True,
+    checker = True,
+    congr   = NoCongr,
+    oomapping   = False,
+    sharing = True,
+    compact = False,
+    parsers = True,
+    random  = False,
+    depth   = False,
+    size    = False
+  }
+
+-- | Represents the three options values for @--withCongruenceStrategies@
+data CongrOpt = NoCongr | SameFile | SeparateFile
+
+-- | Pyhton-like split function.
+-- @split \'x\' \"aaxbbxcc\" = [\"aa\",\"bb\",\"cc\"]@
+split :: Char -> String -> [String]
+split _ [] = []
+split c (x:xs) 
+  | x == c    = split c xs
+  | otherwise = let (xs1,xs2) = break (== c) (x:xs)
+                in xs1:split c xs2
+
+-- | Options description for 'getOpt'.
+options :: [OptDescr (Config -> Either String Config)]
+options =
+  [Option [] ["help"] (NoArg  chelp) 
+          "show this message and exit"
+  ,Option ['V'] ["version"] (NoArg  cversion)                
+          "show version number and exit"
+  ,Option ['P'] ["pretty"] (NoArg  cpretty)
+          "pretty-print the module and exit"
+#if TEST
+  ,Option [] ["test"] (ReqArg cutests "args")
+          (unlines ["run test suite with args"])
+#endif
+  ,Option ['p'] ["package"] (ReqArg cpackage "packageName") 
+          "specify package name"
+  ,Option ['c'] ["congruence"] (ReqArg ccongr "(same|sep)")
+          (unlines ["generate congruence strategies in",
+                    "the same or in a separate .tom file"])
+  ,Option ['r'] ["random"] (NoArg crandom)
+          "generate makeRamdom methods"
+  ,Option ['j'] ["oomappings"] (NoArg coomapping)
+          "generate only Java OO mappings"
+  ,Option ['d'] ["depth"] (NoArg cdepth)
+          "generate depth methods"
+  ,Option ['s'] ["size"] (NoArg csize)
+          "generate size methods"
+  ,Option ['h'] ["haskell"] (NoArg chaskell)                
+          "generate 'toHaskell' methods"
+  ,Option [] ["noSharing"] (NoArg csharing)
+          "don't share structurally equal terms"
+  ,Option [] ["noVisitable"] (NoArg cvisit)
+          "don't implement Visitable"
+  ,Option [] ["noParsers"] (NoArg cparsers)
+          "don't generate from* methods"
+  ,Option [] ["noCheck"] (NoArg ccheck)
+          "don't perform consistency checks"
+  ,Option [] ["compact"] (NoArg ccompact)
+          "generate compact code (no indentation)"]
+
+  where chelp      c = return $ c { help    = True  }
+        cversion   c = return $ c { version = True  }
+        cpretty    c = return $ c { prprint = True  }
+        chaskell   c = return $ c { haskell = True  }
+        cvisit     c = return $ c { visit   = False }
+        ccheck     c = return $ c { checker = False }
+        csharing   c = return $ c { sharing = False }
+        ccompact   c = return $ c { compact = True  }
+        cparsers   c = return $ c { parsers = False }
+        crandom    c = return $ c { random  = True  }
+        coomapping c = return $ c { oomapping = True  }
+        cdepth     c = return $ c { depth   = True  }
+        csize      c = return $ c { size    = True  }
+#if TEST
+        cutests  s c = return $ c { utests = Just (words s) }
+#endif
+        cpackage p c = return $ c { package = Just (split '.' p) }
+
+        ccongr "same" c = return $ c { congr = SameFile }
+        ccongr "sep"  c = return $ c { congr = SeparateFile }
+        ccongr _      _ = throwError 
+          "'--congruence' argument must be 'same' or 'sep'.\n"
+
+-- | Usage info message header : @Usage: hgom [OPTION...] file@.
+header :: String
+header = "Usage: hgom [OPTION...] file"
+
+-- | Usage info message.
+usage :: String
+usage = usageInfo header options
+
+-- | Parse user args. Returns either an error message, 
+-- either a configuration along with unparsed arguments.
+gomOpts :: [String] -> Either String (Config,[String])
+gomOpts argv = 
+  case getOpt Permute options argv of
+    (o,n,[]  ) -> do conf <- foldlM (\c f -> f c) defaultConfig o
+                     return (conf,n)
+    (_,_,errs) -> throwError $ concat errs
+
+-- | Report an error concerning user args (includes usage info reminder).
+paramsError :: String -> IO a
+paramsError err = error (err ++ usageInfo header options)
+
diff --git a/Gom/FileGen.hs b/Gom/FileGen.hs
new file mode 100644
--- /dev/null
+++ b/Gom/FileGen.hs
@@ -0,0 +1,80 @@
+-------------------------------------------------------------------
+-- |
+-- Module      : Gom.FileGen
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--
+-- Exposes 'FileHierarchy', a datatype representing a file hierarchy made of
+-- packages, java files and tom files as well as an impure function for
+-- actually generating the hierarchy.
+--------------------------------------------------------------------
+
+module Gom.FileGen (
+  FileHierarchy(..),
+  generateFileHierarchy
+) where
+
+import Text.PrettyPrint.Leijen
+import Data.List(intercalate)
+import System.FilePath hiding ((</>))
+import System.Directory
+import System.IO
+
+-- | Represents a hierarchy of Java packages, Java classes and .tom files.
+-- Constructors and field names speak for themselves.
+data FileHierarchy
+  = Package { 
+    packageName    :: String,
+    packageContent :: [FileHierarchy]
+  }
+  | Class {
+    className    :: String,
+    classContent :: Doc -- ^ without @package ...@ at the begining
+  }
+  | Tom {
+    fileName    :: String, -- ^ without the extension
+    fileContent :: Doc 
+  }
+
+-- | Actually generates files on disk. If the first argument is
+-- true, generates compact code.
+generateFileHierarchy :: Bool -> FileHierarchy -> IO ()
+generateFileHierarchy c h = do cur <- getCurrentDirectory
+                               generateHierarchyIn c cur [] h
+
+-- | @generateHierarchyIn compact dir [pack]@ generates the files in
+-- directory @dir@ in package @pack@. Adds proper @package ...@ on top of java
+-- files. If @compatc@ is true, the generated code is more compact.
+--
+-- GenMonad usage : @generateFileHierarchyIn compact dir []@
+generateHierarchyIn :: Bool -> FilePath -> [String] -> FileHierarchy -> IO ()
+generateHierarchyIn cp dir pac h = go h
+  where go (Package n hs) = let ndir = dir `combine` n
+                                npac = pac ++ [n]       
+                            in do createDirectoryIfMissing False ndir
+                                  mapM_ (generateHierarchyIn cp ndir npac) hs
+        go (Class n b)    = let fn = dir `combine` (n `addExtension` "java")
+                                fb = rFullClass pac b
+                            in renderInFile fn fb
+        go (Tom n b)      = let fn = dir `combine` (n `addExtension` "tom")
+                            in renderInFile fn b
+        renderInFile n b  = do hdl <- openFile n WriteMode
+                               displayIO hdl (rdr b) 
+                               hClose hdl
+        rdr = if cp then renderCompact else renderPretty 0.6 80 
+
+-- | Adds package name at the top of a class declaration.
+rFullClass
+  :: [String] -- ^ package
+  -> Doc      -- ^ class content
+  -> Doc
+rFullClass [] bd = bd
+rFullClass pk bd = text "package" <+> text (intercalate "." pk) <>
+                   semi <> linebreak <$> bd
+
diff --git a/Gom/OOMappingGen.hs b/Gom/OOMappingGen.hs
new file mode 100644
--- /dev/null
+++ b/Gom/OOMappingGen.hs
@@ -0,0 +1,149 @@
+-------------------------------------------------------------------
+-- |
+-- Module      : Gom.CodeGen
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : emilie.balland@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--
+-- Generation of a file hierarchy from a symbol table.
+-------------------------------------------------------------------- 
+
+module Gom.OOMappingGen (st2oomapping) where
+
+import Gom.Sig
+import Gom.SymbolTable
+import Gom.Config
+import Gom.FileGen
+import Gom.CodeGen.Common
+
+import Text.PrettyPrint.Leijen
+import Control.Arrow((***))
+import Data.Char(toLower)
+
+-- | Compiles a symbol table into OO Mapping
+st2oomapping :: SymbolTable -> Config -> FileHierarchy
+st2oomapping =  runGen compOOMapping
+
+-- | Generates the @Mod.tom@ tom mapping file for module @Mod@ based
+-- on OO mappings and the OOMapping interface class
+compOOMapping :: Gen FileHierarchy
+compOOMapping = do m <- askSt modName
+                   let mn = map toLower m 
+                   pr <- askConf package
+                   ctrs  <- askSt simpleConstructorsIds
+                   vctrs <- askSt variadicConstructorsIds
+                   srts  <- askSt definedSortsIds
+                   tyts  <- mapM compTypeTerm srts
+                   ops   <- mapM compOp ctrs
+                   vops  <- mapM compVOp vctrs
+                   isig  <- compISignature ctrs vctrs 
+                   let mapping = Tom m . vsep $ tyts++ops++vops
+                   return . wrap pr $ Package mn [mapping,isig]
+  where wrap Nothing  h = h
+        wrap (Just l) h = foldr w h l
+        w p h = Package p [h]
+                 
+-- | Given a sort @S@, generates
+--
+-- > %typeterm S {
+-- >   implement { S }
+-- >   is_sort(t) { ($t instanceof S) }
+-- >   equals(t1,t2) { ($t1 == $t2) }
+-- > }
+--
+-- generats @$t1.equals($t2)@ if @--noSharing@ has been
+-- toggled
+compTypeTerm :: SortId -> Gen Doc
+compTypeTerm s = do 
+  cs <- askSt (concreteTypeOf s)
+  return $ rTypeterm (pretty s) (text (getClassName cs)) False 
+
+-- | Given a non-variadic constructor @C(x1:T1,..,xn:Tn)@
+-- of codomain @Co@, generates
+--
+-- > %op Co C(x1:T1,..,xn:Tn) {
+-- >   is_fsym(t) { (getSignature().getMapping_C().isInstanceOf($t)) }
+-- >   get_slot(x1,t) { getSignature().getMapping_f().get1($t) }
+-- >   ...
+-- >   get_slot(xn,t) { getSignature().getMapping_f().getn($t) }
+-- >   make (t1,..,tn) { (getSignature().getMapping_f().make($s1, $s2)) }
+-- > }
+compOp :: CtorId -> Gen Doc
+compOp c = do pfields <- map (pretty *** pretty) `fmap` askSt (fieldsOf c)
+              co <- askSt (codomainOf c)
+              let pfs = map fst pfields
+              return $ rOp (pretty co) (pretty c) pfields
+                           (vcat [isfsym, getters pfs, make pfs])
+  where mapping = text "getSignature().getMapping_" <> pretty c <> text "()"
+        isfsym  = text "is_fsym(t) {" <>  mapping <> text ".isInstanceOf($t) }"
+        make fs = text "make" <> gen fs <+> (sbraces . parens $ body)
+          where body = mapping <> text ".make" <> (gen $ map inline fs)
+                gen  = parens . hcat . punctuate comma
+        getters fs = vcat $ zipWith getter [0 :: Int ..] fs
+        getter i s = text "get_slot(" <> pretty s <> 
+                     text ",t) {" <> mapping <> text ".get" <> 
+                     text (show i) <> text "($t) }"
+
+-- | Given a variadic constructor @L(T*)@
+-- of codomain @Co@, generates
+-- %oplist Co L(T*) {
+--  is_fsym(l)       { getSignature().getMapping_L().isInstanceOf($l) }
+--  make_empty()     { getSignature().getMapping_L().makeEmpty() } 
+--  make_insert(o,l) { getSignature().getMapping_L().makeInsert($o,$l) }
+--  get_head(l)      { getSignature().getMapping_L().getHead($l) }
+--  get_tail(l)      { getSignature().getMapping_L().getTail($l) }
+--  is_empty(l)      { getSignature().getMapping_L().isEmpty($l) }
+--}
+compVOp :: CtorId -> Gen Doc
+compVOp c = do 
+  codom  <- askSt (codomainOf c)
+  dom  <- askSt (fieldOf c)
+  return $ text "%oplist" <+> pretty codom <+> pretty c <> 
+           parens (pretty dom <> text "*") <+> ibraces (vcat $ map text 
+             [" is_fsym(l)       { " ++ mapping ++ ".isInstanceOf($l) }",
+              " make_empty()     { " ++ mapping ++ ".makeEmpty() }",
+              " make_insert(o,l) { " ++ mapping ++ ".makeInsert($o,$l) }",
+              " get_head(l)      { " ++ mapping ++ ".getHead($l) }",
+              " get_tail(l)      { " ++ mapping ++ ".getTail($l) }",
+              " is_empty(l)      { " ++ mapping ++ ".isEmpty($l) }"])
+  where mapping = "getSignature().getMapping_" ++ show c ++ "()"
+
+
+-- | Given a list of constructors @cs@ and a list of var constructors
+-- @vcs@, generates the ISignature of new oo mappings.
+compISignature :: [CtorId] -> [CtorId] -> Gen FileHierarchy
+compISignature cs vcs = do 
+  methDecls  <- mapM compMDecl cs
+  vmethDecls <- mapM compMVDecl vcs
+  let code = rInterface public (text "ISignature") 
+                        (rBody (methDecls ++ vmethDecls))
+  return $ Class "ISignature" code 
+
+compMDecl :: CtorId -> Gen Doc
+compMDecl c = do 
+  cfields <- askSt (fieldsOf c)
+  s       <- askSt (codomainOf c)
+  cs      <- askSt (concreteTypeOf s) 
+  let arity = length cfields
+  classes <- mapM (prettyConcreteType . snd) cfields
+  let types = gen (pretty cs:classes) 
+  return $ text "tom.library.oomapping.Mapping" <> pretty arity <> 
+           types <> text " getMapping_" <> pretty c <> text "()"
+  where gen = angles . hcat . punctuate comma
+        prettyConcreteType s = do cs <- askSt (concreteTypeOf s)
+                                  return $ pretty cs
+
+compMVDecl :: CtorId -> Gen Doc
+compMVDecl c = do 
+  dom    <- askSt (fieldOf c)
+  codom  <- askSt (codomainOf c)
+  cdom   <- askSt (concreteTypeOf dom) 
+  ccodom <- askSt (concreteTypeOf codom) 
+  return $ text "tom.library.oomapping.ListMapping<" <> pretty ccodom <> 
+           text "," <> pretty cdom <> text ">" <+> text "getMapping_" <> 
+           pretty c <> text "()"
diff --git a/Gom/Parser.hs b/Gom/Parser.hs
new file mode 100644
--- /dev/null
+++ b/Gom/Parser.hs
@@ -0,0 +1,130 @@
+-------------------------------------------------------------------
+-- |
+-- Module      : Gom.Parser
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--
+-- Parser for gom modules.
+--------------------------------------------------------------------
+
+module Gom.Parser (parseModule) where
+
+import Text.Parsec
+import Text.Parsec.String(Parser)
+import Text.Parsec.Language
+import qualified Text.Parsec.Token as P
+import Control.Applicative((<$>),(<*),(*>),(<*>))
+
+import Gom.Sig
+import Control.Monad.Identity(Identity)
+import Data.List
+
+defs :: ParsecT String u Identity Char-> LanguageDef u
+defs start = javaStyle { 
+  P.reservedOpNames = ["=","|",":"],
+  P.reservedNames = ["module","abstract","syntax","imports","implemented by"],
+  P.identStart = start
+}
+
+lexer, ulexer :: P.TokenParser a
+lexer  = P.makeTokenParser $ defs letter
+ulexer = P.makeTokenParser $ defs upper
+
+white    :: Parser ()
+parens   :: Parser a -> Parser a
+angles   :: Parser a -> Parser a
+ident    :: Parser String
+uident   :: Parser String
+res      :: String -> Parser ()
+resOp    :: String -> Parser ()
+comma    :: Parser String
+
+white    = P.whiteSpace lexer
+parens   = P.parens     lexer
+angles   = P.angles     lexer
+ident    = P.identifier lexer
+uident   = P.identifier ulexer
+res      = P.reserved   lexer
+resOp    = P.reservedOp lexer
+comma    = P.comma      lexer
+
+-- sorts defined by the user start with a capital letter
+lhsSortidP :: Parser SortId
+lhsSortidP = makeSortId <$> uident 
+             <?> "sort name"
+
+-- ... but not necessarily the imported ones
+rhsSortidP :: Parser SortId
+rhsSortidP = makeSortId <$> ident 
+             <?> "sort name"
+
+-- The code of this function is convoluted because
+-- it reconstructs the string it parses instead of building
+-- a datastructure. They may be a better way to do it with parsec.
+classidP :: Parser ClassId
+classidP = uncurry makeClassId <$> classidP' <?> "class name"
+  where classidP' = do 
+          qname  <- intercalate "." <$> ident `sepBy1` resOp "." 
+          params <- option "" paramsP
+          return (qname,params)
+        paramsP  = do 
+          ps <- angles (classidP' `sepBy` comma)
+          return $ "<" ++ intercalate "," (map glue ps) ++ ">"
+          where glue = uncurry (++)
+
+fieldidP :: Parser FieldId
+fieldidP = makeFieldId <$> ident
+           <?> "field name"
+
+ctoridP :: Parser CtorId
+ctoridP = makeCtorId <$> ident
+          <?> "constructor name"
+
+sigP :: Parser Module
+sigP = Module <$> (res "module" *> ident)
+              <*> option [] (res "imports" *> rhsSortidP `sepBy` spaces)
+              <*  res "abstract" 
+              <*  res "syntax"
+              <*> sortP `sepBy` spaces
+              <*  eof
+              <?> "module definition"
+
+sortP ::  Parser SortDef
+sortP = do n  <- lhsSortidP
+           cn <- option Nothing $ Just <$> (res "implemented by" *> classidP)
+           resOp "=" 
+           c <- ctorP `sepBy` resOp "|"
+           return $ SortDef n cn c
+           <?> "sort definition"
+
+ctorP :: Parser Ctor
+ctorP = try variadicP <|> simpleP 
+        <?> "constructor declaration"
+
+variadicP :: Parser Ctor
+variadicP = Variadic <$> ctoridP <*> parens (rhsSortidP <* resOp "*")
+            <?> "variadic constructor"
+
+simpleP :: Parser Ctor
+simpleP = Simple <$> ctoridP <*> parens (fieldP `sepBy` comma)
+          <?> "non-variadic constructor"
+
+fieldP :: Parser (FieldId, SortId)
+fieldP = do x <- fieldidP
+            resOp ":"
+            ty <- rhsSortidP
+            return (x,ty)
+         <?> "field declaration"
+
+run :: Parser a -> String -> Either ParseError a
+run p = parse (white *> p) ""
+
+-- | Parses a gom module.
+parseModule :: String -> Either ParseError Module
+parseModule = run sigP
diff --git a/Gom/Pretty.hs b/Gom/Pretty.hs
new file mode 100644
--- /dev/null
+++ b/Gom/Pretty.hs
@@ -0,0 +1,51 @@
+-------------------------------------------------------------------
+-- |
+-- Module      : Gom.Pretty
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--
+-- This module exports nothing but defines instances of
+-- 'Text.PrettyPrint.Leijen.Pretty' for 'Ctor', 'SortDef' and 'Module'.
+--------------------------------------------------------------------
+
+
+
+module Gom.Pretty () where
+
+import Gom.Sig
+import Text.PrettyPrint.Leijen
+
+lb ::  Doc
+lb = linebreak
+
+instance Pretty Ctor where
+  pretty (Simple n fs) = 
+     text (show n) <> parens (hsep $ punctuate (char ',') prettyfs)
+     where prettyfs = map (\(x,t) -> text (show x) <> 
+                      char ':' <> text (show t)) fs
+  pretty (Variadic n t) = text (show n) <> parens (text (show t) <> char '*')
+
+instance Pretty SortDef where
+  pretty (SortDef n mcn cs) = 
+    text (show n) <> prettycn mcn <> align (char '=' <+> prettycs)
+    where prettycs = fillSep $ withPipes (map pretty cs)  
+          prettycn Nothing   = empty
+          prettycn (Just cn) = space <> text "implemented by" <+> 
+                               pretty cn <> space
+          withPipes (x:y:xs) = x:withPipes ((char '|' <+> y):xs)
+          withPipes l        = l
+
+instance Pretty Module where
+  pretty (Module n i d) = (text "module" <+> text n) 
+                          <$$> (text "imports" <+> hsep (map (text . show) i))
+                          <$$> text "abstract syntax" <> lb
+                          <$$> vcat (punctuate lb (map pretty d))
+
+instance Show Module where
+  show = show . pretty
diff --git a/Gom/Random.hs b/Gom/Random.hs
new file mode 100644
--- /dev/null
+++ b/Gom/Random.hs
@@ -0,0 +1,87 @@
+------------------------------------------------------------------
+-- |
+-- Module      : Gom.Random
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--
+-- Instances of 'Test.QuickCheck.Arbitrary' for 'Gom.Sig' and other
+-- generators.
+--------------------------------------------------------------------
+
+module Gom.Random () where
+
+import Gom.Sig
+import Test.QuickCheck
+
+genId :: Gen String
+genId = resize 10 . listOf1 $ oneof [choose ('a','z'), choose ('A','Z')]
+
+genUId :: Gen String
+genUId = resize 10 $ do c  <- choose ('A','Z') ; cs <- genId ; return $ c:cs
+
+builtins :: [SortId]
+builtins = map makeSortId 
+  ["boolean","int","char","double","float","long","String"]
+
+instance Arbitrary SortId where arbitrary = makeSortId `fmap` genUId
+instance Arbitrary CtorId where arbitrary = makeCtorId `fmap` genId
+instance Arbitrary FieldId where arbitrary = makeFieldId `fmap` genId
+
+allDiff :: (Eq t) => [t] -> Bool
+allDiff []     = True
+allDiff (x:xs) = x `notElem` xs && allDiff xs
+
+instance Arbitrary Module where
+  arbitrary = do
+    modul <- genId
+    sorts <- arbitrary `suchThat` allDiff
+    -- we need at least one constructor per sort
+    cidss <- resize 10 $ 
+      listOf (listOf1 arbitrary) `suchThat` (allDiff . concat)
+    let mix = zip sorts cidss
+    defs  <- mapM (genSortDef (map fst mix)) mix
+    return $ Module modul builtins defs
+  shrink (Module m i d) = do
+    d' <- shrink d
+    return $ Module m i d'
+
+genTypedFields :: [SortId] -> Gen [(FieldId,SortId)]
+genTypedFields sorts = do
+  flds <- listOf1 arbitrary `suchThat` allDiff
+  doms <- listOf1 (elements $ sorts ++ builtins)
+  return $ zip flds doms
+
+instance Arbitrary SortDef where
+  shrink (SortDef s c l) = do
+    l' <- shrink l
+    return $ SortDef s c l' 
+
+genSortDef :: [SortId] -> (SortId, [CtorId]) -> Gen SortDef
+genSortDef sorts (sid,cids) = do
+  flds   <- genTypedFields sorts
+  ctrs   <- mapM (genCtor sorts flds) cids
+  return $ SortDef sid (Just $ makeClassId "Object" "") ctrs
+
+instance Arbitrary Ctor where
+  shrink (Simple c l) = do l' <- shrink l ; return $ Simple c l' 
+  shrink x            = return x 
+
+genCtor :: [SortId] -> [(FieldId, SortId)] -> CtorId -> Gen Ctor
+genCtor sorts flds cname =
+  oneof [genSCtor flds cname, genVCtor sorts cname]
+
+genSCtor :: [(FieldId, SortId)] -> CtorId -> Gen Ctor
+genSCtor flds cname = do
+  fis <- listOf (elements flds) `suchThat` allDiff
+  return $ Simple cname fis
+
+genVCtor :: [SortId] -> CtorId -> Gen Ctor
+genVCtor sorts cname = do
+  sort <- elements sorts
+  return $ Variadic cname sort
diff --git a/Gom/Sig.hs b/Gom/Sig.hs
new file mode 100644
--- /dev/null
+++ b/Gom/Sig.hs
@@ -0,0 +1,192 @@
+------------------------------------------------------------------
+-- |
+-- Module      : Gom.Sig
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--
+-- This module exposes 'Module', the datatype representing gom modules
+-- after parsing, and several helper functions.
+--------------------------------------------------------------------
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+module Gom.Sig (
+  SortId(),
+  ClassId(),
+  FieldId(),
+  CtorId(),
+  Module(..),
+  SortDef(..),
+  Ctor(..),
+  GomId(..),
+  -- * Building identifiers
+  makeSortId,
+  makeClassId,
+  makeFieldId,
+  makeCtorId,
+  prependEmpty,
+  prependCons,
+  prependHead,
+  prependTail,
+  lowerId,
+  -- * Recovering information in a module
+  definedSorts,
+  exportedSorts,
+  constructorNames,
+  vconstructorNames,
+  simpleFieldsNames,
+  simpleFieldsOf,
+  getClassName
+) where
+
+import Data.Char(toLower)
+import Text.PrettyPrint.Leijen
+
+-- | Sort name (e.g. @Expr@) identifier.
+newtype SortId  = SortId String 
+  deriving (Ord,Eq)
+-- | Java Class name (e.g. @p.c<...>@) identifier.
+data ClassId = ClassId String String 
+  deriving (Ord,Eq)
+-- | Field name (e.g. @x@) identifier.
+newtype FieldId = FieldId String 
+  deriving (Ord,Eq)
+-- | Constructor name (e.g. @f@) identifier.
+newtype CtorId  = CtorId String 
+  deriving (Ord,Eq)
+
+instance Show SortId  where show (SortId s)      = s
+instance Show ClassId where show (ClassId s1 s2) = s1 ++ s2
+instance Show FieldId where show (FieldId s)     = s
+instance Show CtorId  where show (CtorId s)      = s
+
+instance Pretty SortId  where pretty = text . show
+instance Pretty ClassId where pretty = text . show
+instance Pretty FieldId where pretty = text . show
+instance Pretty CtorId  where pretty = text . show
+
+class GomId a where
+  idStr :: a -> String
+
+instance GomId SortId  where idStr (SortId x)  = x
+instance GomId FieldId where idStr (FieldId x) = x
+instance GomId CtorId  where idStr (CtorId x)  = x
+
+-- | Represents a gom module.
+data Module = Module {
+  moduleName :: String,    -- ^ module name
+  imports    :: [SortId],  -- ^ list of imported sorts
+  sortDefs   :: [SortDef]  -- ^ sort definitions
+} deriving (Eq)
+
+-- | Represents a sort definition, 
+-- e.g. @List = nil() | cons(x:int, xs:List)@.
+data SortDef = SortDef {
+  sortName :: SortId,      -- ^ sort name (e.g. @List@)
+  concreteSortName :: Maybe ClassId,      -- ^ sort name (e.g. @List@)
+  ctors    :: [Ctor]       -- ^ constructors
+                           -- (e.g. @nil()@ and @cons(x:int, xs:List)@)
+} deriving (Eq)
+
+-- | Represents a constructor definition.
+data Ctor = 
+    -- | non-variadic constructor, e.g. @f(x:int,y:T)@
+    Simple { 
+      ctorName :: CtorId,          -- ^ constructor name (e.g. @f@)
+      fields :: [(FieldId,SortId)] 
+        -- ^ constructor fields (e.g. @x:int@ and @y:T@)
+    }
+    -- | variadic constructor, e.g. @plus(Expr*)@
+  | Variadic { 
+      ctorName :: CtorId, -- ^ constructor name (e.g. @plus@)
+      field :: SortId     -- ^ sort of the only field (e.g. @Expr@)
+    }
+ deriving (Eq)
+
+makeSortId :: String -> SortId
+makeSortId = SortId
+
+-- | @makeClassId c p@ builds the @c\<p\>@ identifier.
+-- (e.g. @makeClassId \"HashMap\" \"Int,Float\"@)
+makeClassId :: String -> String -> ClassId
+makeClassId = ClassId
+
+makeFieldId :: String -> FieldId
+makeFieldId = FieldId
+
+makeCtorId :: String -> CtorId
+makeCtorId = CtorId
+
+-- | Turns @C@ into @EmptyC@.
+prependEmpty :: CtorId -> CtorId
+prependEmpty (CtorId s) = CtorId ("Empty" ++ s)
+
+-- | Turns @C@ into @ConsC@.
+prependCons :: CtorId -> CtorId
+prependCons (CtorId s) = CtorId ("Cons" ++ s)
+
+-- | Turns @C@ into @HeadC@.
+prependHead :: CtorId -> FieldId
+prependHead (CtorId s) = FieldId ("Head" ++ s)
+
+-- | Turns @C@ into @TailC@.
+prependTail :: CtorId -> FieldId
+prependTail (CtorId s) = FieldId ("Tail" ++ s)
+
+-- | Turns the id into lowercase
+lowerId :: SortId -> SortId
+lowerId (SortId x) = SortId (map toLower x)
+
+
+getClassName :: ClassId -> String
+getClassName (ClassId qualifiedname _) = qualifiedname
+
+-- | @simpleFields def@ is the list of fields of non-variadic 
+-- constructors of @def@, along with their sorts.
+simpleFieldsOf :: SortDef -> [(FieldId, SortId)]
+simpleFieldsOf def = ctors def >>= getfields
+  where getfields (Simple _ f) = f
+        getfields _            = []
+
+-- | @vconstructorNames m@ returns the list of all the variadic constructors
+-- declared in @m@.
+--
+-- As an example, for the following signature
+--
+-- > T = f(A*) | g(x:B)
+-- > U = h(C*)
+--
+-- it returns @A@ and @C@.
+vconstructorNames :: Module -> [CtorId]
+vconstructorNames m = sortDefs m >>= ctors >>= getvtors
+  where getvtors (Variadic f _) = [f]
+        getvtors _              = []
+
+-- | @exportedSorts m@ returns the list of sort names exported by @m@,
+-- i.e. the sorts that appear in the left-hand sides of definitions
+-- and the imported sorts.
+exportedSorts :: Module -> [SortId]
+exportedSorts sig = imports sig ++ definedSorts sig
+
+-- | @definedSorts m@ returns the list of sort names defined by @m@,
+-- i.e. the sorts that appear in the left-hand sides of definitions.
+definedSorts :: Module -> [SortId]
+definedSorts = map sortName . sortDefs
+
+-- | @constructorNames m@ returns the list of all the constructors declared
+-- in @m@ (variadic or not).
+constructorNames :: Module -> [CtorId]
+constructorNames = map ctorName . concatMap ctors . sortDefs
+
+-- | All declared simple fields, duplicates removed
+simpleFieldsNames :: Module -> [FieldId]
+simpleFieldsNames m = sortDefs m >>= ctors >>= getfields
+  where getfields (Simple _ fs) = map fst fs
+        getfields _             = []
+
diff --git a/Gom/SymbolTable.hs b/Gom/SymbolTable.hs
new file mode 100644
--- /dev/null
+++ b/Gom/SymbolTable.hs
@@ -0,0 +1,345 @@
+------------------------------------------------------------------
+-- |
+-- Module      : Gom.SymbolTable
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--
+-- An efficient representation of a gom module.
+--------------------------------------------------------------------
+
+module Gom.SymbolTable (
+  SymbolTable (),
+  -- * Constructing tables
+  emptySt, ast2st,
+  -- * Consulting tables
+  definedSortsIds, simpleConstructorsIds, variadicConstructorsIds,
+  modName, importedSorts, concreteTypeOf, sCtorsOf, vCtorsOf, fieldsOf, 
+  fieldOf, codomainOf, isGenerated, importsString, importsChar,
+  -- * Modifying tables
+  -- ** Modifying mappings
+  -- | These functions allow to change the constructor names (resp. fields)
+  -- associated to a sort (resp. constructor) in a 'SymbolTable'.
+  insertSctors, insertVctors, insertSfields, insertVfield, insertJavaType,
+  addToSctors, addToVctors,
+  -- ** Adding whole definitions
+  -- | These functions perform higher-level modifications of the table than
+  -- 'insertSctors', 'addToSctors', etc.
+  -- They take AST bits of "Gom.Sig" as arguments.
+  addCtor,
+  -- ** Table completion
+  completeVariadics,
+#if TEST
+  -- * Tests
+  testSuite
+#endif
+) where
+
+import Gom.Sig
+import Control.Monad.State
+import qualified Data.Map as M
+import Data.Either(partitionEithers)
+import Data.List(foldl',nub)
+import Gom.CodeGen.Common.Builtins
+
+#if TEST
+import Gom.Random ()
+import Test.Framework (Test, testGroup)
+import Test.Framework.Providers.QuickCheck2 (testProperty)
+import qualified Data.Set as S
+import qualified Data.List as L
+import Gom.Pretty ()
+import Data.Maybe(mapMaybe)
+import Data.List(sort)
+#endif
+
+-- | A private datatype implemented by maps from sorts to constructors, from
+-- constructors to codomains, etc.
+data SymbolTable = 
+  SymbolTable {
+    -- | name of the module encoded by the symbol table
+    mName :: String,
+    -- | sorts imported by the module
+    imported :: [SortId],
+    -- | concrete type associated to a sort
+    javatype :: M.Map SortId ClassId,
+    -- | non-variadic constructors associated to a sort
+    sctors :: M.Map SortId [CtorId],
+    -- | variadic constructors associated to a sort
+    vctors :: M.Map SortId [CtorId],
+    -- | fields associated to a non-variadic constructor
+    sfields :: M.Map CtorId [(FieldId,SortId)],
+    -- | sort of the unique field of a variadic constructor
+    vfield :: M.Map CtorId SortId,
+    -- | codomain of the constructor (redundant information)
+    codom :: M.Map CtorId SortId,
+    -- | maps generated constructors to original ones
+    baseCtor :: M.Map CtorId CtorId
+  } deriving (Show)
+
+-- | Name of the module encoded by the symbol table.
+modName :: SymbolTable -> String
+modName = mName
+
+-- | Sorts imported by the module.
+importedSorts :: SymbolTable -> [SortId]
+importedSorts = imported
+
+-- | Concrete Java Type associated to a sort.
+concreteTypeOf :: SortId -> SymbolTable -> ClassId
+concreteTypeOf s st 
+  | isBuiltin s = makeClassId (show $ qualifiedBuiltin s) ""
+  | otherwise = 
+    case s `M.lookup` javatype st of
+      Just c  -> c
+      Nothing -> error $ "sort " ++ show s ++ " has no concrete type" 
+
+-- | Non-variadic constructors associated to a sort.
+sCtorsOf :: SortId -> SymbolTable -> [CtorId]
+sCtorsOf s st = 
+  case s `M.lookup` sctors st of
+    Just l  -> l
+    Nothing -> error $ "sort " ++ show s ++ " not declared"
+
+-- | Variadic constructors associated to a sort.
+vCtorsOf :: SortId -> SymbolTable -> [CtorId]
+vCtorsOf s st = 
+  case s `M.lookup` vctors st of
+    Just l  -> l
+    Nothing -> error $ "sort " ++ show s ++ " not declared" 
+
+-- | Fields associated to a non-variadic constructor.
+fieldsOf :: CtorId -> SymbolTable -> [(FieldId,SortId)]
+fieldsOf c st = 
+  case c `M.lookup` sfields st of
+    Just l  -> l
+    Nothing -> error $ "non-variadic constructor " ++ 
+                       show c ++ " not declared" 
+
+-- | Sort of the unique field of a variadic constructor.
+fieldOf :: CtorId -> SymbolTable -> SortId
+fieldOf c st =
+  case c `M.lookup` vfield st of
+    Just s  -> s
+    Nothing -> error $ "variadic constructor " ++ 
+                       show c ++ " not declared" 
+
+-- | Codomain of the constructor.
+codomainOf :: CtorId -> SymbolTable -> SortId
+codomainOf c st =
+  case c `M.lookup` codom st of
+    Just s  -> s
+    Nothing -> error $ "constructor " ++ show c ++ " not declared" 
+
+-- | If the field has been generated (e.g. @ConsC@) returns @'Just' C@,
+-- @'Nothing'@ otherwise.
+isGenerated :: CtorId -> SymbolTable -> Maybe CtorId
+isGenerated c = M.lookup c . baseCtor
+
+-- | Returns @True@ if @String@ is imported.
+importsString :: SymbolTable -> Bool
+importsString st = "String" `elem` map idStr (importedSorts st)
+
+-- | Returns @True@ if @char@ is imported.
+importsChar :: SymbolTable -> Bool
+importsChar st = "char" `elem` map idStr (importedSorts st)
+
+-- | @emptySt m is@ is an empty symbol table (no sorts nor constructors) that
+-- encodes a module of name @m@ which imports sorts @is@.
+emptySt :: String -> [SortId] -> SymbolTable
+emptySt m i = SymbolTable m i M.empty M.empty M.empty M.empty 
+                              M.empty M.empty M.empty
+
+-- | The ids of the sorts present in st.
+definedSortsIds :: SymbolTable -> [SortId]
+definedSortsIds st = nub $ M.keys (sctors st) ++ M.keys (vctors st)
+
+-- | The ids of the non-variadic constructors present in st.
+simpleConstructorsIds :: SymbolTable -> [CtorId]
+simpleConstructorsIds = concat  . M.elems . sctors
+
+-- | The ids of the variadic constructors present in st.
+variadicConstructorsIds :: SymbolTable -> [CtorId]
+variadicConstructorsIds = concat . M.elems . vctors
+
+-- | private : breaks redundancy consistency, updates only @codom@
+updateCodom :: CtorId -> SortId -> SymbolTable -> SymbolTable
+updateCodom c s st = st { codom = M.insert c s (codom st) }
+
+-- | @insertSctors s cs st@ inserts, or replaces, the mapping @(s,cs)@ in 
+-- @'sctors' st@.
+insertSctors :: SortId -> [CtorId] -> SymbolTable -> SymbolTable
+insertSctors s cs st = update $ st { sctors = M.insert s cs (sctors st) }
+  where update mst = foldl' (\t c -> updateCodom c s t) mst cs
+
+-- | @insertVctors s cs st@ inserts, or replaces, the mapping @(s,cs)@ in 
+-- @'vctors' st@.
+insertVctors :: SortId -> [CtorId] -> SymbolTable -> SymbolTable
+insertVctors s cs st = update $ st { vctors = M.insert s cs (vctors st) }
+  where update mst = foldl' (\t c -> updateCodom c s t) mst cs
+
+-- | @insertSfields c fs st@ inserts, or replaces, the mapping @(c,fs)@ in 
+-- @'sfields' st@.
+insertSfields :: CtorId -> [(FieldId,SortId)] -> SymbolTable -> SymbolTable
+insertSfields c fs st = st { sfields = M.insert c fs (sfields st) }
+
+-- | @insertVfield c s st@ inserts, or replaces, the mapping @(c,s)@ in 
+-- @'vfield' st@.
+insertVfield :: CtorId -> SortId -> SymbolTable -> SymbolTable
+insertVfield c s st = st { vfield = M.insert c s (vfield st) }
+
+-- | @insertJavaType s cs st@ inserts, or replaces, the mapping @(s,cs)@ in 
+-- @'javatype' st@.
+insertJavaType :: SortId -> Maybe ClassId -> SymbolTable -> SymbolTable
+insertJavaType s (Just cs) st = st { javatype = M.insert s cs (javatype st) }
+insertJavaType _ Nothing st = st
+
+-- | @addToSctors s cs st@ appends @cs@ to the non-variadic constructors
+-- already associated to @s@ in @st@. If there are no non-variadic constructors
+-- associated to @s@, an entry is created.
+addToSctors :: SortId -> [CtorId] -> SymbolTable -> SymbolTable
+addToSctors s cs st = update $ st { 
+    sctors = M.alter (Just . maybe cs (++cs)) s (sctors st) 
+  } where update mst = foldl' (\t c -> updateCodom c s t) mst cs
+
+-- | @addToVctors s cs st@ appends @cs@ to the variadic constructors already
+-- associated to @s@ in @st@.  If there are no variadic constructors associated
+-- to @s@, an entry is created.
+addToVctors :: SortId -> [CtorId] -> SymbolTable -> SymbolTable
+addToVctors s cs st = update $ st { 
+    vctors = M.alter (Just . maybe cs (++cs)) s (vctors st) 
+  } where update mst = foldl' (\t c -> updateCodom c s t) mst cs
+
+-- | Converts a 'Module' into a 'SymbolTable', provided no
+-- error has been detected during the checking phase.
+ast2st :: Module -> SymbolTable
+ast2st (Module m i defs) = execState (conv defs) (emptySt m i)
+
+  where conv :: [SortDef] -> State SymbolTable ()
+        conv = mapM_ convdef 
+
+        convdef :: SortDef -> State SymbolTable ()
+        convdef (SortDef n cn cs) = do
+           modify $ insertJavaType n cn
+           (ss,vs) <- partitionEithers `fmap` mapM convctor cs
+           modify $ insertSctors n ss
+           modify $ insertVctors n vs
+           
+
+        convctor :: Ctor -> State SymbolTable (Either CtorId CtorId)
+        convctor (Simple n fis) = do modify $ insertSfields n fis
+                                     return (Left n)
+        convctor (Variadic n s) = do modify $ insertVfield n s
+                                     return (Right n)
+
+-- | @addCtor s c st@ updates the mappings of @st@ in order
+-- to reflect the addition of @c@ to the constructors already
+-- associated to @s@.
+addCtor :: SortId -> Ctor -> SymbolTable -> SymbolTable
+addCtor s (Simple n f)   = insertSfields n f . addToSctors s [n]
+addCtor s (Variadic n t) = insertVfield n t . addToVctors s [n]
+
+-- | Same as @addCtor@ but for several constructors.
+addCtors :: SortId -> [Ctor] -> SymbolTable -> SymbolTable
+addCtors s cs st = foldl' (flip $ addCtor s) st cs
+
+-- | @tonil c@ constructs a @Nilc@ constructor.
+toNil :: CtorId -> Ctor
+toNil ci = Simple (prependEmpty ci) []
+
+-- | @tocons c co dom@ constructs a @Consc@ constructor of domain @dom@ and
+-- codomain @c@.
+toCons :: CtorId -> SortId -> SortId -> Ctor
+toCons ci co dom = 
+  Simple (prependCons ci) [(prependHead ci,dom),(prependTail ci,co)]
+
+-- | @insertGeneratedCtor gc bc st@ inserts mapping
+-- @(gc,bc)@  from generated constructor
+-- to the orginal one (e.g. @ConsC@ and @C@ in @st@.
+insertGeneratedCtor :: CtorId -> CtorId -> SymbolTable -> SymbolTable
+insertGeneratedCtor gc bc st = st { baseCtor = M.insert gc bc (baseCtor st) }
+
+-- | @insertGeneratedCtors [gc1,..,gcn] bc st@ adds mappings
+-- @(gc1,bc)@ .. @(gcn,bc)@ from generated constructors
+-- to the orginal ones (e.g. @ConsC@ and @EmptyC@ to @C@ in @st@.
+insertGeneratedCtors :: [CtorId] -> CtorId -> SymbolTable -> SymbolTable
+insertGeneratedCtors gcs bc st = 
+  foldl' (\st' gc -> insertGeneratedCtor gc bc st') st gcs
+
+-- | For each variadic constructor @V(T*)@ of codomain @S@,
+-- adds two constuctors @EmptyV()@ and @ConsV(HeadV:T, TailV:S)@
+-- to @S@.
+completeVariadics :: SymbolTable -> SymbolTable
+completeVariadics st = foldl' add st res
+  where res = map conv vcs
+        vcs = variadicConstructorsIds st
+        conv ci = let co  = codomainOf ci st
+                      dom = fieldOf ci st
+                  in (co, ci, [toNil ci, toCons ci co dom])
+        add st' (co,ci,l) = 
+          (insertGeneratedCtors (map ctorName l) ci . addCtors co l) st'
+
+#if TEST
+
+-- | tests for list inclusion modulo AC
+subset ::  (Ord a) => [a] -> [a] -> Bool
+subset x y = S.fromList x `S.isSubsetOf` S.fromList y
+
+-- | checks that redundant information about constructor domains is consistent
+-- with the rest of the table
+propCodomConsistent :: SymbolTable -> Bool
+propCodomConsistent st = sort assocs == sort (M.toList $ codom st)
+  where assocs = toAssoc (sctors st) ++ toAssoc (vctors st)
+        toAssoc amap = [(c,s) | (s,l) <- M.toList amap, c <- l]
+
+-- | checks that the base constructors actually exist
+propBaseConsistent :: SymbolTable -> Bool
+propBaseConsistent st = basectors `subset` variadics
+  where basectors  = M.elems (baseCtor st)
+        variadics  = concat . M.elems . vctors $ st
+
+-- | checks that all constructor domains exist
+propDomainsConsistent :: SymbolTable -> Bool
+propDomainsConsistent st = doms `subset` allSorts
+  where doms = sdoms ++ vdoms
+        sdoms = map snd . concat . M.elems $ sfields st
+        vdoms = M.elems $ vfield st
+        allSorts = M.keys (sctors st) ++ 
+                   M.keys (vctors st) ++ 
+                   imported st
+
+-- | checks that all constructors have different names
+propCtorsAllDiff :: SymbolTable -> Bool
+propCtorsAllDiff st = allDiff allCtors
+  where allCtors  = concat $ M.elems (sctors st) ++ M.elems (vctors st)
+        allDiff l = l == nub l
+
+-- | helper function to determine if some relation is a function
+isFun :: (Eq a, Eq b) => [(a, b)] -> Bool
+isFun []         = True
+isFun ((x,y):as) = let (xs,nxs) = L.partition ((== x) . fst) as
+                   in all ((== y) . snd) xs && isFun nxs
+
+-- | checks that all fields appearing in the constructor of a same sort
+-- have same sort if they have same name
+propFieldsSortConsistent :: SymbolTable -> Bool
+propFieldsSortConsistent st =  all sortOk $ M.elems (sctors st)
+  where sortOk = isFun . concat . mapMaybe (`M.lookup` sfields st) 
+
+-- | test suite for the module
+testSuite :: Test
+testSuite = testGroup "symbol table consistency after completion" 
+  [testProperty "codomain consistency"   $ go propCodomConsistent
+  ,testProperty "base ctors consistency" $ go propBaseConsistent
+  ,testProperty "domains consistency"    $ go propDomainsConsistent
+  ,testProperty "no ctor duplicates"     $ go propCtorsAllDiff
+  ,testProperty "same fields same sorts" $ go propFieldsSortConsistent]
+
+  where go f = f . ast2st
+
+#endif
diff --git a/Gom/UnitTests.hs b/Gom/UnitTests.hs
new file mode 100644
--- /dev/null
+++ b/Gom/UnitTests.hs
@@ -0,0 +1,187 @@
+------------------------------------------------------------------
+-- |
+-- Module      : Gom.UnitTests
+-- Copyright   : (c) Paul Brauner 2009
+--               (c) Emilie Balland 2009
+--               (c) INRIA 2009
+-- Licence     : GPL (see COPYING)
+--
+-- Maintainer  : paul.brauner@inria.fr
+-- Stability   : provisional
+-- Portability : non-portable (requires generalized newtype deriving)
+--
+-- Run all unit tests
+--------------------------------------------------------------------
+
+module Gom.UnitTests (testSuite) where
+
+import Gom.Pretty ()
+import Gom.Random ()
+import Gom.Sig
+import Gom.Parser
+import Gom.Checker
+
+-- imported test suites
+import qualified Gom.SymbolTable
+
+-- for t*.gom testing
+import Test.Framework (Test,testGroup)
+import Test.Framework.Providers.QuickCheck2 (testProperty)
+import Test.Framework.Providers.HUnit (testCase)
+import Test.HUnit.Base((@?=))
+import System.FilePath((</>))
+
+-- generated by cabal
+import Paths_hgom (getDataFileName)
+
+-- for generated parser tesing
+import System.Process(rawSystem)
+import Data.Char(toLower)
+import System.Directory
+import Test.QuickCheck
+import Test.QuickCheck.Monadic
+import System.Exit
+
+-- for generated java testing
+import System.FilePath.Glob
+import Data.List(intercalate)
+import Control.Monad(liftM2)
+import Data.Maybe(isNothing)
+import System.Process(readProcessWithExitCode)
+
+-- | models at which step of the chain a module failed
+data FailsDuring = Parsing | Checking | Never deriving (Show,Eq)
+
+-- | checks how far in the chain a module gets without 
+-- raising a failure of some sort
+failsDuring :: String -> FailsDuring
+failsDuring s = 
+  case parseModule s of
+    Left  _ -> Parsing
+    Right m -> case checkEverything m of
+      Nothing -> Never
+      Just _  -> Checking
+
+-- | run failsDuring on some relative filePath
+fileFailsDuring :: FilePath -> IO FailsDuring
+fileFailsDuring f = do af <- getDataFileName f
+                       failsDuring `fmap` readFile af
+
+-- | regression suite
+regressionSuite :: Test
+regressionSuite = testGroup "regression tests" $
+  concat [map (cook Never   ) (files 1 1 6),
+          map (cook Checking) (files 2 0 9), 
+          map (cook Parsing ) (files 3 1 7)]
+  where files :: Int -> Int -> Int -> [FilePath]
+        files n l h = map fname [l..h]
+          where fname i = "test" </> "data" </> 
+                          "t" ++ show n ++ 
+                          "_" ++ show i ++ ".gom"
+        cook f s = testCase (msg s f) (test f s)
+        test f s = fileFailsDuring s >>= (@?= f)
+        msg s Never    = s ++ " is valid"
+        msg s Parsing  = s ++ " fails parsing"
+        msg s Checking = s ++ " fails checking"
+        
+
+-- | checks that @parse . pretty = id@
+propParsePretty :: Module -> Bool
+propParsePretty m = 
+  case parseModule (show m) of
+    Left  _  -> False
+    Right m' -> m == m'
+
+getTempDir :: IO FilePath
+getTempDir = getTemporaryDirectory >>= getTemp 0
+  where getTemp :: Integer -> FilePath -> IO FilePath
+        getTemp n tmp = do
+          b <- doesDirectoryExist htmp
+          if b then getTemp (n+1) tmp
+               else do createDirectory htmp
+                       return htmp
+          where htmp = tmp </> "hgom-tmp" ++ show n
+    
+
+-- | @doInTempDir a@ creates a directory, change working directory 
+-- to it, perform @a@ and comes back to original directory
+doInTempDir :: IO Bool -> IO Bool
+doInTempDir a = do
+  tmp <- getTempDir
+  cur <- getCurrentDirectory
+  setCurrentDirectory tmp
+  r <- a
+  setCurrentDirectory cur
+  if r then removeDirectoryRecursive tmp
+       else putStrLn $ "guilty files kept in " ++ tmp
+  return r
+
+-- | True iff the module passes the check phase
+checks :: Module -> Bool
+checks = isNothing . checkEverything
+
+-- | test that the generated parser is correct w.r.t. 
+-- the generated pretty printer (@fromString(x.toString()) == x@)
+propGenParsePretty :: Property
+propGenParsePretty = monadicIO $ do
+  sig <- pick (arbitrary `suchThat` liftM2 (&&) hasSort checks)
+  case sig of
+    Module m _ (SortDef s _ _:_) ->
+      let pack = map toLower m 
+      in assert =<< (run . doInTempDir $ do 
+        writeFile "Test.gom" $ show sig
+        _ <- rawSystem "hgom" ["-r","Test.gom"]
+        writeFile "Test.java" $ template pack (show s)
+        cp <- getDataFileName $ "test" </> "data" </> "tom-runtime-full.jar:"
+        (st,_,_) <- readProcessWithExitCode "javac" ["-cp",cp,"Test.java"] ""
+        let res = (st == ExitSuccess)
+        return res)
+    _ -> error "never happens"
+
+  where hasSort = not . null . sortDefs
+        template pack s = unlines
+          ["import " ++ pack ++ ".types.*;",
+           "public class Test {",
+           "  public static void main(String[] args) {",
+           "    for(int i=0; i<10; i++) {",
+           "      " ++ s ++ " t = " ++ s ++ ".makeRandom(i);",
+           "      if (!" ++ s ++ ".fromString(t.toString()).equals(t))",
+           "        System.exit(1);",
+           "    }",
+           "  }",
+           "}"]
+
+-- | @testChecker opts@ generates a random module that passes the checker
+-- phase, and return True iff javac successes on the generated files
+testChecker :: [String] -> Property
+testChecker opts = monadicIO $ do
+  sig <- pick (arbitrary `suchThat` checks)
+  case sig of 
+    Module m _ _ ->
+      let pack = map toLower m
+      in assert =<< (run . doInTempDir $ do
+        writeFile "Test.gom" $ show sig
+        _ <- rawSystem "hgom" ("Test.gom":opts)
+        jfs <- globDir1 (compile $ "**" </> "*.java") pack
+        cp <- getDataFileName $ "test" </> "data" </> "tom-runtime-full.jar:"
+        (st,_,_) <- readProcessWithExitCode "javac" (["-cp",cp]++jfs) ""
+        let res = (st == ExitSuccess)
+        return res)
+
+-- | cross modules quickcheck tests
+crossModuleSuite :: Test
+crossModuleSuite = testGroup "cross module properties" 
+  [testProperty "parse . pretty = id" propParsePretty,
+   check flags1, check flags2, check flags3, 
+   testProperty "generated parse . generated pretty = id" propGenParsePretty]
+  where check fs = testProperty (mes fs) (testChecker fs)
+        flags1 = ["-r","-d","-s","-h","-c","same"]
+        flags2 = ["--noSharing"]
+        flags3 = ["-j"]
+        mes fs = "check ok => compilable java (" ++ intercalate " " fs ++ ")"
+
+-- | all tests
+testSuite :: [Test]
+testSuite = [regressionSuite,
+             Gom.SymbolTable.testSuite,
+             crossModuleSuite]
diff --git a/README.markdown b/README.markdown
new file mode 100644
--- /dev/null
+++ b/README.markdown
@@ -0,0 +1,119 @@
+# HGom #
+
+An haskell clone of the original [java Gom](http://tom.loria.fr) code
+generator.
+
+## Compilation ##
+
+To compile hgom, install 
+[cabal-install](http://hackage.haskell.org/trac/hackage/wiki/CabalInstall)
+and type the following.
+
+    cabal configure
+    cabal build
+
+The `hgom` binary is generated in `dist/build/hgom`.
+
+## Installation ##
+
+    cabal install
+
+## Generate developer documentation ##
+
+By default, cabal generates no documentation since only the executable is
+exported. Developers still can generate the modules' documentation as follows.
+
+    cabal haddock --executables \
+    --html-location='http://hackage.haskell.org/packages/archive/$pkg/latest/doc/html' \
+    --hyperlink-source 
+
+Only exported symbols are documented. Add `--internal` for unexported symbols
+documentation.
+
+The documentation index is then `dist/doc/html/hgom/hgom/index.html`.
+
+## Running hgom ##
+
+Run `hgom --help` to get some basic help. 
+You can test the behaviour of `hgom` by running it as follows. Some examples
+are valid files, other ones demonstrate `hgom` error messages.
+
+    hgom examples/simple.gom
+    hgom examples/big.gom
+    hgom examples/many_errors.gom
+    ...
+
+## Test ##
+
+The test suite is compiled only if the `test` flag is
+set. For instance, run
+
+    cabal configure -ftest
+    cabal build
+    ./dist/build/hgom/hgom --test "-a n"
+
+or
+
+    cabal install -ftest
+    hgom --test "-a n"
+
+where `n` is the number of generated random inputs for each test case.
+
+For other arguments to the `--test` option, try `hgom --test "--help"`.
+
+### Code Coverage ###
+
+Code coverage can be tested as follows.
+
+    cabal build --ghc-options "-fhpc -fforce-recomp"
+    cd test/coverage
+    ./coverage.sh
+
+The documentation is generated in `test/coverage/html`.
+
+### Benchmark ###
+
+There is some benchmark in `test/bench` that generates bigger and bigger gom
+files and runs `hgom` and `gom` on them, measuring the gom/hgom ratio
+concerning the number of generated lines (using
+[sloccount](http://www.dwheeler.com/sloccount)) and the elapsed time.
+
+    cd test/bench
+    make
+
+It takes some time. The generated files can be plotted using
+[gnuplot](http://www.gnuplot.info) for instance.
+
+## Differences with gom ##
+
+### Better ###
+
+ * faster !
+ * a far less permissive checker
+ * smaller code, compiles much faster
+ * almost 100% code coverage,
+ * unit tests using QuickCheck, both on compiler 
+   data structures and generated code
+ * regression tests for parser and checker
+ * more things optional: visitable, checker, ...
+ * `toHaskell`, `makeRandom`, `depth` and `size`
+    methods generation (optional)
+ * smaller code for some generated 
+   methods (string escaping factorized for instance)
+ * faster code for some generated 
+   methods (less function calls, more constants)
+ * faster parser (`from*`) methods: don't use an
+   intermediate ATerm representation
+ * pretty-printed generated code, 
+   optional compact (no indentation) option
+
+### Worse ###
+
+ * no hooks !
+ * no ant task
+ * imports only builtins
+ * generates no comments
+
+### Different ###
+
+ * slightly different command-line arguments syntax
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,3 @@
+import Distribution.Simple
+
+main = defaultMain
diff --git a/examples/big.gom b/examples/big.gom
new file mode 100644
--- /dev/null
+++ b/examples/big.gom
@@ -0,0 +1,1002 @@
+module big
+abstract syntax
+T1 = C1_1(x1: T1,x2: T1,x3: T1,x4: T1,x5: T1,x6: T1,x7: T1,x8: T1,x9: T1,x10: T1)
+|C2_1(x1: T1,x2: T1,x3: T1,x4: T1,x5: T1,x6: T1,x7: T1,x8: T1,x9: T1,x10: T1)
+|C3_1(x1: T1,x2: T1,x3: T1,x4: T1,x5: T1,x6: T1,x7: T1,x8: T1,x9: T1,x10: T1)
+|C4_1(x1: T1,x2: T1,x3: T1,x4: T1,x5: T1,x6: T1,x7: T1,x8: T1,x9: T1,x10: T1)
+|C5_1(x1: T1,x2: T1,x3: T1,x4: T1,x5: T1,x6: T1,x7: T1,x8: T1,x9: T1,x10: T1)
+|C6_1(x1: T1,x2: T1,x3: T1,x4: T1,x5: T1,x6: T1,x7: T1,x8: T1,x9: T1,x10: T1)
+|C7_1(x1: T1,x2: T1,x3: T1,x4: T1,x5: T1,x6: T1,x7: T1,x8: T1,x9: T1,x10: T1)
+|C8_1(x1: T1,x2: T1,x3: T1,x4: T1,x5: T1,x6: T1,x7: T1,x8: T1,x9: T1,x10: T1)
+|C9_1(x1: T1,x2: T1,x3: T1,x4: T1,x5: T1,x6: T1,x7: T1,x8: T1,x9: T1,x10: T1)
+|C10_1(x1: T1,x2: T1,x3: T1,x4: T1,x5: T1,x6: T1,x7: T1,x8: T1,x9: T1,x10: T1)
+T2 = C1_2(x1: T2,x2: T2,x3: T2,x4: T2,x5: T2,x6: T2,x7: T2,x8: T2,x9: T2,x10: T2)
+|C2_2(x1: T2,x2: T2,x3: T2,x4: T2,x5: T2,x6: T2,x7: T2,x8: T2,x9: T2,x10: T2)
+|C3_2(x1: T2,x2: T2,x3: T2,x4: T2,x5: T2,x6: T2,x7: T2,x8: T2,x9: T2,x10: T2)
+|C4_2(x1: T2,x2: T2,x3: T2,x4: T2,x5: T2,x6: T2,x7: T2,x8: T2,x9: T2,x10: T2)
+|C5_2(x1: T2,x2: T2,x3: T2,x4: T2,x5: T2,x6: T2,x7: T2,x8: T2,x9: T2,x10: T2)
+|C6_2(x1: T2,x2: T2,x3: T2,x4: T2,x5: T2,x6: T2,x7: T2,x8: T2,x9: T2,x10: T2)
+|C7_2(x1: T2,x2: T2,x3: T2,x4: T2,x5: T2,x6: T2,x7: T2,x8: T2,x9: T2,x10: T2)
+|C8_2(x1: T2,x2: T2,x3: T2,x4: T2,x5: T2,x6: T2,x7: T2,x8: T2,x9: T2,x10: T2)
+|C9_2(x1: T2,x2: T2,x3: T2,x4: T2,x5: T2,x6: T2,x7: T2,x8: T2,x9: T2,x10: T2)
+|C10_2(x1: T2,x2: T2,x3: T2,x4: T2,x5: T2,x6: T2,x7: T2,x8: T2,x9: T2,x10: T2)
+T3 = C1_3(x1: T3,x2: T3,x3: T3,x4: T3,x5: T3,x6: T3,x7: T3,x8: T3,x9: T3,x10: T3)
+|C2_3(x1: T3,x2: T3,x3: T3,x4: T3,x5: T3,x6: T3,x7: T3,x8: T3,x9: T3,x10: T3)
+|C3_3(x1: T3,x2: T3,x3: T3,x4: T3,x5: T3,x6: T3,x7: T3,x8: T3,x9: T3,x10: T3)
+|C4_3(x1: T3,x2: T3,x3: T3,x4: T3,x5: T3,x6: T3,x7: T3,x8: T3,x9: T3,x10: T3)
+|C5_3(x1: T3,x2: T3,x3: T3,x4: T3,x5: T3,x6: T3,x7: T3,x8: T3,x9: T3,x10: T3)
+|C6_3(x1: T3,x2: T3,x3: T3,x4: T3,x5: T3,x6: T3,x7: T3,x8: T3,x9: T3,x10: T3)
+|C7_3(x1: T3,x2: T3,x3: T3,x4: T3,x5: T3,x6: T3,x7: T3,x8: T3,x9: T3,x10: T3)
+|C8_3(x1: T3,x2: T3,x3: T3,x4: T3,x5: T3,x6: T3,x7: T3,x8: T3,x9: T3,x10: T3)
+|C9_3(x1: T3,x2: T3,x3: T3,x4: T3,x5: T3,x6: T3,x7: T3,x8: T3,x9: T3,x10: T3)
+|C10_3(x1: T3,x2: T3,x3: T3,x4: T3,x5: T3,x6: T3,x7: T3,x8: T3,x9: T3,x10: T3)
+T4 = C1_4(x1: T4,x2: T4,x3: T4,x4: T4,x5: T4,x6: T4,x7: T4,x8: T4,x9: T4,x10: T4)
+|C2_4(x1: T4,x2: T4,x3: T4,x4: T4,x5: T4,x6: T4,x7: T4,x8: T4,x9: T4,x10: T4)
+|C3_4(x1: T4,x2: T4,x3: T4,x4: T4,x5: T4,x6: T4,x7: T4,x8: T4,x9: T4,x10: T4)
+|C4_4(x1: T4,x2: T4,x3: T4,x4: T4,x5: T4,x6: T4,x7: T4,x8: T4,x9: T4,x10: T4)
+|C5_4(x1: T4,x2: T4,x3: T4,x4: T4,x5: T4,x6: T4,x7: T4,x8: T4,x9: T4,x10: T4)
+|C6_4(x1: T4,x2: T4,x3: T4,x4: T4,x5: T4,x6: T4,x7: T4,x8: T4,x9: T4,x10: T4)
+|C7_4(x1: T4,x2: T4,x3: T4,x4: T4,x5: T4,x6: T4,x7: T4,x8: T4,x9: T4,x10: T4)
+|C8_4(x1: T4,x2: T4,x3: T4,x4: T4,x5: T4,x6: T4,x7: T4,x8: T4,x9: T4,x10: T4)
+|C9_4(x1: T4,x2: T4,x3: T4,x4: T4,x5: T4,x6: T4,x7: T4,x8: T4,x9: T4,x10: T4)
+|C10_4(x1: T4,x2: T4,x3: T4,x4: T4,x5: T4,x6: T4,x7: T4,x8: T4,x9: T4,x10: T4)
+T5 = C1_5(x1: T5,x2: T5,x3: T5,x4: T5,x5: T5,x6: T5,x7: T5,x8: T5,x9: T5,x10: T5)
+|C2_5(x1: T5,x2: T5,x3: T5,x4: T5,x5: T5,x6: T5,x7: T5,x8: T5,x9: T5,x10: T5)
+|C3_5(x1: T5,x2: T5,x3: T5,x4: T5,x5: T5,x6: T5,x7: T5,x8: T5,x9: T5,x10: T5)
+|C4_5(x1: T5,x2: T5,x3: T5,x4: T5,x5: T5,x6: T5,x7: T5,x8: T5,x9: T5,x10: T5)
+|C5_5(x1: T5,x2: T5,x3: T5,x4: T5,x5: T5,x6: T5,x7: T5,x8: T5,x9: T5,x10: T5)
+|C6_5(x1: T5,x2: T5,x3: T5,x4: T5,x5: T5,x6: T5,x7: T5,x8: T5,x9: T5,x10: T5)
+|C7_5(x1: T5,x2: T5,x3: T5,x4: T5,x5: T5,x6: T5,x7: T5,x8: T5,x9: T5,x10: T5)
+|C8_5(x1: T5,x2: T5,x3: T5,x4: T5,x5: T5,x6: T5,x7: T5,x8: T5,x9: T5,x10: T5)
+|C9_5(x1: T5,x2: T5,x3: T5,x4: T5,x5: T5,x6: T5,x7: T5,x8: T5,x9: T5,x10: T5)
+|C10_5(x1: T5,x2: T5,x3: T5,x4: T5,x5: T5,x6: T5,x7: T5,x8: T5,x9: T5,x10: T5)
+T6 = C1_6(x1: T6,x2: T6,x3: T6,x4: T6,x5: T6,x6: T6,x7: T6,x8: T6,x9: T6,x10: T6)
+|C2_6(x1: T6,x2: T6,x3: T6,x4: T6,x5: T6,x6: T6,x7: T6,x8: T6,x9: T6,x10: T6)
+|C3_6(x1: T6,x2: T6,x3: T6,x4: T6,x5: T6,x6: T6,x7: T6,x8: T6,x9: T6,x10: T6)
+|C4_6(x1: T6,x2: T6,x3: T6,x4: T6,x5: T6,x6: T6,x7: T6,x8: T6,x9: T6,x10: T6)
+|C5_6(x1: T6,x2: T6,x3: T6,x4: T6,x5: T6,x6: T6,x7: T6,x8: T6,x9: T6,x10: T6)
+|C6_6(x1: T6,x2: T6,x3: T6,x4: T6,x5: T6,x6: T6,x7: T6,x8: T6,x9: T6,x10: T6)
+|C7_6(x1: T6,x2: T6,x3: T6,x4: T6,x5: T6,x6: T6,x7: T6,x8: T6,x9: T6,x10: T6)
+|C8_6(x1: T6,x2: T6,x3: T6,x4: T6,x5: T6,x6: T6,x7: T6,x8: T6,x9: T6,x10: T6)
+|C9_6(x1: T6,x2: T6,x3: T6,x4: T6,x5: T6,x6: T6,x7: T6,x8: T6,x9: T6,x10: T6)
+|C10_6(x1: T6,x2: T6,x3: T6,x4: T6,x5: T6,x6: T6,x7: T6,x8: T6,x9: T6,x10: T6)
+T7 = C1_7(x1: T7,x2: T7,x3: T7,x4: T7,x5: T7,x6: T7,x7: T7,x8: T7,x9: T7,x10: T7)
+|C2_7(x1: T7,x2: T7,x3: T7,x4: T7,x5: T7,x6: T7,x7: T7,x8: T7,x9: T7,x10: T7)
+|C3_7(x1: T7,x2: T7,x3: T7,x4: T7,x5: T7,x6: T7,x7: T7,x8: T7,x9: T7,x10: T7)
+|C4_7(x1: T7,x2: T7,x3: T7,x4: T7,x5: T7,x6: T7,x7: T7,x8: T7,x9: T7,x10: T7)
+|C5_7(x1: T7,x2: T7,x3: T7,x4: T7,x5: T7,x6: T7,x7: T7,x8: T7,x9: T7,x10: T7)
+|C6_7(x1: T7,x2: T7,x3: T7,x4: T7,x5: T7,x6: T7,x7: T7,x8: T7,x9: T7,x10: T7)
+|C7_7(x1: T7,x2: T7,x3: T7,x4: T7,x5: T7,x6: T7,x7: T7,x8: T7,x9: T7,x10: T7)
+|C8_7(x1: T7,x2: T7,x3: T7,x4: T7,x5: T7,x6: T7,x7: T7,x8: T7,x9: T7,x10: T7)
+|C9_7(x1: T7,x2: T7,x3: T7,x4: T7,x5: T7,x6: T7,x7: T7,x8: T7,x9: T7,x10: T7)
+|C10_7(x1: T7,x2: T7,x3: T7,x4: T7,x5: T7,x6: T7,x7: T7,x8: T7,x9: T7,x10: T7)
+T8 = C1_8(x1: T8,x2: T8,x3: T8,x4: T8,x5: T8,x6: T8,x7: T8,x8: T8,x9: T8,x10: T8)
+|C2_8(x1: T8,x2: T8,x3: T8,x4: T8,x5: T8,x6: T8,x7: T8,x8: T8,x9: T8,x10: T8)
+|C3_8(x1: T8,x2: T8,x3: T8,x4: T8,x5: T8,x6: T8,x7: T8,x8: T8,x9: T8,x10: T8)
+|C4_8(x1: T8,x2: T8,x3: T8,x4: T8,x5: T8,x6: T8,x7: T8,x8: T8,x9: T8,x10: T8)
+|C5_8(x1: T8,x2: T8,x3: T8,x4: T8,x5: T8,x6: T8,x7: T8,x8: T8,x9: T8,x10: T8)
+|C6_8(x1: T8,x2: T8,x3: T8,x4: T8,x5: T8,x6: T8,x7: T8,x8: T8,x9: T8,x10: T8)
+|C7_8(x1: T8,x2: T8,x3: T8,x4: T8,x5: T8,x6: T8,x7: T8,x8: T8,x9: T8,x10: T8)
+|C8_8(x1: T8,x2: T8,x3: T8,x4: T8,x5: T8,x6: T8,x7: T8,x8: T8,x9: T8,x10: T8)
+|C9_8(x1: T8,x2: T8,x3: T8,x4: T8,x5: T8,x6: T8,x7: T8,x8: T8,x9: T8,x10: T8)
+|C10_8(x1: T8,x2: T8,x3: T8,x4: T8,x5: T8,x6: T8,x7: T8,x8: T8,x9: T8,x10: T8)
+T9 = C1_9(x1: T9,x2: T9,x3: T9,x4: T9,x5: T9,x6: T9,x7: T9,x8: T9,x9: T9,x10: T9)
+|C2_9(x1: T9,x2: T9,x3: T9,x4: T9,x5: T9,x6: T9,x7: T9,x8: T9,x9: T9,x10: T9)
+|C3_9(x1: T9,x2: T9,x3: T9,x4: T9,x5: T9,x6: T9,x7: T9,x8: T9,x9: T9,x10: T9)
+|C4_9(x1: T9,x2: T9,x3: T9,x4: T9,x5: T9,x6: T9,x7: T9,x8: T9,x9: T9,x10: T9)
+|C5_9(x1: T9,x2: T9,x3: T9,x4: T9,x5: T9,x6: T9,x7: T9,x8: T9,x9: T9,x10: T9)
+|C6_9(x1: T9,x2: T9,x3: T9,x4: T9,x5: T9,x6: T9,x7: T9,x8: T9,x9: T9,x10: T9)
+|C7_9(x1: T9,x2: T9,x3: T9,x4: T9,x5: T9,x6: T9,x7: T9,x8: T9,x9: T9,x10: T9)
+|C8_9(x1: T9,x2: T9,x3: T9,x4: T9,x5: T9,x6: T9,x7: T9,x8: T9,x9: T9,x10: T9)
+|C9_9(x1: T9,x2: T9,x3: T9,x4: T9,x5: T9,x6: T9,x7: T9,x8: T9,x9: T9,x10: T9)
+|C10_9(x1: T9,x2: T9,x3: T9,x4: T9,x5: T9,x6: T9,x7: T9,x8: T9,x9: T9,x10: T9)
+T10 = C1_10(x1: T10,x2: T10,x3: T10,x4: T10,x5: T10,x6: T10,x7: T10,x8: T10,x9: T10,x10: T10)
+|C2_10(x1: T10,x2: T10,x3: T10,x4: T10,x5: T10,x6: T10,x7: T10,x8: T10,x9: T10,x10: T10)
+|C3_10(x1: T10,x2: T10,x3: T10,x4: T10,x5: T10,x6: T10,x7: T10,x8: T10,x9: T10,x10: T10)
+|C4_10(x1: T10,x2: T10,x3: T10,x4: T10,x5: T10,x6: T10,x7: T10,x8: T10,x9: T10,x10: T10)
+|C5_10(x1: T10,x2: T10,x3: T10,x4: T10,x5: T10,x6: T10,x7: T10,x8: T10,x9: T10,x10: T10)
+|C6_10(x1: T10,x2: T10,x3: T10,x4: T10,x5: T10,x6: T10,x7: T10,x8: T10,x9: T10,x10: T10)
+|C7_10(x1: T10,x2: T10,x3: T10,x4: T10,x5: T10,x6: T10,x7: T10,x8: T10,x9: T10,x10: T10)
+|C8_10(x1: T10,x2: T10,x3: T10,x4: T10,x5: T10,x6: T10,x7: T10,x8: T10,x9: T10,x10: T10)
+|C9_10(x1: T10,x2: T10,x3: T10,x4: T10,x5: T10,x6: T10,x7: T10,x8: T10,x9: T10,x10: T10)
+|C10_10(x1: T10,x2: T10,x3: T10,x4: T10,x5: T10,x6: T10,x7: T10,x8: T10,x9: T10,x10: T10)
+T11 = C1_11(x1: T11,x2: T11,x3: T11,x4: T11,x5: T11,x6: T11,x7: T11,x8: T11,x9: T11,x10: T11)
+|C2_11(x1: T11,x2: T11,x3: T11,x4: T11,x5: T11,x6: T11,x7: T11,x8: T11,x9: T11,x10: T11)
+|C3_11(x1: T11,x2: T11,x3: T11,x4: T11,x5: T11,x6: T11,x7: T11,x8: T11,x9: T11,x10: T11)
+|C4_11(x1: T11,x2: T11,x3: T11,x4: T11,x5: T11,x6: T11,x7: T11,x8: T11,x9: T11,x10: T11)
+|C5_11(x1: T11,x2: T11,x3: T11,x4: T11,x5: T11,x6: T11,x7: T11,x8: T11,x9: T11,x10: T11)
+|C6_11(x1: T11,x2: T11,x3: T11,x4: T11,x5: T11,x6: T11,x7: T11,x8: T11,x9: T11,x10: T11)
+|C7_11(x1: T11,x2: T11,x3: T11,x4: T11,x5: T11,x6: T11,x7: T11,x8: T11,x9: T11,x10: T11)
+|C8_11(x1: T11,x2: T11,x3: T11,x4: T11,x5: T11,x6: T11,x7: T11,x8: T11,x9: T11,x10: T11)
+|C9_11(x1: T11,x2: T11,x3: T11,x4: T11,x5: T11,x6: T11,x7: T11,x8: T11,x9: T11,x10: T11)
+|C10_11(x1: T11,x2: T11,x3: T11,x4: T11,x5: T11,x6: T11,x7: T11,x8: T11,x9: T11,x10: T11)
+T12 = C1_12(x1: T12,x2: T12,x3: T12,x4: T12,x5: T12,x6: T12,x7: T12,x8: T12,x9: T12,x10: T12)
+|C2_12(x1: T12,x2: T12,x3: T12,x4: T12,x5: T12,x6: T12,x7: T12,x8: T12,x9: T12,x10: T12)
+|C3_12(x1: T12,x2: T12,x3: T12,x4: T12,x5: T12,x6: T12,x7: T12,x8: T12,x9: T12,x10: T12)
+|C4_12(x1: T12,x2: T12,x3: T12,x4: T12,x5: T12,x6: T12,x7: T12,x8: T12,x9: T12,x10: T12)
+|C5_12(x1: T12,x2: T12,x3: T12,x4: T12,x5: T12,x6: T12,x7: T12,x8: T12,x9: T12,x10: T12)
+|C6_12(x1: T12,x2: T12,x3: T12,x4: T12,x5: T12,x6: T12,x7: T12,x8: T12,x9: T12,x10: T12)
+|C7_12(x1: T12,x2: T12,x3: T12,x4: T12,x5: T12,x6: T12,x7: T12,x8: T12,x9: T12,x10: T12)
+|C8_12(x1: T12,x2: T12,x3: T12,x4: T12,x5: T12,x6: T12,x7: T12,x8: T12,x9: T12,x10: T12)
+|C9_12(x1: T12,x2: T12,x3: T12,x4: T12,x5: T12,x6: T12,x7: T12,x8: T12,x9: T12,x10: T12)
+|C10_12(x1: T12,x2: T12,x3: T12,x4: T12,x5: T12,x6: T12,x7: T12,x8: T12,x9: T12,x10: T12)
+T13 = C1_13(x1: T13,x2: T13,x3: T13,x4: T13,x5: T13,x6: T13,x7: T13,x8: T13,x9: T13,x10: T13)
+|C2_13(x1: T13,x2: T13,x3: T13,x4: T13,x5: T13,x6: T13,x7: T13,x8: T13,x9: T13,x10: T13)
+|C3_13(x1: T13,x2: T13,x3: T13,x4: T13,x5: T13,x6: T13,x7: T13,x8: T13,x9: T13,x10: T13)
+|C4_13(x1: T13,x2: T13,x3: T13,x4: T13,x5: T13,x6: T13,x7: T13,x8: T13,x9: T13,x10: T13)
+|C5_13(x1: T13,x2: T13,x3: T13,x4: T13,x5: T13,x6: T13,x7: T13,x8: T13,x9: T13,x10: T13)
+|C6_13(x1: T13,x2: T13,x3: T13,x4: T13,x5: T13,x6: T13,x7: T13,x8: T13,x9: T13,x10: T13)
+|C7_13(x1: T13,x2: T13,x3: T13,x4: T13,x5: T13,x6: T13,x7: T13,x8: T13,x9: T13,x10: T13)
+|C8_13(x1: T13,x2: T13,x3: T13,x4: T13,x5: T13,x6: T13,x7: T13,x8: T13,x9: T13,x10: T13)
+|C9_13(x1: T13,x2: T13,x3: T13,x4: T13,x5: T13,x6: T13,x7: T13,x8: T13,x9: T13,x10: T13)
+|C10_13(x1: T13,x2: T13,x3: T13,x4: T13,x5: T13,x6: T13,x7: T13,x8: T13,x9: T13,x10: T13)
+T14 = C1_14(x1: T14,x2: T14,x3: T14,x4: T14,x5: T14,x6: T14,x7: T14,x8: T14,x9: T14,x10: T14)
+|C2_14(x1: T14,x2: T14,x3: T14,x4: T14,x5: T14,x6: T14,x7: T14,x8: T14,x9: T14,x10: T14)
+|C3_14(x1: T14,x2: T14,x3: T14,x4: T14,x5: T14,x6: T14,x7: T14,x8: T14,x9: T14,x10: T14)
+|C4_14(x1: T14,x2: T14,x3: T14,x4: T14,x5: T14,x6: T14,x7: T14,x8: T14,x9: T14,x10: T14)
+|C5_14(x1: T14,x2: T14,x3: T14,x4: T14,x5: T14,x6: T14,x7: T14,x8: T14,x9: T14,x10: T14)
+|C6_14(x1: T14,x2: T14,x3: T14,x4: T14,x5: T14,x6: T14,x7: T14,x8: T14,x9: T14,x10: T14)
+|C7_14(x1: T14,x2: T14,x3: T14,x4: T14,x5: T14,x6: T14,x7: T14,x8: T14,x9: T14,x10: T14)
+|C8_14(x1: T14,x2: T14,x3: T14,x4: T14,x5: T14,x6: T14,x7: T14,x8: T14,x9: T14,x10: T14)
+|C9_14(x1: T14,x2: T14,x3: T14,x4: T14,x5: T14,x6: T14,x7: T14,x8: T14,x9: T14,x10: T14)
+|C10_14(x1: T14,x2: T14,x3: T14,x4: T14,x5: T14,x6: T14,x7: T14,x8: T14,x9: T14,x10: T14)
+T15 = C1_15(x1: T15,x2: T15,x3: T15,x4: T15,x5: T15,x6: T15,x7: T15,x8: T15,x9: T15,x10: T15)
+|C2_15(x1: T15,x2: T15,x3: T15,x4: T15,x5: T15,x6: T15,x7: T15,x8: T15,x9: T15,x10: T15)
+|C3_15(x1: T15,x2: T15,x3: T15,x4: T15,x5: T15,x6: T15,x7: T15,x8: T15,x9: T15,x10: T15)
+|C4_15(x1: T15,x2: T15,x3: T15,x4: T15,x5: T15,x6: T15,x7: T15,x8: T15,x9: T15,x10: T15)
+|C5_15(x1: T15,x2: T15,x3: T15,x4: T15,x5: T15,x6: T15,x7: T15,x8: T15,x9: T15,x10: T15)
+|C6_15(x1: T15,x2: T15,x3: T15,x4: T15,x5: T15,x6: T15,x7: T15,x8: T15,x9: T15,x10: T15)
+|C7_15(x1: T15,x2: T15,x3: T15,x4: T15,x5: T15,x6: T15,x7: T15,x8: T15,x9: T15,x10: T15)
+|C8_15(x1: T15,x2: T15,x3: T15,x4: T15,x5: T15,x6: T15,x7: T15,x8: T15,x9: T15,x10: T15)
+|C9_15(x1: T15,x2: T15,x3: T15,x4: T15,x5: T15,x6: T15,x7: T15,x8: T15,x9: T15,x10: T15)
+|C10_15(x1: T15,x2: T15,x3: T15,x4: T15,x5: T15,x6: T15,x7: T15,x8: T15,x9: T15,x10: T15)
+T16 = C1_16(x1: T16,x2: T16,x3: T16,x4: T16,x5: T16,x6: T16,x7: T16,x8: T16,x9: T16,x10: T16)
+|C2_16(x1: T16,x2: T16,x3: T16,x4: T16,x5: T16,x6: T16,x7: T16,x8: T16,x9: T16,x10: T16)
+|C3_16(x1: T16,x2: T16,x3: T16,x4: T16,x5: T16,x6: T16,x7: T16,x8: T16,x9: T16,x10: T16)
+|C4_16(x1: T16,x2: T16,x3: T16,x4: T16,x5: T16,x6: T16,x7: T16,x8: T16,x9: T16,x10: T16)
+|C5_16(x1: T16,x2: T16,x3: T16,x4: T16,x5: T16,x6: T16,x7: T16,x8: T16,x9: T16,x10: T16)
+|C6_16(x1: T16,x2: T16,x3: T16,x4: T16,x5: T16,x6: T16,x7: T16,x8: T16,x9: T16,x10: T16)
+|C7_16(x1: T16,x2: T16,x3: T16,x4: T16,x5: T16,x6: T16,x7: T16,x8: T16,x9: T16,x10: T16)
+|C8_16(x1: T16,x2: T16,x3: T16,x4: T16,x5: T16,x6: T16,x7: T16,x8: T16,x9: T16,x10: T16)
+|C9_16(x1: T16,x2: T16,x3: T16,x4: T16,x5: T16,x6: T16,x7: T16,x8: T16,x9: T16,x10: T16)
+|C10_16(x1: T16,x2: T16,x3: T16,x4: T16,x5: T16,x6: T16,x7: T16,x8: T16,x9: T16,x10: T16)
+T17 = C1_17(x1: T17,x2: T17,x3: T17,x4: T17,x5: T17,x6: T17,x7: T17,x8: T17,x9: T17,x10: T17)
+|C2_17(x1: T17,x2: T17,x3: T17,x4: T17,x5: T17,x6: T17,x7: T17,x8: T17,x9: T17,x10: T17)
+|C3_17(x1: T17,x2: T17,x3: T17,x4: T17,x5: T17,x6: T17,x7: T17,x8: T17,x9: T17,x10: T17)
+|C4_17(x1: T17,x2: T17,x3: T17,x4: T17,x5: T17,x6: T17,x7: T17,x8: T17,x9: T17,x10: T17)
+|C5_17(x1: T17,x2: T17,x3: T17,x4: T17,x5: T17,x6: T17,x7: T17,x8: T17,x9: T17,x10: T17)
+|C6_17(x1: T17,x2: T17,x3: T17,x4: T17,x5: T17,x6: T17,x7: T17,x8: T17,x9: T17,x10: T17)
+|C7_17(x1: T17,x2: T17,x3: T17,x4: T17,x5: T17,x6: T17,x7: T17,x8: T17,x9: T17,x10: T17)
+|C8_17(x1: T17,x2: T17,x3: T17,x4: T17,x5: T17,x6: T17,x7: T17,x8: T17,x9: T17,x10: T17)
+|C9_17(x1: T17,x2: T17,x3: T17,x4: T17,x5: T17,x6: T17,x7: T17,x8: T17,x9: T17,x10: T17)
+|C10_17(x1: T17,x2: T17,x3: T17,x4: T17,x5: T17,x6: T17,x7: T17,x8: T17,x9: T17,x10: T17)
+T18 = C1_18(x1: T18,x2: T18,x3: T18,x4: T18,x5: T18,x6: T18,x7: T18,x8: T18,x9: T18,x10: T18)
+|C2_18(x1: T18,x2: T18,x3: T18,x4: T18,x5: T18,x6: T18,x7: T18,x8: T18,x9: T18,x10: T18)
+|C3_18(x1: T18,x2: T18,x3: T18,x4: T18,x5: T18,x6: T18,x7: T18,x8: T18,x9: T18,x10: T18)
+|C4_18(x1: T18,x2: T18,x3: T18,x4: T18,x5: T18,x6: T18,x7: T18,x8: T18,x9: T18,x10: T18)
+|C5_18(x1: T18,x2: T18,x3: T18,x4: T18,x5: T18,x6: T18,x7: T18,x8: T18,x9: T18,x10: T18)
+|C6_18(x1: T18,x2: T18,x3: T18,x4: T18,x5: T18,x6: T18,x7: T18,x8: T18,x9: T18,x10: T18)
+|C7_18(x1: T18,x2: T18,x3: T18,x4: T18,x5: T18,x6: T18,x7: T18,x8: T18,x9: T18,x10: T18)
+|C8_18(x1: T18,x2: T18,x3: T18,x4: T18,x5: T18,x6: T18,x7: T18,x8: T18,x9: T18,x10: T18)
+|C9_18(x1: T18,x2: T18,x3: T18,x4: T18,x5: T18,x6: T18,x7: T18,x8: T18,x9: T18,x10: T18)
+|C10_18(x1: T18,x2: T18,x3: T18,x4: T18,x5: T18,x6: T18,x7: T18,x8: T18,x9: T18,x10: T18)
+T19 = C1_19(x1: T19,x2: T19,x3: T19,x4: T19,x5: T19,x6: T19,x7: T19,x8: T19,x9: T19,x10: T19)
+|C2_19(x1: T19,x2: T19,x3: T19,x4: T19,x5: T19,x6: T19,x7: T19,x8: T19,x9: T19,x10: T19)
+|C3_19(x1: T19,x2: T19,x3: T19,x4: T19,x5: T19,x6: T19,x7: T19,x8: T19,x9: T19,x10: T19)
+|C4_19(x1: T19,x2: T19,x3: T19,x4: T19,x5: T19,x6: T19,x7: T19,x8: T19,x9: T19,x10: T19)
+|C5_19(x1: T19,x2: T19,x3: T19,x4: T19,x5: T19,x6: T19,x7: T19,x8: T19,x9: T19,x10: T19)
+|C6_19(x1: T19,x2: T19,x3: T19,x4: T19,x5: T19,x6: T19,x7: T19,x8: T19,x9: T19,x10: T19)
+|C7_19(x1: T19,x2: T19,x3: T19,x4: T19,x5: T19,x6: T19,x7: T19,x8: T19,x9: T19,x10: T19)
+|C8_19(x1: T19,x2: T19,x3: T19,x4: T19,x5: T19,x6: T19,x7: T19,x8: T19,x9: T19,x10: T19)
+|C9_19(x1: T19,x2: T19,x3: T19,x4: T19,x5: T19,x6: T19,x7: T19,x8: T19,x9: T19,x10: T19)
+|C10_19(x1: T19,x2: T19,x3: T19,x4: T19,x5: T19,x6: T19,x7: T19,x8: T19,x9: T19,x10: T19)
+T20 = C1_20(x1: T20,x2: T20,x3: T20,x4: T20,x5: T20,x6: T20,x7: T20,x8: T20,x9: T20,x10: T20)
+|C2_20(x1: T20,x2: T20,x3: T20,x4: T20,x5: T20,x6: T20,x7: T20,x8: T20,x9: T20,x10: T20)
+|C3_20(x1: T20,x2: T20,x3: T20,x4: T20,x5: T20,x6: T20,x7: T20,x8: T20,x9: T20,x10: T20)
+|C4_20(x1: T20,x2: T20,x3: T20,x4: T20,x5: T20,x6: T20,x7: T20,x8: T20,x9: T20,x10: T20)
+|C5_20(x1: T20,x2: T20,x3: T20,x4: T20,x5: T20,x6: T20,x7: T20,x8: T20,x9: T20,x10: T20)
+|C6_20(x1: T20,x2: T20,x3: T20,x4: T20,x5: T20,x6: T20,x7: T20,x8: T20,x9: T20,x10: T20)
+|C7_20(x1: T20,x2: T20,x3: T20,x4: T20,x5: T20,x6: T20,x7: T20,x8: T20,x9: T20,x10: T20)
+|C8_20(x1: T20,x2: T20,x3: T20,x4: T20,x5: T20,x6: T20,x7: T20,x8: T20,x9: T20,x10: T20)
+|C9_20(x1: T20,x2: T20,x3: T20,x4: T20,x5: T20,x6: T20,x7: T20,x8: T20,x9: T20,x10: T20)
+|C10_20(x1: T20,x2: T20,x3: T20,x4: T20,x5: T20,x6: T20,x7: T20,x8: T20,x9: T20,x10: T20)
+T21 = C1_21(x1: T21,x2: T21,x3: T21,x4: T21,x5: T21,x6: T21,x7: T21,x8: T21,x9: T21,x10: T21)
+|C2_21(x1: T21,x2: T21,x3: T21,x4: T21,x5: T21,x6: T21,x7: T21,x8: T21,x9: T21,x10: T21)
+|C3_21(x1: T21,x2: T21,x3: T21,x4: T21,x5: T21,x6: T21,x7: T21,x8: T21,x9: T21,x10: T21)
+|C4_21(x1: T21,x2: T21,x3: T21,x4: T21,x5: T21,x6: T21,x7: T21,x8: T21,x9: T21,x10: T21)
+|C5_21(x1: T21,x2: T21,x3: T21,x4: T21,x5: T21,x6: T21,x7: T21,x8: T21,x9: T21,x10: T21)
+|C6_21(x1: T21,x2: T21,x3: T21,x4: T21,x5: T21,x6: T21,x7: T21,x8: T21,x9: T21,x10: T21)
+|C7_21(x1: T21,x2: T21,x3: T21,x4: T21,x5: T21,x6: T21,x7: T21,x8: T21,x9: T21,x10: T21)
+|C8_21(x1: T21,x2: T21,x3: T21,x4: T21,x5: T21,x6: T21,x7: T21,x8: T21,x9: T21,x10: T21)
+|C9_21(x1: T21,x2: T21,x3: T21,x4: T21,x5: T21,x6: T21,x7: T21,x8: T21,x9: T21,x10: T21)
+|C10_21(x1: T21,x2: T21,x3: T21,x4: T21,x5: T21,x6: T21,x7: T21,x8: T21,x9: T21,x10: T21)
+T22 = C1_22(x1: T22,x2: T22,x3: T22,x4: T22,x5: T22,x6: T22,x7: T22,x8: T22,x9: T22,x10: T22)
+|C2_22(x1: T22,x2: T22,x3: T22,x4: T22,x5: T22,x6: T22,x7: T22,x8: T22,x9: T22,x10: T22)
+|C3_22(x1: T22,x2: T22,x3: T22,x4: T22,x5: T22,x6: T22,x7: T22,x8: T22,x9: T22,x10: T22)
+|C4_22(x1: T22,x2: T22,x3: T22,x4: T22,x5: T22,x6: T22,x7: T22,x8: T22,x9: T22,x10: T22)
+|C5_22(x1: T22,x2: T22,x3: T22,x4: T22,x5: T22,x6: T22,x7: T22,x8: T22,x9: T22,x10: T22)
+|C6_22(x1: T22,x2: T22,x3: T22,x4: T22,x5: T22,x6: T22,x7: T22,x8: T22,x9: T22,x10: T22)
+|C7_22(x1: T22,x2: T22,x3: T22,x4: T22,x5: T22,x6: T22,x7: T22,x8: T22,x9: T22,x10: T22)
+|C8_22(x1: T22,x2: T22,x3: T22,x4: T22,x5: T22,x6: T22,x7: T22,x8: T22,x9: T22,x10: T22)
+|C9_22(x1: T22,x2: T22,x3: T22,x4: T22,x5: T22,x6: T22,x7: T22,x8: T22,x9: T22,x10: T22)
+|C10_22(x1: T22,x2: T22,x3: T22,x4: T22,x5: T22,x6: T22,x7: T22,x8: T22,x9: T22,x10: T22)
+T23 = C1_23(x1: T23,x2: T23,x3: T23,x4: T23,x5: T23,x6: T23,x7: T23,x8: T23,x9: T23,x10: T23)
+|C2_23(x1: T23,x2: T23,x3: T23,x4: T23,x5: T23,x6: T23,x7: T23,x8: T23,x9: T23,x10: T23)
+|C3_23(x1: T23,x2: T23,x3: T23,x4: T23,x5: T23,x6: T23,x7: T23,x8: T23,x9: T23,x10: T23)
+|C4_23(x1: T23,x2: T23,x3: T23,x4: T23,x5: T23,x6: T23,x7: T23,x8: T23,x9: T23,x10: T23)
+|C5_23(x1: T23,x2: T23,x3: T23,x4: T23,x5: T23,x6: T23,x7: T23,x8: T23,x9: T23,x10: T23)
+|C6_23(x1: T23,x2: T23,x3: T23,x4: T23,x5: T23,x6: T23,x7: T23,x8: T23,x9: T23,x10: T23)
+|C7_23(x1: T23,x2: T23,x3: T23,x4: T23,x5: T23,x6: T23,x7: T23,x8: T23,x9: T23,x10: T23)
+|C8_23(x1: T23,x2: T23,x3: T23,x4: T23,x5: T23,x6: T23,x7: T23,x8: T23,x9: T23,x10: T23)
+|C9_23(x1: T23,x2: T23,x3: T23,x4: T23,x5: T23,x6: T23,x7: T23,x8: T23,x9: T23,x10: T23)
+|C10_23(x1: T23,x2: T23,x3: T23,x4: T23,x5: T23,x6: T23,x7: T23,x8: T23,x9: T23,x10: T23)
+T24 = C1_24(x1: T24,x2: T24,x3: T24,x4: T24,x5: T24,x6: T24,x7: T24,x8: T24,x9: T24,x10: T24)
+|C2_24(x1: T24,x2: T24,x3: T24,x4: T24,x5: T24,x6: T24,x7: T24,x8: T24,x9: T24,x10: T24)
+|C3_24(x1: T24,x2: T24,x3: T24,x4: T24,x5: T24,x6: T24,x7: T24,x8: T24,x9: T24,x10: T24)
+|C4_24(x1: T24,x2: T24,x3: T24,x4: T24,x5: T24,x6: T24,x7: T24,x8: T24,x9: T24,x10: T24)
+|C5_24(x1: T24,x2: T24,x3: T24,x4: T24,x5: T24,x6: T24,x7: T24,x8: T24,x9: T24,x10: T24)
+|C6_24(x1: T24,x2: T24,x3: T24,x4: T24,x5: T24,x6: T24,x7: T24,x8: T24,x9: T24,x10: T24)
+|C7_24(x1: T24,x2: T24,x3: T24,x4: T24,x5: T24,x6: T24,x7: T24,x8: T24,x9: T24,x10: T24)
+|C8_24(x1: T24,x2: T24,x3: T24,x4: T24,x5: T24,x6: T24,x7: T24,x8: T24,x9: T24,x10: T24)
+|C9_24(x1: T24,x2: T24,x3: T24,x4: T24,x5: T24,x6: T24,x7: T24,x8: T24,x9: T24,x10: T24)
+|C10_24(x1: T24,x2: T24,x3: T24,x4: T24,x5: T24,x6: T24,x7: T24,x8: T24,x9: T24,x10: T24)
+T25 = C1_25(x1: T25,x2: T25,x3: T25,x4: T25,x5: T25,x6: T25,x7: T25,x8: T25,x9: T25,x10: T25)
+|C2_25(x1: T25,x2: T25,x3: T25,x4: T25,x5: T25,x6: T25,x7: T25,x8: T25,x9: T25,x10: T25)
+|C3_25(x1: T25,x2: T25,x3: T25,x4: T25,x5: T25,x6: T25,x7: T25,x8: T25,x9: T25,x10: T25)
+|C4_25(x1: T25,x2: T25,x3: T25,x4: T25,x5: T25,x6: T25,x7: T25,x8: T25,x9: T25,x10: T25)
+|C5_25(x1: T25,x2: T25,x3: T25,x4: T25,x5: T25,x6: T25,x7: T25,x8: T25,x9: T25,x10: T25)
+|C6_25(x1: T25,x2: T25,x3: T25,x4: T25,x5: T25,x6: T25,x7: T25,x8: T25,x9: T25,x10: T25)
+|C7_25(x1: T25,x2: T25,x3: T25,x4: T25,x5: T25,x6: T25,x7: T25,x8: T25,x9: T25,x10: T25)
+|C8_25(x1: T25,x2: T25,x3: T25,x4: T25,x5: T25,x6: T25,x7: T25,x8: T25,x9: T25,x10: T25)
+|C9_25(x1: T25,x2: T25,x3: T25,x4: T25,x5: T25,x6: T25,x7: T25,x8: T25,x9: T25,x10: T25)
+|C10_25(x1: T25,x2: T25,x3: T25,x4: T25,x5: T25,x6: T25,x7: T25,x8: T25,x9: T25,x10: T25)
+T26 = C1_26(x1: T26,x2: T26,x3: T26,x4: T26,x5: T26,x6: T26,x7: T26,x8: T26,x9: T26,x10: T26)
+|C2_26(x1: T26,x2: T26,x3: T26,x4: T26,x5: T26,x6: T26,x7: T26,x8: T26,x9: T26,x10: T26)
+|C3_26(x1: T26,x2: T26,x3: T26,x4: T26,x5: T26,x6: T26,x7: T26,x8: T26,x9: T26,x10: T26)
+|C4_26(x1: T26,x2: T26,x3: T26,x4: T26,x5: T26,x6: T26,x7: T26,x8: T26,x9: T26,x10: T26)
+|C5_26(x1: T26,x2: T26,x3: T26,x4: T26,x5: T26,x6: T26,x7: T26,x8: T26,x9: T26,x10: T26)
+|C6_26(x1: T26,x2: T26,x3: T26,x4: T26,x5: T26,x6: T26,x7: T26,x8: T26,x9: T26,x10: T26)
+|C7_26(x1: T26,x2: T26,x3: T26,x4: T26,x5: T26,x6: T26,x7: T26,x8: T26,x9: T26,x10: T26)
+|C8_26(x1: T26,x2: T26,x3: T26,x4: T26,x5: T26,x6: T26,x7: T26,x8: T26,x9: T26,x10: T26)
+|C9_26(x1: T26,x2: T26,x3: T26,x4: T26,x5: T26,x6: T26,x7: T26,x8: T26,x9: T26,x10: T26)
+|C10_26(x1: T26,x2: T26,x3: T26,x4: T26,x5: T26,x6: T26,x7: T26,x8: T26,x9: T26,x10: T26)
+T27 = C1_27(x1: T27,x2: T27,x3: T27,x4: T27,x5: T27,x6: T27,x7: T27,x8: T27,x9: T27,x10: T27)
+|C2_27(x1: T27,x2: T27,x3: T27,x4: T27,x5: T27,x6: T27,x7: T27,x8: T27,x9: T27,x10: T27)
+|C3_27(x1: T27,x2: T27,x3: T27,x4: T27,x5: T27,x6: T27,x7: T27,x8: T27,x9: T27,x10: T27)
+|C4_27(x1: T27,x2: T27,x3: T27,x4: T27,x5: T27,x6: T27,x7: T27,x8: T27,x9: T27,x10: T27)
+|C5_27(x1: T27,x2: T27,x3: T27,x4: T27,x5: T27,x6: T27,x7: T27,x8: T27,x9: T27,x10: T27)
+|C6_27(x1: T27,x2: T27,x3: T27,x4: T27,x5: T27,x6: T27,x7: T27,x8: T27,x9: T27,x10: T27)
+|C7_27(x1: T27,x2: T27,x3: T27,x4: T27,x5: T27,x6: T27,x7: T27,x8: T27,x9: T27,x10: T27)
+|C8_27(x1: T27,x2: T27,x3: T27,x4: T27,x5: T27,x6: T27,x7: T27,x8: T27,x9: T27,x10: T27)
+|C9_27(x1: T27,x2: T27,x3: T27,x4: T27,x5: T27,x6: T27,x7: T27,x8: T27,x9: T27,x10: T27)
+|C10_27(x1: T27,x2: T27,x3: T27,x4: T27,x5: T27,x6: T27,x7: T27,x8: T27,x9: T27,x10: T27)
+T28 = C1_28(x1: T28,x2: T28,x3: T28,x4: T28,x5: T28,x6: T28,x7: T28,x8: T28,x9: T28,x10: T28)
+|C2_28(x1: T28,x2: T28,x3: T28,x4: T28,x5: T28,x6: T28,x7: T28,x8: T28,x9: T28,x10: T28)
+|C3_28(x1: T28,x2: T28,x3: T28,x4: T28,x5: T28,x6: T28,x7: T28,x8: T28,x9: T28,x10: T28)
+|C4_28(x1: T28,x2: T28,x3: T28,x4: T28,x5: T28,x6: T28,x7: T28,x8: T28,x9: T28,x10: T28)
+|C5_28(x1: T28,x2: T28,x3: T28,x4: T28,x5: T28,x6: T28,x7: T28,x8: T28,x9: T28,x10: T28)
+|C6_28(x1: T28,x2: T28,x3: T28,x4: T28,x5: T28,x6: T28,x7: T28,x8: T28,x9: T28,x10: T28)
+|C7_28(x1: T28,x2: T28,x3: T28,x4: T28,x5: T28,x6: T28,x7: T28,x8: T28,x9: T28,x10: T28)
+|C8_28(x1: T28,x2: T28,x3: T28,x4: T28,x5: T28,x6: T28,x7: T28,x8: T28,x9: T28,x10: T28)
+|C9_28(x1: T28,x2: T28,x3: T28,x4: T28,x5: T28,x6: T28,x7: T28,x8: T28,x9: T28,x10: T28)
+|C10_28(x1: T28,x2: T28,x3: T28,x4: T28,x5: T28,x6: T28,x7: T28,x8: T28,x9: T28,x10: T28)
+T29 = C1_29(x1: T29,x2: T29,x3: T29,x4: T29,x5: T29,x6: T29,x7: T29,x8: T29,x9: T29,x10: T29)
+|C2_29(x1: T29,x2: T29,x3: T29,x4: T29,x5: T29,x6: T29,x7: T29,x8: T29,x9: T29,x10: T29)
+|C3_29(x1: T29,x2: T29,x3: T29,x4: T29,x5: T29,x6: T29,x7: T29,x8: T29,x9: T29,x10: T29)
+|C4_29(x1: T29,x2: T29,x3: T29,x4: T29,x5: T29,x6: T29,x7: T29,x8: T29,x9: T29,x10: T29)
+|C5_29(x1: T29,x2: T29,x3: T29,x4: T29,x5: T29,x6: T29,x7: T29,x8: T29,x9: T29,x10: T29)
+|C6_29(x1: T29,x2: T29,x3: T29,x4: T29,x5: T29,x6: T29,x7: T29,x8: T29,x9: T29,x10: T29)
+|C7_29(x1: T29,x2: T29,x3: T29,x4: T29,x5: T29,x6: T29,x7: T29,x8: T29,x9: T29,x10: T29)
+|C8_29(x1: T29,x2: T29,x3: T29,x4: T29,x5: T29,x6: T29,x7: T29,x8: T29,x9: T29,x10: T29)
+|C9_29(x1: T29,x2: T29,x3: T29,x4: T29,x5: T29,x6: T29,x7: T29,x8: T29,x9: T29,x10: T29)
+|C10_29(x1: T29,x2: T29,x3: T29,x4: T29,x5: T29,x6: T29,x7: T29,x8: T29,x9: T29,x10: T29)
+T30 = C1_30(x1: T30,x2: T30,x3: T30,x4: T30,x5: T30,x6: T30,x7: T30,x8: T30,x9: T30,x10: T30)
+|C2_30(x1: T30,x2: T30,x3: T30,x4: T30,x5: T30,x6: T30,x7: T30,x8: T30,x9: T30,x10: T30)
+|C3_30(x1: T30,x2: T30,x3: T30,x4: T30,x5: T30,x6: T30,x7: T30,x8: T30,x9: T30,x10: T30)
+|C4_30(x1: T30,x2: T30,x3: T30,x4: T30,x5: T30,x6: T30,x7: T30,x8: T30,x9: T30,x10: T30)
+|C5_30(x1: T30,x2: T30,x3: T30,x4: T30,x5: T30,x6: T30,x7: T30,x8: T30,x9: T30,x10: T30)
+|C6_30(x1: T30,x2: T30,x3: T30,x4: T30,x5: T30,x6: T30,x7: T30,x8: T30,x9: T30,x10: T30)
+|C7_30(x1: T30,x2: T30,x3: T30,x4: T30,x5: T30,x6: T30,x7: T30,x8: T30,x9: T30,x10: T30)
+|C8_30(x1: T30,x2: T30,x3: T30,x4: T30,x5: T30,x6: T30,x7: T30,x8: T30,x9: T30,x10: T30)
+|C9_30(x1: T30,x2: T30,x3: T30,x4: T30,x5: T30,x6: T30,x7: T30,x8: T30,x9: T30,x10: T30)
+|C10_30(x1: T30,x2: T30,x3: T30,x4: T30,x5: T30,x6: T30,x7: T30,x8: T30,x9: T30,x10: T30)
+T31 = C1_31(x1: T31,x2: T31,x3: T31,x4: T31,x5: T31,x6: T31,x7: T31,x8: T31,x9: T31,x10: T31)
+|C2_31(x1: T31,x2: T31,x3: T31,x4: T31,x5: T31,x6: T31,x7: T31,x8: T31,x9: T31,x10: T31)
+|C3_31(x1: T31,x2: T31,x3: T31,x4: T31,x5: T31,x6: T31,x7: T31,x8: T31,x9: T31,x10: T31)
+|C4_31(x1: T31,x2: T31,x3: T31,x4: T31,x5: T31,x6: T31,x7: T31,x8: T31,x9: T31,x10: T31)
+|C5_31(x1: T31,x2: T31,x3: T31,x4: T31,x5: T31,x6: T31,x7: T31,x8: T31,x9: T31,x10: T31)
+|C6_31(x1: T31,x2: T31,x3: T31,x4: T31,x5: T31,x6: T31,x7: T31,x8: T31,x9: T31,x10: T31)
+|C7_31(x1: T31,x2: T31,x3: T31,x4: T31,x5: T31,x6: T31,x7: T31,x8: T31,x9: T31,x10: T31)
+|C8_31(x1: T31,x2: T31,x3: T31,x4: T31,x5: T31,x6: T31,x7: T31,x8: T31,x9: T31,x10: T31)
+|C9_31(x1: T31,x2: T31,x3: T31,x4: T31,x5: T31,x6: T31,x7: T31,x8: T31,x9: T31,x10: T31)
+|C10_31(x1: T31,x2: T31,x3: T31,x4: T31,x5: T31,x6: T31,x7: T31,x8: T31,x9: T31,x10: T31)
+T32 = C1_32(x1: T32,x2: T32,x3: T32,x4: T32,x5: T32,x6: T32,x7: T32,x8: T32,x9: T32,x10: T32)
+|C2_32(x1: T32,x2: T32,x3: T32,x4: T32,x5: T32,x6: T32,x7: T32,x8: T32,x9: T32,x10: T32)
+|C3_32(x1: T32,x2: T32,x3: T32,x4: T32,x5: T32,x6: T32,x7: T32,x8: T32,x9: T32,x10: T32)
+|C4_32(x1: T32,x2: T32,x3: T32,x4: T32,x5: T32,x6: T32,x7: T32,x8: T32,x9: T32,x10: T32)
+|C5_32(x1: T32,x2: T32,x3: T32,x4: T32,x5: T32,x6: T32,x7: T32,x8: T32,x9: T32,x10: T32)
+|C6_32(x1: T32,x2: T32,x3: T32,x4: T32,x5: T32,x6: T32,x7: T32,x8: T32,x9: T32,x10: T32)
+|C7_32(x1: T32,x2: T32,x3: T32,x4: T32,x5: T32,x6: T32,x7: T32,x8: T32,x9: T32,x10: T32)
+|C8_32(x1: T32,x2: T32,x3: T32,x4: T32,x5: T32,x6: T32,x7: T32,x8: T32,x9: T32,x10: T32)
+|C9_32(x1: T32,x2: T32,x3: T32,x4: T32,x5: T32,x6: T32,x7: T32,x8: T32,x9: T32,x10: T32)
+|C10_32(x1: T32,x2: T32,x3: T32,x4: T32,x5: T32,x6: T32,x7: T32,x8: T32,x9: T32,x10: T32)
+T33 = C1_33(x1: T33,x2: T33,x3: T33,x4: T33,x5: T33,x6: T33,x7: T33,x8: T33,x9: T33,x10: T33)
+|C2_33(x1: T33,x2: T33,x3: T33,x4: T33,x5: T33,x6: T33,x7: T33,x8: T33,x9: T33,x10: T33)
+|C3_33(x1: T33,x2: T33,x3: T33,x4: T33,x5: T33,x6: T33,x7: T33,x8: T33,x9: T33,x10: T33)
+|C4_33(x1: T33,x2: T33,x3: T33,x4: T33,x5: T33,x6: T33,x7: T33,x8: T33,x9: T33,x10: T33)
+|C5_33(x1: T33,x2: T33,x3: T33,x4: T33,x5: T33,x6: T33,x7: T33,x8: T33,x9: T33,x10: T33)
+|C6_33(x1: T33,x2: T33,x3: T33,x4: T33,x5: T33,x6: T33,x7: T33,x8: T33,x9: T33,x10: T33)
+|C7_33(x1: T33,x2: T33,x3: T33,x4: T33,x5: T33,x6: T33,x7: T33,x8: T33,x9: T33,x10: T33)
+|C8_33(x1: T33,x2: T33,x3: T33,x4: T33,x5: T33,x6: T33,x7: T33,x8: T33,x9: T33,x10: T33)
+|C9_33(x1: T33,x2: T33,x3: T33,x4: T33,x5: T33,x6: T33,x7: T33,x8: T33,x9: T33,x10: T33)
+|C10_33(x1: T33,x2: T33,x3: T33,x4: T33,x5: T33,x6: T33,x7: T33,x8: T33,x9: T33,x10: T33)
+T34 = C1_34(x1: T34,x2: T34,x3: T34,x4: T34,x5: T34,x6: T34,x7: T34,x8: T34,x9: T34,x10: T34)
+|C2_34(x1: T34,x2: T34,x3: T34,x4: T34,x5: T34,x6: T34,x7: T34,x8: T34,x9: T34,x10: T34)
+|C3_34(x1: T34,x2: T34,x3: T34,x4: T34,x5: T34,x6: T34,x7: T34,x8: T34,x9: T34,x10: T34)
+|C4_34(x1: T34,x2: T34,x3: T34,x4: T34,x5: T34,x6: T34,x7: T34,x8: T34,x9: T34,x10: T34)
+|C5_34(x1: T34,x2: T34,x3: T34,x4: T34,x5: T34,x6: T34,x7: T34,x8: T34,x9: T34,x10: T34)
+|C6_34(x1: T34,x2: T34,x3: T34,x4: T34,x5: T34,x6: T34,x7: T34,x8: T34,x9: T34,x10: T34)
+|C7_34(x1: T34,x2: T34,x3: T34,x4: T34,x5: T34,x6: T34,x7: T34,x8: T34,x9: T34,x10: T34)
+|C8_34(x1: T34,x2: T34,x3: T34,x4: T34,x5: T34,x6: T34,x7: T34,x8: T34,x9: T34,x10: T34)
+|C9_34(x1: T34,x2: T34,x3: T34,x4: T34,x5: T34,x6: T34,x7: T34,x8: T34,x9: T34,x10: T34)
+|C10_34(x1: T34,x2: T34,x3: T34,x4: T34,x5: T34,x6: T34,x7: T34,x8: T34,x9: T34,x10: T34)
+T35 = C1_35(x1: T35,x2: T35,x3: T35,x4: T35,x5: T35,x6: T35,x7: T35,x8: T35,x9: T35,x10: T35)
+|C2_35(x1: T35,x2: T35,x3: T35,x4: T35,x5: T35,x6: T35,x7: T35,x8: T35,x9: T35,x10: T35)
+|C3_35(x1: T35,x2: T35,x3: T35,x4: T35,x5: T35,x6: T35,x7: T35,x8: T35,x9: T35,x10: T35)
+|C4_35(x1: T35,x2: T35,x3: T35,x4: T35,x5: T35,x6: T35,x7: T35,x8: T35,x9: T35,x10: T35)
+|C5_35(x1: T35,x2: T35,x3: T35,x4: T35,x5: T35,x6: T35,x7: T35,x8: T35,x9: T35,x10: T35)
+|C6_35(x1: T35,x2: T35,x3: T35,x4: T35,x5: T35,x6: T35,x7: T35,x8: T35,x9: T35,x10: T35)
+|C7_35(x1: T35,x2: T35,x3: T35,x4: T35,x5: T35,x6: T35,x7: T35,x8: T35,x9: T35,x10: T35)
+|C8_35(x1: T35,x2: T35,x3: T35,x4: T35,x5: T35,x6: T35,x7: T35,x8: T35,x9: T35,x10: T35)
+|C9_35(x1: T35,x2: T35,x3: T35,x4: T35,x5: T35,x6: T35,x7: T35,x8: T35,x9: T35,x10: T35)
+|C10_35(x1: T35,x2: T35,x3: T35,x4: T35,x5: T35,x6: T35,x7: T35,x8: T35,x9: T35,x10: T35)
+T36 = C1_36(x1: T36,x2: T36,x3: T36,x4: T36,x5: T36,x6: T36,x7: T36,x8: T36,x9: T36,x10: T36)
+|C2_36(x1: T36,x2: T36,x3: T36,x4: T36,x5: T36,x6: T36,x7: T36,x8: T36,x9: T36,x10: T36)
+|C3_36(x1: T36,x2: T36,x3: T36,x4: T36,x5: T36,x6: T36,x7: T36,x8: T36,x9: T36,x10: T36)
+|C4_36(x1: T36,x2: T36,x3: T36,x4: T36,x5: T36,x6: T36,x7: T36,x8: T36,x9: T36,x10: T36)
+|C5_36(x1: T36,x2: T36,x3: T36,x4: T36,x5: T36,x6: T36,x7: T36,x8: T36,x9: T36,x10: T36)
+|C6_36(x1: T36,x2: T36,x3: T36,x4: T36,x5: T36,x6: T36,x7: T36,x8: T36,x9: T36,x10: T36)
+|C7_36(x1: T36,x2: T36,x3: T36,x4: T36,x5: T36,x6: T36,x7: T36,x8: T36,x9: T36,x10: T36)
+|C8_36(x1: T36,x2: T36,x3: T36,x4: T36,x5: T36,x6: T36,x7: T36,x8: T36,x9: T36,x10: T36)
+|C9_36(x1: T36,x2: T36,x3: T36,x4: T36,x5: T36,x6: T36,x7: T36,x8: T36,x9: T36,x10: T36)
+|C10_36(x1: T36,x2: T36,x3: T36,x4: T36,x5: T36,x6: T36,x7: T36,x8: T36,x9: T36,x10: T36)
+T37 = C1_37(x1: T37,x2: T37,x3: T37,x4: T37,x5: T37,x6: T37,x7: T37,x8: T37,x9: T37,x10: T37)
+|C2_37(x1: T37,x2: T37,x3: T37,x4: T37,x5: T37,x6: T37,x7: T37,x8: T37,x9: T37,x10: T37)
+|C3_37(x1: T37,x2: T37,x3: T37,x4: T37,x5: T37,x6: T37,x7: T37,x8: T37,x9: T37,x10: T37)
+|C4_37(x1: T37,x2: T37,x3: T37,x4: T37,x5: T37,x6: T37,x7: T37,x8: T37,x9: T37,x10: T37)
+|C5_37(x1: T37,x2: T37,x3: T37,x4: T37,x5: T37,x6: T37,x7: T37,x8: T37,x9: T37,x10: T37)
+|C6_37(x1: T37,x2: T37,x3: T37,x4: T37,x5: T37,x6: T37,x7: T37,x8: T37,x9: T37,x10: T37)
+|C7_37(x1: T37,x2: T37,x3: T37,x4: T37,x5: T37,x6: T37,x7: T37,x8: T37,x9: T37,x10: T37)
+|C8_37(x1: T37,x2: T37,x3: T37,x4: T37,x5: T37,x6: T37,x7: T37,x8: T37,x9: T37,x10: T37)
+|C9_37(x1: T37,x2: T37,x3: T37,x4: T37,x5: T37,x6: T37,x7: T37,x8: T37,x9: T37,x10: T37)
+|C10_37(x1: T37,x2: T37,x3: T37,x4: T37,x5: T37,x6: T37,x7: T37,x8: T37,x9: T37,x10: T37)
+T38 = C1_38(x1: T38,x2: T38,x3: T38,x4: T38,x5: T38,x6: T38,x7: T38,x8: T38,x9: T38,x10: T38)
+|C2_38(x1: T38,x2: T38,x3: T38,x4: T38,x5: T38,x6: T38,x7: T38,x8: T38,x9: T38,x10: T38)
+|C3_38(x1: T38,x2: T38,x3: T38,x4: T38,x5: T38,x6: T38,x7: T38,x8: T38,x9: T38,x10: T38)
+|C4_38(x1: T38,x2: T38,x3: T38,x4: T38,x5: T38,x6: T38,x7: T38,x8: T38,x9: T38,x10: T38)
+|C5_38(x1: T38,x2: T38,x3: T38,x4: T38,x5: T38,x6: T38,x7: T38,x8: T38,x9: T38,x10: T38)
+|C6_38(x1: T38,x2: T38,x3: T38,x4: T38,x5: T38,x6: T38,x7: T38,x8: T38,x9: T38,x10: T38)
+|C7_38(x1: T38,x2: T38,x3: T38,x4: T38,x5: T38,x6: T38,x7: T38,x8: T38,x9: T38,x10: T38)
+|C8_38(x1: T38,x2: T38,x3: T38,x4: T38,x5: T38,x6: T38,x7: T38,x8: T38,x9: T38,x10: T38)
+|C9_38(x1: T38,x2: T38,x3: T38,x4: T38,x5: T38,x6: T38,x7: T38,x8: T38,x9: T38,x10: T38)
+|C10_38(x1: T38,x2: T38,x3: T38,x4: T38,x5: T38,x6: T38,x7: T38,x8: T38,x9: T38,x10: T38)
+T39 = C1_39(x1: T39,x2: T39,x3: T39,x4: T39,x5: T39,x6: T39,x7: T39,x8: T39,x9: T39,x10: T39)
+|C2_39(x1: T39,x2: T39,x3: T39,x4: T39,x5: T39,x6: T39,x7: T39,x8: T39,x9: T39,x10: T39)
+|C3_39(x1: T39,x2: T39,x3: T39,x4: T39,x5: T39,x6: T39,x7: T39,x8: T39,x9: T39,x10: T39)
+|C4_39(x1: T39,x2: T39,x3: T39,x4: T39,x5: T39,x6: T39,x7: T39,x8: T39,x9: T39,x10: T39)
+|C5_39(x1: T39,x2: T39,x3: T39,x4: T39,x5: T39,x6: T39,x7: T39,x8: T39,x9: T39,x10: T39)
+|C6_39(x1: T39,x2: T39,x3: T39,x4: T39,x5: T39,x6: T39,x7: T39,x8: T39,x9: T39,x10: T39)
+|C7_39(x1: T39,x2: T39,x3: T39,x4: T39,x5: T39,x6: T39,x7: T39,x8: T39,x9: T39,x10: T39)
+|C8_39(x1: T39,x2: T39,x3: T39,x4: T39,x5: T39,x6: T39,x7: T39,x8: T39,x9: T39,x10: T39)
+|C9_39(x1: T39,x2: T39,x3: T39,x4: T39,x5: T39,x6: T39,x7: T39,x8: T39,x9: T39,x10: T39)
+|C10_39(x1: T39,x2: T39,x3: T39,x4: T39,x5: T39,x6: T39,x7: T39,x8: T39,x9: T39,x10: T39)
+T40 = C1_40(x1: T40,x2: T40,x3: T40,x4: T40,x5: T40,x6: T40,x7: T40,x8: T40,x9: T40,x10: T40)
+|C2_40(x1: T40,x2: T40,x3: T40,x4: T40,x5: T40,x6: T40,x7: T40,x8: T40,x9: T40,x10: T40)
+|C3_40(x1: T40,x2: T40,x3: T40,x4: T40,x5: T40,x6: T40,x7: T40,x8: T40,x9: T40,x10: T40)
+|C4_40(x1: T40,x2: T40,x3: T40,x4: T40,x5: T40,x6: T40,x7: T40,x8: T40,x9: T40,x10: T40)
+|C5_40(x1: T40,x2: T40,x3: T40,x4: T40,x5: T40,x6: T40,x7: T40,x8: T40,x9: T40,x10: T40)
+|C6_40(x1: T40,x2: T40,x3: T40,x4: T40,x5: T40,x6: T40,x7: T40,x8: T40,x9: T40,x10: T40)
+|C7_40(x1: T40,x2: T40,x3: T40,x4: T40,x5: T40,x6: T40,x7: T40,x8: T40,x9: T40,x10: T40)
+|C8_40(x1: T40,x2: T40,x3: T40,x4: T40,x5: T40,x6: T40,x7: T40,x8: T40,x9: T40,x10: T40)
+|C9_40(x1: T40,x2: T40,x3: T40,x4: T40,x5: T40,x6: T40,x7: T40,x8: T40,x9: T40,x10: T40)
+|C10_40(x1: T40,x2: T40,x3: T40,x4: T40,x5: T40,x6: T40,x7: T40,x8: T40,x9: T40,x10: T40)
+T41 = C1_41(x1: T41,x2: T41,x3: T41,x4: T41,x5: T41,x6: T41,x7: T41,x8: T41,x9: T41,x10: T41)
+|C2_41(x1: T41,x2: T41,x3: T41,x4: T41,x5: T41,x6: T41,x7: T41,x8: T41,x9: T41,x10: T41)
+|C3_41(x1: T41,x2: T41,x3: T41,x4: T41,x5: T41,x6: T41,x7: T41,x8: T41,x9: T41,x10: T41)
+|C4_41(x1: T41,x2: T41,x3: T41,x4: T41,x5: T41,x6: T41,x7: T41,x8: T41,x9: T41,x10: T41)
+|C5_41(x1: T41,x2: T41,x3: T41,x4: T41,x5: T41,x6: T41,x7: T41,x8: T41,x9: T41,x10: T41)
+|C6_41(x1: T41,x2: T41,x3: T41,x4: T41,x5: T41,x6: T41,x7: T41,x8: T41,x9: T41,x10: T41)
+|C7_41(x1: T41,x2: T41,x3: T41,x4: T41,x5: T41,x6: T41,x7: T41,x8: T41,x9: T41,x10: T41)
+|C8_41(x1: T41,x2: T41,x3: T41,x4: T41,x5: T41,x6: T41,x7: T41,x8: T41,x9: T41,x10: T41)
+|C9_41(x1: T41,x2: T41,x3: T41,x4: T41,x5: T41,x6: T41,x7: T41,x8: T41,x9: T41,x10: T41)
+|C10_41(x1: T41,x2: T41,x3: T41,x4: T41,x5: T41,x6: T41,x7: T41,x8: T41,x9: T41,x10: T41)
+T42 = C1_42(x1: T42,x2: T42,x3: T42,x4: T42,x5: T42,x6: T42,x7: T42,x8: T42,x9: T42,x10: T42)
+|C2_42(x1: T42,x2: T42,x3: T42,x4: T42,x5: T42,x6: T42,x7: T42,x8: T42,x9: T42,x10: T42)
+|C3_42(x1: T42,x2: T42,x3: T42,x4: T42,x5: T42,x6: T42,x7: T42,x8: T42,x9: T42,x10: T42)
+|C4_42(x1: T42,x2: T42,x3: T42,x4: T42,x5: T42,x6: T42,x7: T42,x8: T42,x9: T42,x10: T42)
+|C5_42(x1: T42,x2: T42,x3: T42,x4: T42,x5: T42,x6: T42,x7: T42,x8: T42,x9: T42,x10: T42)
+|C6_42(x1: T42,x2: T42,x3: T42,x4: T42,x5: T42,x6: T42,x7: T42,x8: T42,x9: T42,x10: T42)
+|C7_42(x1: T42,x2: T42,x3: T42,x4: T42,x5: T42,x6: T42,x7: T42,x8: T42,x9: T42,x10: T42)
+|C8_42(x1: T42,x2: T42,x3: T42,x4: T42,x5: T42,x6: T42,x7: T42,x8: T42,x9: T42,x10: T42)
+|C9_42(x1: T42,x2: T42,x3: T42,x4: T42,x5: T42,x6: T42,x7: T42,x8: T42,x9: T42,x10: T42)
+|C10_42(x1: T42,x2: T42,x3: T42,x4: T42,x5: T42,x6: T42,x7: T42,x8: T42,x9: T42,x10: T42)
+T43 = C1_43(x1: T43,x2: T43,x3: T43,x4: T43,x5: T43,x6: T43,x7: T43,x8: T43,x9: T43,x10: T43)
+|C2_43(x1: T43,x2: T43,x3: T43,x4: T43,x5: T43,x6: T43,x7: T43,x8: T43,x9: T43,x10: T43)
+|C3_43(x1: T43,x2: T43,x3: T43,x4: T43,x5: T43,x6: T43,x7: T43,x8: T43,x9: T43,x10: T43)
+|C4_43(x1: T43,x2: T43,x3: T43,x4: T43,x5: T43,x6: T43,x7: T43,x8: T43,x9: T43,x10: T43)
+|C5_43(x1: T43,x2: T43,x3: T43,x4: T43,x5: T43,x6: T43,x7: T43,x8: T43,x9: T43,x10: T43)
+|C6_43(x1: T43,x2: T43,x3: T43,x4: T43,x5: T43,x6: T43,x7: T43,x8: T43,x9: T43,x10: T43)
+|C7_43(x1: T43,x2: T43,x3: T43,x4: T43,x5: T43,x6: T43,x7: T43,x8: T43,x9: T43,x10: T43)
+|C8_43(x1: T43,x2: T43,x3: T43,x4: T43,x5: T43,x6: T43,x7: T43,x8: T43,x9: T43,x10: T43)
+|C9_43(x1: T43,x2: T43,x3: T43,x4: T43,x5: T43,x6: T43,x7: T43,x8: T43,x9: T43,x10: T43)
+|C10_43(x1: T43,x2: T43,x3: T43,x4: T43,x5: T43,x6: T43,x7: T43,x8: T43,x9: T43,x10: T43)
+T44 = C1_44(x1: T44,x2: T44,x3: T44,x4: T44,x5: T44,x6: T44,x7: T44,x8: T44,x9: T44,x10: T44)
+|C2_44(x1: T44,x2: T44,x3: T44,x4: T44,x5: T44,x6: T44,x7: T44,x8: T44,x9: T44,x10: T44)
+|C3_44(x1: T44,x2: T44,x3: T44,x4: T44,x5: T44,x6: T44,x7: T44,x8: T44,x9: T44,x10: T44)
+|C4_44(x1: T44,x2: T44,x3: T44,x4: T44,x5: T44,x6: T44,x7: T44,x8: T44,x9: T44,x10: T44)
+|C5_44(x1: T44,x2: T44,x3: T44,x4: T44,x5: T44,x6: T44,x7: T44,x8: T44,x9: T44,x10: T44)
+|C6_44(x1: T44,x2: T44,x3: T44,x4: T44,x5: T44,x6: T44,x7: T44,x8: T44,x9: T44,x10: T44)
+|C7_44(x1: T44,x2: T44,x3: T44,x4: T44,x5: T44,x6: T44,x7: T44,x8: T44,x9: T44,x10: T44)
+|C8_44(x1: T44,x2: T44,x3: T44,x4: T44,x5: T44,x6: T44,x7: T44,x8: T44,x9: T44,x10: T44)
+|C9_44(x1: T44,x2: T44,x3: T44,x4: T44,x5: T44,x6: T44,x7: T44,x8: T44,x9: T44,x10: T44)
+|C10_44(x1: T44,x2: T44,x3: T44,x4: T44,x5: T44,x6: T44,x7: T44,x8: T44,x9: T44,x10: T44)
+T45 = C1_45(x1: T45,x2: T45,x3: T45,x4: T45,x5: T45,x6: T45,x7: T45,x8: T45,x9: T45,x10: T45)
+|C2_45(x1: T45,x2: T45,x3: T45,x4: T45,x5: T45,x6: T45,x7: T45,x8: T45,x9: T45,x10: T45)
+|C3_45(x1: T45,x2: T45,x3: T45,x4: T45,x5: T45,x6: T45,x7: T45,x8: T45,x9: T45,x10: T45)
+|C4_45(x1: T45,x2: T45,x3: T45,x4: T45,x5: T45,x6: T45,x7: T45,x8: T45,x9: T45,x10: T45)
+|C5_45(x1: T45,x2: T45,x3: T45,x4: T45,x5: T45,x6: T45,x7: T45,x8: T45,x9: T45,x10: T45)
+|C6_45(x1: T45,x2: T45,x3: T45,x4: T45,x5: T45,x6: T45,x7: T45,x8: T45,x9: T45,x10: T45)
+|C7_45(x1: T45,x2: T45,x3: T45,x4: T45,x5: T45,x6: T45,x7: T45,x8: T45,x9: T45,x10: T45)
+|C8_45(x1: T45,x2: T45,x3: T45,x4: T45,x5: T45,x6: T45,x7: T45,x8: T45,x9: T45,x10: T45)
+|C9_45(x1: T45,x2: T45,x3: T45,x4: T45,x5: T45,x6: T45,x7: T45,x8: T45,x9: T45,x10: T45)
+|C10_45(x1: T45,x2: T45,x3: T45,x4: T45,x5: T45,x6: T45,x7: T45,x8: T45,x9: T45,x10: T45)
+T46 = C1_46(x1: T46,x2: T46,x3: T46,x4: T46,x5: T46,x6: T46,x7: T46,x8: T46,x9: T46,x10: T46)
+|C2_46(x1: T46,x2: T46,x3: T46,x4: T46,x5: T46,x6: T46,x7: T46,x8: T46,x9: T46,x10: T46)
+|C3_46(x1: T46,x2: T46,x3: T46,x4: T46,x5: T46,x6: T46,x7: T46,x8: T46,x9: T46,x10: T46)
+|C4_46(x1: T46,x2: T46,x3: T46,x4: T46,x5: T46,x6: T46,x7: T46,x8: T46,x9: T46,x10: T46)
+|C5_46(x1: T46,x2: T46,x3: T46,x4: T46,x5: T46,x6: T46,x7: T46,x8: T46,x9: T46,x10: T46)
+|C6_46(x1: T46,x2: T46,x3: T46,x4: T46,x5: T46,x6: T46,x7: T46,x8: T46,x9: T46,x10: T46)
+|C7_46(x1: T46,x2: T46,x3: T46,x4: T46,x5: T46,x6: T46,x7: T46,x8: T46,x9: T46,x10: T46)
+|C8_46(x1: T46,x2: T46,x3: T46,x4: T46,x5: T46,x6: T46,x7: T46,x8: T46,x9: T46,x10: T46)
+|C9_46(x1: T46,x2: T46,x3: T46,x4: T46,x5: T46,x6: T46,x7: T46,x8: T46,x9: T46,x10: T46)
+|C10_46(x1: T46,x2: T46,x3: T46,x4: T46,x5: T46,x6: T46,x7: T46,x8: T46,x9: T46,x10: T46)
+T47 = C1_47(x1: T47,x2: T47,x3: T47,x4: T47,x5: T47,x6: T47,x7: T47,x8: T47,x9: T47,x10: T47)
+|C2_47(x1: T47,x2: T47,x3: T47,x4: T47,x5: T47,x6: T47,x7: T47,x8: T47,x9: T47,x10: T47)
+|C3_47(x1: T47,x2: T47,x3: T47,x4: T47,x5: T47,x6: T47,x7: T47,x8: T47,x9: T47,x10: T47)
+|C4_47(x1: T47,x2: T47,x3: T47,x4: T47,x5: T47,x6: T47,x7: T47,x8: T47,x9: T47,x10: T47)
+|C5_47(x1: T47,x2: T47,x3: T47,x4: T47,x5: T47,x6: T47,x7: T47,x8: T47,x9: T47,x10: T47)
+|C6_47(x1: T47,x2: T47,x3: T47,x4: T47,x5: T47,x6: T47,x7: T47,x8: T47,x9: T47,x10: T47)
+|C7_47(x1: T47,x2: T47,x3: T47,x4: T47,x5: T47,x6: T47,x7: T47,x8: T47,x9: T47,x10: T47)
+|C8_47(x1: T47,x2: T47,x3: T47,x4: T47,x5: T47,x6: T47,x7: T47,x8: T47,x9: T47,x10: T47)
+|C9_47(x1: T47,x2: T47,x3: T47,x4: T47,x5: T47,x6: T47,x7: T47,x8: T47,x9: T47,x10: T47)
+|C10_47(x1: T47,x2: T47,x3: T47,x4: T47,x5: T47,x6: T47,x7: T47,x8: T47,x9: T47,x10: T47)
+T48 = C1_48(x1: T48,x2: T48,x3: T48,x4: T48,x5: T48,x6: T48,x7: T48,x8: T48,x9: T48,x10: T48)
+|C2_48(x1: T48,x2: T48,x3: T48,x4: T48,x5: T48,x6: T48,x7: T48,x8: T48,x9: T48,x10: T48)
+|C3_48(x1: T48,x2: T48,x3: T48,x4: T48,x5: T48,x6: T48,x7: T48,x8: T48,x9: T48,x10: T48)
+|C4_48(x1: T48,x2: T48,x3: T48,x4: T48,x5: T48,x6: T48,x7: T48,x8: T48,x9: T48,x10: T48)
+|C5_48(x1: T48,x2: T48,x3: T48,x4: T48,x5: T48,x6: T48,x7: T48,x8: T48,x9: T48,x10: T48)
+|C6_48(x1: T48,x2: T48,x3: T48,x4: T48,x5: T48,x6: T48,x7: T48,x8: T48,x9: T48,x10: T48)
+|C7_48(x1: T48,x2: T48,x3: T48,x4: T48,x5: T48,x6: T48,x7: T48,x8: T48,x9: T48,x10: T48)
+|C8_48(x1: T48,x2: T48,x3: T48,x4: T48,x5: T48,x6: T48,x7: T48,x8: T48,x9: T48,x10: T48)
+|C9_48(x1: T48,x2: T48,x3: T48,x4: T48,x5: T48,x6: T48,x7: T48,x8: T48,x9: T48,x10: T48)
+|C10_48(x1: T48,x2: T48,x3: T48,x4: T48,x5: T48,x6: T48,x7: T48,x8: T48,x9: T48,x10: T48)
+T49 = C1_49(x1: T49,x2: T49,x3: T49,x4: T49,x5: T49,x6: T49,x7: T49,x8: T49,x9: T49,x10: T49)
+|C2_49(x1: T49,x2: T49,x3: T49,x4: T49,x5: T49,x6: T49,x7: T49,x8: T49,x9: T49,x10: T49)
+|C3_49(x1: T49,x2: T49,x3: T49,x4: T49,x5: T49,x6: T49,x7: T49,x8: T49,x9: T49,x10: T49)
+|C4_49(x1: T49,x2: T49,x3: T49,x4: T49,x5: T49,x6: T49,x7: T49,x8: T49,x9: T49,x10: T49)
+|C5_49(x1: T49,x2: T49,x3: T49,x4: T49,x5: T49,x6: T49,x7: T49,x8: T49,x9: T49,x10: T49)
+|C6_49(x1: T49,x2: T49,x3: T49,x4: T49,x5: T49,x6: T49,x7: T49,x8: T49,x9: T49,x10: T49)
+|C7_49(x1: T49,x2: T49,x3: T49,x4: T49,x5: T49,x6: T49,x7: T49,x8: T49,x9: T49,x10: T49)
+|C8_49(x1: T49,x2: T49,x3: T49,x4: T49,x5: T49,x6: T49,x7: T49,x8: T49,x9: T49,x10: T49)
+|C9_49(x1: T49,x2: T49,x3: T49,x4: T49,x5: T49,x6: T49,x7: T49,x8: T49,x9: T49,x10: T49)
+|C10_49(x1: T49,x2: T49,x3: T49,x4: T49,x5: T49,x6: T49,x7: T49,x8: T49,x9: T49,x10: T49)
+T50 = C1_50(x1: T50,x2: T50,x3: T50,x4: T50,x5: T50,x6: T50,x7: T50,x8: T50,x9: T50,x10: T50)
+|C2_50(x1: T50,x2: T50,x3: T50,x4: T50,x5: T50,x6: T50,x7: T50,x8: T50,x9: T50,x10: T50)
+|C3_50(x1: T50,x2: T50,x3: T50,x4: T50,x5: T50,x6: T50,x7: T50,x8: T50,x9: T50,x10: T50)
+|C4_50(x1: T50,x2: T50,x3: T50,x4: T50,x5: T50,x6: T50,x7: T50,x8: T50,x9: T50,x10: T50)
+|C5_50(x1: T50,x2: T50,x3: T50,x4: T50,x5: T50,x6: T50,x7: T50,x8: T50,x9: T50,x10: T50)
+|C6_50(x1: T50,x2: T50,x3: T50,x4: T50,x5: T50,x6: T50,x7: T50,x8: T50,x9: T50,x10: T50)
+|C7_50(x1: T50,x2: T50,x3: T50,x4: T50,x5: T50,x6: T50,x7: T50,x8: T50,x9: T50,x10: T50)
+|C8_50(x1: T50,x2: T50,x3: T50,x4: T50,x5: T50,x6: T50,x7: T50,x8: T50,x9: T50,x10: T50)
+|C9_50(x1: T50,x2: T50,x3: T50,x4: T50,x5: T50,x6: T50,x7: T50,x8: T50,x9: T50,x10: T50)
+|C10_50(x1: T50,x2: T50,x3: T50,x4: T50,x5: T50,x6: T50,x7: T50,x8: T50,x9: T50,x10: T50)
+T51 = C1_51(x1: T51,x2: T51,x3: T51,x4: T51,x5: T51,x6: T51,x7: T51,x8: T51,x9: T51,x10: T51)
+|C2_51(x1: T51,x2: T51,x3: T51,x4: T51,x5: T51,x6: T51,x7: T51,x8: T51,x9: T51,x10: T51)
+|C3_51(x1: T51,x2: T51,x3: T51,x4: T51,x5: T51,x6: T51,x7: T51,x8: T51,x9: T51,x10: T51)
+|C4_51(x1: T51,x2: T51,x3: T51,x4: T51,x5: T51,x6: T51,x7: T51,x8: T51,x9: T51,x10: T51)
+|C5_51(x1: T51,x2: T51,x3: T51,x4: T51,x5: T51,x6: T51,x7: T51,x8: T51,x9: T51,x10: T51)
+|C6_51(x1: T51,x2: T51,x3: T51,x4: T51,x5: T51,x6: T51,x7: T51,x8: T51,x9: T51,x10: T51)
+|C7_51(x1: T51,x2: T51,x3: T51,x4: T51,x5: T51,x6: T51,x7: T51,x8: T51,x9: T51,x10: T51)
+|C8_51(x1: T51,x2: T51,x3: T51,x4: T51,x5: T51,x6: T51,x7: T51,x8: T51,x9: T51,x10: T51)
+|C9_51(x1: T51,x2: T51,x3: T51,x4: T51,x5: T51,x6: T51,x7: T51,x8: T51,x9: T51,x10: T51)
+|C10_51(x1: T51,x2: T51,x3: T51,x4: T51,x5: T51,x6: T51,x7: T51,x8: T51,x9: T51,x10: T51)
+T52 = C1_52(x1: T52,x2: T52,x3: T52,x4: T52,x5: T52,x6: T52,x7: T52,x8: T52,x9: T52,x10: T52)
+|C2_52(x1: T52,x2: T52,x3: T52,x4: T52,x5: T52,x6: T52,x7: T52,x8: T52,x9: T52,x10: T52)
+|C3_52(x1: T52,x2: T52,x3: T52,x4: T52,x5: T52,x6: T52,x7: T52,x8: T52,x9: T52,x10: T52)
+|C4_52(x1: T52,x2: T52,x3: T52,x4: T52,x5: T52,x6: T52,x7: T52,x8: T52,x9: T52,x10: T52)
+|C5_52(x1: T52,x2: T52,x3: T52,x4: T52,x5: T52,x6: T52,x7: T52,x8: T52,x9: T52,x10: T52)
+|C6_52(x1: T52,x2: T52,x3: T52,x4: T52,x5: T52,x6: T52,x7: T52,x8: T52,x9: T52,x10: T52)
+|C7_52(x1: T52,x2: T52,x3: T52,x4: T52,x5: T52,x6: T52,x7: T52,x8: T52,x9: T52,x10: T52)
+|C8_52(x1: T52,x2: T52,x3: T52,x4: T52,x5: T52,x6: T52,x7: T52,x8: T52,x9: T52,x10: T52)
+|C9_52(x1: T52,x2: T52,x3: T52,x4: T52,x5: T52,x6: T52,x7: T52,x8: T52,x9: T52,x10: T52)
+|C10_52(x1: T52,x2: T52,x3: T52,x4: T52,x5: T52,x6: T52,x7: T52,x8: T52,x9: T52,x10: T52)
+T53 = C1_53(x1: T53,x2: T53,x3: T53,x4: T53,x5: T53,x6: T53,x7: T53,x8: T53,x9: T53,x10: T53)
+|C2_53(x1: T53,x2: T53,x3: T53,x4: T53,x5: T53,x6: T53,x7: T53,x8: T53,x9: T53,x10: T53)
+|C3_53(x1: T53,x2: T53,x3: T53,x4: T53,x5: T53,x6: T53,x7: T53,x8: T53,x9: T53,x10: T53)
+|C4_53(x1: T53,x2: T53,x3: T53,x4: T53,x5: T53,x6: T53,x7: T53,x8: T53,x9: T53,x10: T53)
+|C5_53(x1: T53,x2: T53,x3: T53,x4: T53,x5: T53,x6: T53,x7: T53,x8: T53,x9: T53,x10: T53)
+|C6_53(x1: T53,x2: T53,x3: T53,x4: T53,x5: T53,x6: T53,x7: T53,x8: T53,x9: T53,x10: T53)
+|C7_53(x1: T53,x2: T53,x3: T53,x4: T53,x5: T53,x6: T53,x7: T53,x8: T53,x9: T53,x10: T53)
+|C8_53(x1: T53,x2: T53,x3: T53,x4: T53,x5: T53,x6: T53,x7: T53,x8: T53,x9: T53,x10: T53)
+|C9_53(x1: T53,x2: T53,x3: T53,x4: T53,x5: T53,x6: T53,x7: T53,x8: T53,x9: T53,x10: T53)
+|C10_53(x1: T53,x2: T53,x3: T53,x4: T53,x5: T53,x6: T53,x7: T53,x8: T53,x9: T53,x10: T53)
+T54 = C1_54(x1: T54,x2: T54,x3: T54,x4: T54,x5: T54,x6: T54,x7: T54,x8: T54,x9: T54,x10: T54)
+|C2_54(x1: T54,x2: T54,x3: T54,x4: T54,x5: T54,x6: T54,x7: T54,x8: T54,x9: T54,x10: T54)
+|C3_54(x1: T54,x2: T54,x3: T54,x4: T54,x5: T54,x6: T54,x7: T54,x8: T54,x9: T54,x10: T54)
+|C4_54(x1: T54,x2: T54,x3: T54,x4: T54,x5: T54,x6: T54,x7: T54,x8: T54,x9: T54,x10: T54)
+|C5_54(x1: T54,x2: T54,x3: T54,x4: T54,x5: T54,x6: T54,x7: T54,x8: T54,x9: T54,x10: T54)
+|C6_54(x1: T54,x2: T54,x3: T54,x4: T54,x5: T54,x6: T54,x7: T54,x8: T54,x9: T54,x10: T54)
+|C7_54(x1: T54,x2: T54,x3: T54,x4: T54,x5: T54,x6: T54,x7: T54,x8: T54,x9: T54,x10: T54)
+|C8_54(x1: T54,x2: T54,x3: T54,x4: T54,x5: T54,x6: T54,x7: T54,x8: T54,x9: T54,x10: T54)
+|C9_54(x1: T54,x2: T54,x3: T54,x4: T54,x5: T54,x6: T54,x7: T54,x8: T54,x9: T54,x10: T54)
+|C10_54(x1: T54,x2: T54,x3: T54,x4: T54,x5: T54,x6: T54,x7: T54,x8: T54,x9: T54,x10: T54)
+T55 = C1_55(x1: T55,x2: T55,x3: T55,x4: T55,x5: T55,x6: T55,x7: T55,x8: T55,x9: T55,x10: T55)
+|C2_55(x1: T55,x2: T55,x3: T55,x4: T55,x5: T55,x6: T55,x7: T55,x8: T55,x9: T55,x10: T55)
+|C3_55(x1: T55,x2: T55,x3: T55,x4: T55,x5: T55,x6: T55,x7: T55,x8: T55,x9: T55,x10: T55)
+|C4_55(x1: T55,x2: T55,x3: T55,x4: T55,x5: T55,x6: T55,x7: T55,x8: T55,x9: T55,x10: T55)
+|C5_55(x1: T55,x2: T55,x3: T55,x4: T55,x5: T55,x6: T55,x7: T55,x8: T55,x9: T55,x10: T55)
+|C6_55(x1: T55,x2: T55,x3: T55,x4: T55,x5: T55,x6: T55,x7: T55,x8: T55,x9: T55,x10: T55)
+|C7_55(x1: T55,x2: T55,x3: T55,x4: T55,x5: T55,x6: T55,x7: T55,x8: T55,x9: T55,x10: T55)
+|C8_55(x1: T55,x2: T55,x3: T55,x4: T55,x5: T55,x6: T55,x7: T55,x8: T55,x9: T55,x10: T55)
+|C9_55(x1: T55,x2: T55,x3: T55,x4: T55,x5: T55,x6: T55,x7: T55,x8: T55,x9: T55,x10: T55)
+|C10_55(x1: T55,x2: T55,x3: T55,x4: T55,x5: T55,x6: T55,x7: T55,x8: T55,x9: T55,x10: T55)
+T56 = C1_56(x1: T56,x2: T56,x3: T56,x4: T56,x5: T56,x6: T56,x7: T56,x8: T56,x9: T56,x10: T56)
+|C2_56(x1: T56,x2: T56,x3: T56,x4: T56,x5: T56,x6: T56,x7: T56,x8: T56,x9: T56,x10: T56)
+|C3_56(x1: T56,x2: T56,x3: T56,x4: T56,x5: T56,x6: T56,x7: T56,x8: T56,x9: T56,x10: T56)
+|C4_56(x1: T56,x2: T56,x3: T56,x4: T56,x5: T56,x6: T56,x7: T56,x8: T56,x9: T56,x10: T56)
+|C5_56(x1: T56,x2: T56,x3: T56,x4: T56,x5: T56,x6: T56,x7: T56,x8: T56,x9: T56,x10: T56)
+|C6_56(x1: T56,x2: T56,x3: T56,x4: T56,x5: T56,x6: T56,x7: T56,x8: T56,x9: T56,x10: T56)
+|C7_56(x1: T56,x2: T56,x3: T56,x4: T56,x5: T56,x6: T56,x7: T56,x8: T56,x9: T56,x10: T56)
+|C8_56(x1: T56,x2: T56,x3: T56,x4: T56,x5: T56,x6: T56,x7: T56,x8: T56,x9: T56,x10: T56)
+|C9_56(x1: T56,x2: T56,x3: T56,x4: T56,x5: T56,x6: T56,x7: T56,x8: T56,x9: T56,x10: T56)
+|C10_56(x1: T56,x2: T56,x3: T56,x4: T56,x5: T56,x6: T56,x7: T56,x8: T56,x9: T56,x10: T56)
+T57 = C1_57(x1: T57,x2: T57,x3: T57,x4: T57,x5: T57,x6: T57,x7: T57,x8: T57,x9: T57,x10: T57)
+|C2_57(x1: T57,x2: T57,x3: T57,x4: T57,x5: T57,x6: T57,x7: T57,x8: T57,x9: T57,x10: T57)
+|C3_57(x1: T57,x2: T57,x3: T57,x4: T57,x5: T57,x6: T57,x7: T57,x8: T57,x9: T57,x10: T57)
+|C4_57(x1: T57,x2: T57,x3: T57,x4: T57,x5: T57,x6: T57,x7: T57,x8: T57,x9: T57,x10: T57)
+|C5_57(x1: T57,x2: T57,x3: T57,x4: T57,x5: T57,x6: T57,x7: T57,x8: T57,x9: T57,x10: T57)
+|C6_57(x1: T57,x2: T57,x3: T57,x4: T57,x5: T57,x6: T57,x7: T57,x8: T57,x9: T57,x10: T57)
+|C7_57(x1: T57,x2: T57,x3: T57,x4: T57,x5: T57,x6: T57,x7: T57,x8: T57,x9: T57,x10: T57)
+|C8_57(x1: T57,x2: T57,x3: T57,x4: T57,x5: T57,x6: T57,x7: T57,x8: T57,x9: T57,x10: T57)
+|C9_57(x1: T57,x2: T57,x3: T57,x4: T57,x5: T57,x6: T57,x7: T57,x8: T57,x9: T57,x10: T57)
+|C10_57(x1: T57,x2: T57,x3: T57,x4: T57,x5: T57,x6: T57,x7: T57,x8: T57,x9: T57,x10: T57)
+T58 = C1_58(x1: T58,x2: T58,x3: T58,x4: T58,x5: T58,x6: T58,x7: T58,x8: T58,x9: T58,x10: T58)
+|C2_58(x1: T58,x2: T58,x3: T58,x4: T58,x5: T58,x6: T58,x7: T58,x8: T58,x9: T58,x10: T58)
+|C3_58(x1: T58,x2: T58,x3: T58,x4: T58,x5: T58,x6: T58,x7: T58,x8: T58,x9: T58,x10: T58)
+|C4_58(x1: T58,x2: T58,x3: T58,x4: T58,x5: T58,x6: T58,x7: T58,x8: T58,x9: T58,x10: T58)
+|C5_58(x1: T58,x2: T58,x3: T58,x4: T58,x5: T58,x6: T58,x7: T58,x8: T58,x9: T58,x10: T58)
+|C6_58(x1: T58,x2: T58,x3: T58,x4: T58,x5: T58,x6: T58,x7: T58,x8: T58,x9: T58,x10: T58)
+|C7_58(x1: T58,x2: T58,x3: T58,x4: T58,x5: T58,x6: T58,x7: T58,x8: T58,x9: T58,x10: T58)
+|C8_58(x1: T58,x2: T58,x3: T58,x4: T58,x5: T58,x6: T58,x7: T58,x8: T58,x9: T58,x10: T58)
+|C9_58(x1: T58,x2: T58,x3: T58,x4: T58,x5: T58,x6: T58,x7: T58,x8: T58,x9: T58,x10: T58)
+|C10_58(x1: T58,x2: T58,x3: T58,x4: T58,x5: T58,x6: T58,x7: T58,x8: T58,x9: T58,x10: T58)
+T59 = C1_59(x1: T59,x2: T59,x3: T59,x4: T59,x5: T59,x6: T59,x7: T59,x8: T59,x9: T59,x10: T59)
+|C2_59(x1: T59,x2: T59,x3: T59,x4: T59,x5: T59,x6: T59,x7: T59,x8: T59,x9: T59,x10: T59)
+|C3_59(x1: T59,x2: T59,x3: T59,x4: T59,x5: T59,x6: T59,x7: T59,x8: T59,x9: T59,x10: T59)
+|C4_59(x1: T59,x2: T59,x3: T59,x4: T59,x5: T59,x6: T59,x7: T59,x8: T59,x9: T59,x10: T59)
+|C5_59(x1: T59,x2: T59,x3: T59,x4: T59,x5: T59,x6: T59,x7: T59,x8: T59,x9: T59,x10: T59)
+|C6_59(x1: T59,x2: T59,x3: T59,x4: T59,x5: T59,x6: T59,x7: T59,x8: T59,x9: T59,x10: T59)
+|C7_59(x1: T59,x2: T59,x3: T59,x4: T59,x5: T59,x6: T59,x7: T59,x8: T59,x9: T59,x10: T59)
+|C8_59(x1: T59,x2: T59,x3: T59,x4: T59,x5: T59,x6: T59,x7: T59,x8: T59,x9: T59,x10: T59)
+|C9_59(x1: T59,x2: T59,x3: T59,x4: T59,x5: T59,x6: T59,x7: T59,x8: T59,x9: T59,x10: T59)
+|C10_59(x1: T59,x2: T59,x3: T59,x4: T59,x5: T59,x6: T59,x7: T59,x8: T59,x9: T59,x10: T59)
+T60 = C1_60(x1: T60,x2: T60,x3: T60,x4: T60,x5: T60,x6: T60,x7: T60,x8: T60,x9: T60,x10: T60)
+|C2_60(x1: T60,x2: T60,x3: T60,x4: T60,x5: T60,x6: T60,x7: T60,x8: T60,x9: T60,x10: T60)
+|C3_60(x1: T60,x2: T60,x3: T60,x4: T60,x5: T60,x6: T60,x7: T60,x8: T60,x9: T60,x10: T60)
+|C4_60(x1: T60,x2: T60,x3: T60,x4: T60,x5: T60,x6: T60,x7: T60,x8: T60,x9: T60,x10: T60)
+|C5_60(x1: T60,x2: T60,x3: T60,x4: T60,x5: T60,x6: T60,x7: T60,x8: T60,x9: T60,x10: T60)
+|C6_60(x1: T60,x2: T60,x3: T60,x4: T60,x5: T60,x6: T60,x7: T60,x8: T60,x9: T60,x10: T60)
+|C7_60(x1: T60,x2: T60,x3: T60,x4: T60,x5: T60,x6: T60,x7: T60,x8: T60,x9: T60,x10: T60)
+|C8_60(x1: T60,x2: T60,x3: T60,x4: T60,x5: T60,x6: T60,x7: T60,x8: T60,x9: T60,x10: T60)
+|C9_60(x1: T60,x2: T60,x3: T60,x4: T60,x5: T60,x6: T60,x7: T60,x8: T60,x9: T60,x10: T60)
+|C10_60(x1: T60,x2: T60,x3: T60,x4: T60,x5: T60,x6: T60,x7: T60,x8: T60,x9: T60,x10: T60)
+T61 = C1_61(x1: T61,x2: T61,x3: T61,x4: T61,x5: T61,x6: T61,x7: T61,x8: T61,x9: T61,x10: T61)
+|C2_61(x1: T61,x2: T61,x3: T61,x4: T61,x5: T61,x6: T61,x7: T61,x8: T61,x9: T61,x10: T61)
+|C3_61(x1: T61,x2: T61,x3: T61,x4: T61,x5: T61,x6: T61,x7: T61,x8: T61,x9: T61,x10: T61)
+|C4_61(x1: T61,x2: T61,x3: T61,x4: T61,x5: T61,x6: T61,x7: T61,x8: T61,x9: T61,x10: T61)
+|C5_61(x1: T61,x2: T61,x3: T61,x4: T61,x5: T61,x6: T61,x7: T61,x8: T61,x9: T61,x10: T61)
+|C6_61(x1: T61,x2: T61,x3: T61,x4: T61,x5: T61,x6: T61,x7: T61,x8: T61,x9: T61,x10: T61)
+|C7_61(x1: T61,x2: T61,x3: T61,x4: T61,x5: T61,x6: T61,x7: T61,x8: T61,x9: T61,x10: T61)
+|C8_61(x1: T61,x2: T61,x3: T61,x4: T61,x5: T61,x6: T61,x7: T61,x8: T61,x9: T61,x10: T61)
+|C9_61(x1: T61,x2: T61,x3: T61,x4: T61,x5: T61,x6: T61,x7: T61,x8: T61,x9: T61,x10: T61)
+|C10_61(x1: T61,x2: T61,x3: T61,x4: T61,x5: T61,x6: T61,x7: T61,x8: T61,x9: T61,x10: T61)
+T62 = C1_62(x1: T62,x2: T62,x3: T62,x4: T62,x5: T62,x6: T62,x7: T62,x8: T62,x9: T62,x10: T62)
+|C2_62(x1: T62,x2: T62,x3: T62,x4: T62,x5: T62,x6: T62,x7: T62,x8: T62,x9: T62,x10: T62)
+|C3_62(x1: T62,x2: T62,x3: T62,x4: T62,x5: T62,x6: T62,x7: T62,x8: T62,x9: T62,x10: T62)
+|C4_62(x1: T62,x2: T62,x3: T62,x4: T62,x5: T62,x6: T62,x7: T62,x8: T62,x9: T62,x10: T62)
+|C5_62(x1: T62,x2: T62,x3: T62,x4: T62,x5: T62,x6: T62,x7: T62,x8: T62,x9: T62,x10: T62)
+|C6_62(x1: T62,x2: T62,x3: T62,x4: T62,x5: T62,x6: T62,x7: T62,x8: T62,x9: T62,x10: T62)
+|C7_62(x1: T62,x2: T62,x3: T62,x4: T62,x5: T62,x6: T62,x7: T62,x8: T62,x9: T62,x10: T62)
+|C8_62(x1: T62,x2: T62,x3: T62,x4: T62,x5: T62,x6: T62,x7: T62,x8: T62,x9: T62,x10: T62)
+|C9_62(x1: T62,x2: T62,x3: T62,x4: T62,x5: T62,x6: T62,x7: T62,x8: T62,x9: T62,x10: T62)
+|C10_62(x1: T62,x2: T62,x3: T62,x4: T62,x5: T62,x6: T62,x7: T62,x8: T62,x9: T62,x10: T62)
+T63 = C1_63(x1: T63,x2: T63,x3: T63,x4: T63,x5: T63,x6: T63,x7: T63,x8: T63,x9: T63,x10: T63)
+|C2_63(x1: T63,x2: T63,x3: T63,x4: T63,x5: T63,x6: T63,x7: T63,x8: T63,x9: T63,x10: T63)
+|C3_63(x1: T63,x2: T63,x3: T63,x4: T63,x5: T63,x6: T63,x7: T63,x8: T63,x9: T63,x10: T63)
+|C4_63(x1: T63,x2: T63,x3: T63,x4: T63,x5: T63,x6: T63,x7: T63,x8: T63,x9: T63,x10: T63)
+|C5_63(x1: T63,x2: T63,x3: T63,x4: T63,x5: T63,x6: T63,x7: T63,x8: T63,x9: T63,x10: T63)
+|C6_63(x1: T63,x2: T63,x3: T63,x4: T63,x5: T63,x6: T63,x7: T63,x8: T63,x9: T63,x10: T63)
+|C7_63(x1: T63,x2: T63,x3: T63,x4: T63,x5: T63,x6: T63,x7: T63,x8: T63,x9: T63,x10: T63)
+|C8_63(x1: T63,x2: T63,x3: T63,x4: T63,x5: T63,x6: T63,x7: T63,x8: T63,x9: T63,x10: T63)
+|C9_63(x1: T63,x2: T63,x3: T63,x4: T63,x5: T63,x6: T63,x7: T63,x8: T63,x9: T63,x10: T63)
+|C10_63(x1: T63,x2: T63,x3: T63,x4: T63,x5: T63,x6: T63,x7: T63,x8: T63,x9: T63,x10: T63)
+T64 = C1_64(x1: T64,x2: T64,x3: T64,x4: T64,x5: T64,x6: T64,x7: T64,x8: T64,x9: T64,x10: T64)
+|C2_64(x1: T64,x2: T64,x3: T64,x4: T64,x5: T64,x6: T64,x7: T64,x8: T64,x9: T64,x10: T64)
+|C3_64(x1: T64,x2: T64,x3: T64,x4: T64,x5: T64,x6: T64,x7: T64,x8: T64,x9: T64,x10: T64)
+|C4_64(x1: T64,x2: T64,x3: T64,x4: T64,x5: T64,x6: T64,x7: T64,x8: T64,x9: T64,x10: T64)
+|C5_64(x1: T64,x2: T64,x3: T64,x4: T64,x5: T64,x6: T64,x7: T64,x8: T64,x9: T64,x10: T64)
+|C6_64(x1: T64,x2: T64,x3: T64,x4: T64,x5: T64,x6: T64,x7: T64,x8: T64,x9: T64,x10: T64)
+|C7_64(x1: T64,x2: T64,x3: T64,x4: T64,x5: T64,x6: T64,x7: T64,x8: T64,x9: T64,x10: T64)
+|C8_64(x1: T64,x2: T64,x3: T64,x4: T64,x5: T64,x6: T64,x7: T64,x8: T64,x9: T64,x10: T64)
+|C9_64(x1: T64,x2: T64,x3: T64,x4: T64,x5: T64,x6: T64,x7: T64,x8: T64,x9: T64,x10: T64)
+|C10_64(x1: T64,x2: T64,x3: T64,x4: T64,x5: T64,x6: T64,x7: T64,x8: T64,x9: T64,x10: T64)
+T65 = C1_65(x1: T65,x2: T65,x3: T65,x4: T65,x5: T65,x6: T65,x7: T65,x8: T65,x9: T65,x10: T65)
+|C2_65(x1: T65,x2: T65,x3: T65,x4: T65,x5: T65,x6: T65,x7: T65,x8: T65,x9: T65,x10: T65)
+|C3_65(x1: T65,x2: T65,x3: T65,x4: T65,x5: T65,x6: T65,x7: T65,x8: T65,x9: T65,x10: T65)
+|C4_65(x1: T65,x2: T65,x3: T65,x4: T65,x5: T65,x6: T65,x7: T65,x8: T65,x9: T65,x10: T65)
+|C5_65(x1: T65,x2: T65,x3: T65,x4: T65,x5: T65,x6: T65,x7: T65,x8: T65,x9: T65,x10: T65)
+|C6_65(x1: T65,x2: T65,x3: T65,x4: T65,x5: T65,x6: T65,x7: T65,x8: T65,x9: T65,x10: T65)
+|C7_65(x1: T65,x2: T65,x3: T65,x4: T65,x5: T65,x6: T65,x7: T65,x8: T65,x9: T65,x10: T65)
+|C8_65(x1: T65,x2: T65,x3: T65,x4: T65,x5: T65,x6: T65,x7: T65,x8: T65,x9: T65,x10: T65)
+|C9_65(x1: T65,x2: T65,x3: T65,x4: T65,x5: T65,x6: T65,x7: T65,x8: T65,x9: T65,x10: T65)
+|C10_65(x1: T65,x2: T65,x3: T65,x4: T65,x5: T65,x6: T65,x7: T65,x8: T65,x9: T65,x10: T65)
+T66 = C1_66(x1: T66,x2: T66,x3: T66,x4: T66,x5: T66,x6: T66,x7: T66,x8: T66,x9: T66,x10: T66)
+|C2_66(x1: T66,x2: T66,x3: T66,x4: T66,x5: T66,x6: T66,x7: T66,x8: T66,x9: T66,x10: T66)
+|C3_66(x1: T66,x2: T66,x3: T66,x4: T66,x5: T66,x6: T66,x7: T66,x8: T66,x9: T66,x10: T66)
+|C4_66(x1: T66,x2: T66,x3: T66,x4: T66,x5: T66,x6: T66,x7: T66,x8: T66,x9: T66,x10: T66)
+|C5_66(x1: T66,x2: T66,x3: T66,x4: T66,x5: T66,x6: T66,x7: T66,x8: T66,x9: T66,x10: T66)
+|C6_66(x1: T66,x2: T66,x3: T66,x4: T66,x5: T66,x6: T66,x7: T66,x8: T66,x9: T66,x10: T66)
+|C7_66(x1: T66,x2: T66,x3: T66,x4: T66,x5: T66,x6: T66,x7: T66,x8: T66,x9: T66,x10: T66)
+|C8_66(x1: T66,x2: T66,x3: T66,x4: T66,x5: T66,x6: T66,x7: T66,x8: T66,x9: T66,x10: T66)
+|C9_66(x1: T66,x2: T66,x3: T66,x4: T66,x5: T66,x6: T66,x7: T66,x8: T66,x9: T66,x10: T66)
+|C10_66(x1: T66,x2: T66,x3: T66,x4: T66,x5: T66,x6: T66,x7: T66,x8: T66,x9: T66,x10: T66)
+T67 = C1_67(x1: T67,x2: T67,x3: T67,x4: T67,x5: T67,x6: T67,x7: T67,x8: T67,x9: T67,x10: T67)
+|C2_67(x1: T67,x2: T67,x3: T67,x4: T67,x5: T67,x6: T67,x7: T67,x8: T67,x9: T67,x10: T67)
+|C3_67(x1: T67,x2: T67,x3: T67,x4: T67,x5: T67,x6: T67,x7: T67,x8: T67,x9: T67,x10: T67)
+|C4_67(x1: T67,x2: T67,x3: T67,x4: T67,x5: T67,x6: T67,x7: T67,x8: T67,x9: T67,x10: T67)
+|C5_67(x1: T67,x2: T67,x3: T67,x4: T67,x5: T67,x6: T67,x7: T67,x8: T67,x9: T67,x10: T67)
+|C6_67(x1: T67,x2: T67,x3: T67,x4: T67,x5: T67,x6: T67,x7: T67,x8: T67,x9: T67,x10: T67)
+|C7_67(x1: T67,x2: T67,x3: T67,x4: T67,x5: T67,x6: T67,x7: T67,x8: T67,x9: T67,x10: T67)
+|C8_67(x1: T67,x2: T67,x3: T67,x4: T67,x5: T67,x6: T67,x7: T67,x8: T67,x9: T67,x10: T67)
+|C9_67(x1: T67,x2: T67,x3: T67,x4: T67,x5: T67,x6: T67,x7: T67,x8: T67,x9: T67,x10: T67)
+|C10_67(x1: T67,x2: T67,x3: T67,x4: T67,x5: T67,x6: T67,x7: T67,x8: T67,x9: T67,x10: T67)
+T68 = C1_68(x1: T68,x2: T68,x3: T68,x4: T68,x5: T68,x6: T68,x7: T68,x8: T68,x9: T68,x10: T68)
+|C2_68(x1: T68,x2: T68,x3: T68,x4: T68,x5: T68,x6: T68,x7: T68,x8: T68,x9: T68,x10: T68)
+|C3_68(x1: T68,x2: T68,x3: T68,x4: T68,x5: T68,x6: T68,x7: T68,x8: T68,x9: T68,x10: T68)
+|C4_68(x1: T68,x2: T68,x3: T68,x4: T68,x5: T68,x6: T68,x7: T68,x8: T68,x9: T68,x10: T68)
+|C5_68(x1: T68,x2: T68,x3: T68,x4: T68,x5: T68,x6: T68,x7: T68,x8: T68,x9: T68,x10: T68)
+|C6_68(x1: T68,x2: T68,x3: T68,x4: T68,x5: T68,x6: T68,x7: T68,x8: T68,x9: T68,x10: T68)
+|C7_68(x1: T68,x2: T68,x3: T68,x4: T68,x5: T68,x6: T68,x7: T68,x8: T68,x9: T68,x10: T68)
+|C8_68(x1: T68,x2: T68,x3: T68,x4: T68,x5: T68,x6: T68,x7: T68,x8: T68,x9: T68,x10: T68)
+|C9_68(x1: T68,x2: T68,x3: T68,x4: T68,x5: T68,x6: T68,x7: T68,x8: T68,x9: T68,x10: T68)
+|C10_68(x1: T68,x2: T68,x3: T68,x4: T68,x5: T68,x6: T68,x7: T68,x8: T68,x9: T68,x10: T68)
+T69 = C1_69(x1: T69,x2: T69,x3: T69,x4: T69,x5: T69,x6: T69,x7: T69,x8: T69,x9: T69,x10: T69)
+|C2_69(x1: T69,x2: T69,x3: T69,x4: T69,x5: T69,x6: T69,x7: T69,x8: T69,x9: T69,x10: T69)
+|C3_69(x1: T69,x2: T69,x3: T69,x4: T69,x5: T69,x6: T69,x7: T69,x8: T69,x9: T69,x10: T69)
+|C4_69(x1: T69,x2: T69,x3: T69,x4: T69,x5: T69,x6: T69,x7: T69,x8: T69,x9: T69,x10: T69)
+|C5_69(x1: T69,x2: T69,x3: T69,x4: T69,x5: T69,x6: T69,x7: T69,x8: T69,x9: T69,x10: T69)
+|C6_69(x1: T69,x2: T69,x3: T69,x4: T69,x5: T69,x6: T69,x7: T69,x8: T69,x9: T69,x10: T69)
+|C7_69(x1: T69,x2: T69,x3: T69,x4: T69,x5: T69,x6: T69,x7: T69,x8: T69,x9: T69,x10: T69)
+|C8_69(x1: T69,x2: T69,x3: T69,x4: T69,x5: T69,x6: T69,x7: T69,x8: T69,x9: T69,x10: T69)
+|C9_69(x1: T69,x2: T69,x3: T69,x4: T69,x5: T69,x6: T69,x7: T69,x8: T69,x9: T69,x10: T69)
+|C10_69(x1: T69,x2: T69,x3: T69,x4: T69,x5: T69,x6: T69,x7: T69,x8: T69,x9: T69,x10: T69)
+T70 = C1_70(x1: T70,x2: T70,x3: T70,x4: T70,x5: T70,x6: T70,x7: T70,x8: T70,x9: T70,x10: T70)
+|C2_70(x1: T70,x2: T70,x3: T70,x4: T70,x5: T70,x6: T70,x7: T70,x8: T70,x9: T70,x10: T70)
+|C3_70(x1: T70,x2: T70,x3: T70,x4: T70,x5: T70,x6: T70,x7: T70,x8: T70,x9: T70,x10: T70)
+|C4_70(x1: T70,x2: T70,x3: T70,x4: T70,x5: T70,x6: T70,x7: T70,x8: T70,x9: T70,x10: T70)
+|C5_70(x1: T70,x2: T70,x3: T70,x4: T70,x5: T70,x6: T70,x7: T70,x8: T70,x9: T70,x10: T70)
+|C6_70(x1: T70,x2: T70,x3: T70,x4: T70,x5: T70,x6: T70,x7: T70,x8: T70,x9: T70,x10: T70)
+|C7_70(x1: T70,x2: T70,x3: T70,x4: T70,x5: T70,x6: T70,x7: T70,x8: T70,x9: T70,x10: T70)
+|C8_70(x1: T70,x2: T70,x3: T70,x4: T70,x5: T70,x6: T70,x7: T70,x8: T70,x9: T70,x10: T70)
+|C9_70(x1: T70,x2: T70,x3: T70,x4: T70,x5: T70,x6: T70,x7: T70,x8: T70,x9: T70,x10: T70)
+|C10_70(x1: T70,x2: T70,x3: T70,x4: T70,x5: T70,x6: T70,x7: T70,x8: T70,x9: T70,x10: T70)
+T71 = C1_71(x1: T71,x2: T71,x3: T71,x4: T71,x5: T71,x6: T71,x7: T71,x8: T71,x9: T71,x10: T71)
+|C2_71(x1: T71,x2: T71,x3: T71,x4: T71,x5: T71,x6: T71,x7: T71,x8: T71,x9: T71,x10: T71)
+|C3_71(x1: T71,x2: T71,x3: T71,x4: T71,x5: T71,x6: T71,x7: T71,x8: T71,x9: T71,x10: T71)
+|C4_71(x1: T71,x2: T71,x3: T71,x4: T71,x5: T71,x6: T71,x7: T71,x8: T71,x9: T71,x10: T71)
+|C5_71(x1: T71,x2: T71,x3: T71,x4: T71,x5: T71,x6: T71,x7: T71,x8: T71,x9: T71,x10: T71)
+|C6_71(x1: T71,x2: T71,x3: T71,x4: T71,x5: T71,x6: T71,x7: T71,x8: T71,x9: T71,x10: T71)
+|C7_71(x1: T71,x2: T71,x3: T71,x4: T71,x5: T71,x6: T71,x7: T71,x8: T71,x9: T71,x10: T71)
+|C8_71(x1: T71,x2: T71,x3: T71,x4: T71,x5: T71,x6: T71,x7: T71,x8: T71,x9: T71,x10: T71)
+|C9_71(x1: T71,x2: T71,x3: T71,x4: T71,x5: T71,x6: T71,x7: T71,x8: T71,x9: T71,x10: T71)
+|C10_71(x1: T71,x2: T71,x3: T71,x4: T71,x5: T71,x6: T71,x7: T71,x8: T71,x9: T71,x10: T71)
+T72 = C1_72(x1: T72,x2: T72,x3: T72,x4: T72,x5: T72,x6: T72,x7: T72,x8: T72,x9: T72,x10: T72)
+|C2_72(x1: T72,x2: T72,x3: T72,x4: T72,x5: T72,x6: T72,x7: T72,x8: T72,x9: T72,x10: T72)
+|C3_72(x1: T72,x2: T72,x3: T72,x4: T72,x5: T72,x6: T72,x7: T72,x8: T72,x9: T72,x10: T72)
+|C4_72(x1: T72,x2: T72,x3: T72,x4: T72,x5: T72,x6: T72,x7: T72,x8: T72,x9: T72,x10: T72)
+|C5_72(x1: T72,x2: T72,x3: T72,x4: T72,x5: T72,x6: T72,x7: T72,x8: T72,x9: T72,x10: T72)
+|C6_72(x1: T72,x2: T72,x3: T72,x4: T72,x5: T72,x6: T72,x7: T72,x8: T72,x9: T72,x10: T72)
+|C7_72(x1: T72,x2: T72,x3: T72,x4: T72,x5: T72,x6: T72,x7: T72,x8: T72,x9: T72,x10: T72)
+|C8_72(x1: T72,x2: T72,x3: T72,x4: T72,x5: T72,x6: T72,x7: T72,x8: T72,x9: T72,x10: T72)
+|C9_72(x1: T72,x2: T72,x3: T72,x4: T72,x5: T72,x6: T72,x7: T72,x8: T72,x9: T72,x10: T72)
+|C10_72(x1: T72,x2: T72,x3: T72,x4: T72,x5: T72,x6: T72,x7: T72,x8: T72,x9: T72,x10: T72)
+T73 = C1_73(x1: T73,x2: T73,x3: T73,x4: T73,x5: T73,x6: T73,x7: T73,x8: T73,x9: T73,x10: T73)
+|C2_73(x1: T73,x2: T73,x3: T73,x4: T73,x5: T73,x6: T73,x7: T73,x8: T73,x9: T73,x10: T73)
+|C3_73(x1: T73,x2: T73,x3: T73,x4: T73,x5: T73,x6: T73,x7: T73,x8: T73,x9: T73,x10: T73)
+|C4_73(x1: T73,x2: T73,x3: T73,x4: T73,x5: T73,x6: T73,x7: T73,x8: T73,x9: T73,x10: T73)
+|C5_73(x1: T73,x2: T73,x3: T73,x4: T73,x5: T73,x6: T73,x7: T73,x8: T73,x9: T73,x10: T73)
+|C6_73(x1: T73,x2: T73,x3: T73,x4: T73,x5: T73,x6: T73,x7: T73,x8: T73,x9: T73,x10: T73)
+|C7_73(x1: T73,x2: T73,x3: T73,x4: T73,x5: T73,x6: T73,x7: T73,x8: T73,x9: T73,x10: T73)
+|C8_73(x1: T73,x2: T73,x3: T73,x4: T73,x5: T73,x6: T73,x7: T73,x8: T73,x9: T73,x10: T73)
+|C9_73(x1: T73,x2: T73,x3: T73,x4: T73,x5: T73,x6: T73,x7: T73,x8: T73,x9: T73,x10: T73)
+|C10_73(x1: T73,x2: T73,x3: T73,x4: T73,x5: T73,x6: T73,x7: T73,x8: T73,x9: T73,x10: T73)
+T74 = C1_74(x1: T74,x2: T74,x3: T74,x4: T74,x5: T74,x6: T74,x7: T74,x8: T74,x9: T74,x10: T74)
+|C2_74(x1: T74,x2: T74,x3: T74,x4: T74,x5: T74,x6: T74,x7: T74,x8: T74,x9: T74,x10: T74)
+|C3_74(x1: T74,x2: T74,x3: T74,x4: T74,x5: T74,x6: T74,x7: T74,x8: T74,x9: T74,x10: T74)
+|C4_74(x1: T74,x2: T74,x3: T74,x4: T74,x5: T74,x6: T74,x7: T74,x8: T74,x9: T74,x10: T74)
+|C5_74(x1: T74,x2: T74,x3: T74,x4: T74,x5: T74,x6: T74,x7: T74,x8: T74,x9: T74,x10: T74)
+|C6_74(x1: T74,x2: T74,x3: T74,x4: T74,x5: T74,x6: T74,x7: T74,x8: T74,x9: T74,x10: T74)
+|C7_74(x1: T74,x2: T74,x3: T74,x4: T74,x5: T74,x6: T74,x7: T74,x8: T74,x9: T74,x10: T74)
+|C8_74(x1: T74,x2: T74,x3: T74,x4: T74,x5: T74,x6: T74,x7: T74,x8: T74,x9: T74,x10: T74)
+|C9_74(x1: T74,x2: T74,x3: T74,x4: T74,x5: T74,x6: T74,x7: T74,x8: T74,x9: T74,x10: T74)
+|C10_74(x1: T74,x2: T74,x3: T74,x4: T74,x5: T74,x6: T74,x7: T74,x8: T74,x9: T74,x10: T74)
+T75 = C1_75(x1: T75,x2: T75,x3: T75,x4: T75,x5: T75,x6: T75,x7: T75,x8: T75,x9: T75,x10: T75)
+|C2_75(x1: T75,x2: T75,x3: T75,x4: T75,x5: T75,x6: T75,x7: T75,x8: T75,x9: T75,x10: T75)
+|C3_75(x1: T75,x2: T75,x3: T75,x4: T75,x5: T75,x6: T75,x7: T75,x8: T75,x9: T75,x10: T75)
+|C4_75(x1: T75,x2: T75,x3: T75,x4: T75,x5: T75,x6: T75,x7: T75,x8: T75,x9: T75,x10: T75)
+|C5_75(x1: T75,x2: T75,x3: T75,x4: T75,x5: T75,x6: T75,x7: T75,x8: T75,x9: T75,x10: T75)
+|C6_75(x1: T75,x2: T75,x3: T75,x4: T75,x5: T75,x6: T75,x7: T75,x8: T75,x9: T75,x10: T75)
+|C7_75(x1: T75,x2: T75,x3: T75,x4: T75,x5: T75,x6: T75,x7: T75,x8: T75,x9: T75,x10: T75)
+|C8_75(x1: T75,x2: T75,x3: T75,x4: T75,x5: T75,x6: T75,x7: T75,x8: T75,x9: T75,x10: T75)
+|C9_75(x1: T75,x2: T75,x3: T75,x4: T75,x5: T75,x6: T75,x7: T75,x8: T75,x9: T75,x10: T75)
+|C10_75(x1: T75,x2: T75,x3: T75,x4: T75,x5: T75,x6: T75,x7: T75,x8: T75,x9: T75,x10: T75)
+T76 = C1_76(x1: T76,x2: T76,x3: T76,x4: T76,x5: T76,x6: T76,x7: T76,x8: T76,x9: T76,x10: T76)
+|C2_76(x1: T76,x2: T76,x3: T76,x4: T76,x5: T76,x6: T76,x7: T76,x8: T76,x9: T76,x10: T76)
+|C3_76(x1: T76,x2: T76,x3: T76,x4: T76,x5: T76,x6: T76,x7: T76,x8: T76,x9: T76,x10: T76)
+|C4_76(x1: T76,x2: T76,x3: T76,x4: T76,x5: T76,x6: T76,x7: T76,x8: T76,x9: T76,x10: T76)
+|C5_76(x1: T76,x2: T76,x3: T76,x4: T76,x5: T76,x6: T76,x7: T76,x8: T76,x9: T76,x10: T76)
+|C6_76(x1: T76,x2: T76,x3: T76,x4: T76,x5: T76,x6: T76,x7: T76,x8: T76,x9: T76,x10: T76)
+|C7_76(x1: T76,x2: T76,x3: T76,x4: T76,x5: T76,x6: T76,x7: T76,x8: T76,x9: T76,x10: T76)
+|C8_76(x1: T76,x2: T76,x3: T76,x4: T76,x5: T76,x6: T76,x7: T76,x8: T76,x9: T76,x10: T76)
+|C9_76(x1: T76,x2: T76,x3: T76,x4: T76,x5: T76,x6: T76,x7: T76,x8: T76,x9: T76,x10: T76)
+|C10_76(x1: T76,x2: T76,x3: T76,x4: T76,x5: T76,x6: T76,x7: T76,x8: T76,x9: T76,x10: T76)
+T77 = C1_77(x1: T77,x2: T77,x3: T77,x4: T77,x5: T77,x6: T77,x7: T77,x8: T77,x9: T77,x10: T77)
+|C2_77(x1: T77,x2: T77,x3: T77,x4: T77,x5: T77,x6: T77,x7: T77,x8: T77,x9: T77,x10: T77)
+|C3_77(x1: T77,x2: T77,x3: T77,x4: T77,x5: T77,x6: T77,x7: T77,x8: T77,x9: T77,x10: T77)
+|C4_77(x1: T77,x2: T77,x3: T77,x4: T77,x5: T77,x6: T77,x7: T77,x8: T77,x9: T77,x10: T77)
+|C5_77(x1: T77,x2: T77,x3: T77,x4: T77,x5: T77,x6: T77,x7: T77,x8: T77,x9: T77,x10: T77)
+|C6_77(x1: T77,x2: T77,x3: T77,x4: T77,x5: T77,x6: T77,x7: T77,x8: T77,x9: T77,x10: T77)
+|C7_77(x1: T77,x2: T77,x3: T77,x4: T77,x5: T77,x6: T77,x7: T77,x8: T77,x9: T77,x10: T77)
+|C8_77(x1: T77,x2: T77,x3: T77,x4: T77,x5: T77,x6: T77,x7: T77,x8: T77,x9: T77,x10: T77)
+|C9_77(x1: T77,x2: T77,x3: T77,x4: T77,x5: T77,x6: T77,x7: T77,x8: T77,x9: T77,x10: T77)
+|C10_77(x1: T77,x2: T77,x3: T77,x4: T77,x5: T77,x6: T77,x7: T77,x8: T77,x9: T77,x10: T77)
+T78 = C1_78(x1: T78,x2: T78,x3: T78,x4: T78,x5: T78,x6: T78,x7: T78,x8: T78,x9: T78,x10: T78)
+|C2_78(x1: T78,x2: T78,x3: T78,x4: T78,x5: T78,x6: T78,x7: T78,x8: T78,x9: T78,x10: T78)
+|C3_78(x1: T78,x2: T78,x3: T78,x4: T78,x5: T78,x6: T78,x7: T78,x8: T78,x9: T78,x10: T78)
+|C4_78(x1: T78,x2: T78,x3: T78,x4: T78,x5: T78,x6: T78,x7: T78,x8: T78,x9: T78,x10: T78)
+|C5_78(x1: T78,x2: T78,x3: T78,x4: T78,x5: T78,x6: T78,x7: T78,x8: T78,x9: T78,x10: T78)
+|C6_78(x1: T78,x2: T78,x3: T78,x4: T78,x5: T78,x6: T78,x7: T78,x8: T78,x9: T78,x10: T78)
+|C7_78(x1: T78,x2: T78,x3: T78,x4: T78,x5: T78,x6: T78,x7: T78,x8: T78,x9: T78,x10: T78)
+|C8_78(x1: T78,x2: T78,x3: T78,x4: T78,x5: T78,x6: T78,x7: T78,x8: T78,x9: T78,x10: T78)
+|C9_78(x1: T78,x2: T78,x3: T78,x4: T78,x5: T78,x6: T78,x7: T78,x8: T78,x9: T78,x10: T78)
+|C10_78(x1: T78,x2: T78,x3: T78,x4: T78,x5: T78,x6: T78,x7: T78,x8: T78,x9: T78,x10: T78)
+T79 = C1_79(x1: T79,x2: T79,x3: T79,x4: T79,x5: T79,x6: T79,x7: T79,x8: T79,x9: T79,x10: T79)
+|C2_79(x1: T79,x2: T79,x3: T79,x4: T79,x5: T79,x6: T79,x7: T79,x8: T79,x9: T79,x10: T79)
+|C3_79(x1: T79,x2: T79,x3: T79,x4: T79,x5: T79,x6: T79,x7: T79,x8: T79,x9: T79,x10: T79)
+|C4_79(x1: T79,x2: T79,x3: T79,x4: T79,x5: T79,x6: T79,x7: T79,x8: T79,x9: T79,x10: T79)
+|C5_79(x1: T79,x2: T79,x3: T79,x4: T79,x5: T79,x6: T79,x7: T79,x8: T79,x9: T79,x10: T79)
+|C6_79(x1: T79,x2: T79,x3: T79,x4: T79,x5: T79,x6: T79,x7: T79,x8: T79,x9: T79,x10: T79)
+|C7_79(x1: T79,x2: T79,x3: T79,x4: T79,x5: T79,x6: T79,x7: T79,x8: T79,x9: T79,x10: T79)
+|C8_79(x1: T79,x2: T79,x3: T79,x4: T79,x5: T79,x6: T79,x7: T79,x8: T79,x9: T79,x10: T79)
+|C9_79(x1: T79,x2: T79,x3: T79,x4: T79,x5: T79,x6: T79,x7: T79,x8: T79,x9: T79,x10: T79)
+|C10_79(x1: T79,x2: T79,x3: T79,x4: T79,x5: T79,x6: T79,x7: T79,x8: T79,x9: T79,x10: T79)
+T80 = C1_80(x1: T80,x2: T80,x3: T80,x4: T80,x5: T80,x6: T80,x7: T80,x8: T80,x9: T80,x10: T80)
+|C2_80(x1: T80,x2: T80,x3: T80,x4: T80,x5: T80,x6: T80,x7: T80,x8: T80,x9: T80,x10: T80)
+|C3_80(x1: T80,x2: T80,x3: T80,x4: T80,x5: T80,x6: T80,x7: T80,x8: T80,x9: T80,x10: T80)
+|C4_80(x1: T80,x2: T80,x3: T80,x4: T80,x5: T80,x6: T80,x7: T80,x8: T80,x9: T80,x10: T80)
+|C5_80(x1: T80,x2: T80,x3: T80,x4: T80,x5: T80,x6: T80,x7: T80,x8: T80,x9: T80,x10: T80)
+|C6_80(x1: T80,x2: T80,x3: T80,x4: T80,x5: T80,x6: T80,x7: T80,x8: T80,x9: T80,x10: T80)
+|C7_80(x1: T80,x2: T80,x3: T80,x4: T80,x5: T80,x6: T80,x7: T80,x8: T80,x9: T80,x10: T80)
+|C8_80(x1: T80,x2: T80,x3: T80,x4: T80,x5: T80,x6: T80,x7: T80,x8: T80,x9: T80,x10: T80)
+|C9_80(x1: T80,x2: T80,x3: T80,x4: T80,x5: T80,x6: T80,x7: T80,x8: T80,x9: T80,x10: T80)
+|C10_80(x1: T80,x2: T80,x3: T80,x4: T80,x5: T80,x6: T80,x7: T80,x8: T80,x9: T80,x10: T80)
+T81 = C1_81(x1: T81,x2: T81,x3: T81,x4: T81,x5: T81,x6: T81,x7: T81,x8: T81,x9: T81,x10: T81)
+|C2_81(x1: T81,x2: T81,x3: T81,x4: T81,x5: T81,x6: T81,x7: T81,x8: T81,x9: T81,x10: T81)
+|C3_81(x1: T81,x2: T81,x3: T81,x4: T81,x5: T81,x6: T81,x7: T81,x8: T81,x9: T81,x10: T81)
+|C4_81(x1: T81,x2: T81,x3: T81,x4: T81,x5: T81,x6: T81,x7: T81,x8: T81,x9: T81,x10: T81)
+|C5_81(x1: T81,x2: T81,x3: T81,x4: T81,x5: T81,x6: T81,x7: T81,x8: T81,x9: T81,x10: T81)
+|C6_81(x1: T81,x2: T81,x3: T81,x4: T81,x5: T81,x6: T81,x7: T81,x8: T81,x9: T81,x10: T81)
+|C7_81(x1: T81,x2: T81,x3: T81,x4: T81,x5: T81,x6: T81,x7: T81,x8: T81,x9: T81,x10: T81)
+|C8_81(x1: T81,x2: T81,x3: T81,x4: T81,x5: T81,x6: T81,x7: T81,x8: T81,x9: T81,x10: T81)
+|C9_81(x1: T81,x2: T81,x3: T81,x4: T81,x5: T81,x6: T81,x7: T81,x8: T81,x9: T81,x10: T81)
+|C10_81(x1: T81,x2: T81,x3: T81,x4: T81,x5: T81,x6: T81,x7: T81,x8: T81,x9: T81,x10: T81)
+T82 = C1_82(x1: T82,x2: T82,x3: T82,x4: T82,x5: T82,x6: T82,x7: T82,x8: T82,x9: T82,x10: T82)
+|C2_82(x1: T82,x2: T82,x3: T82,x4: T82,x5: T82,x6: T82,x7: T82,x8: T82,x9: T82,x10: T82)
+|C3_82(x1: T82,x2: T82,x3: T82,x4: T82,x5: T82,x6: T82,x7: T82,x8: T82,x9: T82,x10: T82)
+|C4_82(x1: T82,x2: T82,x3: T82,x4: T82,x5: T82,x6: T82,x7: T82,x8: T82,x9: T82,x10: T82)
+|C5_82(x1: T82,x2: T82,x3: T82,x4: T82,x5: T82,x6: T82,x7: T82,x8: T82,x9: T82,x10: T82)
+|C6_82(x1: T82,x2: T82,x3: T82,x4: T82,x5: T82,x6: T82,x7: T82,x8: T82,x9: T82,x10: T82)
+|C7_82(x1: T82,x2: T82,x3: T82,x4: T82,x5: T82,x6: T82,x7: T82,x8: T82,x9: T82,x10: T82)
+|C8_82(x1: T82,x2: T82,x3: T82,x4: T82,x5: T82,x6: T82,x7: T82,x8: T82,x9: T82,x10: T82)
+|C9_82(x1: T82,x2: T82,x3: T82,x4: T82,x5: T82,x6: T82,x7: T82,x8: T82,x9: T82,x10: T82)
+|C10_82(x1: T82,x2: T82,x3: T82,x4: T82,x5: T82,x6: T82,x7: T82,x8: T82,x9: T82,x10: T82)
+T83 = C1_83(x1: T83,x2: T83,x3: T83,x4: T83,x5: T83,x6: T83,x7: T83,x8: T83,x9: T83,x10: T83)
+|C2_83(x1: T83,x2: T83,x3: T83,x4: T83,x5: T83,x6: T83,x7: T83,x8: T83,x9: T83,x10: T83)
+|C3_83(x1: T83,x2: T83,x3: T83,x4: T83,x5: T83,x6: T83,x7: T83,x8: T83,x9: T83,x10: T83)
+|C4_83(x1: T83,x2: T83,x3: T83,x4: T83,x5: T83,x6: T83,x7: T83,x8: T83,x9: T83,x10: T83)
+|C5_83(x1: T83,x2: T83,x3: T83,x4: T83,x5: T83,x6: T83,x7: T83,x8: T83,x9: T83,x10: T83)
+|C6_83(x1: T83,x2: T83,x3: T83,x4: T83,x5: T83,x6: T83,x7: T83,x8: T83,x9: T83,x10: T83)
+|C7_83(x1: T83,x2: T83,x3: T83,x4: T83,x5: T83,x6: T83,x7: T83,x8: T83,x9: T83,x10: T83)
+|C8_83(x1: T83,x2: T83,x3: T83,x4: T83,x5: T83,x6: T83,x7: T83,x8: T83,x9: T83,x10: T83)
+|C9_83(x1: T83,x2: T83,x3: T83,x4: T83,x5: T83,x6: T83,x7: T83,x8: T83,x9: T83,x10: T83)
+|C10_83(x1: T83,x2: T83,x3: T83,x4: T83,x5: T83,x6: T83,x7: T83,x8: T83,x9: T83,x10: T83)
+T84 = C1_84(x1: T84,x2: T84,x3: T84,x4: T84,x5: T84,x6: T84,x7: T84,x8: T84,x9: T84,x10: T84)
+|C2_84(x1: T84,x2: T84,x3: T84,x4: T84,x5: T84,x6: T84,x7: T84,x8: T84,x9: T84,x10: T84)
+|C3_84(x1: T84,x2: T84,x3: T84,x4: T84,x5: T84,x6: T84,x7: T84,x8: T84,x9: T84,x10: T84)
+|C4_84(x1: T84,x2: T84,x3: T84,x4: T84,x5: T84,x6: T84,x7: T84,x8: T84,x9: T84,x10: T84)
+|C5_84(x1: T84,x2: T84,x3: T84,x4: T84,x5: T84,x6: T84,x7: T84,x8: T84,x9: T84,x10: T84)
+|C6_84(x1: T84,x2: T84,x3: T84,x4: T84,x5: T84,x6: T84,x7: T84,x8: T84,x9: T84,x10: T84)
+|C7_84(x1: T84,x2: T84,x3: T84,x4: T84,x5: T84,x6: T84,x7: T84,x8: T84,x9: T84,x10: T84)
+|C8_84(x1: T84,x2: T84,x3: T84,x4: T84,x5: T84,x6: T84,x7: T84,x8: T84,x9: T84,x10: T84)
+|C9_84(x1: T84,x2: T84,x3: T84,x4: T84,x5: T84,x6: T84,x7: T84,x8: T84,x9: T84,x10: T84)
+|C10_84(x1: T84,x2: T84,x3: T84,x4: T84,x5: T84,x6: T84,x7: T84,x8: T84,x9: T84,x10: T84)
+T85 = C1_85(x1: T85,x2: T85,x3: T85,x4: T85,x5: T85,x6: T85,x7: T85,x8: T85,x9: T85,x10: T85)
+|C2_85(x1: T85,x2: T85,x3: T85,x4: T85,x5: T85,x6: T85,x7: T85,x8: T85,x9: T85,x10: T85)
+|C3_85(x1: T85,x2: T85,x3: T85,x4: T85,x5: T85,x6: T85,x7: T85,x8: T85,x9: T85,x10: T85)
+|C4_85(x1: T85,x2: T85,x3: T85,x4: T85,x5: T85,x6: T85,x7: T85,x8: T85,x9: T85,x10: T85)
+|C5_85(x1: T85,x2: T85,x3: T85,x4: T85,x5: T85,x6: T85,x7: T85,x8: T85,x9: T85,x10: T85)
+|C6_85(x1: T85,x2: T85,x3: T85,x4: T85,x5: T85,x6: T85,x7: T85,x8: T85,x9: T85,x10: T85)
+|C7_85(x1: T85,x2: T85,x3: T85,x4: T85,x5: T85,x6: T85,x7: T85,x8: T85,x9: T85,x10: T85)
+|C8_85(x1: T85,x2: T85,x3: T85,x4: T85,x5: T85,x6: T85,x7: T85,x8: T85,x9: T85,x10: T85)
+|C9_85(x1: T85,x2: T85,x3: T85,x4: T85,x5: T85,x6: T85,x7: T85,x8: T85,x9: T85,x10: T85)
+|C10_85(x1: T85,x2: T85,x3: T85,x4: T85,x5: T85,x6: T85,x7: T85,x8: T85,x9: T85,x10: T85)
+T86 = C1_86(x1: T86,x2: T86,x3: T86,x4: T86,x5: T86,x6: T86,x7: T86,x8: T86,x9: T86,x10: T86)
+|C2_86(x1: T86,x2: T86,x3: T86,x4: T86,x5: T86,x6: T86,x7: T86,x8: T86,x9: T86,x10: T86)
+|C3_86(x1: T86,x2: T86,x3: T86,x4: T86,x5: T86,x6: T86,x7: T86,x8: T86,x9: T86,x10: T86)
+|C4_86(x1: T86,x2: T86,x3: T86,x4: T86,x5: T86,x6: T86,x7: T86,x8: T86,x9: T86,x10: T86)
+|C5_86(x1: T86,x2: T86,x3: T86,x4: T86,x5: T86,x6: T86,x7: T86,x8: T86,x9: T86,x10: T86)
+|C6_86(x1: T86,x2: T86,x3: T86,x4: T86,x5: T86,x6: T86,x7: T86,x8: T86,x9: T86,x10: T86)
+|C7_86(x1: T86,x2: T86,x3: T86,x4: T86,x5: T86,x6: T86,x7: T86,x8: T86,x9: T86,x10: T86)
+|C8_86(x1: T86,x2: T86,x3: T86,x4: T86,x5: T86,x6: T86,x7: T86,x8: T86,x9: T86,x10: T86)
+|C9_86(x1: T86,x2: T86,x3: T86,x4: T86,x5: T86,x6: T86,x7: T86,x8: T86,x9: T86,x10: T86)
+|C10_86(x1: T86,x2: T86,x3: T86,x4: T86,x5: T86,x6: T86,x7: T86,x8: T86,x9: T86,x10: T86)
+T87 = C1_87(x1: T87,x2: T87,x3: T87,x4: T87,x5: T87,x6: T87,x7: T87,x8: T87,x9: T87,x10: T87)
+|C2_87(x1: T87,x2: T87,x3: T87,x4: T87,x5: T87,x6: T87,x7: T87,x8: T87,x9: T87,x10: T87)
+|C3_87(x1: T87,x2: T87,x3: T87,x4: T87,x5: T87,x6: T87,x7: T87,x8: T87,x9: T87,x10: T87)
+|C4_87(x1: T87,x2: T87,x3: T87,x4: T87,x5: T87,x6: T87,x7: T87,x8: T87,x9: T87,x10: T87)
+|C5_87(x1: T87,x2: T87,x3: T87,x4: T87,x5: T87,x6: T87,x7: T87,x8: T87,x9: T87,x10: T87)
+|C6_87(x1: T87,x2: T87,x3: T87,x4: T87,x5: T87,x6: T87,x7: T87,x8: T87,x9: T87,x10: T87)
+|C7_87(x1: T87,x2: T87,x3: T87,x4: T87,x5: T87,x6: T87,x7: T87,x8: T87,x9: T87,x10: T87)
+|C8_87(x1: T87,x2: T87,x3: T87,x4: T87,x5: T87,x6: T87,x7: T87,x8: T87,x9: T87,x10: T87)
+|C9_87(x1: T87,x2: T87,x3: T87,x4: T87,x5: T87,x6: T87,x7: T87,x8: T87,x9: T87,x10: T87)
+|C10_87(x1: T87,x2: T87,x3: T87,x4: T87,x5: T87,x6: T87,x7: T87,x8: T87,x9: T87,x10: T87)
+T88 = C1_88(x1: T88,x2: T88,x3: T88,x4: T88,x5: T88,x6: T88,x7: T88,x8: T88,x9: T88,x10: T88)
+|C2_88(x1: T88,x2: T88,x3: T88,x4: T88,x5: T88,x6: T88,x7: T88,x8: T88,x9: T88,x10: T88)
+|C3_88(x1: T88,x2: T88,x3: T88,x4: T88,x5: T88,x6: T88,x7: T88,x8: T88,x9: T88,x10: T88)
+|C4_88(x1: T88,x2: T88,x3: T88,x4: T88,x5: T88,x6: T88,x7: T88,x8: T88,x9: T88,x10: T88)
+|C5_88(x1: T88,x2: T88,x3: T88,x4: T88,x5: T88,x6: T88,x7: T88,x8: T88,x9: T88,x10: T88)
+|C6_88(x1: T88,x2: T88,x3: T88,x4: T88,x5: T88,x6: T88,x7: T88,x8: T88,x9: T88,x10: T88)
+|C7_88(x1: T88,x2: T88,x3: T88,x4: T88,x5: T88,x6: T88,x7: T88,x8: T88,x9: T88,x10: T88)
+|C8_88(x1: T88,x2: T88,x3: T88,x4: T88,x5: T88,x6: T88,x7: T88,x8: T88,x9: T88,x10: T88)
+|C9_88(x1: T88,x2: T88,x3: T88,x4: T88,x5: T88,x6: T88,x7: T88,x8: T88,x9: T88,x10: T88)
+|C10_88(x1: T88,x2: T88,x3: T88,x4: T88,x5: T88,x6: T88,x7: T88,x8: T88,x9: T88,x10: T88)
+T89 = C1_89(x1: T89,x2: T89,x3: T89,x4: T89,x5: T89,x6: T89,x7: T89,x8: T89,x9: T89,x10: T89)
+|C2_89(x1: T89,x2: T89,x3: T89,x4: T89,x5: T89,x6: T89,x7: T89,x8: T89,x9: T89,x10: T89)
+|C3_89(x1: T89,x2: T89,x3: T89,x4: T89,x5: T89,x6: T89,x7: T89,x8: T89,x9: T89,x10: T89)
+|C4_89(x1: T89,x2: T89,x3: T89,x4: T89,x5: T89,x6: T89,x7: T89,x8: T89,x9: T89,x10: T89)
+|C5_89(x1: T89,x2: T89,x3: T89,x4: T89,x5: T89,x6: T89,x7: T89,x8: T89,x9: T89,x10: T89)
+|C6_89(x1: T89,x2: T89,x3: T89,x4: T89,x5: T89,x6: T89,x7: T89,x8: T89,x9: T89,x10: T89)
+|C7_89(x1: T89,x2: T89,x3: T89,x4: T89,x5: T89,x6: T89,x7: T89,x8: T89,x9: T89,x10: T89)
+|C8_89(x1: T89,x2: T89,x3: T89,x4: T89,x5: T89,x6: T89,x7: T89,x8: T89,x9: T89,x10: T89)
+|C9_89(x1: T89,x2: T89,x3: T89,x4: T89,x5: T89,x6: T89,x7: T89,x8: T89,x9: T89,x10: T89)
+|C10_89(x1: T89,x2: T89,x3: T89,x4: T89,x5: T89,x6: T89,x7: T89,x8: T89,x9: T89,x10: T89)
+T90 = C1_90(x1: T90,x2: T90,x3: T90,x4: T90,x5: T90,x6: T90,x7: T90,x8: T90,x9: T90,x10: T90)
+|C2_90(x1: T90,x2: T90,x3: T90,x4: T90,x5: T90,x6: T90,x7: T90,x8: T90,x9: T90,x10: T90)
+|C3_90(x1: T90,x2: T90,x3: T90,x4: T90,x5: T90,x6: T90,x7: T90,x8: T90,x9: T90,x10: T90)
+|C4_90(x1: T90,x2: T90,x3: T90,x4: T90,x5: T90,x6: T90,x7: T90,x8: T90,x9: T90,x10: T90)
+|C5_90(x1: T90,x2: T90,x3: T90,x4: T90,x5: T90,x6: T90,x7: T90,x8: T90,x9: T90,x10: T90)
+|C6_90(x1: T90,x2: T90,x3: T90,x4: T90,x5: T90,x6: T90,x7: T90,x8: T90,x9: T90,x10: T90)
+|C7_90(x1: T90,x2: T90,x3: T90,x4: T90,x5: T90,x6: T90,x7: T90,x8: T90,x9: T90,x10: T90)
+|C8_90(x1: T90,x2: T90,x3: T90,x4: T90,x5: T90,x6: T90,x7: T90,x8: T90,x9: T90,x10: T90)
+|C9_90(x1: T90,x2: T90,x3: T90,x4: T90,x5: T90,x6: T90,x7: T90,x8: T90,x9: T90,x10: T90)
+|C10_90(x1: T90,x2: T90,x3: T90,x4: T90,x5: T90,x6: T90,x7: T90,x8: T90,x9: T90,x10: T90)
+T91 = C1_91(x1: T91,x2: T91,x3: T91,x4: T91,x5: T91,x6: T91,x7: T91,x8: T91,x9: T91,x10: T91)
+|C2_91(x1: T91,x2: T91,x3: T91,x4: T91,x5: T91,x6: T91,x7: T91,x8: T91,x9: T91,x10: T91)
+|C3_91(x1: T91,x2: T91,x3: T91,x4: T91,x5: T91,x6: T91,x7: T91,x8: T91,x9: T91,x10: T91)
+|C4_91(x1: T91,x2: T91,x3: T91,x4: T91,x5: T91,x6: T91,x7: T91,x8: T91,x9: T91,x10: T91)
+|C5_91(x1: T91,x2: T91,x3: T91,x4: T91,x5: T91,x6: T91,x7: T91,x8: T91,x9: T91,x10: T91)
+|C6_91(x1: T91,x2: T91,x3: T91,x4: T91,x5: T91,x6: T91,x7: T91,x8: T91,x9: T91,x10: T91)
+|C7_91(x1: T91,x2: T91,x3: T91,x4: T91,x5: T91,x6: T91,x7: T91,x8: T91,x9: T91,x10: T91)
+|C8_91(x1: T91,x2: T91,x3: T91,x4: T91,x5: T91,x6: T91,x7: T91,x8: T91,x9: T91,x10: T91)
+|C9_91(x1: T91,x2: T91,x3: T91,x4: T91,x5: T91,x6: T91,x7: T91,x8: T91,x9: T91,x10: T91)
+|C10_91(x1: T91,x2: T91,x3: T91,x4: T91,x5: T91,x6: T91,x7: T91,x8: T91,x9: T91,x10: T91)
+T92 = C1_92(x1: T92,x2: T92,x3: T92,x4: T92,x5: T92,x6: T92,x7: T92,x8: T92,x9: T92,x10: T92)
+|C2_92(x1: T92,x2: T92,x3: T92,x4: T92,x5: T92,x6: T92,x7: T92,x8: T92,x9: T92,x10: T92)
+|C3_92(x1: T92,x2: T92,x3: T92,x4: T92,x5: T92,x6: T92,x7: T92,x8: T92,x9: T92,x10: T92)
+|C4_92(x1: T92,x2: T92,x3: T92,x4: T92,x5: T92,x6: T92,x7: T92,x8: T92,x9: T92,x10: T92)
+|C5_92(x1: T92,x2: T92,x3: T92,x4: T92,x5: T92,x6: T92,x7: T92,x8: T92,x9: T92,x10: T92)
+|C6_92(x1: T92,x2: T92,x3: T92,x4: T92,x5: T92,x6: T92,x7: T92,x8: T92,x9: T92,x10: T92)
+|C7_92(x1: T92,x2: T92,x3: T92,x4: T92,x5: T92,x6: T92,x7: T92,x8: T92,x9: T92,x10: T92)
+|C8_92(x1: T92,x2: T92,x3: T92,x4: T92,x5: T92,x6: T92,x7: T92,x8: T92,x9: T92,x10: T92)
+|C9_92(x1: T92,x2: T92,x3: T92,x4: T92,x5: T92,x6: T92,x7: T92,x8: T92,x9: T92,x10: T92)
+|C10_92(x1: T92,x2: T92,x3: T92,x4: T92,x5: T92,x6: T92,x7: T92,x8: T92,x9: T92,x10: T92)
+T93 = C1_93(x1: T93,x2: T93,x3: T93,x4: T93,x5: T93,x6: T93,x7: T93,x8: T93,x9: T93,x10: T93)
+|C2_93(x1: T93,x2: T93,x3: T93,x4: T93,x5: T93,x6: T93,x7: T93,x8: T93,x9: T93,x10: T93)
+|C3_93(x1: T93,x2: T93,x3: T93,x4: T93,x5: T93,x6: T93,x7: T93,x8: T93,x9: T93,x10: T93)
+|C4_93(x1: T93,x2: T93,x3: T93,x4: T93,x5: T93,x6: T93,x7: T93,x8: T93,x9: T93,x10: T93)
+|C5_93(x1: T93,x2: T93,x3: T93,x4: T93,x5: T93,x6: T93,x7: T93,x8: T93,x9: T93,x10: T93)
+|C6_93(x1: T93,x2: T93,x3: T93,x4: T93,x5: T93,x6: T93,x7: T93,x8: T93,x9: T93,x10: T93)
+|C7_93(x1: T93,x2: T93,x3: T93,x4: T93,x5: T93,x6: T93,x7: T93,x8: T93,x9: T93,x10: T93)
+|C8_93(x1: T93,x2: T93,x3: T93,x4: T93,x5: T93,x6: T93,x7: T93,x8: T93,x9: T93,x10: T93)
+|C9_93(x1: T93,x2: T93,x3: T93,x4: T93,x5: T93,x6: T93,x7: T93,x8: T93,x9: T93,x10: T93)
+|C10_93(x1: T93,x2: T93,x3: T93,x4: T93,x5: T93,x6: T93,x7: T93,x8: T93,x9: T93,x10: T93)
+T94 = C1_94(x1: T94,x2: T94,x3: T94,x4: T94,x5: T94,x6: T94,x7: T94,x8: T94,x9: T94,x10: T94)
+|C2_94(x1: T94,x2: T94,x3: T94,x4: T94,x5: T94,x6: T94,x7: T94,x8: T94,x9: T94,x10: T94)
+|C3_94(x1: T94,x2: T94,x3: T94,x4: T94,x5: T94,x6: T94,x7: T94,x8: T94,x9: T94,x10: T94)
+|C4_94(x1: T94,x2: T94,x3: T94,x4: T94,x5: T94,x6: T94,x7: T94,x8: T94,x9: T94,x10: T94)
+|C5_94(x1: T94,x2: T94,x3: T94,x4: T94,x5: T94,x6: T94,x7: T94,x8: T94,x9: T94,x10: T94)
+|C6_94(x1: T94,x2: T94,x3: T94,x4: T94,x5: T94,x6: T94,x7: T94,x8: T94,x9: T94,x10: T94)
+|C7_94(x1: T94,x2: T94,x3: T94,x4: T94,x5: T94,x6: T94,x7: T94,x8: T94,x9: T94,x10: T94)
+|C8_94(x1: T94,x2: T94,x3: T94,x4: T94,x5: T94,x6: T94,x7: T94,x8: T94,x9: T94,x10: T94)
+|C9_94(x1: T94,x2: T94,x3: T94,x4: T94,x5: T94,x6: T94,x7: T94,x8: T94,x9: T94,x10: T94)
+|C10_94(x1: T94,x2: T94,x3: T94,x4: T94,x5: T94,x6: T94,x7: T94,x8: T94,x9: T94,x10: T94)
+T95 = C1_95(x1: T95,x2: T95,x3: T95,x4: T95,x5: T95,x6: T95,x7: T95,x8: T95,x9: T95,x10: T95)
+|C2_95(x1: T95,x2: T95,x3: T95,x4: T95,x5: T95,x6: T95,x7: T95,x8: T95,x9: T95,x10: T95)
+|C3_95(x1: T95,x2: T95,x3: T95,x4: T95,x5: T95,x6: T95,x7: T95,x8: T95,x9: T95,x10: T95)
+|C4_95(x1: T95,x2: T95,x3: T95,x4: T95,x5: T95,x6: T95,x7: T95,x8: T95,x9: T95,x10: T95)
+|C5_95(x1: T95,x2: T95,x3: T95,x4: T95,x5: T95,x6: T95,x7: T95,x8: T95,x9: T95,x10: T95)
+|C6_95(x1: T95,x2: T95,x3: T95,x4: T95,x5: T95,x6: T95,x7: T95,x8: T95,x9: T95,x10: T95)
+|C7_95(x1: T95,x2: T95,x3: T95,x4: T95,x5: T95,x6: T95,x7: T95,x8: T95,x9: T95,x10: T95)
+|C8_95(x1: T95,x2: T95,x3: T95,x4: T95,x5: T95,x6: T95,x7: T95,x8: T95,x9: T95,x10: T95)
+|C9_95(x1: T95,x2: T95,x3: T95,x4: T95,x5: T95,x6: T95,x7: T95,x8: T95,x9: T95,x10: T95)
+|C10_95(x1: T95,x2: T95,x3: T95,x4: T95,x5: T95,x6: T95,x7: T95,x8: T95,x9: T95,x10: T95)
+T96 = C1_96(x1: T96,x2: T96,x3: T96,x4: T96,x5: T96,x6: T96,x7: T96,x8: T96,x9: T96,x10: T96)
+|C2_96(x1: T96,x2: T96,x3: T96,x4: T96,x5: T96,x6: T96,x7: T96,x8: T96,x9: T96,x10: T96)
+|C3_96(x1: T96,x2: T96,x3: T96,x4: T96,x5: T96,x6: T96,x7: T96,x8: T96,x9: T96,x10: T96)
+|C4_96(x1: T96,x2: T96,x3: T96,x4: T96,x5: T96,x6: T96,x7: T96,x8: T96,x9: T96,x10: T96)
+|C5_96(x1: T96,x2: T96,x3: T96,x4: T96,x5: T96,x6: T96,x7: T96,x8: T96,x9: T96,x10: T96)
+|C6_96(x1: T96,x2: T96,x3: T96,x4: T96,x5: T96,x6: T96,x7: T96,x8: T96,x9: T96,x10: T96)
+|C7_96(x1: T96,x2: T96,x3: T96,x4: T96,x5: T96,x6: T96,x7: T96,x8: T96,x9: T96,x10: T96)
+|C8_96(x1: T96,x2: T96,x3: T96,x4: T96,x5: T96,x6: T96,x7: T96,x8: T96,x9: T96,x10: T96)
+|C9_96(x1: T96,x2: T96,x3: T96,x4: T96,x5: T96,x6: T96,x7: T96,x8: T96,x9: T96,x10: T96)
+|C10_96(x1: T96,x2: T96,x3: T96,x4: T96,x5: T96,x6: T96,x7: T96,x8: T96,x9: T96,x10: T96)
+T97 = C1_97(x1: T97,x2: T97,x3: T97,x4: T97,x5: T97,x6: T97,x7: T97,x8: T97,x9: T97,x10: T97)
+|C2_97(x1: T97,x2: T97,x3: T97,x4: T97,x5: T97,x6: T97,x7: T97,x8: T97,x9: T97,x10: T97)
+|C3_97(x1: T97,x2: T97,x3: T97,x4: T97,x5: T97,x6: T97,x7: T97,x8: T97,x9: T97,x10: T97)
+|C4_97(x1: T97,x2: T97,x3: T97,x4: T97,x5: T97,x6: T97,x7: T97,x8: T97,x9: T97,x10: T97)
+|C5_97(x1: T97,x2: T97,x3: T97,x4: T97,x5: T97,x6: T97,x7: T97,x8: T97,x9: T97,x10: T97)
+|C6_97(x1: T97,x2: T97,x3: T97,x4: T97,x5: T97,x6: T97,x7: T97,x8: T97,x9: T97,x10: T97)
+|C7_97(x1: T97,x2: T97,x3: T97,x4: T97,x5: T97,x6: T97,x7: T97,x8: T97,x9: T97,x10: T97)
+|C8_97(x1: T97,x2: T97,x3: T97,x4: T97,x5: T97,x6: T97,x7: T97,x8: T97,x9: T97,x10: T97)
+|C9_97(x1: T97,x2: T97,x3: T97,x4: T97,x5: T97,x6: T97,x7: T97,x8: T97,x9: T97,x10: T97)
+|C10_97(x1: T97,x2: T97,x3: T97,x4: T97,x5: T97,x6: T97,x7: T97,x8: T97,x9: T97,x10: T97)
+T98 = C1_98(x1: T98,x2: T98,x3: T98,x4: T98,x5: T98,x6: T98,x7: T98,x8: T98,x9: T98,x10: T98)
+|C2_98(x1: T98,x2: T98,x3: T98,x4: T98,x5: T98,x6: T98,x7: T98,x8: T98,x9: T98,x10: T98)
+|C3_98(x1: T98,x2: T98,x3: T98,x4: T98,x5: T98,x6: T98,x7: T98,x8: T98,x9: T98,x10: T98)
+|C4_98(x1: T98,x2: T98,x3: T98,x4: T98,x5: T98,x6: T98,x7: T98,x8: T98,x9: T98,x10: T98)
+|C5_98(x1: T98,x2: T98,x3: T98,x4: T98,x5: T98,x6: T98,x7: T98,x8: T98,x9: T98,x10: T98)
+|C6_98(x1: T98,x2: T98,x3: T98,x4: T98,x5: T98,x6: T98,x7: T98,x8: T98,x9: T98,x10: T98)
+|C7_98(x1: T98,x2: T98,x3: T98,x4: T98,x5: T98,x6: T98,x7: T98,x8: T98,x9: T98,x10: T98)
+|C8_98(x1: T98,x2: T98,x3: T98,x4: T98,x5: T98,x6: T98,x7: T98,x8: T98,x9: T98,x10: T98)
+|C9_98(x1: T98,x2: T98,x3: T98,x4: T98,x5: T98,x6: T98,x7: T98,x8: T98,x9: T98,x10: T98)
+|C10_98(x1: T98,x2: T98,x3: T98,x4: T98,x5: T98,x6: T98,x7: T98,x8: T98,x9: T98,x10: T98)
+T99 = C1_99(x1: T99,x2: T99,x3: T99,x4: T99,x5: T99,x6: T99,x7: T99,x8: T99,x9: T99,x10: T99)
+|C2_99(x1: T99,x2: T99,x3: T99,x4: T99,x5: T99,x6: T99,x7: T99,x8: T99,x9: T99,x10: T99)
+|C3_99(x1: T99,x2: T99,x3: T99,x4: T99,x5: T99,x6: T99,x7: T99,x8: T99,x9: T99,x10: T99)
+|C4_99(x1: T99,x2: T99,x3: T99,x4: T99,x5: T99,x6: T99,x7: T99,x8: T99,x9: T99,x10: T99)
+|C5_99(x1: T99,x2: T99,x3: T99,x4: T99,x5: T99,x6: T99,x7: T99,x8: T99,x9: T99,x10: T99)
+|C6_99(x1: T99,x2: T99,x3: T99,x4: T99,x5: T99,x6: T99,x7: T99,x8: T99,x9: T99,x10: T99)
+|C7_99(x1: T99,x2: T99,x3: T99,x4: T99,x5: T99,x6: T99,x7: T99,x8: T99,x9: T99,x10: T99)
+|C8_99(x1: T99,x2: T99,x3: T99,x4: T99,x5: T99,x6: T99,x7: T99,x8: T99,x9: T99,x10: T99)
+|C9_99(x1: T99,x2: T99,x3: T99,x4: T99,x5: T99,x6: T99,x7: T99,x8: T99,x9: T99,x10: T99)
+|C10_99(x1: T99,x2: T99,x3: T99,x4: T99,x5: T99,x6: T99,x7: T99,x8: T99,x9: T99,x10: T99)
+T100 = C1_100(x1: T100,x2: T100,x3: T100,x4: T100,x5: T100,x6: T100,x7: T100,x8: T100,x9: T100,x10: T100)
+|C2_100(x1: T100,x2: T100,x3: T100,x4: T100,x5: T100,x6: T100,x7: T100,x8: T100,x9: T100,x10: T100)
+|C3_100(x1: T100,x2: T100,x3: T100,x4: T100,x5: T100,x6: T100,x7: T100,x8: T100,x9: T100,x10: T100)
+|C4_100(x1: T100,x2: T100,x3: T100,x4: T100,x5: T100,x6: T100,x7: T100,x8: T100,x9: T100,x10: T100)
+|C5_100(x1: T100,x2: T100,x3: T100,x4: T100,x5: T100,x6: T100,x7: T100,x8: T100,x9: T100,x10: T100)
+|C6_100(x1: T100,x2: T100,x3: T100,x4: T100,x5: T100,x6: T100,x7: T100,x8: T100,x9: T100,x10: T100)
+|C7_100(x1: T100,x2: T100,x3: T100,x4: T100,x5: T100,x6: T100,x7: T100,x8: T100,x9: T100,x10: T100)
+|C8_100(x1: T100,x2: T100,x3: T100,x4: T100,x5: T100,x6: T100,x7: T100,x8: T100,x9: T100,x10: T100)
+|C9_100(x1: T100,x2: T100,x3: T100,x4: T100,x5: T100,x6: T100,x7: T100,x8: T100,x9: T100,x10: T100)
+|C10_100(x1: T100,x2: T100,x3: T100,x4: T100,x5: T100,x6: T100,x7: T100,x8: T100,x9: T100,x10: T100)
diff --git a/examples/example.gom b/examples/example.gom
new file mode 100644
--- /dev/null
+++ b/examples/example.gom
@@ -0,0 +1,39 @@
+module Definition
+imports String int
+abstract syntax
+
+Input = Input(ctx: Context, cl: ConstraintList, t: Term, ty: Type)
+
+// comment
+
+Type = Atom(name: String)
+     | Composed(dom: TypeList, codom: Type)
+
+TypeList = TyList(Type*)
+
+Term = Var(name: /* comment */ String)
+     | Fun(name: String, args: TermList)
+
+TermList = TeList(Term*)
+
+Constraint = Subtype(type1: String, type2: String)
+
+ConstraintList = CList(Constraint*)
+
+Jugement = SigOf(name: String, sig: Type)
+
+Mapping = TypeOf(term: Term, sig: Type)
+   
+Context = Context(Jugement*)
+
+Statement = Statement1(name: String, path: PathTree, ctx: Context, consequence1: Mapping)
+          | Statement2(name: String, path: PathTree, ctx: Context, consequence2: Constraint)
+
+Tree = SList(Statement*)
+
+Label = Label(num: int)
+
+PathTree = PTree(Label*)
+
+Paths = Paths(PathTree*)
+
diff --git a/examples/many_errors.gom b/examples/many_errors.gom
new file mode 100644
--- /dev/null
+++ b/examples/many_errors.gom
@@ -0,0 +1,9 @@
+module Foo
+imports int String
+
+abstract syntax
+
+T = f(x:A,y:int) | g(z:B) | f(A*) | f(x:B,y:int) | g(x:A,y:String) | f(x:A,y:int) | f(x:A,y:int)  | h(x:A,x:A)
+String = a() | b(w:A) | c(w:B,z:A,w:B,z:A) | Emptyf() | Emptyl()
+T = a() | t() | l(A*) | Consf()
+
diff --git a/examples/simple.gom b/examples/simple.gom
new file mode 100644
--- /dev/null
+++ b/examples/simple.gom
@@ -0,0 +1,11 @@
+module Foo
+imports int String char
+abstract syntax
+
+T1 = f(x:T2,y:T1) | a(x:T2)
+T2 = g(x:T1,y:T2) | b()
+T3 = S(x:String)
+T4 = T(x:char)
+
+List = List(T1*)
+IList = iList(int*)
diff --git a/hgom.cabal b/hgom.cabal
new file mode 100644
--- /dev/null
+++ b/hgom.cabal
@@ -0,0 +1,72 @@
+name:           hgom
+version:        0.5.1
+author:         Paul Brauner and Emilie Balland
+maintainer:     Paul Brauner <paul.brauner@inria.fr>
+copyright:      (c) Paul Brauner 2009
+                (c) Emilie Balland 2009
+                (c) INRIA 2009
+homepage:       http://www.loria.fr/~brauner
+synopsis:       An haskell port of the java version of gom 
+description:
+  The executable hgom takes a module consisting of several abstract datatypes
+  declarations as an input and ouputs java classes. It is meant to mimic the java
+  version of Gom: <http://tom.loria.fr/wiki/index.php5/Documentation:Gom>.
+category:          Compilers
+license:           GPL
+license-file:      COPYING
+cabal-version:     >= 1.6.0
+build-type:        Simple
+tested-with:       GHC >= 6.10
+
+extra-source-files: examples/*.gom
+                    test/coverage/coverage.sh
+                    test/bench/bench.sh 
+                    test/bench/Gen.hs
+                    test/bench/Makefile
+                    README.markdown
+
+data-files: test/data/*.gom
+            test/data/*.jar
+
+Flag test
+  Description: enable test support
+  Default:     False
+
+executable hgom
+  main-is:       Gom.hs
+  other-modules: Gom.Config,
+                 Gom.Parser,
+                 Gom.Checker,
+                 Gom.Pretty,
+                 Gom.FileGen,
+                 Gom.CodeGen,
+                 Gom.OOMappingGen,
+                 Gom.CodeGen.Common,
+                 Gom.CodeGen.Common.Constants,
+                 Gom.CodeGen.Common.Builtins,
+                 Gom.CodeGen.Common.Helpers,
+                 Gom.CodeGen.Common.GenMonad,
+                 Gom.CodeGen.Abstract,
+                 Gom.CodeGen.Constructors,
+                 Gom.CodeGen.Mappings,
+                 Gom.CodeGen.Strategies,
+                 Gom.CodeGen.Sorts,
+                 Gom.SymbolTable,
+                 Gom.Sig, 
+                 Paths_hgom
+  build-depends: base >= 4 && < 5, containers >= 0.2,
+                 parsec >= 3.0.0, wl-pprint >= 1.0,
+                 mtl >= 1.1.0.2, directory >= 1.0.0.2,
+                 filepath >= 1.1.0.2
+  extensions:    CPP
+  ghc-options:   -Wall -fno-warn-orphans
+
+  if flag(test)
+    cpp-options:   -DTEST
+    build-depends: QuickCheck >= 2, test-framework >= 0.2.4, 
+                   test-framework-quickcheck2 >= 0.2.5,
+                   test-framework-hunit >= 0.2.4, Glob >= 0.5,
+                   HUnit >= 1.2.2.1, process >= 1.0.1.1
+                   
+    other-modules: Gom.UnitTests, Gom.Random
+
diff --git a/test/bench/Gen.hs b/test/bench/Gen.hs
new file mode 100644
--- /dev/null
+++ b/test/bench/Gen.hs
@@ -0,0 +1,13 @@
+import System.Environment
+import Data.List
+
+field i n = "x" ++ show i ++ ": T" ++ show n
+fields n = intercalate "," [field i n | i <- [1..10]]
+constr i n = "C" ++ show i ++ "_" ++ show n ++ "(" ++ fields n ++ ")"
+constrs n = intercalate "\n|" [constr i n | i <- [1..10]]
+ty n = "T" ++ show n ++ " = " ++ constrs n
+tys n = intercalate "\n" [ty i | i <- [1..n]]
+modul n = "module big\nabstract syntax\n" ++ tys n
+
+main = do [n] <- getArgs
+          putStrLn $ modul (read n)
diff --git a/test/bench/Makefile b/test/bench/Makefile
new file mode 100644
--- /dev/null
+++ b/test/bench/Makefile
@@ -0,0 +1,11 @@
+all: Gen
+	./bench.sh
+
+Gen: Gen.hs
+	ghc --make -O Gen
+
+clean:
+	rm -f Gen.hi Gen.o Gen
+	rm -rf big
+	rm -rf big.gom
+	rm -f *.data
diff --git a/test/bench/bench.sh b/test/bench/bench.sh
new file mode 100644
--- /dev/null
+++ b/test/bench/bench.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+rm -rf big
+rm -f big.gom
+rm -f time_ratio.data space_ratio.data
+
+for i in `seq 1 1000`; do
+  ./Gen $i > big.gom
+  t1=`/usr/bin/time -f '%e' hgom big.gom 2>&1`
+  s1=`sloccount big | grep 'java:' | awk '{print $2}'`
+  rm -rf big
+  t2=`/usr/bin/time -f '%e' gom big.gom 2>&1`
+  s2=`sloccount big | grep 'java:' | awk '{print $2}'`
+  rm -rf big
+  rm big.gom
+  t=`echo "$t2/$t1" | bc -l`
+  s=`echo "$s2/$s1" | bc -l`
+  echo $t >> time_ratio.data
+  echo $s >> space_ratio.data
+done
diff --git a/test/coverage/coverage.sh b/test/coverage/coverage.sh
new file mode 100644
--- /dev/null
+++ b/test/coverage/coverage.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+HGOM=../../dist/build/hgom/hgom
+DATA=../data
+
+for i in $DATA/t*.gom; do
+  $HGOM $i
+done 
+
+$HGOM --help
+$HGOM -P $DATA/t1_1.gom 
+$HGOM -P $DATA/t1_5.gom 
+$HGOM -c no $DATA/t1_1.gom 
+$HGOM -c sep $DATA/t1_1.gom 
+$HGOM -c same $DATA/t1_1.gom 
+$HGOM -c foo $DATA/t1_1.gom 
+$HGOM -j $DATA/t1_1.gom 
+$HGOM -j -p aa.bb.cc $DATA/t1_5.gom 
+$HGOM -j -p aa.bb.cc $DATA/t1_1.gom 
+$HGOM -h $DATA/t1_1.gom 
+$HGOM --test 5 $DATA/t1_1.gom 
+$HGOM --compact $DATA/t1_1.gom 
+$HGOM --random $DATA/t1_1.gom 
+$HGOM --size $DATA/t1_1.gom 
+$HGOM --depth $DATA/t1_1.gom 
+$HGOM --noVisitable $DATA/t1_1.gom
+$HGOM --noSharing $DATA/t1_1.gom
+$HGOM --noCheck $DATA/t1_1.gom
+$HGOM --noParsers $DATA/t1_1.gom
+$HGOM -p aa.bb.cc $DATA/t1_1.gom 
+$HGOM -V
+$HGOM aa -p 
+$HGOM
+$HGOM aa bb
+
+hpc markup --srcdir=../.. --destdir=html hgom.tix 
+
+rm -rf hgom.tix foo aa
diff --git a/test/data/t1_1.gom b/test/data/t1_1.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t1_1.gom
@@ -0,0 +1,14 @@
+/* valid */
+
+module Foo
+imports int String char
+abstract syntax
+
+T1 = f(x:T2,y:T1) | a(x:T2)
+T2 = g(x:T1,y:T2) | b()
+T3 = S(x:String)
+T4 = T(x:char)
+
+List = List(T1*)
+IList = iList(int*)
+IList2 = iList21(int*) | iList22(int*)
diff --git a/test/data/t1_2.gom b/test/data/t1_2.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t1_2.gom
@@ -0,0 +1,10 @@
+/* valid */
+
+module Foo
+imports
+abstract syntax
+
+T1 = F(x:T2,y:T1) | A(x:T2)
+T2 = G(x:T1,y:T2) | B()
+
+List = List(T1*)
diff --git a/test/data/t1_3.gom b/test/data/t1_3.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t1_3.gom
@@ -0,0 +1,5 @@
+module Foo
+imports T2
+abstract syntax
+
+T1 = f(x:T2,y:T1) |a()
diff --git a/test/data/t1_4.gom b/test/data/t1_4.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t1_4.gom
@@ -0,0 +1,11 @@
+module Foo
+imports int String char boolean double long float
+abstract syntax
+
+T1 = f(x:T2,y:T1) | a(x:T2)
+T2 = g(x:T1,y:T2) | b()
+T3 = S(x:String)
+T4 = T(x:float,y:boolean,z:double,w:long)
+
+List = List(T1*)
+IList = iList(int*)
diff --git a/test/data/t1_5.gom b/test/data/t1_5.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t1_5.gom
@@ -0,0 +1,12 @@
+module Foo
+imports int String char
+abstract syntax
+
+T1 implemented by Object = f(x:T2,y:T1) | a(x:T2)
+T2 implemented by Object = g(x:T1,y:T2) | b()
+T3 implemented by Map<Int,Int> = S(x:String)
+T4 implemented by java.lang.Object = T(x:char)
+
+List implemented by Object = List(T1*)
+IList implemented by Object = iList(int*)
+IList2 implemented by Object = iList21(int*) | iList22(int*)
diff --git a/test/data/t1_6.gom b/test/data/t1_6.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t1_6.gom
@@ -0,0 +1,3 @@
+module Foo
+imports int char
+abstract syntax
diff --git a/test/data/t2_0.gom b/test/data/t2_0.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t2_0.gom
@@ -0,0 +1,8 @@
+// two different errors to cover linebreak in error display
+
+module Foo
+imports int String
+
+abstract syntax
+
+T = foo(x:A)
diff --git a/test/data/t2_1.gom b/test/data/t2_1.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t2_1.gom
@@ -0,0 +1,8 @@
+/* invalid: ctor/module clash */
+
+module Foo
+imports int String
+
+abstract syntax
+
+T = foo()
diff --git a/test/data/t2_2.gom b/test/data/t2_2.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t2_2.gom
@@ -0,0 +1,8 @@
+/* invalid: String declared twice */
+
+module Foo
+imports int String
+
+abstract syntax
+
+String = a() 
diff --git a/test/data/t2_3.gom b/test/data/t2_3.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t2_3.gom
@@ -0,0 +1,9 @@
+/* invalid: a declared twice */
+
+module Foo
+imports int String
+
+abstract syntax
+
+T1 = a()
+T2 = a()
diff --git a/test/data/t2_4.gom b/test/data/t2_4.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t2_4.gom
@@ -0,0 +1,8 @@
+/* invalid: two fields with the same name */
+
+module Foo
+imports int String
+
+abstract syntax
+
+T = h(x:T,x:T)
diff --git a/test/data/t2_5.gom b/test/data/t2_5.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t2_5.gom
@@ -0,0 +1,8 @@
+/* invalid: same field with two different sorts */
+
+module Foo
+imports int String
+
+abstract syntax
+
+T = f(x:int) | g(x:T)
diff --git a/test/data/t2_6.gom b/test/data/t2_6.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t2_6.gom
@@ -0,0 +1,8 @@
+/* A and B not declared */
+
+module Foo
+imports int String
+
+abstract syntax
+
+T = f(x:A,y:B) 
diff --git a/test/data/t2_7.gom b/test/data/t2_7.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t2_7.gom
@@ -0,0 +1,9 @@
+/* clash between Emptyf, Consf and f */
+
+module Foo
+imports int String
+
+abstract syntax
+
+T1 = Emptyf() | Consf()
+T2 = f(int*)
diff --git a/test/data/t2_8.gom b/test/data/t2_8.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t2_8.gom
@@ -0,0 +1,6 @@
+/* invalid: T2 not declared */
+
+module Foo
+abstract syntax
+
+T1 = f(x:T2,y:T1) |a()
diff --git a/test/data/t2_9.gom b/test/data/t2_9.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t2_9.gom
@@ -0,0 +1,9 @@
+/* invalid: 
+ * Int, while and public clash with keywords */
+
+module for
+abstract syntax
+
+INt = a()
+B = while()
+C = f(public:B)
diff --git a/test/data/t3_1.gom b/test/data/t3_1.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t3_1.gom
@@ -0,0 +1,13 @@
+/* invalid syntax: lacks 'module' */
+
+Foo
+imports int String char
+abstract syntax
+
+T1 = f(x:T2,y:T1) | a(x:T2)
+T2 = g(x:T1,y:T2) | b()
+T3 = S(x:String)
+T4 = T(x:char)
+
+List = List(T1*)
+IList = iList(int*)
diff --git a/test/data/t3_2.gom b/test/data/t3_2.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t3_2.gom
@@ -0,0 +1,14 @@
+/* invalid syntax:
+ * lacks 'imports' */
+
+module Foo
+int String char
+abstract syntax
+
+T1 = f(x:T2,y:T1) | a(x:T2)
+T2 = g(x:T1,y:T2) | b()
+T3 = S(x:String)
+T4 = T(x:char)
+
+List = List(T1*)
+IList = iList(int*)
diff --git a/test/data/t3_3.gom b/test/data/t3_3.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t3_3.gom
@@ -0,0 +1,14 @@
+/* ivalid syntax:
+ * lacks 'abstract syntax' */
+
+module Foo
+imports int String char
+
+
+T1 = f(x:T2,y:T1) | a(x:T2)
+T2 = g(x:T1,y:T2) | b()
+T3 = S(x:String)
+T4 = T(x:char)
+
+List = List(T1*)
+IList = iList(int*)
diff --git a/test/data/t3_4.gom b/test/data/t3_4.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t3_4.gom
@@ -0,0 +1,14 @@
+/* invalid syntax 
+ * waits for a sort declaration */
+
+module Foo
+imports int String char
+abstract syntax
+
+:T2,y:T1) | a(x:T2)
+T2 = g(x:T1,y:T2) | b()
+T3 = S(x:String)
+T4 = T(x:char)
+
+List = List(T1*)
+IList = iList(int*)
diff --git a/test/data/t3_5.gom b/test/data/t3_5.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t3_5.gom
@@ -0,0 +1,14 @@
+/* invalid syntax:
+ * waits for a field declaration */
+
+module Foo
+imports int String char
+abstract syntax
+
+T1 = f(,y:T1) | a(x:T2)
+T2 = g(x:T1,y:T2) | b()
+T3 = S(x:String)
+T4 = T(x:char)
+
+List = List(T1*)
+IList = iList(int*)
diff --git a/test/data/t3_6.gom b/test/data/t3_6.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t3_6.gom
@@ -0,0 +1,8 @@
+/* invalid syntax:
+ * waits for a constructor declaration */
+
+module Foo
+imports int String char
+abstract syntax
+
+T1 = f(x:T2,y:T1) |
diff --git a/test/data/t3_7.gom b/test/data/t3_7.gom
new file mode 100644
--- /dev/null
+++ b/test/data/t3_7.gom
@@ -0,0 +1,8 @@
+/* invalid syntax:
+ * waits for a class id */
+
+module Foo
+imports int String char
+abstract syntax
+
+T implemented by = a()
diff --git a/test/data/tom-runtime-full.jar b/test/data/tom-runtime-full.jar
new file mode 100644
# file too large to diff: test/data/tom-runtime-full.jar
