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/Control/Hmk.lhs b/Control/Hmk.lhs
new file mode 100644
--- /dev/null
+++ b/Control/Hmk.lhs
@@ -0,0 +1,140 @@
+
+2007 Sep 15
+
+The author disclaims copyright to this source. In place of a legal
+notice, here is a blessing:
+
+   May you do good and not evil.
+   May you find forgiveness for yourself and forgive others.
+   May you share freely, never taking more than you give.
+
+(after the sqlite source code)
+
+--
+
+A Haskell implementation of the plan9 mk program. This can be used as
+a standalone program or as a library, for convenience.
+
+> module Control.Hmk ( module Control.Hmk.Analyze
+>                    , mk
+>                    , Cmp, Rule(..), Task
+>                    , Schedule, Result(..) ) where
+>
+> import Control.Hmk.Analyze
+> import Control.Applicative
+> import Control.Monad.State
+> import Control.Monad.Reader
+> import Data.List (find)
+> import qualified Data.Set as Set
+
+Hmk manages dependencies between entities. These dependencies are
+specified by means of rules, establishing a dependency between the
+target and prerequesites. Rules also package a means of comparing
+targets and prerequisites to determine whether the target is out of
+date.
+
+> type Cmp m a = a -> a -> m Bool
+> data Rule m a = Rule { target :: a
+>                      , prereqs :: [a]
+>                      , recipe :: Maybe ([a] -> Task m)
+>                      , isStale :: Cmp m a }
+>
+> instance Show a => Show (Rule m a) where
+>     show rule = "Rule " ++ show (target rule) ++ " " ++ show (prereqs rule)
+
+The rules induce a dependency graph. It is from this dependency graph
+that we will compute a schedule, ie a list of tasks.
+
+> type DepGraph m a = [Tree m a]
+> data Tree m a = Node a (DepGraph m a) (Rule m a)
+>                 deriving Show
+>
+> data Result = TaskSuccess | TaskFailure
+>               deriving (Eq, Show)
+> type Task m = m Result
+> type Schedule m = [Task m]
+
+Here's how we construct one, with the given set of targets as the
+roots of the DAG. The dependency graph is represented as a forest.
+This is the natural representation in a functional language. We could
+of course use adjacency lists or matrices, but that would only
+complicate the code for essentially no gain, and perhaps even a
+performance hit.
+
+One could consider the forest constructed hither as the reification of
+control induced by the graph structure. One could argue that a tree is
+wasteful but it is always possible to build it with sharing of
+subtrees, even if the sharing cannot be observed. But we dispense with
+this sophistication, trusting instead that the garbage collector will
+work hard enough that only the current path down the tree is in memory
+while traversing it.
+
+Invariant 1: The targets in each rule should not appear as targets in
+any other rules.
+
+Invariant 2: The induced graph must be acyclic.
+
+Invariant 3: every prerequisite should be the target of some rule.
+
+> depgraph :: Ord a => [Rule m a] -> [a] -> DepGraph m a
+> depgraph rules targets = runReader (mapM aux targets) Set.empty where
+>     aux x = do
+>       visited <- ask
+>       if x `Set.member` visited then
+>          error "Cycle detected." else
+>           case find (\r -> target r == x) rules of
+>             Just rule -> mdo
+>               let n = Node x ps rule
+>               ps <- local (Set.insert x) $ mapM aux (prereqs rule)
+>               return n
+>             Nothing -> error "Invariant 3 violated."
+
+From the mk(1) manual:
+
+"A target is considered up to date if it has no prerequisites or if
+all its prerequisites are up to date and it is newer than all its
+prerequisites. Once the recipe for a target has executed, the target
+is considered up to date."
+
+So let's remove all those targets that are up to date. We detect
+targets that do not exist by comparing them with themselves with the
+isStale function of the rule.
+
+> prune :: (Applicative m, Monad m) => DepGraph m a -> m (DepGraph m a)
+> prune = foldM aux [] where
+>     aux gr (Node x ps rule) = do
+>       ps' <- prune ps
+>       if null ps' then
+>          do ood <- or <$> mapM (isStale rule x) (x : prereqs rule)
+>             if ood then
+>                return $ Node x ps' rule : gr else
+>                return gr
+>          else return $ Node x ps' rule : gr
+
+Given a dependency graph take the longest path to each out of date
+dependency and execute recipes in reverse order. Schedule recipes for
+execution at most once. This can be done with a simple topological
+sort because at this stage the graph now contains exactly those nodes
+that need to be built.
+
+> schedule :: Ord a => DepGraph m a -> Schedule m
+> schedule gr = reverse $ evalState (foldM aux [] gr) Set.empty where
+>     aux result (Node x ps rule) = do
+>       visited <- get
+>       if x `Set.member` visited then
+>          return result else
+>          do put (Set.insert x visited)
+>             tasks <- foldM aux result ps
+>             return $ maybe tasks ((:tasks) . ($ prereqs rule)) (recipe rule)
+
+Let's piece everything together.
+
+> mk :: (Ord a, Applicative m, Monad m) => [Rule m a] -> [a] -> m (Schedule m)
+> mk rules targets = schedule <$> (prune $ depgraph rules targets)
+
+** Tests **
+
+> rl x ps = Rule x ps (Just (\_ -> putStrLn (show x) >> return TaskSuccess))
+>           (\_ _ -> return True)
+> t1 = [rl 1 [2,3], rl 2 [4], rl 3 [4], rl 4 []]
+> t2 = [rl 1 [2,3], rl 2 [4], rl 3 [4], rl 4 [6,5], rl 5 [], rl 6 [5]]
diff --git a/Control/Hmk/Analyze.lhs b/Control/Hmk/Analyze.lhs
new file mode 100644
--- /dev/null
+++ b/Control/Hmk/Analyze.lhs
@@ -0,0 +1,75 @@
+
+2009 Apr 15
+
+The author disclaims copyright to this source. In place of a legal
+notice, here is a blessing:
+
+   May you do good and not evil.
+   May you find forgiveness for yourself and forgive others.
+   May you share freely, never taking more than you give.
+
+(after the sqlite source code)
+
+--
+
+Rule coalescing, rule completion and ambiguity checking.
+
+> module Control.Hmk.Analyze (coalesce, complete, process) where
+> import {-# SOURCE #-} Control.Hmk
+> import Data.List (sortBy)
+> import Data.Maybe (isNothing)
+> import qualified Data.Set as Set
+
+From the mk(1) man page:
+
+"A later rule may modify or override an existing rule under the
+following conditions:
+
+ - If the targets of the rules exactly match and one rule contains
+only a prerequisite clause and no recipe, the clause is added to the
+prerequisites of the other rule. If either or both targets are
+virtual, the recipe is always executed.
+
+ - If the targets of the rules match exactly and the prerequisites do
+not match and both rules contain recipes, mk reports an ``ambiguous
+recipe'' error.
+
+ - If the target and prerequisites of both rules match exactly, the
+second rule overrides the first."
+
+> coalesce :: Ord a => [Rule m a] -> [Rule m a]
+> coalesce = aux . sortBy cmp
+>     where aux (r:rs@(r':_))
+>               | target r == target r', isNothing (recipe r) =
+>                   r'{prereqs = prereqs r' ++ prereqs r} : aux rs
+>               | target r == target r', prereqs r == prereqs r' =
+>                   aux rs
+>               | target r == target r' =
+>                   error "Ambiguous rules."
+>               | otherwise = r : aux rs
+>           aux rs = rs
+>           cmp x y = case compare (target x) (target y) of
+>                       EQ -> maybe LT (const GT) (recipe x)
+>                       x -> x
+
+For simplicity, we assume as invariant that for all prerequisites p in
+every rule there exists a rule whose target is p. 'complete' adds new
+rules if necessary to achieve this invariant.
+
+> complete :: (Ord a, Show a) =>
+>             Cmp m a    -- ^ The default comparison operation.
+>          -> [Rule m a]
+>          -> [Rule m a]
+> complete cmp rules = let targets = Set.fromList (map target rules)
+>                          prereqss = Set.unions $
+>                                     map (Set.fromList . prereqs) rules
+>                          mkrule p rules | Set.member p targets = rules
+>                                         | otherwise =
+>                                             Rule p [] (err p) cmp : rules
+>                      in Set.fold mkrule [] prereqss ++ rules
+>     where err p = error $ "Don't know how to build " ++ show p ++ "."
+
+Putting everything together:
+
+> process :: (Ord a, Show a) => Cmp m a -> [Rule m a] -> [Rule m a]
+> process cmp = complete cmp . coalesce
diff --git a/Control/Hmk/IO.lhs b/Control/Hmk/IO.lhs
new file mode 100644
--- /dev/null
+++ b/Control/Hmk/IO.lhs
@@ -0,0 +1,54 @@
+
+2009 Apr 19
+
+The author disclaims copyright to this source. In place of a legal
+notice, here is a blessing:
+
+   May you do good and not evil.
+   May you find forgiveness for yourself and forgive others.
+   May you share freely, never taking more than you give.
+
+(after the sqlite source code)
+
+--
+
+Construct rules with recipes and other actions in the IO monad.
+Staleness of targets determined according to stat(2) system call, or
+using user-defined comparison functions in the IO monad.
+
+This module should be imported qualified.
+
+> module Control.Hmk.IO where
+> import Control.Hmk hiding (isStale)
+> import Control.Monad (foldM)
+> import System.FilePath
+> import System.Posix.Files
+> import System.Exit
+
+Staleness check.
+
+> isStale :: Cmp IO FilePath
+> isStale x y = do
+>   xe <- fileExist x
+>   ye <- fileExist x
+>   if not (xe && ye) then
+>       return True else
+>       do xstat <- getFileStatus x
+>          ystat <- getFileStatus y
+>          let xtime = modificationTime xstat
+>              ytime = modificationTime ystat
+>          return (xtime < ytime)
+
+Project exit code to task result.
+
+> testExitCode :: ExitCode -> IO Result
+> testExitCode ExitSuccess = return TaskSuccess
+> testExitCode (ExitFailure _) = return TaskFailure
+
+Perform each system action, aborting if an action returns
+non-zero exit code.
+
+> abortOnError :: [IO Result] -> IO Result
+> abortOnError = foldM f TaskSuccess where
+>     f TaskSuccess k = k
+>     f TaskFailure _ = error "Command exited with non-zero status."
diff --git a/Eval.lhs b/Eval.lhs
new file mode 100644
--- /dev/null
+++ b/Eval.lhs
@@ -0,0 +1,252 @@
+Copyright (C) 2009 Mathieu Boespflug <mboes@tweag.net>
+
+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/>.
+
+> module Eval (Target(..), eval, evalNoMeta, Eval.isStale, substituteStem) where
+>
+> import Parse
+> import Control.Hmk
+> import qualified Control.Hmk.IO as IO
+>
+> import Data.Sequence (Seq)
+> import qualified Data.Sequence as Seq
+> import qualified Data.Traversable as Seq
+> import qualified Data.Foldable as Seq
+> import qualified Data.Map as Map
+> import qualified Data.Foldable as Map
+> import qualified Data.Set as Set
+> import Control.Applicative
+> import Control.Monad.State
+> import Control.Monad.Writer
+> import Data.List (intercalate)
+> import Data.Maybe (isNothing)
+>
+> import System.IO
+> import System.Directory
+> import System.Exit
+> import System.Process
+> import System.Posix.Env
+> import System.Posix.Process (getProcessID)
+
+Default shell to pass recipes to. The shell used should understand the -e and
+-x switches, which means stop executing on first non-zero exit status and
+trace execution, respectively.
+
+> defaultShell = "/bin/sh"
+
+> instance Monad m => Applicative (StateT s m) where
+>     pure = return
+>     (<*>) = ap
+>
+> instance (Monoid w, Monad m) => Applicative (WriterT w m) where
+>     pure = return
+>     (<*>) = ap
+
+Targets are either regular files, virtual or patterns. After instantiation of
+meta-rules the patterns disappear, leaving only files and virtual targets. But
+it cannot be known until after evaluation of all rules whether a target is
+virtual or not. However, thanks to lazy evaluation, we can lookup wether a
+target is virtual or not now, if we promise to build it later.
+
+> data Target = File { name :: FilePath }
+>             | Virtual { name :: String }
+>             | Pattern { name :: String }
+>               deriving Show
+
+> newtype RevAppend a = RevAppend a
+>
+> instance Monoid a => Monoid (RevAppend a) where
+>     mempty = RevAppend mempty
+>     mappend (RevAppend x) (RevAppend y) = RevAppend (mappend y x)
+
+Only the name of targets matters when comparing them, so we make equality into
+an equivalence relation rather than the default structural equality.
+
+> instance Eq Target where
+>     x == y = name x == name y
+>
+> instance Ord Target where
+>     compare x y = compare (name x) (name y)
+
+Variable references are substituted for their values, using the environment.
+
+A list of tokens can be spliced, appended to, etc, to form a new list of
+tokens. Freezing means turning a list of tokens into a string, which cannot be
+manipulated any further. This string representation is used to export values
+to the outside world, such as the system environment.
+
+> freeze :: Seq String -> String
+> freeze = intercalate " " . Seq.toList
+
+The environment is a variable store that can be updated in place. It is very
+much not a persistent abstraction. We implement it using an internal map
+rather than using the system environment directly because using the system
+environment would require retokenizing values when we look them up. The
+content of this internal map is immediately reflected into the system
+environment, however, because assignments that are exported need to be
+available to subprocesses forked during sourcing and piping.
+
+Evaluation substitutes values for all variable references, using the system
+environment as a variable store. Assignments are executed first, then PRule's
+are evaluated to Rule's, the data structure for rules used by Control.Hmk. The
+return value is a sequence of functions mapping stems to rules. This is
+because stems are synthesized as a by-product of meta-rule instantiaton, but
+this instantiation is performed post evaluation.
+
+> type Stem = String
+>
+> addVariable attr var val = do
+>   modify (Map.insert var (val :: Seq String))
+>   case attr of
+>     Export -> liftIO $ setEnv var (freeze val) True
+>     Local -> return ()
+>
+> lookupVariable var = Map.findWithDefault (Seq.empty) var <$> get
+>
+> evalToken (Lit x) = return (Seq.singleton x)
+> evalToken (Coll toks) = Seq.singleton <$> Seq.concat <$>
+>                         Seq.mapM ((f <$>) . evalToken) toks
+>     where f ls | Seq.length ls == 1 = Seq.index ls 0
+>                | otherwise = error "Cannot collate lists."
+> evalToken (Ref tok) = do
+>                var <- evalToken tok
+>                lookupVariable (freeze var)
+>
+> eval :: Mkfile -> IO (Seq (Stem -> Rule IO Target))
+> eval mkfile = evalStateT (init >> go) Map.empty
+>     where init = addVariable Export "MKSHELL" (Seq.singleton defaultShell)
+>           go = mdo (rules, RevAppend virtuals) <- runWriterT (eval' virtuals mkfile)
+>                    return rules
+>
+> eval' virtuals (Mkrule ts flags ps r cont) = do
+>   let tag t = if t `elem` virtuals
+>               then Virtual t
+>               else case t of
+>                      '%':_ -> Pattern t
+>                      _ -> File t
+>   tsv <- Seq.msum <$> Seq.mapM evalToken ts
+>   psv <- fmap tag <$> Seq.msum <$> Seq.mapM evalToken ps
+>   flagsv <- evalFlags flags
+>   shell <- (`Seq.index` 0) <$> lookupVariable "MKSHELL"
+>   let f tv stem = let t | Set.member Flag_V flagsv = Virtual tv
+>                         | '%':_ <- tv              = Pattern tv
+>                         | otherwise                = File tv
+>                       rv = if Set.member Flag_N flagsv && isNothing r
+>                            then Just $ evalRecipe tsv t flagsv psv stem shell ("touch " ++ name t)
+>                            else fmap (evalRecipe tsv t flagsv psv stem shell) r
+>                       cmp = Set.fold (\x cmp -> case x of
+>                                                   Flag_P cmp -> evalCompare cmp
+>                                                   _ -> cmp) Eval.isStale flagsv
+>                   in if Set.member Flag_V flagsv
+>                      then Rule t (Seq.toList psv) rv (\_ _ -> return True)
+>                      else Rule t (Seq.toList psv) rv cmp
+>   when (Set.member Flag_V flagsv) (Seq.mapM_ (tell . RevAppend . return) tsv)
+>   (Seq.><) <$> pure (fmap f tsv) <*> eval' virtuals cont
+> eval' virtuals (Mkassign attr var val cont) = do
+>   -- xxx take into account attributes.
+>   lits <- Seq.msum <$> Seq.mapM evalToken val
+>   addVariable attr var lits
+>   eval' virtuals cont
+> eval' virtuals (Mkinsert file cont) = do
+>   filev <- evalToken file
+>   unless (Seq.length filev == 1)
+>              (error "Insertion must evaluate to a unique filename.")
+>   let fp = Seq.index filev 0
+>   (Seq.><) <$> (eval' virtuals =<< parse fp <$> liftIO (readFile fp)) <*> eval' virtuals cont
+> eval' virtuals (Mkinpipe command cont) = do
+>   commandv <- Seq.msum <$> Seq.mapM evalToken command
+>   when (Seq.length commandv == 0)
+>              (error "Command evaluated to empty string.")
+>   let (cmd:args) = Seq.toList commandv
+>   (_, Just outh, _, ph) <- liftIO $ createProcess (proc cmd args) { std_out = CreatePipe }
+>   result <- liftIO $ hGetContents outh
+>   code <- liftIO $ waitForProcess ph
+>   case code of
+>     ExitSuccess ->
+>         (Seq.><) <$> eval' virtuals (parse "<pipe>" result) <*> eval' virtuals cont
+>     ExitFailure n ->
+>         error $ "Sub-process " ++ cmd ++ " exited with error status " ++ show n ++ "."
+> eval' virtuals Mkeof = return Seq.empty
+
+A recipe is executed by supplying the recipe as standard input to the shell.
+(Note that unlike make, hmk feeds the entire recipe to the shell rather than
+running each line of the recipe separately.)
+
+> substituteStem stem (Pattern ('%':suffix)) = File (stem ++ suffix)
+> substituteStem stem x = x
+>
+> evalRecipe alltarget target flags prereq stem shell text newprereq = do
+>   pid <- show <$> getProcessID
+>   setEnv "alltarget" (freeze alltarget) True
+>   setEnv "newprereq" (intercalate " " (map (name . substituteStem stem) newprereq)) True
+>   setEnv "newmember" "" True -- xxx aggregates not supported.
+>   setEnv "nproc" (show 0) True
+>   setEnv "pid" pid True
+>   setEnv "prereq" (freeze (fmap (name . substituteStem stem) prereq)) True
+>   setEnv "stem" stem True
+>   setEnv "target" (name $ substituteStem stem $ target) True
+>   let p = if Set.member Flag_Q flags
+>           then proc shell ["-e"]
+>           else proc shell ["-ex"]
+>   (Just inh, _, _, ph) <- createProcess p { std_in = CreatePipe }
+>   hSetBinaryMode inh False
+>   hPutStrLn inh text
+>   hClose inh
+>   code <- waitForProcess ph >>= IO.testExitCode
+>   let final = if Set.member Flag_E flags
+>               then return TaskSuccess else return code :: IO Result
+>   let final' = if Set.member Flag_D flags
+>               then case code of
+>                        TaskFailure -> removeFile (name target) >> final
+>                        TaskSuccess -> final
+>               else final
+>   final'
+
+Parsing flags has to be done at evaluation time because we allow variable
+references in place of flag characters, for instance to programmatically turn
+on or off verbosity of rules, etc. The content of the flags field of a rule is
+necessarily either a collation or a literal.
+
+> evalFlags toks = do
+>   v <- Seq.msum <$> Seq.mapM evalToken toks
+>   return $ interp (freeze v)
+>     where interp "" = Set.empty
+>           interp ('D':xs) = Set.insert Flag_D (interp xs)
+>           interp ('E':xs) = Set.insert Flag_E (interp xs)
+>           interp ('N':xs) = Set.insert Flag_N (interp xs)
+>           interp ('n':xs) = Set.insert Flag_n (interp xs)
+>           interp ('P':xs) = Set.singleton (Flag_P xs)
+>           interp ('Q':xs) = Set.insert Flag_Q (interp xs)
+>           interp ('R':xs) = Set.insert Flag_R (interp xs)
+>           interp ('U':xs) = Set.insert Flag_U (interp xs)
+>           interp ('V':xs) = Set.insert Flag_V (interp xs)
+
+A user supplied comparison command is wrapped into an action in the IO monad.
+
+> evalCompare cmp (File x) (File y) = do
+>   code <- rawSystem cmp [x, y]
+>   case code of
+>       ExitSuccess -> return False
+>       ExitFailure _ -> return True
+
+The default comparison action.
+
+> isStale (File x) (File y) = IO.isStale x y
+> isStale (File x) (Virtual y) = return True
+> isStale _ _ = error "impossible."
+
+Version of eval where stems are instantiated to the empty string.
+
+> evalNoMeta :: Mkfile -> IO (Seq (Rule IO Target))
+> evalNoMeta mkfile = fmap ($ "") <$> eval mkfile
diff --git a/Main.lhs b/Main.lhs
new file mode 100644
--- /dev/null
+++ b/Main.lhs
@@ -0,0 +1,58 @@
+Copyright (C) 2009 Mathieu Boespflug <mboes@tweag.net>
+
+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/>.
+
+> module Main where
+
+This file brings together the various pieces that make up the hmk command. The
+core logic is in Control.Hmk. That module knows only rules, from which it can
+produce a schedule of recipes to run. Despite the name, it is the most generic
+part of the application.
+
+Rules may be generated by instantiating meta-rules, as often appears in
+mkfile's. Instantiation of meta-rules is done by the parser, with the help of
+the Metarule module. In fact most of the work is done by the parser, as it is
+also the parser's job to carry forward any variable substitutions.
+
+> import Control.Hmk
+> import Control.Hmk.Analyze
+> import Parse
+> import Eval
+> import Metarule
+> import Control.Monad
+> import Control.Applicative
+> import qualified Data.Sequence as Seq
+> import qualified Data.Foldable as Seq
+
+The exit code of the command is the exit code of the last recipe executed.
+
+> import System.IO
+> import System.Environment
+>
+>
+> main :: IO ()
+> main = do
+>   targets <- map File <$> getArgs
+>   metarules <- eval =<< parse "mkfile" <$> readFile "mkfile"
+>   let rules = process Eval.isStale $ Seq.toList $
+>               instantiateRecurse (Seq.fromList targets) metarules
+>   when (null rules) (fail "No rules in mkfile.")
+
+Per the mk man page, if no targets are specified on the command line, then
+assume the target is that of the first rule.
+
+>   schedule <- case targets of
+>               [] -> mk rules [target (head rules)]
+>               _  -> mk rules targets
+>   sequence_ schedule
diff --git a/Metarule.lhs b/Metarule.lhs
new file mode 100644
--- /dev/null
+++ b/Metarule.lhs
@@ -0,0 +1,83 @@
+Copyright (C) 2009 Mathieu Boespflug <mboes@tweag.net>
+
+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/>.
+
+> module Metarule (instantiate, instantiateRecurse) where
+>
+> import Control.Hmk
+> import Eval
+>
+> import Data.Sequence (Seq)
+> import qualified Data.Sequence as Seq
+> import qualified Data.Foldable as Seq
+> import qualified Data.Set as Set
+> import Control.Applicative
+> import Control.Monad.State
+>
+> import Text.Regex.PCRE.Light.Char8
+
+Remove any uninstantiated meta-rule.
+
+> cleanup :: Seq (Rule a Target) -> Seq (Rule a Target)
+> cleanup = Seq.foldr f Seq.empty where
+>     f r rs = case target r of
+>                Pattern _ -> rs
+>                _ -> r Seq.<| rs
+
+Instantiation of meta-rules. 'instantiate' is a helper function for
+'instantiateRecurse', which instantiates meta-rules based on current targets
+and then recursively instantiates meta-rules with the prerequesites of the
+matching rules.
+
+> type Stem = String
+>
+> seqFilter :: (a -> Bool) -> Seq a -> Seq a
+> seqFilter f = Seq.foldr (\x xs -> if f x then x Seq.<| xs else xs) Seq.empty
+>
+> seqCatMaybes :: Seq (Maybe a) -> Seq a
+> seqCatMaybes = Seq.foldr (\x xs -> maybe xs (Seq.<| xs) x) Seq.empty
+>
+> instantiate :: Seq Target   -- ^ Targets.
+>             -> Seq (Stem -> Rule a Target)
+>             -> Seq (Rule a Target)
+> instantiate targets closures = join $ fmap f closures where
+>     f clo = let schema = target (clo undefined)
+>                 stems = collectMatches schema targets
+>             in fmap (\stem -> expand stem (clo stem)) stems
+>     collectMatches (Pattern ('%':suffix)) ts =
+>         let re = compile ("(.*)" ++ suffix ++ "$") [anchored, dollar_endonly]
+>         -- The prefix is in the captured sub-pattern at index 1.
+>         in seqCatMaybes (fmap (\t -> fmap (!! 1) (match re t [])) (fmap name ts))
+>     collectMatches s ts = Seq.empty
+>     -- Substitute the stem for the percent characters in targets and
+>     -- prerequesites.
+>     expand stem r@Rule{target,prereqs} = r { target = substituteStem stem target
+>                                            , prereqs = map (substituteStem stem) prereqs }
+>
+> instantiateRecurse :: Seq Target
+>                    -> Seq (Stem -> Rule a Target)
+>                    -> Seq (Rule a Target)
+> instantiateRecurse targets closures =
+>     let new = evalState (go targets) Set.empty
+>     in cleanup origrules Seq.>< new
+>     where origrules = fmap ($ "") closures
+>           go targets | Seq.null targets = return Seq.empty
+>                      | otherwise = do
+>             seen <- get
+>             let rules = instantiate targets closures
+>                 ts = (Set.\\ seen) $ Set.unions $ Seq.toList $
+>                      fmap (Set.fromList . prereqs) $
+>                      seqFilter (\r -> target r `Seq.elem` targets) origrules
+>             put (seen `Set.union` ts)
+>             (rules Seq.><) <$> go (Seq.fromList (Set.toList ts))
diff --git a/Parse.lhs b/Parse.lhs
new file mode 100644
--- /dev/null
+++ b/Parse.lhs
@@ -0,0 +1,203 @@
+Copyright (C) 2009 Mathieu Boespflug <mboes@tweag.net>
+
+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/>.
+
+> module Parse ( Token(..), Flag(..), Mkfile(..), AssignAttr(..), parse ) where
+
+Parse mkfile's to a set of rules. The following quoted comments in this source
+file are all excerpts from the man page for plan9's mk command, so are
+copyright Lucent Technologies.
+
+> import Text.Parsec hiding (parse, token)
+> import Data.List (intercalate)
+> import Data.Sequence (Seq)
+> import qualified Data.Sequence as Seq
+> import Control.Applicative hiding ((<|>), many)
+> import System.FilePath (FilePath)
+
+
+"A mkfile consists of assignments (described under `Environment') and rules. A
+rule contains targets and a tail. A target is a literal string and is normally
+a file name. The tail contains zero or more prerequisites and an optional
+recipe, which is an rc script. Each line of the recipe must begin with white
+space."
+
+An mkfile is carved out into lines, each of which is separated into tokens,
+which are either a literal or a reference. Reference names may themselves
+contain references and literals, so a reference name is a sequence of tokens.
+Tokens can be composed, as in 'a${b}c', a token made of 2 literals and 1
+reference.
+
+> data Token = Lit String
+>            | Coll (Seq Token)
+>            | Ref Token
+>              deriving Show
+>
+> data AssignAttr = Export | Local
+>                   deriving Show
+
+Rule flags, according to the mk manual for plan9:
+
+ status, the target is deleted.
+
+E : Continue execution if the recipe draws errors.
+
+N : If there is no recipe, the target has its time updated.
+
+n : The rule is a meta-rule that cannot be a target of a virtual rule.
+    Only files match the pattern in the target.
+
+P : The characters after the P until the terminating : are taken as a program
+    name. It will be invoked as $MKSHELL -c prog 'arg1' 'arg2' and should
+    return a zero exit status if and only if arg1 is up to date with respect
+    to arg2. Date stamps are still propagated in the normal way.
+
+Q : The recipe is not printed prior to execution.
+
+R : The rule is a meta-rule using regular expressions. In the rule, % has no
+    special meaning. The target is interpreted as a regular expression as
+    defined in regexp(7). The prerequisites may contain references to
+    subexpressions in form \n, as in the substitute command of sed(1).
+
+U : The targets are considered to have been updated even if the recipe
+    did not do so.
+
+V : The targets of this rule are marked as virtual. They are distinct
+    from files of the same name.
+
+> data Flag = Flag_D | Flag_E | Flag_N | Flag_n | Flag_P String
+>           | Flag_Q | Flag_R | Flag_U | Flag_V
+>             deriving (Eq, Ord, Show)
+>
+> data Mkfile = Mkrule (Seq Token)    -- targets
+>                      (Seq Token)  -- flags
+>                      (Seq Token)    -- prerequesites
+>                      (Maybe String) -- recipe
+>                      Mkfile
+>             | Mkassign AssignAttr String (Seq Token) Mkfile
+>             | Mkinsert Token Mkfile -- lines beginning with '<'
+>             | Mkinpipe (Seq Token) Mkfile -- lines beginning with '<|'
+>             | Mkeof
+
+Parsing produces unevaluated rules, represented by the PRule type. Evaluation
+takes values of this type as input to produce values of type Rule used in
+Control.Hmk. The parser also accumulates assignments by side-effect, that will
+be executed during evaluation.
+
+> parse :: FilePath -> String -> Mkfile
+> parse fp input =
+>     case runParser p_toplevel () fp input of
+>         Left e -> error (show e)
+>         Right x -> x
+
+Contrary to Plan9's mk, all ':' characters in prerequesites as well as in
+targets must be escaped. This is to simplify the implementation slightly.
+
+> token = reference
+>         <|> substitution
+>         <|> collation
+>
+> reference = (Ref <$> do
+>   char '$'
+>   -- $name or ${name} or ${name:A%B=C%D}
+>   name <|> bname) <?> "reference"
+>     -- banned characters from variable references according to rc(1) manual.
+>     where name = Lit <$> many1 (noneOf " \t\n#;&|^$=`'{}()<>:")
+>           bname = between (char '{') (char '}') collation
+>
+> substitution = (between (char '{') (char '}') $ do
+>                      a <- quotableTill "%"; char '%'
+>                      b <- quotableTill "="; char '='
+>                      c <- quotableTill "%"; char '%'
+>                      d <- quotableTill "}"
+>                      return (error "Unimplemented.")) -- xxx
+>                <?> "substitution"
+
+A literal or a collation of tokens.
+
+> collation = do
+>   x <- many1 (literal <|> reference)
+>   case x of
+>     [l] -> return l
+>     toks -> return $ Coll (Seq.fromList toks)
+>
+> literal = (Lit <$> quotableTill " \t\n:$") <?> "literal"
+
+"Special characters may be quoted using single quotes '' as in rc(1)."
+
+When parsing strings, we must allow for escaping of special characters using
+quotes. 'quotableTill' munches characters until a character in the terminal
+set is reached, dealing with quotes as appropriate. In a quoted string a quote
+is written as a pair ''.
+
+> quotableTill terminals = quoted <|> unquoted where
+>     end = return []
+>     unquoted = ((:) <$> noneOf terminals <*> (quoted <|> unquoted <|> end))
+>     quoted = do
+>       char '\''
+>       xs <- manyTill ((string "''" >> return '\'') <|> anyChar)
+>                      (try (char '\'' >> notFollowedBy (char '\'')))
+>       (++) <$> pure xs <*> (quoted <|> unquoted <|> end)
+
+Munch all whitespace on a line.
+
+> whitespace = skipMany (oneOf " \t")
+> indentation = skipMany1 (oneOf " \t")
+
+> p_toplevel = do
+>   many (newline <|> p_comment)
+>   p_inpipe <|> p_insert <|> p_assignment <|> p_rule <|> (Mkeof <$ eof)
+>
+> p_comment = char '#' <* manyTill anyChar newline
+
+" Assignments and rules are distinguished by the first unquoted occurrence of
+: (rule) or = (assignment)."
+
+> p_assignment = try (do
+>   var <- quotableTill " \t="
+>   char '='
+>   attr <- option Export p_assignment_attr
+>   value <- sepBy token whitespace
+>   newline
+>   return $ Mkassign attr var (Seq.fromList value)) <*> p_toplevel
+>
+> p_assignment_attr = try $ do
+>   c <- anyChar
+>   char '='
+>   case c of
+>     'U' -> return Local
+>     _ -> error "Unknown attribute."
+>
+> p_rule = do
+>   targets <- Seq.fromList <$> sepBy1 token whitespace
+>   whitespace
+>   char ':'
+>   flags <- option Seq.empty p_rule_flags
+>   whitespace
+>   prereqs <- Seq.fromList <$> sepBy token whitespace
+>   newline
+>   recipe <- p_recipe
+>   Mkrule targets flags prereqs recipe <$> p_toplevel
+>
+> p_rule_flags = try (Seq.fromList <$> sepBy1 token whitespace <* char ':')
+>
+> p_recipe = do
+>   lines <- collect
+>   if null lines then return Nothing else return $ Just $ intercalate "\n" lines
+>     where collect = (do indentation; (:) <$> (many (noneOf "\n") <* newline) <*> collect)
+>                     <|> return []
+>
+> p_inpipe = Mkinpipe <$> (try (string "<|") *> (Seq.fromList <$> sepBy1 token whitespace) <* newline) <*> p_toplevel
+>
+> p_insert = Mkinsert <$> (char '<' *> token <* newline) <*> p_toplevel
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,3 @@
+#!/usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMain
diff --git a/hmk.cabal b/hmk.cabal
new file mode 100644
--- /dev/null
+++ b/hmk.cabal
@@ -0,0 +1,42 @@
+name:           hmk
+version:        0.9
+author:         Mathieu Boespflug
+maintainer:     Mathieu Boespflug <mboes@tweag.net>
+homepage:       http://code.haskell.org/~mboes/hmk
+synopsis:       A make alternative based on Plan9's mk.
+description:
+        Clone of Plan9's mk command, said to have \"improved on make by
+        removing all the vowels from the name\".
+        .
+        The library exports a generic dependency graph traversal that
+        can be used independently of the rest.
+        .
+        The documentation is embedded in the literate Haskell source.
+        .
+        /Note:/ the library portion is released to the /public
+        domain/. Those source files that are not part of the library
+        are released under GPLv3 or later.
+category:       Distribution
+license:        GPL
+license-file:   COPYING
+copyright:      (c) 2008-2009. Mathieu Boespflug <mboes@tweag.net>
+cabal-version:  >= 1.2.0
+build-type:     Simple
+tested-with:    GHC ==6.10
+
+library
+    build-depends:   base < 5, containers
+    extensions:	     RecursiveDo, PatternGuards
+    exposed-modules: Control.Hmk
+                     Control.Hmk.Analyze
+                     Control.Hmk.IO
+
+executable hmk
+    main-is:         Main.lhs
+    ghc-options:     -fwarn-unused-imports
+    other-modules:   Parse, Eval, Metarule
+    extensions:	     RecursiveDo, PatternGuards, NamedFieldPuns
+    build-depends:   base < 5, bytestring, containers,
+                     directory, process, unix, filepath >= 1.1,
+                     mtl, parsec >= 3.0.0, pcre-light >= 0.3
+                     
